aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/crypto/api-intro.txt36
-rw-r--r--MAINTAINERS25
-rw-r--r--arch/i386/crypto/Makefile3
-rw-r--r--arch/i386/crypto/aes.c3
-rw-r--r--arch/i386/crypto/twofish-i586-asm.S335
-rw-r--r--arch/i386/crypto/twofish.c97
-rw-r--r--arch/powerpc/Kconfig14
-rw-r--r--arch/powerpc/Kconfig.debug16
-rw-r--r--arch/powerpc/boot/Makefile7
-rw-r--r--arch/powerpc/boot/dts/mpc8349emds.dts16
-rw-r--r--arch/powerpc/boot/flatdevtree.h46
-rw-r--r--arch/powerpc/boot/main.c250
-rw-r--r--arch/powerpc/boot/of.c (renamed from arch/powerpc/boot/prom.c)144
-rw-r--r--arch/powerpc/boot/ops.h100
-rw-r--r--arch/powerpc/boot/prom.h41
-rw-r--r--arch/powerpc/boot/stdio.c4
-rw-r--r--arch/powerpc/boot/stdio.h8
-rw-r--r--arch/powerpc/boot/types.h23
-rw-r--r--arch/powerpc/configs/maple_defconfig2
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c17
-rw-r--r--arch/powerpc/kernel/btext.c24
-rw-r--r--arch/powerpc/kernel/cpu_setup_ppc970.S (renamed from arch/powerpc/kernel/cpu_setup_power4.S)103
-rw-r--r--arch/powerpc/kernel/cputable.c21
-rw-r--r--arch/powerpc/kernel/crash_dump.c2
-rw-r--r--arch/powerpc/kernel/dma_64.c65
-rw-r--r--arch/powerpc/kernel/entry_64.S8
-rw-r--r--arch/powerpc/kernel/head_64.S54
-rw-r--r--arch/powerpc/kernel/ibmebus.c6
-rw-r--r--arch/powerpc/kernel/io.c131
-rw-r--r--arch/powerpc/kernel/irq.c5
-rw-r--r--arch/powerpc/kernel/legacy_serial.c35
-rw-r--r--arch/powerpc/kernel/lparcfg.c30
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c10
-rw-r--r--arch/powerpc/kernel/misc.S159
-rw-r--r--arch/powerpc/kernel/of_device.c24
-rw-r--r--arch/powerpc/kernel/paca.c15
-rw-r--r--arch/powerpc/kernel/pci_32.c39
-rw-r--r--arch/powerpc/kernel/pci_64.c67
-rw-r--r--arch/powerpc/kernel/pci_dn.c13
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c19
-rw-r--r--arch/powerpc/kernel/prom.c44
-rw-r--r--arch/powerpc/kernel/prom_init.c10
-rw-r--r--arch/powerpc/kernel/prom_parse.c90
-rw-r--r--arch/powerpc/kernel/rtas-proc.c25
-rw-r--r--arch/powerpc/kernel/rtas.c47
-rw-r--r--arch/powerpc/kernel/rtas_pci.c28
-rw-r--r--arch/powerpc/kernel/setup-common.c32
-rw-r--r--arch/powerpc/kernel/setup_64.c23
-rw-r--r--arch/powerpc/kernel/sysfs.c9
-rw-r--r--arch/powerpc/kernel/time.c8
-rw-r--r--arch/powerpc/kernel/traps.c25
-rw-r--r--arch/powerpc/kernel/vio.c16
-rw-r--r--arch/powerpc/lib/Makefile1
-rw-r--r--arch/powerpc/lib/e2a.c116
-rw-r--r--arch/powerpc/lib/locks.c27
-rw-r--r--arch/powerpc/mm/numa.c31
-rw-r--r--arch/powerpc/mm/slb.c37
-rw-r--r--arch/powerpc/mm/tlb_64.c1
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c4
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.c4
-rw-r--r--arch/powerpc/platforms/83xx/pci.c4
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c4
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c4
-rw-r--r--arch/powerpc/platforms/85xx/pci.c4
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c4
-rw-r--r--arch/powerpc/platforms/86xx/pci.c4
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.c8
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c25
-rw-r--r--arch/powerpc/platforms/cell/iommu.c22
-rw-r--r--arch/powerpc/platforms/cell/setup.c4
-rw-r--r--arch/powerpc/platforms/cell/smp.c4
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c10
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c18
-rw-r--r--arch/powerpc/platforms/chrp/nvram.c5
-rw-r--r--arch/powerpc/platforms/chrp/pci.c53
-rw-r--r--arch/powerpc/platforms/chrp/setup.c48
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c8
-rw-r--r--arch/powerpc/platforms/iseries/Kconfig8
-rw-r--r--arch/powerpc/platforms/iseries/dt.c45
-rw-r--r--arch/powerpc/platforms/iseries/hvlpconfig.c13
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c19
-rw-r--r--arch/powerpc/platforms/iseries/it_exp_vpd_panel.h (renamed from include/asm-powerpc/iseries/it_exp_vpd_panel.h)6
-rw-r--r--arch/powerpc/platforms/iseries/it_lp_naca.h (renamed from include/asm-powerpc/iseries/it_lp_naca.h)6
-rw-r--r--arch/powerpc/platforms/iseries/lpardata.c6
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c2
-rw-r--r--arch/powerpc/platforms/iseries/main_store.h126
-rw-r--r--arch/powerpc/platforms/iseries/pci.c289
-rw-r--r--arch/powerpc/platforms/iseries/setup.c1
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c28
-rw-r--r--arch/powerpc/platforms/iseries/vpdinfo.c22
-rw-r--r--arch/powerpc/platforms/maple/pci.c70
-rw-r--r--arch/powerpc/platforms/maple/setup.c27
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile1
-rw-r--r--arch/powerpc/platforms/pasemi/pasemi.h8
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c198
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c188
-rw-r--r--arch/powerpc/platforms/pasemi/time.c29
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c3
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c23
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c27
-rw-r--r--arch/powerpc/platforms/powermac/feature.c30
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c24
-rw-r--r--arch/powerpc/platforms/powermac/pci.c37
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c2
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c5
-rw-r--r--arch/powerpc/platforms/powermac/setup.c18
-rw-r--r--arch/powerpc/platforms/powermac/smp.c7
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c10
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c96
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c17
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c112
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c4
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c2
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S273
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c129
-rw-r--r--arch/powerpc/platforms/pseries/hvconsole.c5
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c13
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c46
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c5
-rw-r--r--arch/powerpc/platforms/pseries/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h107
-rw-r--r--arch/powerpc/platforms/pseries/ras.c4
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c4
-rw-r--r--arch/powerpc/platforms/pseries/setup.c42
-rw-r--r--arch/powerpc/platforms/pseries/smp.c12
-rw-r--r--arch/powerpc/platforms/pseries/xics.c44
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c28
-rw-r--r--arch/powerpc/sysdev/fsl_soc.h2
-rw-r--r--arch/powerpc/sysdev/i8259.c2
-rw-r--r--arch/powerpc/sysdev/ipic.c42
-rw-r--r--arch/powerpc/sysdev/mmio_nvram.c4
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c4
-rw-r--r--arch/powerpc/xmon/xmon.c10
-rw-r--r--arch/ppc/Kconfig6
-rw-r--r--arch/ppc/kernel/misc.S88
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c9
-rw-r--r--arch/ppc/kernel/setup.c17
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.h1
-rw-r--r--arch/ppc/platforms/85xx/sbc85xx.h18
-rw-r--r--arch/ppc/syslib/m8260_pci_erratum9.c16
-rw-r--r--arch/ppc/xmon/start.c28
-rw-r--r--arch/ppc/xmon/xmon.c28
-rw-r--r--arch/s390/Kconfig17
-rw-r--r--arch/s390/appldata/appldata.h16
-rw-r--r--arch/s390/appldata/appldata_base.c81
-rw-r--r--arch/s390/appldata/appldata_os.c1
-rw-r--r--arch/s390/crypto/aes_s390.c285
-rw-r--r--arch/s390/crypto/crypt_s390.h3
-rw-r--r--arch/s390/crypto/des_s390.c559
-rw-r--r--arch/s390/crypto/sha1_s390.c2
-rw-r--r--arch/s390/crypto/sha256_s390.c2
-rw-r--r--arch/s390/defconfig1
-rw-r--r--arch/s390/hypfs/hypfs.h2
-rw-r--r--arch/s390/hypfs/hypfs_diag.c16
-rw-r--r--arch/s390/hypfs/hypfs_diag.h2
-rw-r--r--arch/s390/hypfs/inode.c12
-rw-r--r--arch/s390/kernel/Makefile3
-rw-r--r--arch/s390/kernel/entry.S12
-rw-r--r--arch/s390/kernel/entry64.S16
-rw-r--r--arch/s390/kernel/head.S69
-rw-r--r--arch/s390/kernel/head31.S48
-rw-r--r--arch/s390/kernel/head64.S59
-rw-r--r--arch/s390/kernel/ipl.c942
-rw-r--r--arch/s390/kernel/kprobes.c657
-rw-r--r--arch/s390/kernel/reipl.S33
-rw-r--r--arch/s390/kernel/reipl64.S34
-rw-r--r--arch/s390/kernel/reipl_diag.c39
-rw-r--r--arch/s390/kernel/s390_ksyms.c6
-rw-r--r--arch/s390/kernel/setup.c272
-rw-r--r--arch/s390/kernel/signal.c40
-rw-r--r--arch/s390/kernel/smp.c10
-rw-r--r--arch/s390/kernel/traps.c31
-rw-r--r--arch/s390/kernel/vmlinux.lds.S3
-rw-r--r--arch/s390/lib/Makefile4
-rw-r--r--arch/s390/lib/uaccess.S211
-rw-r--r--arch/s390/lib/uaccess64.S207
-rw-r--r--arch/s390/lib/uaccess_mvcos.c156
-rw-r--r--arch/s390/lib/uaccess_std.c340
-rw-r--r--arch/s390/mm/cmm.c30
-rw-r--r--arch/s390/mm/fault.c40
-rw-r--r--arch/s390/mm/init.c36
-rw-r--r--arch/x86_64/crypto/Makefile3
-rw-r--r--arch/x86_64/crypto/aes.c5
-rw-r--r--arch/x86_64/crypto/twofish-x86_64-asm.S324
-rw-r--r--arch/x86_64/crypto/twofish.c97
-rw-r--r--crypto/Kconfig154
-rw-r--r--crypto/Makefile16
-rw-r--r--crypto/aes.c5
-rw-r--r--crypto/algapi.c486
-rw-r--r--crypto/anubis.c3
-rw-r--r--crypto/api.c428
-rw-r--r--crypto/arc4.c2
-rw-r--r--crypto/blkcipher.c405
-rw-r--r--crypto/blowfish.c3
-rw-r--r--crypto/cast5.c8
-rw-r--r--crypto/cast6.c5
-rw-r--r--crypto/cbc.c344
-rw-r--r--crypto/cipher.c117
-rw-r--r--crypto/crc32c.c30
-rw-r--r--crypto/crypto_null.c2
-rw-r--r--crypto/cryptomgr.c156
-rw-r--r--crypto/des.c6
-rw-r--r--crypto/digest.c155
-rw-r--r--crypto/ecb.c181
-rw-r--r--crypto/hash.c61
-rw-r--r--crypto/hmac.c278
-rw-r--r--crypto/internal.h106
-rw-r--r--crypto/khazad.c8
-rw-r--r--crypto/michael_mic.c5
-rw-r--r--crypto/proc.c13
-rw-r--r--crypto/scatterwalk.c89
-rw-r--r--crypto/scatterwalk.h52
-rw-r--r--crypto/serpent.c19
-rw-r--r--crypto/sha1.c3
-rw-r--r--crypto/sha256.c3
-rw-r--r--crypto/tcrypt.c901
-rw-r--r--crypto/tcrypt.h202
-rw-r--r--crypto/tea.c16
-rw-r--r--crypto/twofish.c700
-rw-r--r--crypto/twofish_common.c744
-rw-r--r--drivers/base/hypervisor.c3
-rw-r--r--drivers/block/cryptoloop.c160
-rw-r--r--drivers/char/Kconfig22
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/agp/uninorth-agp.c4
-rw-r--r--drivers/char/briq_panel.c268
-rw-r--r--drivers/char/hvc_console.c18
-rw-r--r--drivers/char/hvc_console.h2
-rw-r--r--drivers/char/hvc_iseries.c594
-rw-r--r--drivers/char/hvc_rtas.c2
-rw-r--r--drivers/char/hvc_vio.c7
-rw-r--r--drivers/char/hvsi.c7
-rw-r--r--drivers/char/tpm/tpm_atmel.h4
-rw-r--r--drivers/char/viocons.c31
-rw-r--r--drivers/char/viotape.c6
-rw-r--r--drivers/crypto/Kconfig45
-rw-r--r--drivers/crypto/Makefile8
-rw-r--r--drivers/crypto/padlock-aes.c258
-rw-r--r--drivers/crypto/padlock-generic.c63
-rw-r--r--drivers/crypto/padlock-sha.c318
-rw-r--r--drivers/crypto/padlock.c58
-rw-r--r--drivers/crypto/padlock.h17
-rw-r--r--drivers/i2c/busses/i2c-powermac.c3
-rw-r--r--drivers/ide/ppc/pmac.c8
-rw-r--r--drivers/infiniband/Kconfig4
-rw-r--r--drivers/infiniband/Makefile4
-rw-r--r--drivers/infiniband/core/Makefile4
-rw-r--r--drivers/infiniband/core/addr.c22
-rw-r--r--drivers/infiniband/core/cache.c5
-rw-r--r--drivers/infiniband/core/cm.c66
-rw-r--r--drivers/infiniband/core/cma.c403
-rw-r--r--drivers/infiniband/core/device.c6
-rw-r--r--drivers/infiniband/core/iwcm.c1019
-rw-r--r--drivers/infiniband/core/iwcm.h62
-rw-r--r--drivers/infiniband/core/mad.c19
-rw-r--r--drivers/infiniband/core/mad_priv.h1
-rw-r--r--drivers/infiniband/core/mad_rmpp.c94
-rw-r--r--drivers/infiniband/core/sa_query.c67
-rw-r--r--drivers/infiniband/core/smi.c16
-rw-r--r--drivers/infiniband/core/sysfs.c13
-rw-r--r--drivers/infiniband/core/ucm.c9
-rw-r--r--drivers/infiniband/core/user_mad.c7
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c64
-rw-r--r--drivers/infiniband/core/verbs.c21
-rw-r--r--drivers/infiniband/hw/amso1100/Kbuild8
-rw-r--r--drivers/infiniband/hw/amso1100/Kconfig15
-rw-r--r--drivers/infiniband/hw/amso1100/c2.c1255
-rw-r--r--drivers/infiniband/hw/amso1100/c2.h551
-rw-r--r--drivers/infiniband/hw/amso1100/c2_ae.c321
-rw-r--r--drivers/infiniband/hw/amso1100/c2_ae.h108
-rw-r--r--drivers/infiniband/hw/amso1100/c2_alloc.c144
-rw-r--r--drivers/infiniband/hw/amso1100/c2_cm.c452
-rw-r--r--drivers/infiniband/hw/amso1100/c2_cq.c433
-rw-r--r--drivers/infiniband/hw/amso1100/c2_intr.c209
-rw-r--r--drivers/infiniband/hw/amso1100/c2_mm.c375
-rw-r--r--drivers/infiniband/hw/amso1100/c2_mq.c174
-rw-r--r--drivers/infiniband/hw/amso1100/c2_mq.h106
-rw-r--r--drivers/infiniband/hw/amso1100/c2_pd.c89
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c869
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.h181
-rw-r--r--drivers/infiniband/hw/amso1100/c2_qp.c975
-rw-r--r--drivers/infiniband/hw/amso1100/c2_rnic.c663
-rw-r--r--drivers/infiniband/hw/amso1100/c2_status.h158
-rw-r--r--drivers/infiniband/hw/amso1100/c2_user.h82
-rw-r--r--drivers/infiniband/hw/amso1100/c2_vq.c260
-rw-r--r--drivers/infiniband/hw/amso1100/c2_vq.h63
-rw-r--r--drivers/infiniband/hw/amso1100/c2_wr.h1520
-rw-r--r--drivers/infiniband/hw/ehca/Kconfig16
-rw-r--r--drivers/infiniband/hw/ehca/Makefile16
-rw-r--r--drivers/infiniband/hw/ehca/ehca_av.c271
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h346
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes_pSeries.h236
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c427
-rw-r--r--drivers/infiniband/hw/ehca/ehca_eq.c185
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c241
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.c762
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.h77
-rw-r--r--drivers/infiniband/hw/ehca/ehca_iverbs.h182
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c818
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mcast.c131
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c2261
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.h140
-rw-r--r--drivers/infiniband/hw/ehca/ehca_pd.c114
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qes.h259
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c1507
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c653
-rw-r--r--drivers/infiniband/hw/ehca/ehca_sqp.c111
-rw-r--r--drivers/infiniband/hw/ehca/ehca_tools.h172
-rw-r--r--drivers/infiniband/hw/ehca/ehca_uverbs.c392
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.c874
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.h261
-rw-r--r--drivers/infiniband/hw/ehca/hcp_phyp.c80
-rw-r--r--drivers/infiniband/hw/ehca/hcp_phyp.h90
-rw-r--r--drivers/infiniband/hw/ehca/hipz_fns.h68
-rw-r--r--drivers/infiniband/hw/ehca/hipz_fns_core.h100
-rw-r--r--drivers/infiniband/hw/ehca/hipz_hw.h388
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.c149
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.h247
-rw-r--r--drivers/infiniband/hw/ipath/Kconfig21
-rw-r--r--drivers/infiniband/hw/ipath/Makefile29
-rw-r--r--drivers/infiniband/hw/ipath/ipath_common.h19
-rw-r--r--drivers/infiniband/hw/ipath/ipath_cq.c183
-rw-r--r--drivers/infiniband/hw/ipath/ipath_debug.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_diag.c154
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c349
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c35
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6110.c (renamed from drivers/infiniband/hw/ipath/ipath_ht400.c)53
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c (renamed from drivers/infiniband/hw/ipath/ipath_pe800.c)82
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c21
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c24
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h57
-rw-r--r--drivers/infiniband/hw/ipath/ipath_keys.c3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_layer.c1179
-rw-r--r--drivers/infiniband/hw/ipath/ipath_layer.h115
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mad.c339
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mmap.c122
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mr.c12
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c242
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c9
-rw-r--r--drivers/infiniband/hw/ipath/ipath_registers.h7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ruc.c160
-rw-r--r--drivers/infiniband/hw/ipath/ipath_srq.c244
-rw-r--r--drivers/infiniband/hw/ipath/ipath_stats.c27
-rw-r--r--drivers/infiniband/hw/ipath/ipath_sysfs.c41
-rw-r--r--drivers/infiniband/hw/ipath/ipath_uc.c5
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c182
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c687
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h252
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs_mcast.c7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_wc_ppc64.c52
-rw-r--r--drivers/infiniband/hw/ipath/verbs_debug.h108
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_catas.c62
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c88
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c20
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_uar.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c194
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c37
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c34
-rw-r--r--drivers/infiniband/ulp/iser/Kconfig2
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c1
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h7
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c80
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c10
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c43
-rw-r--r--drivers/macintosh/macio_asic.c10
-rw-r--r--drivers/macintosh/macio_sysfs.c8
-rw-r--r--drivers/macintosh/smu.c19
-rw-r--r--drivers/macintosh/therm_adt746x.c8
-rw-r--r--drivers/macintosh/therm_pm72.c14
-rw-r--r--drivers/macintosh/therm_windtunnel.c4
-rw-r--r--drivers/macintosh/via-cuda.c4
-rw-r--r--drivers/macintosh/via-pmu-led.c2
-rw-r--r--drivers/macintosh/via-pmu.c10
-rw-r--r--drivers/macintosh/windfarm_pm81.c4
-rw-r--r--drivers/macintosh/windfarm_pm91.c2
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c13
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c8
-rw-r--r--drivers/macintosh/windfarm_smu_sensors.c12
-rw-r--r--drivers/md/dm-crypt.c146
-rw-r--r--drivers/mtd/Kconfig8
-rw-r--r--drivers/mtd/Makefile1
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c1
-rw-r--r--drivers/mtd/devices/pmc551.c1154
-rw-r--r--drivers/mtd/maps/Kconfig8
-rw-r--r--drivers/mtd/maps/Makefile1
-rw-r--r--drivers/mtd/maps/amd76xrom.c5
-rw-r--r--drivers/mtd/maps/arctic-mtd.c14
-rw-r--r--drivers/mtd/maps/beech-mtd.c14
-rw-r--r--drivers/mtd/maps/cstm_mips_ixx.c18
-rw-r--r--drivers/mtd/maps/ebony.c4
-rw-r--r--drivers/mtd/maps/fortunet.c3
-rw-r--r--drivers/mtd/maps/ichxrom.c3
-rw-r--r--drivers/mtd/maps/iq80310.c118
-rw-r--r--drivers/mtd/maps/ixp4xx.c2
-rw-r--r--drivers/mtd/maps/l440gx.c12
-rw-r--r--drivers/mtd/maps/lasat.c2
-rw-r--r--drivers/mtd/maps/nettel.c34
-rw-r--r--drivers/mtd/maps/ocotea.c4
-rw-r--r--drivers/mtd/maps/pcmciamtd.c4
-rw-r--r--drivers/mtd/maps/physmap.c33
-rw-r--r--drivers/mtd/maps/redwood.c11
-rw-r--r--drivers/mtd/maps/sbc8240.c11
-rw-r--r--drivers/mtd/maps/scx200_docflash.c9
-rw-r--r--drivers/mtd/maps/walnut.c4
-rw-r--r--drivers/mtd/mtdcore.c10
-rw-r--r--drivers/mtd/nand/au1550nd.c11
-rw-r--r--drivers/mtd/nand/edb7312.c3
-rw-r--r--drivers/mtd/nand/ndfc.c2
-rw-r--r--drivers/mtd/nand/ppchameleonevb.c7
-rw-r--r--drivers/mtd/ssfdc.c468
-rw-r--r--drivers/net/bmac.c13
-rw-r--r--drivers/net/ibmveth.c3
-rw-r--r--drivers/net/ibmveth.h27
-rw-r--r--drivers/net/mace.c2
-rw-r--r--drivers/net/ppp_mppe.c68
-rw-r--r--drivers/net/spider_net.c12
-rw-r--r--drivers/net/sungem.c2
-rw-r--r--drivers/net/wireless/airo.c22
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c32
-rw-r--r--drivers/s390/Kconfig30
-rw-r--r--drivers/s390/block/dasd.c8
-rw-r--r--drivers/s390/block/dasd_devmap.c82
-rw-r--r--drivers/s390/block/dasd_eer.c2
-rw-r--r--drivers/s390/block/dasd_int.h1
-rw-r--r--drivers/s390/block/xpram.c2
-rw-r--r--drivers/s390/char/Makefile1
-rw-r--r--drivers/s390/char/monwriter.c292
-rw-r--r--drivers/s390/char/vmcp.c2
-rw-r--r--drivers/s390/char/vmcp.h2
-rw-r--r--drivers/s390/cio/chsc.c5
-rw-r--r--drivers/s390/cio/cio.c95
-rw-r--r--drivers/s390/cio/css.c203
-rw-r--r--drivers/s390/cio/device.c109
-rw-r--r--drivers/s390/cio/device_fsm.c40
-rw-r--r--drivers/s390/cio/device_ops.c17
-rw-r--r--drivers/s390/cio/device_pgid.c81
-rw-r--r--drivers/s390/cio/qdio.c4
-rw-r--r--drivers/s390/cio/qdio.h16
-rw-r--r--drivers/s390/crypto/Makefile15
-rw-r--r--drivers/s390/crypto/ap_bus.c1221
-rw-r--r--drivers/s390/crypto/ap_bus.h158
-rw-r--r--drivers/s390/crypto/z90common.h166
-rw-r--r--drivers/s390/crypto/z90crypt.h71
-rw-r--r--drivers/s390/crypto/z90hardware.c2531
-rw-r--r--drivers/s390/crypto/z90main.c3379
-rw-r--r--drivers/s390/crypto/zcrypt_api.c1091
-rw-r--r--drivers/s390/crypto/zcrypt_api.h141
-rw-r--r--drivers/s390/crypto/zcrypt_cca_key.h350
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c435
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.h126
-rw-r--r--drivers/s390/crypto/zcrypt_error.h133
-rw-r--r--drivers/s390/crypto/zcrypt_mono.c100
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c418
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.h117
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.c630
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.h176
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c951
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.h79
-rw-r--r--drivers/s390/s390mach.c17
-rw-r--r--drivers/s390/scsi/zfcp_def.h8
-rw-r--r--drivers/s390/sysinfo.c455
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c11
-rw-r--r--drivers/scsi/iscsi_tcp.c134
-rw-r--r--drivers/scsi/iscsi_tcp.h9
-rw-r--r--drivers/scsi/mac53c94.c2
-rw-r--r--drivers/scsi/mesh.c5
-rw-r--r--drivers/scsi/sata_svw.c2
-rw-r--r--drivers/serial/pmac_zilog.c9
-rw-r--r--drivers/video/S3triofb.c12
-rw-r--r--drivers/video/aty/radeon_base.c8
-rw-r--r--drivers/video/aty/radeon_monitor.c12
-rw-r--r--drivers/video/aty/radeon_pm.c4
-rw-r--r--drivers/video/nvidia/nv_of.c12
-rw-r--r--drivers/video/offb.c22
-rw-r--r--drivers/video/riva/fbdev.c5
-rw-r--r--fs/Kconfig4
-rw-r--r--fs/configfs/dir.c32
-rw-r--r--fs/jffs2/jffs2_fs_i.h4
-rw-r--r--fs/nfsd/nfs4recover.c21
-rw-r--r--fs/ocfs2/Makefile1
-rw-r--r--fs/ocfs2/alloc.c28
-rw-r--r--fs/ocfs2/aops.c83
-rw-r--r--fs/ocfs2/buffer_head_io.c95
-rw-r--r--fs/ocfs2/buffer_head_io.h2
-rw-r--r--fs/ocfs2/cluster/heartbeat.c8
-rw-r--r--fs/ocfs2/dir.c28
-rw-r--r--fs/ocfs2/dlm/dlmast.c10
-rw-r--r--fs/ocfs2/dlmglue.c9
-rw-r--r--fs/ocfs2/dlmglue.h5
-rw-r--r--fs/ocfs2/file.c3
-rw-r--r--fs/ocfs2/inode.c32
-rw-r--r--fs/ocfs2/inode.h3
-rw-r--r--fs/ocfs2/ioctl.c136
-rw-r--r--fs/ocfs2/ioctl.h16
-rw-r--r--fs/ocfs2/namei.c32
-rw-r--r--fs/ocfs2/ocfs2_fs.h24
-rw-r--r--fs/ocfs2/uptodate.c21
-rw-r--r--fs/ocfs2/uptodate.h2
-rw-r--r--include/Kbuild11
-rw-r--r--include/asm-alpha/Kbuild10
-rw-r--r--include/asm-generic/Kbuild15
-rw-r--r--include/asm-generic/Kbuild.asm38
-rw-r--r--include/asm-i386/Kbuild9
-rw-r--r--include/asm-ia64/Kbuild18
-rw-r--r--include/asm-powerpc/Kbuild45
-rw-r--r--include/asm-powerpc/cputable.h27
-rw-r--r--include/asm-powerpc/hvcall.h121
-rw-r--r--include/asm-powerpc/ibmebus.h2
-rw-r--r--include/asm-powerpc/ide.h12
-rw-r--r--include/asm-powerpc/io.h183
-rw-r--r--include/asm-powerpc/irq.h24
-rw-r--r--include/asm-powerpc/iseries/hv_call_xm.h17
-rw-r--r--include/asm-powerpc/iseries/hv_lp_config.h13
-rw-r--r--include/asm-powerpc/iseries/iseries_io.h60
-rw-r--r--include/asm-powerpc/iseries/it_lp_queue.h2
-rw-r--r--include/asm-powerpc/iseries/vio.h28
-rw-r--r--include/asm-powerpc/lppaca.h23
-rw-r--r--include/asm-powerpc/paca.h3
-rw-r--r--include/asm-powerpc/page.h6
-rw-r--r--include/asm-powerpc/ppc-pci.h11
-rw-r--r--include/asm-powerpc/processor.h1
-rw-r--r--include/asm-powerpc/prom.h40
-rw-r--r--include/asm-powerpc/ptrace.h4
-rw-r--r--include/asm-powerpc/reg.h1
-rw-r--r--include/asm-powerpc/rtas.h16
-rw-r--r--include/asm-powerpc/smu.h2
-rw-r--r--include/asm-powerpc/spu.h2
-rw-r--r--include/asm-powerpc/system.h5
-rw-r--r--include/asm-powerpc/vio.h4
-rw-r--r--include/asm-ppc/io.h26
-rw-r--r--include/asm-ppc/mpc8260_pci9.h4
-rw-r--r--include/asm-ppc/reg_booke.h16
-rw-r--r--include/asm-s390/Kbuild12
-rw-r--r--include/asm-s390/appldata.h90
-rw-r--r--include/asm-s390/cio.h7
-rw-r--r--include/asm-s390/dma.h2
-rw-r--r--include/asm-s390/futex.h87
-rw-r--r--include/asm-s390/io.h2
-rw-r--r--include/asm-s390/kdebug.h59
-rw-r--r--include/asm-s390/kprobes.h114
-rw-r--r--include/asm-s390/lowcore.h14
-rw-r--r--include/asm-s390/monwriter.h33
-rw-r--r--include/asm-s390/pgalloc.h67
-rw-r--r--include/asm-s390/pgtable.h124
-rw-r--r--include/asm-s390/processor.h17
-rw-r--r--include/asm-s390/setup.h66
-rw-r--r--include/asm-s390/smp.h2
-rw-r--r--include/asm-s390/uaccess.h172
-rw-r--r--include/asm-s390/unistd.h170
-rw-r--r--include/asm-s390/z90crypt.h212
-rw-r--r--include/asm-s390/zcrypt.h285
-rw-r--r--include/asm-sparc/Kbuild24
-rw-r--r--include/asm-sparc64/Kbuild27
-rw-r--r--include/asm-x86_64/Kbuild18
-rw-r--r--include/crypto/algapi.h156
-rw-r--r--include/crypto/twofish.h22
-rw-r--r--include/linux/Kbuild400
-rw-r--r--include/linux/byteorder/Kbuild9
-rw-r--r--include/linux/crypto.h689
-rw-r--r--include/linux/dvb/Kbuild11
-rw-r--r--include/linux/mod_devicetable.h11
-rw-r--r--include/linux/netfilter/Kbuild47
-rw-r--r--include/linux/netfilter_arp/Kbuild5
-rw-r--r--include/linux/netfilter_bridge/Kbuild21
-rw-r--r--include/linux/netfilter_ipv4/Kbuild82
-rw-r--r--include/linux/netfilter_ipv6/Kbuild27
-rw-r--r--include/linux/nfsd/Kbuild9
-rw-r--r--include/linux/raid/Kbuild3
-rw-r--r--include/linux/scatterlist.h4
-rw-r--r--include/linux/sunrpc/Kbuild2
-rw-r--r--include/linux/sunrpc/gss_krb5.h19
-rw-r--r--include/linux/sunrpc/gss_spkm3.h4
-rw-r--r--include/linux/tc_act/Kbuild5
-rw-r--r--include/linux/tc_ematch/Kbuild5
-rw-r--r--include/mtd/Kbuild8
-rw-r--r--include/mtd/mtd-abi.h1
-rw-r--r--include/net/ah.h30
-rw-r--r--include/net/esp.h31
-rw-r--r--include/net/ipcomp.h5
-rw-r--r--include/net/sctp/constants.h4
-rw-r--r--include/net/sctp/sctp.h11
-rw-r--r--include/net/sctp/structs.h3
-rw-r--r--include/net/xfrm.h12
-rw-r--r--include/rdma/Kbuild2
-rw-r--r--include/rdma/ib_addr.h17
-rw-r--r--include/rdma/ib_sa.h45
-rw-r--r--include/rdma/ib_user_verbs.h2
-rw-r--r--include/rdma/ib_verbs.h31
-rw-r--r--include/rdma/iw_cm.h258
-rw-r--r--include/rdma/rdma_cm.h12
-rw-r--r--include/scsi/Kbuild4
-rw-r--r--include/sound/Kbuild12
-rw-r--r--include/video/Kbuild2
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c32
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c100
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c35
-rw-r--r--net/ipv4/Kconfig1
-rw-r--r--net/ipv4/ah4.c36
-rw-r--r--net/ipv4/esp4.c85
-rw-r--r--net/ipv4/ipcomp.c25
-rw-r--r--net/ipv6/Kconfig1
-rw-r--r--net/ipv6/ah6.c35
-rw-r--r--net/ipv6/esp6.c90
-rw-r--r--net/ipv6/ipcomp6.c25
-rw-r--r--net/sctp/endpointola.c2
-rw-r--r--net/sctp/sm_make_chunk.c37
-rw-r--r--net/sctp/socket.c6
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c95
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c24
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seqnum.c4
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c4
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c29
-rw-r--r--net/xfrm/xfrm_algo.c94
-rw-r--r--net/xfrm/xfrm_user.c2
-rwxr-xr-xscripts/checkstack.pl2
-rw-r--r--scripts/mod/file2alias.c12
-rw-r--r--security/seclvl.c18
-rw-r--r--sound/aoa/core/snd-aoa-gpio-feature.c2
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c11
-rw-r--r--sound/ppc/tumbler.c15
632 files changed, 50610 insertions, 17265 deletions
diff --git a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt
index 74dffc68ff9f..5a03a2801d67 100644
--- a/Documentation/crypto/api-intro.txt
+++ b/Documentation/crypto/api-intro.txt
@@ -19,15 +19,14 @@ At the lowest level are algorithms, which register dynamically with the
19API. 19API.
20 20
21'Transforms' are user-instantiated objects, which maintain state, handle all 21'Transforms' are user-instantiated objects, which maintain state, handle all
22of the implementation logic (e.g. manipulating page vectors), provide an 22of the implementation logic (e.g. manipulating page vectors) and provide an
23abstraction to the underlying algorithms, and handle common logical 23abstraction to the underlying algorithms. However, at the user
24operations (e.g. cipher modes, HMAC for digests). However, at the user
25level they are very simple. 24level they are very simple.
26 25
27Conceptually, the API layering looks like this: 26Conceptually, the API layering looks like this:
28 27
29 [transform api] (user interface) 28 [transform api] (user interface)
30 [transform ops] (per-type logic glue e.g. cipher.c, digest.c) 29 [transform ops] (per-type logic glue e.g. cipher.c, compress.c)
31 [algorithm api] (for registering algorithms) 30 [algorithm api] (for registering algorithms)
32 31
33The idea is to make the user interface and algorithm registration API 32The idea is to make the user interface and algorithm registration API
@@ -44,22 +43,27 @@ under development.
44Here's an example of how to use the API: 43Here's an example of how to use the API:
45 44
46 #include <linux/crypto.h> 45 #include <linux/crypto.h>
46 #include <linux/err.h>
47 #include <linux/scatterlist.h>
47 48
48 struct scatterlist sg[2]; 49 struct scatterlist sg[2];
49 char result[128]; 50 char result[128];
50 struct crypto_tfm *tfm; 51 struct crypto_hash *tfm;
52 struct hash_desc desc;
51 53
52 tfm = crypto_alloc_tfm("md5", 0); 54 tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
53 if (tfm == NULL) 55 if (IS_ERR(tfm))
54 fail(); 56 fail();
55 57
56 /* ... set up the scatterlists ... */ 58 /* ... set up the scatterlists ... */
59
60 desc.tfm = tfm;
61 desc.flags = 0;
57 62
58 crypto_digest_init(tfm); 63 if (crypto_hash_digest(&desc, &sg, 2, result))
59 crypto_digest_update(tfm, &sg, 2); 64 fail();
60 crypto_digest_final(tfm, result);
61 65
62 crypto_free_tfm(tfm); 66 crypto_free_hash(tfm);
63 67
64 68
65Many real examples are available in the regression test module (tcrypt.c). 69Many real examples are available in the regression test module (tcrypt.c).
@@ -126,7 +130,7 @@ might already be working on.
126BUGS 130BUGS
127 131
128Send bug reports to: 132Send bug reports to:
129James Morris <jmorris@redhat.com> 133Herbert Xu <herbert@gondor.apana.org.au>
130Cc: David S. Miller <davem@redhat.com> 134Cc: David S. Miller <davem@redhat.com>
131 135
132 136
@@ -134,13 +138,14 @@ FURTHER INFORMATION
134 138
135For further patches and various updates, including the current TODO 139For further patches and various updates, including the current TODO
136list, see: 140list, see:
137http://samba.org/~jamesm/crypto/ 141http://gondor.apana.org.au/~herbert/crypto/
138 142
139 143
140AUTHORS 144AUTHORS
141 145
142James Morris 146James Morris
143David S. Miller 147David S. Miller
148Herbert Xu
144 149
145 150
146CREDITS 151CREDITS
@@ -238,8 +243,11 @@ Anubis algorithm contributors:
238Tiger algorithm contributors: 243Tiger algorithm contributors:
239 Aaron Grothe 244 Aaron Grothe
240 245
246VIA PadLock contributors:
247 Michal Ludvig
248
241Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com> 249Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
242 250
243Please send any credits updates or corrections to: 251Please send any credits updates or corrections to:
244James Morris <jmorris@redhat.com> 252Herbert Xu <herbert@gondor.apana.org.au>
245 253
diff --git a/MAINTAINERS b/MAINTAINERS
index 7a08cdbb246a..766b1ad1d0f9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -298,6 +298,14 @@ L: info-linux@geode.amd.com
298W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html 298W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
299S: Supported 299S: Supported
300 300
301AMSO1100 RNIC DRIVER
302P: Tom Tucker
303M: tom@opengridcomputing.com
304P: Steve Wise
305M: swise@opengridcomputing.com
306L: openib-general@openib.org
307S: Maintained
308
301AOA (Apple Onboard Audio) ALSA DRIVER 309AOA (Apple Onboard Audio) ALSA DRIVER
302P: Johannes Berg 310P: Johannes Berg
303M: johannes@sipsolutions.net 311M: johannes@sipsolutions.net
@@ -991,6 +999,14 @@ EFS FILESYSTEM
991W: http://aeschi.ch.eu.org/efs/ 999W: http://aeschi.ch.eu.org/efs/
992S: Orphan 1000S: Orphan
993 1001
1002EHCA (IBM GX bus InfiniBand adapter) DRIVER:
1003P: Hoang-Nam Nguyen
1004M: hnguyen@de.ibm.com
1005P: Christoph Raisch
1006M: raisch@de.ibm.com
1007L: openib-general@openib.org
1008S: Supported
1009
994EMU10K1 SOUND DRIVER 1010EMU10K1 SOUND DRIVER
995P: James Courtier-Dutton 1011P: James Courtier-Dutton
996M: James@superbug.demon.co.uk 1012M: James@superbug.demon.co.uk
@@ -1783,6 +1799,13 @@ W: http://www.penguinppc.org/
1783L: linuxppc-embedded@ozlabs.org 1799L: linuxppc-embedded@ozlabs.org
1784S: Maintained 1800S: Maintained
1785 1801
1802LINUX FOR POWERPC PA SEMI PWRFICIENT
1803P: Olof Johansson
1804M: olof@lixom.net
1805W: http://www.pasemi.com/
1806L: linuxppc-dev@ozlabs.org
1807S: Supported
1808
1786LLC (802.2) 1809LLC (802.2)
1787P: Arnaldo Carvalho de Melo 1810P: Arnaldo Carvalho de Melo
1788M: acme@conectiva.com.br 1811M: acme@conectiva.com.br
@@ -2451,6 +2474,8 @@ S: Maintained
2451S390 2474S390
2452P: Martin Schwidefsky 2475P: Martin Schwidefsky
2453M: schwidefsky@de.ibm.com 2476M: schwidefsky@de.ibm.com
2477P: Heiko Carstens
2478M: heiko.carstens@de.ibm.com
2454M: linux390@de.ibm.com 2479M: linux390@de.ibm.com
2455L: linux-390@vm.marist.edu 2480L: linux-390@vm.marist.edu
2456W: http://www.ibm.com/developerworks/linux/linux390/ 2481W: http://www.ibm.com/developerworks/linux/linux390/
diff --git a/arch/i386/crypto/Makefile b/arch/i386/crypto/Makefile
index 103c353d0a63..3fd19af18e34 100644
--- a/arch/i386/crypto/Makefile
+++ b/arch/i386/crypto/Makefile
@@ -5,5 +5,8 @@
5# 5#
6 6
7obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o 7obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
8obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
8 9
9aes-i586-y := aes-i586-asm.o aes.o 10aes-i586-y := aes-i586-asm.o aes.o
11twofish-i586-y := twofish-i586-asm.o twofish.o
12
diff --git a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c
index d3806daa3de3..49aad9397f10 100644
--- a/arch/i386/crypto/aes.c
+++ b/arch/i386/crypto/aes.c
@@ -379,12 +379,13 @@ static void gen_tabs(void)
379} 379}
380 380
381static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 381static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
382 unsigned int key_len, u32 *flags) 382 unsigned int key_len)
383{ 383{
384 int i; 384 int i;
385 u32 ss[8]; 385 u32 ss[8];
386 struct aes_ctx *ctx = crypto_tfm_ctx(tfm); 386 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
387 const __le32 *key = (const __le32 *)in_key; 387 const __le32 *key = (const __le32 *)in_key;
388 u32 *flags = &tfm->crt_flags;
388 389
389 /* encryption schedule */ 390 /* encryption schedule */
390 391
diff --git a/arch/i386/crypto/twofish-i586-asm.S b/arch/i386/crypto/twofish-i586-asm.S
new file mode 100644
index 000000000000..39b98ed2c1b9
--- /dev/null
+++ b/arch/i386/crypto/twofish-i586-asm.S
@@ -0,0 +1,335 @@
1/***************************************************************************
2* Copyright (C) 2006 by Joachim Fritschi, <jfritschi@freenet.de> *
3* *
4* This program is free software; you can redistribute it and/or modify *
5* it under the terms of the GNU General Public License as published by *
6* the Free Software Foundation; either version 2 of the License, or *
7* (at your option) any later version. *
8* *
9* This program is distributed in the hope that it will be useful, *
10* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12* GNU General Public License for more details. *
13* *
14* You should have received a copy of the GNU General Public License *
15* along with this program; if not, write to the *
16* Free Software Foundation, Inc., *
17* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18***************************************************************************/
19
20.file "twofish-i586-asm.S"
21.text
22
23#include <asm/asm-offsets.h>
24
25/* return adress at 0 */
26
27#define in_blk 12 /* input byte array address parameter*/
28#define out_blk 8 /* output byte array address parameter*/
29#define tfm 4 /* Twofish context structure */
30
31#define a_offset 0
32#define b_offset 4
33#define c_offset 8
34#define d_offset 12
35
36/* Structure of the crypto context struct*/
37
38#define s0 0 /* S0 Array 256 Words each */
39#define s1 1024 /* S1 Array */
40#define s2 2048 /* S2 Array */
41#define s3 3072 /* S3 Array */
42#define w 4096 /* 8 whitening keys (word) */
43#define k 4128 /* key 1-32 ( word ) */
44
45/* define a few register aliases to allow macro substitution */
46
47#define R0D %eax
48#define R0B %al
49#define R0H %ah
50
51#define R1D %ebx
52#define R1B %bl
53#define R1H %bh
54
55#define R2D %ecx
56#define R2B %cl
57#define R2H %ch
58
59#define R3D %edx
60#define R3B %dl
61#define R3H %dh
62
63
64/* performs input whitening */
65#define input_whitening(src,context,offset)\
66 xor w+offset(context), src;
67
68/* performs input whitening */
69#define output_whitening(src,context,offset)\
70 xor w+16+offset(context), src;
71
72/*
73 * a input register containing a (rotated 16)
74 * b input register containing b
75 * c input register containing c
76 * d input register containing d (already rol $1)
77 * operations on a and b are interleaved to increase performance
78 */
79#define encrypt_round(a,b,c,d,round)\
80 push d ## D;\
81 movzx b ## B, %edi;\
82 mov s1(%ebp,%edi,4),d ## D;\
83 movzx a ## B, %edi;\
84 mov s2(%ebp,%edi,4),%esi;\
85 movzx b ## H, %edi;\
86 ror $16, b ## D;\
87 xor s2(%ebp,%edi,4),d ## D;\
88 movzx a ## H, %edi;\
89 ror $16, a ## D;\
90 xor s3(%ebp,%edi,4),%esi;\
91 movzx b ## B, %edi;\
92 xor s3(%ebp,%edi,4),d ## D;\
93 movzx a ## B, %edi;\
94 xor (%ebp,%edi,4), %esi;\
95 movzx b ## H, %edi;\
96 ror $15, b ## D;\
97 xor (%ebp,%edi,4), d ## D;\
98 movzx a ## H, %edi;\
99 xor s1(%ebp,%edi,4),%esi;\
100 pop %edi;\
101 add d ## D, %esi;\
102 add %esi, d ## D;\
103 add k+round(%ebp), %esi;\
104 xor %esi, c ## D;\
105 rol $15, c ## D;\
106 add k+4+round(%ebp),d ## D;\
107 xor %edi, d ## D;
108
109/*
110 * a input register containing a (rotated 16)
111 * b input register containing b
112 * c input register containing c
113 * d input register containing d (already rol $1)
114 * operations on a and b are interleaved to increase performance
115 * last round has different rotations for the output preparation
116 */
117#define encrypt_last_round(a,b,c,d,round)\
118 push d ## D;\
119 movzx b ## B, %edi;\
120 mov s1(%ebp,%edi,4),d ## D;\
121 movzx a ## B, %edi;\
122 mov s2(%ebp,%edi,4),%esi;\
123 movzx b ## H, %edi;\
124 ror $16, b ## D;\
125 xor s2(%ebp,%edi,4),d ## D;\
126 movzx a ## H, %edi;\
127 ror $16, a ## D;\
128 xor s3(%ebp,%edi,4),%esi;\
129 movzx b ## B, %edi;\
130 xor s3(%ebp,%edi,4),d ## D;\
131 movzx a ## B, %edi;\
132 xor (%ebp,%edi,4), %esi;\
133 movzx b ## H, %edi;\
134 ror $16, b ## D;\
135 xor (%ebp,%edi,4), d ## D;\
136 movzx a ## H, %edi;\
137 xor s1(%ebp,%edi,4),%esi;\
138 pop %edi;\
139 add d ## D, %esi;\
140 add %esi, d ## D;\
141 add k+round(%ebp), %esi;\
142 xor %esi, c ## D;\
143 ror $1, c ## D;\
144 add k+4+round(%ebp),d ## D;\
145 xor %edi, d ## D;
146
147/*
148 * a input register containing a
149 * b input register containing b (rotated 16)
150 * c input register containing c
151 * d input register containing d (already rol $1)
152 * operations on a and b are interleaved to increase performance
153 */
154#define decrypt_round(a,b,c,d,round)\
155 push c ## D;\
156 movzx a ## B, %edi;\
157 mov (%ebp,%edi,4), c ## D;\
158 movzx b ## B, %edi;\
159 mov s3(%ebp,%edi,4),%esi;\
160 movzx a ## H, %edi;\
161 ror $16, a ## D;\
162 xor s1(%ebp,%edi,4),c ## D;\
163 movzx b ## H, %edi;\
164 ror $16, b ## D;\
165 xor (%ebp,%edi,4), %esi;\
166 movzx a ## B, %edi;\
167 xor s2(%ebp,%edi,4),c ## D;\
168 movzx b ## B, %edi;\
169 xor s1(%ebp,%edi,4),%esi;\
170 movzx a ## H, %edi;\
171 ror $15, a ## D;\
172 xor s3(%ebp,%edi,4),c ## D;\
173 movzx b ## H, %edi;\
174 xor s2(%ebp,%edi,4),%esi;\
175 pop %edi;\
176 add %esi, c ## D;\
177 add c ## D, %esi;\
178 add k+round(%ebp), c ## D;\
179 xor %edi, c ## D;\
180 add k+4+round(%ebp),%esi;\
181 xor %esi, d ## D;\
182 rol $15, d ## D;
183
184/*
185 * a input register containing a
186 * b input register containing b (rotated 16)
187 * c input register containing c
188 * d input register containing d (already rol $1)
189 * operations on a and b are interleaved to increase performance
190 * last round has different rotations for the output preparation
191 */
192#define decrypt_last_round(a,b,c,d,round)\
193 push c ## D;\
194 movzx a ## B, %edi;\
195 mov (%ebp,%edi,4), c ## D;\
196 movzx b ## B, %edi;\
197 mov s3(%ebp,%edi,4),%esi;\
198 movzx a ## H, %edi;\
199 ror $16, a ## D;\
200 xor s1(%ebp,%edi,4),c ## D;\
201 movzx b ## H, %edi;\
202 ror $16, b ## D;\
203 xor (%ebp,%edi,4), %esi;\
204 movzx a ## B, %edi;\
205 xor s2(%ebp,%edi,4),c ## D;\
206 movzx b ## B, %edi;\
207 xor s1(%ebp,%edi,4),%esi;\
208 movzx a ## H, %edi;\
209 ror $16, a ## D;\
210 xor s3(%ebp,%edi,4),c ## D;\
211 movzx b ## H, %edi;\
212 xor s2(%ebp,%edi,4),%esi;\
213 pop %edi;\
214 add %esi, c ## D;\
215 add c ## D, %esi;\
216 add k+round(%ebp), c ## D;\
217 xor %edi, c ## D;\
218 add k+4+round(%ebp),%esi;\
219 xor %esi, d ## D;\
220 ror $1, d ## D;
221
222.align 4
223.global twofish_enc_blk
224.global twofish_dec_blk
225
226twofish_enc_blk:
227 push %ebp /* save registers according to calling convention*/
228 push %ebx
229 push %esi
230 push %edi
231
232 mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
233 add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
234 mov in_blk+16(%esp),%edi /* input adress in edi */
235
236 mov (%edi), %eax
237 mov b_offset(%edi), %ebx
238 mov c_offset(%edi), %ecx
239 mov d_offset(%edi), %edx
240 input_whitening(%eax,%ebp,a_offset)
241 ror $16, %eax
242 input_whitening(%ebx,%ebp,b_offset)
243 input_whitening(%ecx,%ebp,c_offset)
244 input_whitening(%edx,%ebp,d_offset)
245 rol $1, %edx
246
247 encrypt_round(R0,R1,R2,R3,0);
248 encrypt_round(R2,R3,R0,R1,8);
249 encrypt_round(R0,R1,R2,R3,2*8);
250 encrypt_round(R2,R3,R0,R1,3*8);
251 encrypt_round(R0,R1,R2,R3,4*8);
252 encrypt_round(R2,R3,R0,R1,5*8);
253 encrypt_round(R0,R1,R2,R3,6*8);
254 encrypt_round(R2,R3,R0,R1,7*8);
255 encrypt_round(R0,R1,R2,R3,8*8);
256 encrypt_round(R2,R3,R0,R1,9*8);
257 encrypt_round(R0,R1,R2,R3,10*8);
258 encrypt_round(R2,R3,R0,R1,11*8);
259 encrypt_round(R0,R1,R2,R3,12*8);
260 encrypt_round(R2,R3,R0,R1,13*8);
261 encrypt_round(R0,R1,R2,R3,14*8);
262 encrypt_last_round(R2,R3,R0,R1,15*8);
263
264 output_whitening(%eax,%ebp,c_offset)
265 output_whitening(%ebx,%ebp,d_offset)
266 output_whitening(%ecx,%ebp,a_offset)
267 output_whitening(%edx,%ebp,b_offset)
268 mov out_blk+16(%esp),%edi;
269 mov %eax, c_offset(%edi)
270 mov %ebx, d_offset(%edi)
271 mov %ecx, (%edi)
272 mov %edx, b_offset(%edi)
273
274 pop %edi
275 pop %esi
276 pop %ebx
277 pop %ebp
278 mov $1, %eax
279 ret
280
281twofish_dec_blk:
282 push %ebp /* save registers according to calling convention*/
283 push %ebx
284 push %esi
285 push %edi
286
287
288 mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
289 add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
290 mov in_blk+16(%esp),%edi /* input adress in edi */
291
292 mov (%edi), %eax
293 mov b_offset(%edi), %ebx
294 mov c_offset(%edi), %ecx
295 mov d_offset(%edi), %edx
296 output_whitening(%eax,%ebp,a_offset)
297 output_whitening(%ebx,%ebp,b_offset)
298 ror $16, %ebx
299 output_whitening(%ecx,%ebp,c_offset)
300 output_whitening(%edx,%ebp,d_offset)
301 rol $1, %ecx
302
303 decrypt_round(R0,R1,R2,R3,15*8);
304 decrypt_round(R2,R3,R0,R1,14*8);
305 decrypt_round(R0,R1,R2,R3,13*8);
306 decrypt_round(R2,R3,R0,R1,12*8);
307 decrypt_round(R0,R1,R2,R3,11*8);
308 decrypt_round(R2,R3,R0,R1,10*8);
309 decrypt_round(R0,R1,R2,R3,9*8);
310 decrypt_round(R2,R3,R0,R1,8*8);
311 decrypt_round(R0,R1,R2,R3,7*8);
312 decrypt_round(R2,R3,R0,R1,6*8);
313 decrypt_round(R0,R1,R2,R3,5*8);
314 decrypt_round(R2,R3,R0,R1,4*8);
315 decrypt_round(R0,R1,R2,R3,3*8);
316 decrypt_round(R2,R3,R0,R1,2*8);
317 decrypt_round(R0,R1,R2,R3,1*8);
318 decrypt_last_round(R2,R3,R0,R1,0);
319
320 input_whitening(%eax,%ebp,c_offset)
321 input_whitening(%ebx,%ebp,d_offset)
322 input_whitening(%ecx,%ebp,a_offset)
323 input_whitening(%edx,%ebp,b_offset)
324 mov out_blk+16(%esp),%edi;
325 mov %eax, c_offset(%edi)
326 mov %ebx, d_offset(%edi)
327 mov %ecx, (%edi)
328 mov %edx, b_offset(%edi)
329
330 pop %edi
331 pop %esi
332 pop %ebx
333 pop %ebp
334 mov $1, %eax
335 ret
diff --git a/arch/i386/crypto/twofish.c b/arch/i386/crypto/twofish.c
new file mode 100644
index 000000000000..e3004dfe9c7a
--- /dev/null
+++ b/arch/i386/crypto/twofish.c
@@ -0,0 +1,97 @@
1/*
2 * Glue Code for optimized 586 assembler version of TWOFISH
3 *
4 * Originally Twofish for GPG
5 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
6 * 256-bit key length added March 20, 1999
7 * Some modifications to reduce the text size by Werner Koch, April, 1998
8 * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
9 * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
10 *
11 * The original author has disclaimed all copyright interest in this
12 * code and thus put it in the public domain. The subsequent authors
13 * have put this under the GNU General Public License.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 * USA
29 *
30 * This code is a "clean room" implementation, written from the paper
31 * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
32 * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
33 * through http://www.counterpane.com/twofish.html
34 *
35 * For background information on multiplication in finite fields, used for
36 * the matrix operations in the key schedule, see the book _Contemporary
37 * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
38 * Third Edition.
39 */
40
41#include <crypto/twofish.h>
42#include <linux/crypto.h>
43#include <linux/init.h>
44#include <linux/module.h>
45#include <linux/types.h>
46
47
48asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
49asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
50
51static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
52{
53 twofish_enc_blk(tfm, dst, src);
54}
55
56static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
57{
58 twofish_dec_blk(tfm, dst, src);
59}
60
61static struct crypto_alg alg = {
62 .cra_name = "twofish",
63 .cra_driver_name = "twofish-i586",
64 .cra_priority = 200,
65 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
66 .cra_blocksize = TF_BLOCK_SIZE,
67 .cra_ctxsize = sizeof(struct twofish_ctx),
68 .cra_alignmask = 3,
69 .cra_module = THIS_MODULE,
70 .cra_list = LIST_HEAD_INIT(alg.cra_list),
71 .cra_u = {
72 .cipher = {
73 .cia_min_keysize = TF_MIN_KEY_SIZE,
74 .cia_max_keysize = TF_MAX_KEY_SIZE,
75 .cia_setkey = twofish_setkey,
76 .cia_encrypt = twofish_encrypt,
77 .cia_decrypt = twofish_decrypt
78 }
79 }
80};
81
82static int __init init(void)
83{
84 return crypto_register_alg(&alg);
85}
86
87static void __exit fini(void)
88{
89 crypto_unregister_alg(&alg);
90}
91
92module_init(init);
93module_exit(fini);
94
95MODULE_LICENSE("GPL");
96MODULE_DESCRIPTION ("Twofish Cipher Algorithm, i586 asm optimized");
97MODULE_ALIAS("twofish");
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 694b0c63ee50..de1ef2fa1a20 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -417,6 +417,17 @@ config PPC_MAPLE
417 This option enables support for the Maple 970FX Evaluation Board. 417 This option enables support for the Maple 970FX Evaluation Board.
418 For more informations, refer to <http://www.970eval.com> 418 For more informations, refer to <http://www.970eval.com>
419 419
420config PPC_PASEMI
421 depends on PPC_MULTIPLATFORM && PPC64
422 bool "PA Semi SoC-based platforms"
423 default n
424 select MPIC
425 select PPC_UDBG_16550
426 select GENERIC_TBSYNC
427 help
428 This option enables support for PA Semi's PWRficient line
429 of SoC processors, including PA6T-1682M
430
420config PPC_CELL 431config PPC_CELL
421 bool 432 bool
422 default n 433 default n
@@ -436,7 +447,8 @@ config PPC_IBM_CELL_BLADE
436 select UDBG_RTAS_CONSOLE 447 select UDBG_RTAS_CONSOLE
437 448
438config UDBG_RTAS_CONSOLE 449config UDBG_RTAS_CONSOLE
439 bool 450 bool "RTAS based debug console"
451 depends on PPC_RTAS
440 default n 452 default n
441 453
442config XICS 454config XICS
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index e29ef77d3b00..5ad149b47e34 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -18,6 +18,20 @@ config DEBUG_STACK_USAGE
18 18
19 This option will slow down process creation somewhat. 19 This option will slow down process creation somewhat.
20 20
21config HCALL_STATS
22 bool "Hypervisor call instrumentation"
23 depends on PPC_PSERIES && DEBUG_FS
24 help
25 Adds code to keep track of the number of hypervisor calls made and
26 the amount of time spent in hypervisor callsr. Wall time spent in
27 each call is always calculated, and if available CPU cycles spent
28 are also calculated. A directory named hcall_inst is added at the
29 root of the debugfs filesystem. Within the hcall_inst directory
30 are files that contain CPU specific call statistics.
31
32 This option will add a small amount of overhead to all hypervisor
33 calls.
34
21config DEBUGGER 35config DEBUGGER
22 bool "Enable debugger hooks" 36 bool "Enable debugger hooks"
23 depends on DEBUG_KERNEL 37 depends on DEBUG_KERNEL
@@ -74,6 +88,8 @@ config XMON
74 very early during boot. 'xmon=on' will just enable the xmon 88 very early during boot. 'xmon=on' will just enable the xmon
75 debugger hooks. 'xmon=off' will disable the debugger hooks 89 debugger hooks. 'xmon=off' will disable the debugger hooks
76 if CONFIG_XMON_DEFAULT is set. 90 if CONFIG_XMON_DEFAULT is set.
91 xmon will print a backtrace on the very first invocation.
92 'xmon=nobt' will disable this autobacktrace.
77 93
78config XMON_DEFAULT 94config XMON_DEFAULT
79 bool "Enable xmon by default" 95 bool "Enable xmon by default"
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index d961bfeed05f..e73774136b55 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -36,11 +36,16 @@ zliblinuxheader := zlib.h zconf.h zutil.h
36$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) 36$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
37#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) 37#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
38 38
39src-boot := crt0.S string.S prom.c stdio.c main.c div64.S 39src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
40src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
40src-boot += $(zlib) 41src-boot += $(zlib)
41src-boot := $(addprefix $(obj)/, $(src-boot)) 42src-boot := $(addprefix $(obj)/, $(src-boot))
42obj-boot := $(addsuffix .o, $(basename $(src-boot))) 43obj-boot := $(addsuffix .o, $(basename $(src-boot)))
43 44
45ifeq ($(call cc-option-yn, -fstack-protector),y)
46BOOTCFLAGS += -fno-stack-protector
47endif
48
44BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) 49BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
45 50
46quiet_cmd_copy_zlib = COPY $@ 51quiet_cmd_copy_zlib = COPY $@
diff --git a/arch/powerpc/boot/dts/mpc8349emds.dts b/arch/powerpc/boot/dts/mpc8349emds.dts
index 12f5dbf3055f..efceb3432653 100644
--- a/arch/powerpc/boot/dts/mpc8349emds.dts
+++ b/arch/powerpc/boot/dts/mpc8349emds.dts
@@ -214,10 +214,10 @@
214 b800 0 0 4 700 15 8 214 b800 0 0 4 700 15 8
215 215
216 /* IDSEL 0x18 */ 216 /* IDSEL 0x18 */
217 b000 0 0 1 700 15 8 217 c000 0 0 1 700 15 8
218 b000 0 0 2 700 16 8 218 c000 0 0 2 700 16 8
219 b000 0 0 3 700 17 8 219 c000 0 0 3 700 17 8
220 b000 0 0 4 700 14 8>; 220 c000 0 0 4 700 14 8>;
221 interrupt-parent = <700>; 221 interrupt-parent = <700>;
222 interrupts = <42 8>; 222 interrupts = <42 8>;
223 bus-range = <0 0>; 223 bus-range = <0 0>;
@@ -274,10 +274,10 @@
274 b800 0 0 4 700 15 8 274 b800 0 0 4 700 15 8
275 275
276 /* IDSEL 0x18 */ 276 /* IDSEL 0x18 */
277 b000 0 0 1 700 15 8 277 c000 0 0 1 700 15 8
278 b000 0 0 2 700 16 8 278 c000 0 0 2 700 16 8
279 b000 0 0 3 700 17 8 279 c000 0 0 3 700 17 8
280 b000 0 0 4 700 14 8>; 280 c000 0 0 4 700 14 8>;
281 interrupt-parent = <700>; 281 interrupt-parent = <700>;
282 interrupts = <42 8>; 282 interrupts = <42 8>;
283 bus-range = <0 0>; 283 bus-range = <0 0>;
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h
new file mode 100644
index 000000000000..761c8dc84008
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree.h
@@ -0,0 +1,46 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16
17#ifndef FLATDEVTREE_H
18#define FLATDEVTREE_H
19
20#include "types.h"
21
22/* Definitions used by the flattened device tree */
23#define OF_DT_HEADER 0xd00dfeed /* marker */
24#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
25#define OF_DT_END_NODE 0x2 /* End node */
26#define OF_DT_PROP 0x3 /* Property: name off, size, content */
27#define OF_DT_NOP 0x4 /* nop */
28#define OF_DT_END 0x9
29
30#define OF_DT_VERSION 0x10
31
32struct boot_param_header {
33 u32 magic; /* magic word OF_DT_HEADER */
34 u32 totalsize; /* total size of DT block */
35 u32 off_dt_struct; /* offset to structure */
36 u32 off_dt_strings; /* offset to strings */
37 u32 off_mem_rsvmap; /* offset to memory reserve map */
38 u32 version; /* format version */
39 u32 last_comp_version; /* last compatible version */
40 /* version 2 fields below */
41 u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
42 /* version 3 fields below */
43 u32 dt_strings_size; /* size of the DT strings block */
44};
45
46#endif /* FLATDEVTREE_H */
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index b66634c9ea34..d719bb9333d1 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -14,17 +14,12 @@
14#include "page.h" 14#include "page.h"
15#include "string.h" 15#include "string.h"
16#include "stdio.h" 16#include "stdio.h"
17#include "prom.h"
18#include "zlib.h" 17#include "zlib.h"
18#include "ops.h"
19#include "flatdevtree.h"
19 20
20extern void flush_cache(void *, unsigned long); 21extern void flush_cache(void *, unsigned long);
21 22
22
23/* Value picked to match that used by yaboot */
24#define PROG_START 0x01400000 /* only used on 64-bit systems */
25#define RAM_END (512<<20) /* Fixme: use OF */
26#define ONE_MB 0x100000
27
28extern char _start[]; 23extern char _start[];
29extern char __bss_start[]; 24extern char __bss_start[];
30extern char _end[]; 25extern char _end[];
@@ -33,14 +28,6 @@ extern char _vmlinux_end[];
33extern char _initrd_start[]; 28extern char _initrd_start[];
34extern char _initrd_end[]; 29extern char _initrd_end[];
35 30
36/* A buffer that may be edited by tools operating on a zImage binary so as to
37 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
38 * The buffer is put in it's own section so that tools may locate it easier.
39 */
40static char builtin_cmdline[512]
41 __attribute__((section("__builtin_cmdline")));
42
43
44struct addr_range { 31struct addr_range {
45 unsigned long addr; 32 unsigned long addr;
46 unsigned long size; 33 unsigned long size;
@@ -51,21 +38,16 @@ static struct addr_range vmlinuz;
51static struct addr_range initrd; 38static struct addr_range initrd;
52 39
53static unsigned long elfoffset; 40static unsigned long elfoffset;
41static int is_64bit;
54 42
55static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ 43/* scratch space for gunzip; 46912 is from zlib_inflate_workspacesize() */
44static char scratch[46912];
56static char elfheader[256]; 45static char elfheader[256];
57 46
58 47typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
59typedef void (*kernel_entry_t)( unsigned long,
60 unsigned long,
61 void *,
62 void *);
63
64 48
65#undef DEBUG 49#undef DEBUG
66 50
67static unsigned long claim_base;
68
69#define HEAD_CRC 2 51#define HEAD_CRC 2
70#define EXTRA_FIELD 4 52#define EXTRA_FIELD 4
71#define ORIG_NAME 8 53#define ORIG_NAME 8
@@ -123,24 +105,6 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
123 zlib_inflateEnd(&s); 105 zlib_inflateEnd(&s);
124} 106}
125 107
126static unsigned long try_claim(unsigned long size)
127{
128 unsigned long addr = 0;
129
130 for(; claim_base < RAM_END; claim_base += ONE_MB) {
131#ifdef DEBUG
132 printf(" trying: 0x%08lx\n\r", claim_base);
133#endif
134 addr = (unsigned long)claim(claim_base, size, 0);
135 if ((void *)addr != (void *)-1)
136 break;
137 }
138 if (addr == 0)
139 return 0;
140 claim_base = PAGE_ALIGN(claim_base + size);
141 return addr;
142}
143
144static int is_elf64(void *hdr) 108static int is_elf64(void *hdr)
145{ 109{
146 Elf64_Ehdr *elf64 = hdr; 110 Elf64_Ehdr *elf64 = hdr;
@@ -169,16 +133,7 @@ static int is_elf64(void *hdr)
169 vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset; 133 vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
170 vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset; 134 vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
171 135
172#if defined(PROG_START) 136 is_64bit = 1;
173 /*
174 * Maintain a "magic" minimum address. This keeps some older
175 * firmware platforms running.
176 */
177
178 if (claim_base < PROG_START)
179 claim_base = PROG_START;
180#endif
181
182 return 1; 137 return 1;
183} 138}
184 139
@@ -212,47 +167,9 @@ static int is_elf32(void *hdr)
212 return 1; 167 return 1;
213} 168}
214 169
215void export_cmdline(void* chosen_handle) 170static void prep_kernel(unsigned long *a1, unsigned long *a2)
216{
217 int len;
218 char cmdline[2] = { 0, 0 };
219
220 if (builtin_cmdline[0] == 0)
221 return;
222
223 len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline));
224 if (len > 0 && cmdline[0] != 0)
225 return;
226
227 setprop(chosen_handle, "bootargs", builtin_cmdline,
228 strlen(builtin_cmdline) + 1);
229}
230
231
232void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
233{ 171{
234 int len; 172 int len;
235 kernel_entry_t kernel_entry;
236
237 memset(__bss_start, 0, _end - __bss_start);
238
239 prom = (int (*)(void *)) promptr;
240 chosen_handle = finddevice("/chosen");
241 if (chosen_handle == (void *) -1)
242 exit();
243 if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
244 exit();
245
246 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
247
248 /*
249 * The first available claim_base must be above the end of the
250 * the loaded kernel wrapper file (_start to _end includes the
251 * initrd image if it is present) and rounded up to a nice
252 * 1 MB boundary for good measure.
253 */
254
255 claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
256 173
257 vmlinuz.addr = (unsigned long)_vmlinux_start; 174 vmlinuz.addr = (unsigned long)_vmlinux_start;
258 vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); 175 vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
@@ -263,43 +180,51 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
263 gunzip(elfheader, sizeof(elfheader), 180 gunzip(elfheader, sizeof(elfheader),
264 (unsigned char *)vmlinuz.addr, &len); 181 (unsigned char *)vmlinuz.addr, &len);
265 } else 182 } else
266 memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader)); 183 memcpy(elfheader, (const void *)vmlinuz.addr,
184 sizeof(elfheader));
267 185
268 if (!is_elf64(elfheader) && !is_elf32(elfheader)) { 186 if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
269 printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r"); 187 printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
270 exit(); 188 exit();
271 } 189 }
190 if (platform_ops.image_hdr)
191 platform_ops.image_hdr(elfheader);
272 192
273 /* We need to claim the memsize plus the file offset since gzip 193 /* We need to alloc the memsize plus the file offset since gzip
274 * will expand the header (file offset), then the kernel, then 194 * will expand the header (file offset), then the kernel, then
275 * possible rubbish we don't care about. But the kernel bss must 195 * possible rubbish we don't care about. But the kernel bss must
276 * be claimed (it will be zero'd by the kernel itself) 196 * be claimed (it will be zero'd by the kernel itself)
277 */ 197 */
278 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize); 198 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
279 vmlinux.addr = try_claim(vmlinux.memsize); 199 vmlinux.addr = (unsigned long)malloc(vmlinux.memsize);
280 if (vmlinux.addr == 0) { 200 if (vmlinux.addr == 0) {
281 printf("Can't allocate memory for kernel image !\n\r"); 201 printf("Can't allocate memory for kernel image !\n\r");
282 exit(); 202 exit();
283 } 203 }
284 204
285 /* 205 /*
286 * Now we try to claim memory for the initrd (and copy it there) 206 * Now we try to alloc memory for the initrd (and copy it there)
287 */ 207 */
288 initrd.size = (unsigned long)(_initrd_end - _initrd_start); 208 initrd.size = (unsigned long)(_initrd_end - _initrd_start);
289 initrd.memsize = initrd.size; 209 initrd.memsize = initrd.size;
290 if ( initrd.size > 0 ) { 210 if ( initrd.size > 0 ) {
291 printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size); 211 printf("Allocating 0x%lx bytes for initrd ...\n\r",
292 initrd.addr = try_claim(initrd.size); 212 initrd.size);
213 initrd.addr = (unsigned long)malloc((u32)initrd.size);
293 if (initrd.addr == 0) { 214 if (initrd.addr == 0) {
294 printf("Can't allocate memory for initial ramdisk !\n\r"); 215 printf("Can't allocate memory for initial "
216 "ramdisk !\n\r");
295 exit(); 217 exit();
296 } 218 }
297 a1 = initrd.addr; 219 *a1 = initrd.addr;
298 a2 = initrd.size; 220 *a2 = initrd.size;
299 printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", 221 printf("initial ramdisk moving 0x%lx <- 0x%lx "
300 initrd.addr, (unsigned long)_initrd_start, initrd.size); 222 "(0x%lx bytes)\n\r", initrd.addr,
301 memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); 223 (unsigned long)_initrd_start, initrd.size);
302 printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); 224 memmove((void *)initrd.addr, (void *)_initrd_start,
225 initrd.size);
226 printf("initrd head: 0x%lx\n\r",
227 *((unsigned long *)initrd.addr));
303 } 228 }
304 229
305 /* Eventually gunzip the kernel */ 230 /* Eventually gunzip the kernel */
@@ -311,11 +236,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
311 (unsigned char *)vmlinuz.addr, &len); 236 (unsigned char *)vmlinuz.addr, &len);
312 printf("done 0x%lx bytes\n\r", len); 237 printf("done 0x%lx bytes\n\r", len);
313 } else { 238 } else {
314 memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); 239 memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,
240 vmlinuz.size);
315 } 241 }
316 242
317 export_cmdline(chosen_handle);
318
319 /* Skip over the ELF header */ 243 /* Skip over the ELF header */
320#ifdef DEBUG 244#ifdef DEBUG
321 printf("... skipping 0x%lx bytes of ELF header\n\r", 245 printf("... skipping 0x%lx bytes of ELF header\n\r",
@@ -324,23 +248,107 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
324 vmlinux.addr += elfoffset; 248 vmlinux.addr += elfoffset;
325 249
326 flush_cache((void *)vmlinux.addr, vmlinux.size); 250 flush_cache((void *)vmlinux.addr, vmlinux.size);
251}
327 252
328 kernel_entry = (kernel_entry_t)vmlinux.addr; 253void __attribute__ ((weak)) ft_init(void *dt_blob)
329#ifdef DEBUG 254{
330 printf( "kernel:\n\r" 255}
331 " entry addr = 0x%lx\n\r"
332 " a1 = 0x%lx,\n\r"
333 " a2 = 0x%lx,\n\r"
334 " prom = 0x%lx,\n\r"
335 " bi_recs = 0x%lx,\n\r",
336 (unsigned long)kernel_entry, a1, a2,
337 (unsigned long)prom, NULL);
338#endif
339 256
340 kernel_entry(a1, a2, prom, NULL); 257/* A buffer that may be edited by tools operating on a zImage binary so as to
258 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
259 * The buffer is put in it's own section so that tools may locate it easier.
260 */
261static char builtin_cmdline[COMMAND_LINE_SIZE]
262 __attribute__((__section__("__builtin_cmdline")));
341 263
342 printf("Error: Linux kernel returned to zImage bootloader!\n\r"); 264static void get_cmdline(char *buf, int size)
265{
266 void *devp;
267 int len = strlen(builtin_cmdline);
343 268
344 exit(); 269 buf[0] = '\0';
270
271 if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */
272 len = min(len, size-1);
273 strncpy(buf, builtin_cmdline, len);
274 buf[len] = '\0';
275 }
276 else if ((devp = finddevice("/chosen")))
277 getprop(devp, "bootargs", buf, size);
278}
279
280static void set_cmdline(char *buf)
281{
282 void *devp;
283
284 if ((devp = finddevice("/chosen")))
285 setprop(devp, "bootargs", buf, strlen(buf) + 1);
345} 286}
346 287
288/* Section where ft can be tacked on after zImage is built */
289union blobspace {
290 struct boot_param_header hdr;
291 char space[8*1024];
292} dt_blob __attribute__((__section__("__builtin_ft")));
293
294struct platform_ops platform_ops;
295struct dt_ops dt_ops;
296struct console_ops console_ops;
297
298void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
299{
300 int have_dt = 0;
301 kernel_entry_t kentry;
302 char cmdline[COMMAND_LINE_SIZE];
303
304 memset(__bss_start, 0, _end - __bss_start);
305 memset(&platform_ops, 0, sizeof(platform_ops));
306 memset(&dt_ops, 0, sizeof(dt_ops));
307 memset(&console_ops, 0, sizeof(console_ops));
308
309 /* Override the dt_ops and device tree if there was an flat dev
310 * tree attached to the zImage.
311 */
312 if (dt_blob.hdr.magic == OF_DT_HEADER) {
313 have_dt = 1;
314 ft_init(&dt_blob);
315 }
316
317 if (platform_init(promptr))
318 exit();
319 if (console_ops.open && (console_ops.open() < 0))
320 exit();
321 if (platform_ops.fixups)
322 platform_ops.fixups();
323
324 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
325 _start, sp);
326
327 prep_kernel(&a1, &a2);
328
329 /* If cmdline came from zimage wrapper or if we can edit the one
330 * in the dt, print it out and edit it, if possible.
331 */
332 if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) {
333 get_cmdline(cmdline, COMMAND_LINE_SIZE);
334 printf("\n\rLinux/PowerPC load: %s", cmdline);
335 if (console_ops.edit_cmdline)
336 console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
337 printf("\n\r");
338 set_cmdline(cmdline);
339 }
340
341 if (console_ops.close)
342 console_ops.close();
343
344 kentry = (kernel_entry_t) vmlinux.addr;
345 if (have_dt)
346 kentry(dt_ops.ft_addr(), 0, NULL);
347 else
348 /* XXX initrd addr/size should be passed in properties */
349 kentry(a1, a2, promptr);
350
351 /* console closed so printf below may not work */
352 printf("Error: Linux kernel returned to zImage boot wrapper!\n\r");
353 exit();
354}
diff --git a/arch/powerpc/boot/prom.c b/arch/powerpc/boot/of.c
index fa0057736f6b..fd99f789a37b 100644
--- a/arch/powerpc/boot/prom.c
+++ b/arch/powerpc/boot/of.c
@@ -8,15 +8,29 @@
8 */ 8 */
9#include <stdarg.h> 9#include <stdarg.h>
10#include <stddef.h> 10#include <stddef.h>
11#include "types.h"
12#include "elf.h"
11#include "string.h" 13#include "string.h"
12#include "stdio.h" 14#include "stdio.h"
13#include "prom.h" 15#include "page.h"
16#include "ops.h"
14 17
15int (*prom)(void *); 18typedef void *ihandle;
16phandle chosen_handle; 19typedef void *phandle;
17ihandle stdout;
18 20
19int call_prom(const char *service, int nargs, int nret, ...) 21extern char _end[];
22
23/* Value picked to match that used by yaboot */
24#define PROG_START 0x01400000 /* only used on 64-bit systems */
25#define RAM_END (512<<20) /* Fixme: use OF */
26#define ONE_MB 0x100000
27
28int (*prom) (void *);
29
30
31static unsigned long claim_base;
32
33static int call_prom(const char *service, int nargs, int nret, ...)
20{ 34{
21 int i; 35 int i;
22 struct prom_args { 36 struct prom_args {
@@ -45,7 +59,7 @@ int call_prom(const char *service, int nargs, int nret, ...)
45 return (nret > 0)? args.args[nargs]: 0; 59 return (nret > 0)? args.args[nargs]: 0;
46} 60}
47 61
48int call_prom_ret(const char *service, int nargs, int nret, 62static int call_prom_ret(const char *service, int nargs, int nret,
49 unsigned int *rets, ...) 63 unsigned int *rets, ...)
50{ 64{
51 int i; 65 int i;
@@ -79,11 +93,6 @@ int call_prom_ret(const char *service, int nargs, int nret,
79 return (nret > 0)? args.args[nargs]: 0; 93 return (nret > 0)? args.args[nargs]: 0;
80} 94}
81 95
82int write(void *handle, void *ptr, int nb)
83{
84 return call_prom("write", 3, 1, handle, ptr, nb);
85}
86
87/* 96/*
88 * Older OF's require that when claiming a specific range of addresses, 97 * Older OF's require that when claiming a specific range of addresses,
89 * we claim the physical space in the /memory node and the virtual 98 * we claim the physical space in the /memory node and the virtual
@@ -142,7 +151,7 @@ static int check_of_version(void)
142 return 1; 151 return 1;
143} 152}
144 153
145void *claim(unsigned long virt, unsigned long size, unsigned long align) 154static void *claim(unsigned long virt, unsigned long size, unsigned long align)
146{ 155{
147 int ret; 156 int ret;
148 unsigned int result; 157 unsigned int result;
@@ -151,7 +160,7 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
151 need_map = check_of_version(); 160 need_map = check_of_version();
152 if (align || !need_map) 161 if (align || !need_map)
153 return (void *) call_prom("claim", 3, 1, virt, size, align); 162 return (void *) call_prom("claim", 3, 1, virt, size, align);
154 163
155 ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory, 164 ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
156 align, size, virt); 165 align, size, virt);
157 if (ret != 0 || result == -1) 166 if (ret != 0 || result == -1)
@@ -163,3 +172,112 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
163 0x12, size, virt, virt); 172 0x12, size, virt, virt);
164 return (void *) virt; 173 return (void *) virt;
165} 174}
175
176static void *of_try_claim(u32 size)
177{
178 unsigned long addr = 0;
179 static u8 first_time = 1;
180
181 if (first_time) {
182 claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
183 first_time = 0;
184 }
185
186 for(; claim_base < RAM_END; claim_base += ONE_MB) {
187#ifdef DEBUG
188 printf(" trying: 0x%08lx\n\r", claim_base);
189#endif
190 addr = (unsigned long)claim(claim_base, size, 0);
191 if ((void *)addr != (void *)-1)
192 break;
193 }
194 if (addr == 0)
195 return NULL;
196 claim_base = PAGE_ALIGN(claim_base + size);
197 return (void *)addr;
198}
199
200static void of_image_hdr(const void *hdr)
201{
202 const Elf64_Ehdr *elf64 = hdr;
203
204 if (elf64->e_ident[EI_CLASS] == ELFCLASS64) {
205 /*
206 * Maintain a "magic" minimum address. This keeps some older
207 * firmware platforms running.
208 */
209 if (claim_base < PROG_START)
210 claim_base = PROG_START;
211 }
212}
213
214static void of_exit(void)
215{
216 call_prom("exit", 0, 0);
217}
218
219/*
220 * OF device tree routines
221 */
222static void *of_finddevice(const char *name)
223{
224 return (phandle) call_prom("finddevice", 1, 1, name);
225}
226
227static int of_getprop(const void *phandle, const char *name, void *buf,
228 const int buflen)
229{
230 return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
231}
232
233static int of_setprop(const void *phandle, const char *name, const void *buf,
234 const int buflen)
235{
236 return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
237}
238
239/*
240 * OF console routines
241 */
242static void *of_stdout_handle;
243
244static int of_console_open(void)
245{
246 void *devp;
247
248 if (((devp = finddevice("/chosen")) != NULL)
249 && (getprop(devp, "stdout", &of_stdout_handle,
250 sizeof(of_stdout_handle))
251 == sizeof(of_stdout_handle)))
252 return 0;
253
254 return -1;
255}
256
257static void of_console_write(char *buf, int len)
258{
259 call_prom("write", 3, 1, of_stdout_handle, buf, len);
260}
261
262int platform_init(void *promptr)
263{
264 platform_ops.fixups = NULL;
265 platform_ops.image_hdr = of_image_hdr;
266 platform_ops.malloc = of_try_claim;
267 platform_ops.free = NULL;
268 platform_ops.exit = of_exit;
269
270 dt_ops.finddevice = of_finddevice;
271 dt_ops.getprop = of_getprop;
272 dt_ops.setprop = of_setprop;
273 dt_ops.translate_addr = NULL;
274
275 console_ops.open = of_console_open;
276 console_ops.write = of_console_write;
277 console_ops.edit_cmdline = NULL;
278 console_ops.close = NULL;
279 console_ops.data = NULL;
280
281 prom = (int (*)(void *))promptr;
282 return 0;
283}
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
new file mode 100644
index 000000000000..135eb4bb03b4
--- /dev/null
+++ b/arch/powerpc/boot/ops.h
@@ -0,0 +1,100 @@
1/*
2 * Global definition of all the bootwrapper operations.
3 *
4 * Author: Mark A. Greer <mgreer@mvista.com>
5 *
6 * 2006 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11#ifndef _PPC_BOOT_OPS_H_
12#define _PPC_BOOT_OPS_H_
13
14#include "types.h"
15
16#define COMMAND_LINE_SIZE 512
17#define MAX_PATH_LEN 256
18#define MAX_PROP_LEN 256 /* What should this be? */
19
20/* Platform specific operations */
21struct platform_ops {
22 void (*fixups)(void);
23 void (*image_hdr)(const void *);
24 void * (*malloc)(u32 size);
25 void (*free)(void *ptr, u32 size);
26 void (*exit)(void);
27};
28extern struct platform_ops platform_ops;
29
30/* Device Tree operations */
31struct dt_ops {
32 void * (*finddevice)(const char *name);
33 int (*getprop)(const void *node, const char *name, void *buf,
34 const int buflen);
35 int (*setprop)(const void *node, const char *name,
36 const void *buf, const int buflen);
37 u64 (*translate_addr)(const char *path, const u32 *in_addr,
38 const u32 addr_len);
39 unsigned long (*ft_addr)(void);
40};
41extern struct dt_ops dt_ops;
42
43/* Console operations */
44struct console_ops {
45 int (*open)(void);
46 void (*write)(char *buf, int len);
47 void (*edit_cmdline)(char *buf, int len);
48 void (*close)(void);
49 void *data;
50};
51extern struct console_ops console_ops;
52
53/* Serial console operations */
54struct serial_console_data {
55 int (*open)(void);
56 void (*putc)(unsigned char c);
57 unsigned char (*getc)(void);
58 u8 (*tstc)(void);
59 void (*close)(void);
60};
61
62extern int platform_init(void *promptr);
63extern void simple_alloc_init(void);
64extern void ft_init(void *dt_blob);
65extern int serial_console_init(void);
66
67static inline void *finddevice(const char *name)
68{
69 return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
70}
71
72static inline int getprop(void *devp, const char *name, void *buf, int buflen)
73{
74 return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1;
75}
76
77static inline int setprop(void *devp, const char *name, void *buf, int buflen)
78{
79 return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1;
80}
81
82static inline void *malloc(u32 size)
83{
84 return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
85}
86
87static inline void free(void *ptr, u32 size)
88{
89 if (platform_ops.free)
90 platform_ops.free(ptr, size);
91}
92
93static inline void exit(void)
94{
95 if (platform_ops.exit)
96 platform_ops.exit();
97 for(;;);
98}
99
100#endif /* _PPC_BOOT_OPS_H_ */
diff --git a/arch/powerpc/boot/prom.h b/arch/powerpc/boot/prom.h
deleted file mode 100644
index a57b184c564f..000000000000
--- a/arch/powerpc/boot/prom.h
+++ /dev/null
@@ -1,41 +0,0 @@
1#ifndef _PPC_BOOT_PROM_H_
2#define _PPC_BOOT_PROM_H_
3
4typedef void *phandle;
5typedef void *ihandle;
6
7extern int (*prom) (void *);
8extern phandle chosen_handle;
9extern ihandle stdout;
10
11int call_prom(const char *service, int nargs, int nret, ...);
12int call_prom_ret(const char *service, int nargs, int nret,
13 unsigned int *rets, ...);
14
15extern int write(void *handle, void *ptr, int nb);
16extern void *claim(unsigned long virt, unsigned long size, unsigned long aln);
17
18static inline void exit(void)
19{
20 call_prom("exit", 0, 0);
21}
22
23static inline phandle finddevice(const char *name)
24{
25 return (phandle) call_prom("finddevice", 1, 1, name);
26}
27
28static inline int getprop(void *phandle, const char *name,
29 void *buf, int buflen)
30{
31 return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
32}
33
34
35static inline int setprop(void *phandle, const char *name,
36 void *buf, int buflen)
37{
38 return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
39}
40
41#endif /* _PPC_BOOT_PROM_H_ */
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c
index b5aa522f8b77..6d5f6382e1ce 100644
--- a/arch/powerpc/boot/stdio.c
+++ b/arch/powerpc/boot/stdio.c
@@ -10,7 +10,7 @@
10#include <stddef.h> 10#include <stddef.h>
11#include "string.h" 11#include "string.h"
12#include "stdio.h" 12#include "stdio.h"
13#include "prom.h" 13#include "ops.h"
14 14
15size_t strnlen(const char * s, size_t count) 15size_t strnlen(const char * s, size_t count)
16{ 16{
@@ -320,6 +320,6 @@ printf(const char *fmt, ...)
320 va_start(args, fmt); 320 va_start(args, fmt);
321 n = vsprintf(sprint_buf, fmt, args); 321 n = vsprintf(sprint_buf, fmt, args);
322 va_end(args); 322 va_end(args);
323 write(stdout, sprint_buf, n); 323 console_ops.write(sprint_buf, n);
324 return n; 324 return n;
325} 325}
diff --git a/arch/powerpc/boot/stdio.h b/arch/powerpc/boot/stdio.h
index eb9e16c87aef..73b8a91bfb34 100644
--- a/arch/powerpc/boot/stdio.h
+++ b/arch/powerpc/boot/stdio.h
@@ -1,8 +1,16 @@
1#ifndef _PPC_BOOT_STDIO_H_ 1#ifndef _PPC_BOOT_STDIO_H_
2#define _PPC_BOOT_STDIO_H_ 2#define _PPC_BOOT_STDIO_H_
3 3
4#include <stdarg.h>
5
6#define ENOMEM 12 /* Out of Memory */
7#define EINVAL 22 /* Invalid argument */
8#define ENOSPC 28 /* No space left on device */
9
4extern int printf(const char *fmt, ...); 10extern int printf(const char *fmt, ...);
5 11
12#define fprintf(fmt, args...) printf(args)
13
6extern int sprintf(char *buf, const char *fmt, ...); 14extern int sprintf(char *buf, const char *fmt, ...);
7 15
8extern int vsprintf(char *buf, const char *fmt, va_list args); 16extern int vsprintf(char *buf, const char *fmt, va_list args);
diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h
new file mode 100644
index 000000000000..79d26e708677
--- /dev/null
+++ b/arch/powerpc/boot/types.h
@@ -0,0 +1,23 @@
1#ifndef _TYPES_H_
2#define _TYPES_H_
3
4#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
5
6typedef unsigned char u8;
7typedef unsigned short u16;
8typedef unsigned int u32;
9typedef unsigned long long u64;
10
11#define min(x,y) ({ \
12 typeof(x) _x = (x); \
13 typeof(y) _y = (y); \
14 (void) (&_x == &_y); \
15 _x < _y ? _x : _y; })
16
17#define max(x,y) ({ \
18 typeof(x) _x = (x); \
19 typeof(y) _y = (y); \
20 (void) (&_x == &_y); \
21 _x > _y ? _x : _y; })
22
23#endif /* _TYPES_H_ */
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig
index 2860be106f4f..62ba66091a13 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -496,7 +496,7 @@ CONFIG_E1000=y
496# CONFIG_SKY2 is not set 496# CONFIG_SKY2 is not set
497# CONFIG_SK98LIN is not set 497# CONFIG_SK98LIN is not set
498# CONFIG_VIA_VELOCITY is not set 498# CONFIG_VIA_VELOCITY is not set
499# CONFIG_TIGON3 is not set 499CONFIG_TIGON3=y
500# CONFIG_BNX2 is not set 500# CONFIG_BNX2 is not set
501# CONFIG_MV643XX_ETH is not set 501# CONFIG_MV643XX_ETH is not set
502 502
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 7d32ad0194a4..8b133afbdc20 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -16,7 +16,7 @@ obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
16obj-y += vdso32/ 16obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o \ 18 signal_64.o ptrace32.o \
19 paca.o cpu_setup_power4.o \ 19 paca.o cpu_setup_ppc970.o \
20 firmware.o sysfs.o 20 firmware.o sysfs.o
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
@@ -51,7 +51,7 @@ extra-$(CONFIG_8xx) := head_8xx.o
51extra-y += vmlinux.lds 51extra-y += vmlinux.lds
52 52
53obj-y += time.o prom.o traps.o setup-common.o \ 53obj-y += time.o prom.o traps.o setup-common.o \
54 udbg.o misc.o 54 udbg.o misc.o io.o
55obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o 55obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o
56obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o 56obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
57obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 57obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 7ee84968087b..d06f378597bb 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -40,9 +40,10 @@
40#ifdef CONFIG_PPC64 40#ifdef CONFIG_PPC64
41#include <asm/paca.h> 41#include <asm/paca.h>
42#include <asm/lppaca.h> 42#include <asm/lppaca.h>
43#include <asm/iseries/hv_lp_event.h>
44#include <asm/cache.h> 43#include <asm/cache.h>
45#include <asm/compat.h> 44#include <asm/compat.h>
45#include <asm/mmu.h>
46#include <asm/hvcall.h>
46#endif 47#endif
47 48
48#define DEFINE(sym, val) \ 49#define DEFINE(sym, val) \
@@ -136,11 +137,18 @@ int main(void)
136 DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); 137 DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
137 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); 138 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
138 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); 139 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
140 DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
141 DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
139 142
143 DEFINE(SLBSHADOW_STACKVSID,
144 offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid));
145 DEFINE(SLBSHADOW_STACKESID,
146 offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid));
140 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); 147 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
141 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); 148 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
142 DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); 149 DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
143 DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); 150 DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
151 DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
144#endif /* CONFIG_PPC64 */ 152#endif /* CONFIG_PPC64 */
145 153
146 /* RTAS */ 154 /* RTAS */
@@ -159,6 +167,12 @@ int main(void)
159 /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */ 167 /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
160 DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); 168 DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
161 DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); 169 DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
170
171 /* hcall statistics */
172 DEFINE(HCALL_STAT_SIZE, sizeof(struct hcall_stats));
173 DEFINE(HCALL_STAT_CALLS, offsetof(struct hcall_stats, num_calls));
174 DEFINE(HCALL_STAT_TB, offsetof(struct hcall_stats, tb_total));
175 DEFINE(HCALL_STAT_PURR, offsetof(struct hcall_stats, purr_total));
162#endif /* CONFIG_PPC64 */ 176#endif /* CONFIG_PPC64 */
163 DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0])); 177 DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
164 DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1])); 178 DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
@@ -240,6 +254,7 @@ int main(void)
240 DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); 254 DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
241 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); 255 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
242 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); 256 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
257 DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
243 258
244#ifndef CONFIG_PPC64 259#ifndef CONFIG_PPC64
245 DEFINE(pbe_address, offsetof(struct pbe, address)); 260 DEFINE(pbe_address, offsetof(struct pbe, address));
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index f4e5e14ee2b6..995fcef156fd 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -158,35 +158,35 @@ int btext_initialize(struct device_node *np)
158{ 158{
159 unsigned int width, height, depth, pitch; 159 unsigned int width, height, depth, pitch;
160 unsigned long address = 0; 160 unsigned long address = 0;
161 u32 *prop; 161 const u32 *prop;
162 162
163 prop = (u32 *)get_property(np, "linux,bootx-width", NULL); 163 prop = get_property(np, "linux,bootx-width", NULL);
164 if (prop == NULL) 164 if (prop == NULL)
165 prop = (u32 *)get_property(np, "width", NULL); 165 prop = get_property(np, "width", NULL);
166 if (prop == NULL) 166 if (prop == NULL)
167 return -EINVAL; 167 return -EINVAL;
168 width = *prop; 168 width = *prop;
169 prop = (u32 *)get_property(np, "linux,bootx-height", NULL); 169 prop = get_property(np, "linux,bootx-height", NULL);
170 if (prop == NULL) 170 if (prop == NULL)
171 prop = (u32 *)get_property(np, "height", NULL); 171 prop = get_property(np, "height", NULL);
172 if (prop == NULL) 172 if (prop == NULL)
173 return -EINVAL; 173 return -EINVAL;
174 height = *prop; 174 height = *prop;
175 prop = (u32 *)get_property(np, "linux,bootx-depth", NULL); 175 prop = get_property(np, "linux,bootx-depth", NULL);
176 if (prop == NULL) 176 if (prop == NULL)
177 prop = (u32 *)get_property(np, "depth", NULL); 177 prop = get_property(np, "depth", NULL);
178 if (prop == NULL) 178 if (prop == NULL)
179 return -EINVAL; 179 return -EINVAL;
180 depth = *prop; 180 depth = *prop;
181 pitch = width * ((depth + 7) / 8); 181 pitch = width * ((depth + 7) / 8);
182 prop = (u32 *)get_property(np, "linux,bootx-linebytes", NULL); 182 prop = get_property(np, "linux,bootx-linebytes", NULL);
183 if (prop == NULL) 183 if (prop == NULL)
184 prop = (u32 *)get_property(np, "linebytes", NULL); 184 prop = get_property(np, "linebytes", NULL);
185 if (prop) 185 if (prop)
186 pitch = *prop; 186 pitch = *prop;
187 if (pitch == 1) 187 if (pitch == 1)
188 pitch = 0x1000; 188 pitch = 0x1000;
189 prop = (u32 *)get_property(np, "address", NULL); 189 prop = get_property(np, "address", NULL);
190 if (prop) 190 if (prop)
191 address = *prop; 191 address = *prop;
192 192
@@ -214,11 +214,11 @@ int btext_initialize(struct device_node *np)
214 214
215int __init btext_find_display(int allow_nonstdout) 215int __init btext_find_display(int allow_nonstdout)
216{ 216{
217 char *name; 217 const char *name;
218 struct device_node *np = NULL; 218 struct device_node *np = NULL;
219 int rc = -ENODEV; 219 int rc = -ENODEV;
220 220
221 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 221 name = get_property(of_chosen, "linux,stdout-path", NULL);
222 if (name != NULL) { 222 if (name != NULL) {
223 np = of_find_node_by_path(name); 223 np = of_find_node_by_path(name);
224 if (np != NULL) { 224 if (np != NULL) {
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_ppc970.S
index 76e97aa71c45..652594891d58 100644
--- a/arch/powerpc/kernel/cpu_setup_power4.S
+++ b/arch/powerpc/kernel/cpu_setup_ppc970.S
@@ -16,27 +16,12 @@
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/cache.h> 17#include <asm/cache.h>
18 18
19_GLOBAL(__970_cpu_preinit) 19_GLOBAL(__cpu_preinit_ppc970)
20 /* 20 /* Do nothing if not running in HV mode */
21 * Do nothing if not running in HV mode
22 */
23 mfmsr r0 21 mfmsr r0
24 rldicl. r0,r0,4,63 22 rldicl. r0,r0,4,63
25 beqlr 23 beqlr
26 24
27 /*
28 * Deal only with PPC970 and PPC970FX.
29 */
30 mfspr r0,SPRN_PVR
31 srwi r0,r0,16
32 cmpwi r0,0x39
33 beq 1f
34 cmpwi r0,0x3c
35 beq 1f
36 cmpwi r0,0x44
37 bnelr
381:
39
40 /* Make sure HID4:rm_ci is off before MMU is turned off, that large 25 /* Make sure HID4:rm_ci is off before MMU is turned off, that large
41 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and 26 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
42 * HID5:DCBZ32_ill 27 * HID5:DCBZ32_ill
@@ -72,23 +57,6 @@ _GLOBAL(__970_cpu_preinit)
72 isync 57 isync
73 blr 58 blr
74 59
75_GLOBAL(__setup_cpu_ppc970)
76 mfspr r0,SPRN_HID0
77 li r11,5 /* clear DOZE and SLEEP */
78 rldimi r0,r11,52,8 /* set NAP and DPM */
79 li r11,0
80 rldimi r0,r11,32,31 /* clear EN_ATTN */
81 mtspr SPRN_HID0,r0
82 mfspr r0,SPRN_HID0
83 mfspr r0,SPRN_HID0
84 mfspr r0,SPRN_HID0
85 mfspr r0,SPRN_HID0
86 mfspr r0,SPRN_HID0
87 mfspr r0,SPRN_HID0
88 sync
89 isync
90 blr
91
92/* Definitions for the table use to save CPU states */ 60/* Definitions for the table use to save CPU states */
93#define CS_HID0 0 61#define CS_HID0 0
94#define CS_HID1 8 62#define CS_HID1 8
@@ -103,33 +71,30 @@ cpu_state_storage:
103 .balign L1_CACHE_BYTES,0 71 .balign L1_CACHE_BYTES,0
104 .text 72 .text
105 73
106/* Called in normal context to backup CPU 0 state. This
107 * does not include cache settings. This function is also
108 * called for machine sleep. This does not include the MMU
109 * setup, BATs, etc... but rather the "special" registers
110 * like HID0, HID1, HID4, etc...
111 */
112_GLOBAL(__save_cpu_setup)
113 /* Some CR fields are volatile, we back it up all */
114 mfcr r7
115
116 /* Get storage ptr */
117 LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
118 74
119 /* We only deal with 970 for now */ 75_GLOBAL(__setup_cpu_ppc970)
120 mfspr r0,SPRN_PVR 76 /* Do nothing if not running in HV mode */
121 srwi r0,r0,16
122 cmpwi r0,0x39
123 beq 1f
124 cmpwi r0,0x3c
125 beq 1f
126 cmpwi r0,0x44
127 bne 2f
128
1291: /* skip if not running in HV mode */
130 mfmsr r0 77 mfmsr r0
131 rldicl. r0,r0,4,63 78 rldicl. r0,r0,4,63
132 beq 2f 79 beqlr
80
81 mfspr r0,SPRN_HID0
82 li r11,5 /* clear DOZE and SLEEP */
83 rldimi r0,r11,52,8 /* set NAP and DPM */
84 li r11,0
85 rldimi r0,r11,32,31 /* clear EN_ATTN */
86 mtspr SPRN_HID0,r0
87 mfspr r0,SPRN_HID0
88 mfspr r0,SPRN_HID0
89 mfspr r0,SPRN_HID0
90 mfspr r0,SPRN_HID0
91 mfspr r0,SPRN_HID0
92 mfspr r0,SPRN_HID0
93 sync
94 isync
95
96 /* Save away cpu state */
97 LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
133 98
134 /* Save HID0,1,4 and 5 */ 99 /* Save HID0,1,4 and 5 */
135 mfspr r3,SPRN_HID0 100 mfspr r3,SPRN_HID0
@@ -141,35 +106,19 @@ _GLOBAL(__save_cpu_setup)
141 mfspr r3,SPRN_HID5 106 mfspr r3,SPRN_HID5
142 std r3,CS_HID5(r5) 107 std r3,CS_HID5(r5)
143 108
1442:
145 mtcr r7
146 blr 109 blr
147 110
148/* Called with no MMU context (typically MSR:IR/DR off) to 111/* Called with no MMU context (typically MSR:IR/DR off) to
149 * restore CPU state as backed up by the previous 112 * restore CPU state as backed up by the previous
150 * function. This does not include cache setting 113 * function. This does not include cache setting
151 */ 114 */
152_GLOBAL(__restore_cpu_setup) 115_GLOBAL(__restore_cpu_ppc970)
153 /* Get storage ptr (FIXME when using anton reloc as we 116 /* Do nothing if not running in HV mode */
154 * are running with translation disabled here
155 */
156 LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
157
158 /* We only deal with 970 for now */
159 mfspr r0,SPRN_PVR
160 srwi r0,r0,16
161 cmpwi r0,0x39
162 beq 1f
163 cmpwi r0,0x3c
164 beq 1f
165 cmpwi r0,0x44
166 bnelr
167
1681: /* skip if not running in HV mode */
169 mfmsr r0 117 mfmsr r0
170 rldicl. r0,r0,4,63 118 rldicl. r0,r0,4,63
171 beqlr 119 beqlr
172 120
121 LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
173 /* Before accessing memory, we make sure rm_ci is clear */ 122 /* Before accessing memory, we make sure rm_ci is clear */
174 li r0,0 123 li r0,0
175 mfspr r3,SPRN_HID4 124 mfspr r3,SPRN_HID4
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 272e43622fd6..190a57e20765 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -39,7 +39,10 @@ extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec);
39extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec); 39extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
40extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); 40extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
41#endif /* CONFIG_PPC32 */ 41#endif /* CONFIG_PPC32 */
42#ifdef CONFIG_PPC64
42extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); 43extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
44extern void __restore_cpu_ppc970(void);
45#endif /* CONFIG_PPC64 */
43 46
44/* This table only contains "desktop" CPUs, it need to be filled with embedded 47/* This table only contains "desktop" CPUs, it need to be filled with embedded
45 * ones as well... 48 * ones as well...
@@ -55,6 +58,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
55#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\ 58#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
56 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \ 59 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
57 PPC_FEATURE_TRUE_LE) 60 PPC_FEATURE_TRUE_LE)
61#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
62 PPC_FEATURE_TRUE_LE | \
63 PPC_FEATURE_HAS_ALTIVEC_COMP)
58#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ 64#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
59 PPC_FEATURE_BOOKE) 65 PPC_FEATURE_BOOKE)
60 66
@@ -184,6 +190,7 @@ struct cpu_spec cpu_specs[] = {
184 .dcache_bsize = 128, 190 .dcache_bsize = 128,
185 .num_pmcs = 8, 191 .num_pmcs = 8,
186 .cpu_setup = __setup_cpu_ppc970, 192 .cpu_setup = __setup_cpu_ppc970,
193 .cpu_restore = __restore_cpu_ppc970,
187 .oprofile_cpu_type = "ppc64/970", 194 .oprofile_cpu_type = "ppc64/970",
188 .oprofile_type = PPC_OPROFILE_POWER4, 195 .oprofile_type = PPC_OPROFILE_POWER4,
189 .platform = "ppc970", 196 .platform = "ppc970",
@@ -199,6 +206,7 @@ struct cpu_spec cpu_specs[] = {
199 .dcache_bsize = 128, 206 .dcache_bsize = 128,
200 .num_pmcs = 8, 207 .num_pmcs = 8,
201 .cpu_setup = __setup_cpu_ppc970, 208 .cpu_setup = __setup_cpu_ppc970,
209 .cpu_restore = __restore_cpu_ppc970,
202 .oprofile_cpu_type = "ppc64/970", 210 .oprofile_cpu_type = "ppc64/970",
203 .oprofile_type = PPC_OPROFILE_POWER4, 211 .oprofile_type = PPC_OPROFILE_POWER4,
204 .platform = "ppc970", 212 .platform = "ppc970",
@@ -214,6 +222,7 @@ struct cpu_spec cpu_specs[] = {
214 .dcache_bsize = 128, 222 .dcache_bsize = 128,
215 .num_pmcs = 8, 223 .num_pmcs = 8,
216 .cpu_setup = __setup_cpu_ppc970, 224 .cpu_setup = __setup_cpu_ppc970,
225 .cpu_restore = __restore_cpu_ppc970,
217 .oprofile_cpu_type = "ppc64/970", 226 .oprofile_cpu_type = "ppc64/970",
218 .oprofile_type = PPC_OPROFILE_POWER4, 227 .oprofile_type = PPC_OPROFILE_POWER4,
219 .platform = "ppc970", 228 .platform = "ppc970",
@@ -280,6 +289,17 @@ struct cpu_spec cpu_specs[] = {
280 .dcache_bsize = 128, 289 .dcache_bsize = 128,
281 .platform = "ppc-cell-be", 290 .platform = "ppc-cell-be",
282 }, 291 },
292 { /* PA Semi PA6T */
293 .pvr_mask = 0x7fff0000,
294 .pvr_value = 0x00900000,
295 .cpu_name = "PA6T",
296 .cpu_features = CPU_FTRS_PA6T,
297 .cpu_user_features = COMMON_USER_PA6T,
298 .icache_bsize = 64,
299 .dcache_bsize = 64,
300 .num_pmcs = 6,
301 .platform = "pa6t",
302 },
283 { /* default match */ 303 { /* default match */
284 .pvr_mask = 0x00000000, 304 .pvr_mask = 0x00000000,
285 .pvr_value = 0x00000000, 305 .pvr_value = 0x00000000,
@@ -929,6 +949,7 @@ struct cpu_spec cpu_specs[] = {
929 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 949 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
930 .icache_bsize = 32, 950 .icache_bsize = 32,
931 .dcache_bsize = 32, 951 .dcache_bsize = 32,
952 .platform = "ppc405",
932 }, 953 },
933 { /* 405EP */ 954 { /* 405EP */
934 .pvr_mask = 0xffff0000, 955 .pvr_mask = 0xffff0000,
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 371973be8d71..2f6f5a7bc69e 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -80,7 +80,7 @@ static int __init parse_savemaxmem(char *p)
80} 80}
81__setup("savemaxmem=", parse_savemaxmem); 81__setup("savemaxmem=", parse_savemaxmem);
82 82
83/* 83/**
84 * copy_oldmem_page - copy one page from "oldmem" 84 * copy_oldmem_page - copy one page from "oldmem"
85 * @pfn: page frame number to be copied 85 * @pfn: page frame number to be copied
86 * @buf: target memory address for the copy; this can be in kernel address 86 * @buf: target memory address for the copy; this can be in kernel address
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 36aaa7663f02..6c168f6ea142 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -35,10 +35,9 @@ int dma_supported(struct device *dev, u64 mask)
35{ 35{
36 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 36 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
37 37
38 if (dma_ops) 38 BUG_ON(!dma_ops);
39 return dma_ops->dma_supported(dev, mask); 39
40 BUG(); 40 return dma_ops->dma_supported(dev, mask);
41 return 0;
42} 41}
43EXPORT_SYMBOL(dma_supported); 42EXPORT_SYMBOL(dma_supported);
44 43
@@ -66,10 +65,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
66{ 65{
67 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 66 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
68 67
69 if (dma_ops) 68 BUG_ON(!dma_ops);
70 return dma_ops->alloc_coherent(dev, size, dma_handle, flag); 69
71 BUG(); 70 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
72 return NULL;
73} 71}
74EXPORT_SYMBOL(dma_alloc_coherent); 72EXPORT_SYMBOL(dma_alloc_coherent);
75 73
@@ -78,10 +76,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
78{ 76{
79 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 77 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
80 78
81 if (dma_ops) 79 BUG_ON(!dma_ops);
82 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); 80
83 else 81 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
84 BUG();
85} 82}
86EXPORT_SYMBOL(dma_free_coherent); 83EXPORT_SYMBOL(dma_free_coherent);
87 84
@@ -90,10 +87,9 @@ dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
90{ 87{
91 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 88 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
92 89
93 if (dma_ops) 90 BUG_ON(!dma_ops);
94 return dma_ops->map_single(dev, cpu_addr, size, direction); 91
95 BUG(); 92 return dma_ops->map_single(dev, cpu_addr, size, direction);
96 return (dma_addr_t)0;
97} 93}
98EXPORT_SYMBOL(dma_map_single); 94EXPORT_SYMBOL(dma_map_single);
99 95
@@ -102,10 +98,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
102{ 98{
103 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 99 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
104 100
105 if (dma_ops) 101 BUG_ON(!dma_ops);
106 dma_ops->unmap_single(dev, dma_addr, size, direction); 102
107 else 103 dma_ops->unmap_single(dev, dma_addr, size, direction);
108 BUG();
109} 104}
110EXPORT_SYMBOL(dma_unmap_single); 105EXPORT_SYMBOL(dma_unmap_single);
111 106
@@ -115,11 +110,10 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
115{ 110{
116 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 111 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
117 112
118 if (dma_ops) 113 BUG_ON(!dma_ops);
119 return dma_ops->map_single(dev, 114
120 (page_address(page) + offset), size, direction); 115 return dma_ops->map_single(dev, page_address(page) + offset, size,
121 BUG(); 116 direction);
122 return (dma_addr_t)0;
123} 117}
124EXPORT_SYMBOL(dma_map_page); 118EXPORT_SYMBOL(dma_map_page);
125 119
@@ -128,10 +122,9 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
128{ 122{
129 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 123 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
130 124
131 if (dma_ops) 125 BUG_ON(!dma_ops);
132 dma_ops->unmap_single(dev, dma_address, size, direction); 126
133 else 127 dma_ops->unmap_single(dev, dma_address, size, direction);
134 BUG();
135} 128}
136EXPORT_SYMBOL(dma_unmap_page); 129EXPORT_SYMBOL(dma_unmap_page);
137 130
@@ -140,10 +133,9 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
140{ 133{
141 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 134 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
142 135
143 if (dma_ops) 136 BUG_ON(!dma_ops);
144 return dma_ops->map_sg(dev, sg, nents, direction); 137
145 BUG(); 138 return dma_ops->map_sg(dev, sg, nents, direction);
146 return 0;
147} 139}
148EXPORT_SYMBOL(dma_map_sg); 140EXPORT_SYMBOL(dma_map_sg);
149 141
@@ -152,9 +144,8 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
152{ 144{
153 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 145 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
154 146
155 if (dma_ops) 147 BUG_ON(!dma_ops);
156 dma_ops->unmap_sg(dev, sg, nhwentries, direction); 148
157 else 149 dma_ops->unmap_sg(dev, sg, nhwentries, direction);
158 BUG();
159} 150}
160EXPORT_SYMBOL(dma_unmap_sg); 151EXPORT_SYMBOL(dma_unmap_sg);
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 54d9f5cdaab4..2cd872b5283b 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -375,6 +375,14 @@ BEGIN_FTR_SECTION
375 ld r7,KSP_VSID(r4) /* Get new stack's VSID */ 375 ld r7,KSP_VSID(r4) /* Get new stack's VSID */
376 oris r0,r6,(SLB_ESID_V)@h 376 oris r0,r6,(SLB_ESID_V)@h
377 ori r0,r0,(SLB_NUM_BOLTED-1)@l 377 ori r0,r0,(SLB_NUM_BOLTED-1)@l
378
379 /* Update the last bolted SLB */
380 ld r9,PACA_SLBSHADOWPTR(r13)
381 li r12,0
382 std r12,SLBSHADOW_STACKESID(r9) /* Clear ESID */
383 std r7,SLBSHADOW_STACKVSID(r9) /* Save VSID */
384 std r0,SLBSHADOW_STACKESID(r9) /* Save ESID */
385
378 slbie r6 386 slbie r6
379 slbie r6 /* Workaround POWER5 < DD2.1 issue */ 387 slbie r6 /* Workaround POWER5 < DD2.1 issue */
380 slbmte r7,r0 388 slbmte r7,r0
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 6ff3cf506088..3065b472b95d 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -132,7 +132,7 @@ _GLOBAL(__secondary_hold)
132 bne 100b 132 bne 100b
133 133
134#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) 134#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
135 LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init) 135 LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init)
136 mtctr r4 136 mtctr r4
137 mr r3,r24 137 mr r3,r24
138 bctr 138 bctr
@@ -1484,19 +1484,17 @@ fwnmi_data_area:
1484 . = 0x8000 1484 . = 0x8000
1485 1485
1486/* 1486/*
1487 * On pSeries, secondary processors spin in the following code. 1487 * On pSeries and most other platforms, secondary processors spin
1488 * in the following code.
1488 * At entry, r3 = this processor's number (physical cpu id) 1489 * At entry, r3 = this processor's number (physical cpu id)
1489 */ 1490 */
1490_GLOBAL(pSeries_secondary_smp_init) 1491_GLOBAL(generic_secondary_smp_init)
1491 mr r24,r3 1492 mr r24,r3
1492 1493
1493 /* turn on 64-bit mode */ 1494 /* turn on 64-bit mode */
1494 bl .enable_64b_mode 1495 bl .enable_64b_mode
1495 isync 1496 isync
1496 1497
1497 /* Copy some CPU settings from CPU 0 */
1498 bl .__restore_cpu_setup
1499
1500 /* Set up a paca value for this processor. Since we have the 1498 /* Set up a paca value for this processor. Since we have the
1501 * physical cpu id in r24, we need to search the pacas to find 1499 * physical cpu id in r24, we need to search the pacas to find
1502 * which logical id maps to our physical one. 1500 * which logical id maps to our physical one.
@@ -1522,15 +1520,28 @@ _GLOBAL(pSeries_secondary_smp_init)
1522 /* start. */ 1520 /* start. */
1523 sync 1521 sync
1524 1522
1525 /* Create a temp kernel stack for use before relocation is on. */ 1523#ifndef CONFIG_SMP
1524 b 3b /* Never go on non-SMP */
1525#else
1526 cmpwi 0,r23,0
1527 beq 3b /* Loop until told to go */
1528
1529 /* See if we need to call a cpu state restore handler */
1530 LOAD_REG_IMMEDIATE(r23, cur_cpu_spec)
1531 ld r23,0(r23)
1532 ld r23,CPU_SPEC_RESTORE(r23)
1533 cmpdi 0,r23,0
1534 beq 4f
1535 ld r23,0(r23)
1536 mtctr r23
1537 bctrl
1538
15394: /* Create a temp kernel stack for use before relocation is on. */
1526 ld r1,PACAEMERGSP(r13) 1540 ld r1,PACAEMERGSP(r13)
1527 subi r1,r1,STACK_FRAME_OVERHEAD 1541 subi r1,r1,STACK_FRAME_OVERHEAD
1528 1542
1529 cmpwi 0,r23,0 1543 b .__secondary_start
1530#ifdef CONFIG_SMP
1531 bne .__secondary_start
1532#endif 1544#endif
1533 b 3b /* Loop until told to go */
1534 1545
1535#ifdef CONFIG_PPC_ISERIES 1546#ifdef CONFIG_PPC_ISERIES
1536_STATIC(__start_initialization_iSeries) 1547_STATIC(__start_initialization_iSeries)
@@ -1611,7 +1622,16 @@ _GLOBAL(__start_initialization_multiplatform)
1611 bl .enable_64b_mode 1622 bl .enable_64b_mode
1612 1623
1613 /* Setup some critical 970 SPRs before switching MMU off */ 1624 /* Setup some critical 970 SPRs before switching MMU off */
1614 bl .__970_cpu_preinit 1625 mfspr r0,SPRN_PVR
1626 srwi r0,r0,16
1627 cmpwi r0,0x39 /* 970 */
1628 beq 1f
1629 cmpwi r0,0x3c /* 970FX */
1630 beq 1f
1631 cmpwi r0,0x44 /* 970MP */
1632 bne 2f
16331: bl .__cpu_preinit_ppc970
16342:
1615 1635
1616 /* Switch off MMU if not already */ 1636 /* Switch off MMU if not already */
1617 LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) 1637 LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
@@ -1728,7 +1748,7 @@ _STATIC(__after_prom_start)
1728_GLOBAL(copy_and_flush) 1748_GLOBAL(copy_and_flush)
1729 addi r5,r5,-8 1749 addi r5,r5,-8
1730 addi r6,r6,-8 1750 addi r6,r6,-8
17314: li r0,16 /* Use the least common */ 17514: li r0,8 /* Use the smallest common */
1732 /* denominator cache line */ 1752 /* denominator cache line */
1733 /* size. This results in */ 1753 /* size. This results in */
1734 /* extra cache line flushes */ 1754 /* extra cache line flushes */
@@ -1782,7 +1802,7 @@ _GLOBAL(pmac_secondary_start)
1782 isync 1802 isync
1783 1803
1784 /* Copy some CPU settings from CPU 0 */ 1804 /* Copy some CPU settings from CPU 0 */
1785 bl .__restore_cpu_setup 1805 bl .__restore_cpu_ppc970
1786 1806
1787 /* pSeries do that early though I don't think we really need it */ 1807 /* pSeries do that early though I don't think we really need it */
1788 mfmsr r3 1808 mfmsr r3
@@ -1932,12 +1952,6 @@ _STATIC(start_here_multiplatform)
1932 mr r5,r26 1952 mr r5,r26
1933 bl .identify_cpu 1953 bl .identify_cpu
1934 1954
1935 /* Save some low level config HIDs of CPU0 to be copied to
1936 * other CPUs later on, or used for suspend/resume
1937 */
1938 bl .__save_cpu_setup
1939 sync
1940
1941 /* Do very early kernel initializations, including initial hash table, 1955 /* Do very early kernel initializations, including initial hash table,
1942 * stab and slb setup before we turn on relocation. */ 1956 * stab and slb setup before we turn on relocation. */
1943 1957
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 68e5ab0443d2..124dbcba94a8 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -167,7 +167,7 @@ static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name,
167 NULL); 167 NULL);
168 168
169static struct ibmebus_dev* __devinit ibmebus_register_device_common( 169static struct ibmebus_dev* __devinit ibmebus_register_device_common(
170 struct ibmebus_dev *dev, char *name) 170 struct ibmebus_dev *dev, const char *name)
171{ 171{
172 int err = 0; 172 int err = 0;
173 173
@@ -194,10 +194,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node(
194 struct device_node *dn) 194 struct device_node *dn)
195{ 195{
196 struct ibmebus_dev *dev; 196 struct ibmebus_dev *dev;
197 char *loc_code; 197 const char *loc_code;
198 int length; 198 int length;
199 199
200 loc_code = (char *)get_property(dn, "ibm,loc-code", NULL); 200 loc_code = get_property(dn, "ibm,loc-code", NULL);
201 if (!loc_code) { 201 if (!loc_code) {
202 printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n", 202 printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
203 __FUNCTION__, dn->name ? dn->name : "<unknown>"); 203 __FUNCTION__, dn->name ? dn->name : "<unknown>");
diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c
new file mode 100644
index 000000000000..e98180686b35
--- /dev/null
+++ b/arch/powerpc/kernel/io.c
@@ -0,0 +1,131 @@
1/*
2 * I/O string operations
3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4 * Copyright (C) 2006 IBM Corporation
5 *
6 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
7 * and Paul Mackerras.
8 *
9 * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
10 * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
11 *
12 * Rewritten in C by Stephen Rothwell.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
18 */
19#include <linux/kernel.h>
20#include <linux/types.h>
21#include <linux/compiler.h>
22#include <linux/module.h>
23
24#include <asm/io.h>
25#include <asm/firmware.h>
26#include <asm/bug.h>
27
28void _insb(volatile u8 __iomem *port, void *buf, long count)
29{
30 u8 *tbuf = buf;
31 u8 tmp;
32
33 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
34
35 if (unlikely(count <= 0))
36 return;
37 asm volatile("sync");
38 do {
39 tmp = *port;
40 asm volatile("eieio");
41 *tbuf++ = tmp;
42 } while (--count != 0);
43 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
44}
45EXPORT_SYMBOL(_insb);
46
47void _outsb(volatile u8 __iomem *port, const void *buf, long count)
48{
49 const u8 *tbuf = buf;
50
51 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
52
53 if (unlikely(count <= 0))
54 return;
55 asm volatile("sync");
56 do {
57 *port = *tbuf++;
58 } while (--count != 0);
59 asm volatile("sync");
60}
61EXPORT_SYMBOL(_outsb);
62
63void _insw_ns(volatile u16 __iomem *port, void *buf, long count)
64{
65 u16 *tbuf = buf;
66 u16 tmp;
67
68 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
69
70 if (unlikely(count <= 0))
71 return;
72 asm volatile("sync");
73 do {
74 tmp = *port;
75 asm volatile("eieio");
76 *tbuf++ = tmp;
77 } while (--count != 0);
78 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
79}
80EXPORT_SYMBOL(_insw_ns);
81
82void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
83{
84 const u16 *tbuf = buf;
85
86 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
87
88 if (unlikely(count <= 0))
89 return;
90 asm volatile("sync");
91 do {
92 *port = *tbuf++;
93 } while (--count != 0);
94 asm volatile("sync");
95}
96EXPORT_SYMBOL(_outsw_ns);
97
98void _insl_ns(volatile u32 __iomem *port, void *buf, long count)
99{
100 u32 *tbuf = buf;
101 u32 tmp;
102
103 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
104
105 if (unlikely(count <= 0))
106 return;
107 asm volatile("sync");
108 do {
109 tmp = *port;
110 asm volatile("eieio");
111 *tbuf++ = tmp;
112 } while (--count != 0);
113 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
114}
115EXPORT_SYMBOL(_insl_ns);
116
117void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
118{
119 const u32 *tbuf = buf;
120
121 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
122
123 if (unlikely(count <= 0))
124 return;
125 asm volatile("sync");
126 do {
127 *port = *tbuf++;
128 } while (--count != 0);
129 asm volatile("sync");
130}
131EXPORT_SYMBOL(_outsl_ns);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 12c5971d6565..b4432332341f 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -52,6 +52,7 @@
52#include <linux/radix-tree.h> 52#include <linux/radix-tree.h>
53#include <linux/mutex.h> 53#include <linux/mutex.h>
54#include <linux/bootmem.h> 54#include <linux/bootmem.h>
55#include <linux/pci.h>
55 56
56#include <asm/uaccess.h> 57#include <asm/uaccess.h>
57#include <asm/system.h> 58#include <asm/system.h>
@@ -875,12 +876,14 @@ int pci_enable_msi(struct pci_dev * pdev)
875 else 876 else
876 return -1; 877 return -1;
877} 878}
879EXPORT_SYMBOL(pci_enable_msi);
878 880
879void pci_disable_msi(struct pci_dev * pdev) 881void pci_disable_msi(struct pci_dev * pdev)
880{ 882{
881 if (ppc_md.disable_msi) 883 if (ppc_md.disable_msi)
882 ppc_md.disable_msi(pdev); 884 ppc_md.disable_msi(pdev);
883} 885}
886EXPORT_SYMBOL(pci_disable_msi);
884 887
885void pci_scan_msi_device(struct pci_dev *dev) {} 888void pci_scan_msi_device(struct pci_dev *dev) {}
886int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;} 889int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
@@ -888,6 +891,8 @@ void pci_disable_msix(struct pci_dev *dev) {}
888void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} 891void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
889void disable_msi_mode(struct pci_dev *dev, int pos, int type) {} 892void disable_msi_mode(struct pci_dev *dev, int pos, int type) {}
890void pci_no_msi(void) {} 893void pci_no_msi(void) {}
894EXPORT_SYMBOL(pci_enable_msix);
895EXPORT_SYMBOL(pci_disable_msix);
891 896
892#endif 897#endif
893 898
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 40a39291861f..5e6ddfa474c0 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -39,16 +39,17 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
39 phys_addr_t taddr, unsigned long irq, 39 phys_addr_t taddr, unsigned long irq,
40 upf_t flags, int irq_check_parent) 40 upf_t flags, int irq_check_parent)
41{ 41{
42 u32 *clk, *spd, clock = BASE_BAUD * 16; 42 const u32 *clk, *spd;
43 u32 clock = BASE_BAUD * 16;
43 int index; 44 int index;
44 45
45 /* get clock freq. if present */ 46 /* get clock freq. if present */
46 clk = (u32 *)get_property(np, "clock-frequency", NULL); 47 clk = get_property(np, "clock-frequency", NULL);
47 if (clk && *clk) 48 if (clk && *clk)
48 clock = *clk; 49 clock = *clk;
49 50
50 /* get default speed if present */ 51 /* get default speed if present */
51 spd = (u32 *)get_property(np, "current-speed", NULL); 52 spd = get_property(np, "current-speed", NULL);
52 53
53 /* If we have a location index, then try to use it */ 54 /* If we have a location index, then try to use it */
54 if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS) 55 if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
@@ -113,7 +114,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
113 struct device_node *soc_dev) 114 struct device_node *soc_dev)
114{ 115{
115 u64 addr; 116 u64 addr;
116 u32 *addrp; 117 const u32 *addrp;
117 upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; 118 upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
118 struct device_node *tsi = of_get_parent(np); 119 struct device_node *tsi = of_get_parent(np);
119 120
@@ -144,15 +145,15 @@ static int __init add_legacy_soc_port(struct device_node *np,
144static int __init add_legacy_isa_port(struct device_node *np, 145static int __init add_legacy_isa_port(struct device_node *np,
145 struct device_node *isa_brg) 146 struct device_node *isa_brg)
146{ 147{
147 u32 *reg; 148 const u32 *reg;
148 char *typep; 149 const char *typep;
149 int index = -1; 150 int index = -1;
150 u64 taddr; 151 u64 taddr;
151 152
152 DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); 153 DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
153 154
154 /* Get the ISA port number */ 155 /* Get the ISA port number */
155 reg = (u32 *)get_property(np, "reg", NULL); 156 reg = get_property(np, "reg", NULL);
156 if (reg == NULL) 157 if (reg == NULL)
157 return -1; 158 return -1;
158 159
@@ -163,7 +164,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
163 /* Now look for an "ibm,aix-loc" property that gives us ordering 164 /* Now look for an "ibm,aix-loc" property that gives us ordering
164 * if any... 165 * if any...
165 */ 166 */
166 typep = (char *)get_property(np, "ibm,aix-loc", NULL); 167 typep = get_property(np, "ibm,aix-loc", NULL);
167 168
168 /* If we have a location index, then use it */ 169 /* If we have a location index, then use it */
169 if (typep && *typep == 'S') 170 if (typep && *typep == 'S')
@@ -188,7 +189,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
188 struct device_node *pci_dev) 189 struct device_node *pci_dev)
189{ 190{
190 u64 addr, base; 191 u64 addr, base;
191 u32 *addrp; 192 const u32 *addrp;
192 unsigned int flags; 193 unsigned int flags;
193 int iotype, index = -1, lindex = 0; 194 int iotype, index = -1, lindex = 0;
194 195
@@ -227,7 +228,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
227 * we get to their "reg" property 228 * we get to their "reg" property
228 */ 229 */
229 if (np != pci_dev) { 230 if (np != pci_dev) {
230 u32 *reg = (u32 *)get_property(np, "reg", NULL); 231 const u32 *reg = get_property(np, "reg", NULL);
231 if (reg && (*reg < 4)) 232 if (reg && (*reg < 4))
232 index = lindex = *reg; 233 index = lindex = *reg;
233 } 234 }
@@ -285,13 +286,13 @@ static void __init setup_legacy_serial_console(int console)
285void __init find_legacy_serial_ports(void) 286void __init find_legacy_serial_ports(void)
286{ 287{
287 struct device_node *np, *stdout = NULL; 288 struct device_node *np, *stdout = NULL;
288 char *path; 289 const char *path;
289 int index; 290 int index;
290 291
291 DBG(" -> find_legacy_serial_port()\n"); 292 DBG(" -> find_legacy_serial_port()\n");
292 293
293 /* Now find out if one of these is out firmware console */ 294 /* Now find out if one of these is out firmware console */
294 path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 295 path = get_property(of_chosen, "linux,stdout-path", NULL);
295 if (path != NULL) { 296 if (path != NULL) {
296 stdout = of_find_node_by_path(path); 297 stdout = of_find_node_by_path(path);
297 if (stdout) 298 if (stdout)
@@ -491,8 +492,8 @@ static int __init check_legacy_serial_console(void)
491{ 492{
492 struct device_node *prom_stdout = NULL; 493 struct device_node *prom_stdout = NULL;
493 int speed = 0, offset = 0; 494 int speed = 0, offset = 0;
494 char *name; 495 const char *name;
495 u32 *spd; 496 const u32 *spd;
496 497
497 DBG(" -> check_legacy_serial_console()\n"); 498 DBG(" -> check_legacy_serial_console()\n");
498 499
@@ -513,7 +514,7 @@ static int __init check_legacy_serial_console(void)
513 } 514 }
514 /* We are getting a weird phandle from OF ... */ 515 /* We are getting a weird phandle from OF ... */
515 /* ... So use the full path instead */ 516 /* ... So use the full path instead */
516 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 517 name = get_property(of_chosen, "linux,stdout-path", NULL);
517 if (name == NULL) { 518 if (name == NULL) {
518 DBG(" no linux,stdout-path !\n"); 519 DBG(" no linux,stdout-path !\n");
519 return -ENODEV; 520 return -ENODEV;
@@ -525,12 +526,12 @@ static int __init check_legacy_serial_console(void)
525 } 526 }
526 DBG("stdout is %s\n", prom_stdout->full_name); 527 DBG("stdout is %s\n", prom_stdout->full_name);
527 528
528 name = (char *)get_property(prom_stdout, "name", NULL); 529 name = get_property(prom_stdout, "name", NULL);
529 if (!name) { 530 if (!name) {
530 DBG(" stdout package has no name !\n"); 531 DBG(" stdout package has no name !\n");
531 goto not_found; 532 goto not_found;
532 } 533 }
533 spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); 534 spd = get_property(prom_stdout, "current-speed", NULL);
534 if (spd) 535 if (spd)
535 speed = *spd; 536 speed = *spd;
536 537
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 23f34daa044a..41c05dcd68f4 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -32,7 +32,6 @@
32#include <asm/rtas.h> 32#include <asm/rtas.h>
33#include <asm/system.h> 33#include <asm/system.h>
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/iseries/it_exp_vpd_panel.h>
36#include <asm/prom.h> 35#include <asm/prom.h>
37#include <asm/vdso_datapage.h> 36#include <asm/vdso_datapage.h>
38 37
@@ -183,8 +182,14 @@ static unsigned int h_get_ppp(unsigned long *entitled,
183 unsigned long *resource) 182 unsigned long *resource)
184{ 183{
185 unsigned long rc; 184 unsigned long rc;
186 rc = plpar_hcall_4out(H_GET_PPP, 0, 0, 0, 0, entitled, unallocated, 185 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
187 aggregation, resource); 186
187 rc = plpar_hcall(H_GET_PPP, retbuf);
188
189 *entitled = retbuf[0];
190 *unallocated = retbuf[1];
191 *aggregation = retbuf[2];
192 *resource = retbuf[3];
188 193
189 log_plpar_hcall_return(rc, "H_GET_PPP"); 194 log_plpar_hcall_return(rc, "H_GET_PPP");
190 195
@@ -194,8 +199,12 @@ static unsigned int h_get_ppp(unsigned long *entitled,
194static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) 199static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
195{ 200{
196 unsigned long rc; 201 unsigned long rc;
197 unsigned long dummy; 202 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
198 rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy); 203
204 rc = plpar_hcall(H_PIC, retbuf);
205
206 *pool_idle_time = retbuf[0];
207 *num_procs = retbuf[1];
199 208
200 if (rc != H_AUTHORITY) 209 if (rc != H_AUTHORITY)
201 log_plpar_hcall_return(rc, "H_PIC"); 210 log_plpar_hcall_return(rc, "H_PIC");
@@ -310,12 +319,11 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
310 int partition_potential_processors; 319 int partition_potential_processors;
311 int partition_active_processors; 320 int partition_active_processors;
312 struct device_node *rtas_node; 321 struct device_node *rtas_node;
313 int *lrdrp = NULL; 322 const int *lrdrp = NULL;
314 323
315 rtas_node = find_path_device("/rtas"); 324 rtas_node = find_path_device("/rtas");
316 if (rtas_node) 325 if (rtas_node)
317 lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", 326 lrdrp = get_property(rtas_node, "ibm,lrdr-capacity", NULL);
318 NULL);
319 327
320 if (lrdrp == NULL) { 328 if (lrdrp == NULL) {
321 partition_potential_processors = vdso_data->processorCount; 329 partition_potential_processors = vdso_data->processorCount;
@@ -520,7 +528,8 @@ static int lparcfg_data(struct seq_file *m, void *v)
520 const char *model = ""; 528 const char *model = "";
521 const char *system_id = ""; 529 const char *system_id = "";
522 const char *tmp; 530 const char *tmp;
523 unsigned int *lp_index_ptr, lp_index = 0; 531 const unsigned int *lp_index_ptr;
532 unsigned int lp_index = 0;
524 533
525 seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); 534 seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
526 535
@@ -540,8 +549,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
540 if (firmware_has_feature(FW_FEATURE_ISERIES)) 549 if (firmware_has_feature(FW_FEATURE_ISERIES))
541 system_id += 4; 550 system_id += 4;
542 } 551 }
543 lp_index_ptr = (unsigned int *) 552 lp_index_ptr = get_property(rootdn, "ibm,partition-no", NULL);
544 get_property(rootdn, "ibm,partition-no", NULL);
545 if (lp_index_ptr) 553 if (lp_index_ptr)
546 lp_index = *lp_index_ptr; 554 lp_index = *lp_index_ptr;
547 } 555 }
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index be58985c7681..a24b09c27718 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -31,8 +31,8 @@ int default_machine_kexec_prepare(struct kimage *image)
31 unsigned long begin, end; /* limits of segment */ 31 unsigned long begin, end; /* limits of segment */
32 unsigned long low, high; /* limits of blocked memory range */ 32 unsigned long low, high; /* limits of blocked memory range */
33 struct device_node *node; 33 struct device_node *node;
34 unsigned long *basep; 34 const unsigned long *basep;
35 unsigned int *sizep; 35 const unsigned int *sizep;
36 36
37 if (!ppc_md.hpte_clear_all) 37 if (!ppc_md.hpte_clear_all)
38 return -ENOENT; 38 return -ENOENT;
@@ -72,10 +72,8 @@ int default_machine_kexec_prepare(struct kimage *image)
72 /* We also should not overwrite the tce tables */ 72 /* We also should not overwrite the tce tables */
73 for (node = of_find_node_by_type(NULL, "pci"); node != NULL; 73 for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
74 node = of_find_node_by_type(node, "pci")) { 74 node = of_find_node_by_type(node, "pci")) {
75 basep = (unsigned long *)get_property(node, "linux,tce-base", 75 basep = get_property(node, "linux,tce-base", NULL);
76 NULL); 76 sizep = get_property(node, "linux,tce-size", NULL);
77 sizep = (unsigned int *)get_property(node, "linux,tce-size",
78 NULL);
79 if (basep == NULL || sizep == NULL) 77 if (basep == NULL || sizep == NULL)
80 continue; 78 continue;
81 79
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index f770805f1215..330c9dc7db86 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -43,162 +43,3 @@ _GLOBAL(add_reloc_offset)
43 add r3,r3,r5 43 add r3,r3,r5
44 mtlr r0 44 mtlr r0
45 blr 45 blr
46
47/*
48 * I/O string operations
49 *
50 * insb(port, buf, len)
51 * outsb(port, buf, len)
52 * insw(port, buf, len)
53 * outsw(port, buf, len)
54 * insl(port, buf, len)
55 * outsl(port, buf, len)
56 * insw_ns(port, buf, len)
57 * outsw_ns(port, buf, len)
58 * insl_ns(port, buf, len)
59 * outsl_ns(port, buf, len)
60 *
61 * The *_ns versions don't do byte-swapping.
62 */
63_GLOBAL(_insb)
64 sync
65 cmpwi 0,r5,0
66 mtctr r5
67 subi r4,r4,1
68 blelr-
6900: lbz r5,0(r3)
70 eieio
71 stbu r5,1(r4)
72 bdnz 00b
73 twi 0,r5,0
74 isync
75 blr
76
77_GLOBAL(_outsb)
78 cmpwi 0,r5,0
79 mtctr r5
80 subi r4,r4,1
81 blelr-
82 sync
8300: lbzu r5,1(r4)
84 stb r5,0(r3)
85 bdnz 00b
86 sync
87 blr
88
89_GLOBAL(_insw)
90 sync
91 cmpwi 0,r5,0
92 mtctr r5
93 subi r4,r4,2
94 blelr-
9500: lhbrx r5,0,r3
96 eieio
97 sthu r5,2(r4)
98 bdnz 00b
99 twi 0,r5,0
100 isync
101 blr
102
103_GLOBAL(_outsw)
104 cmpwi 0,r5,0
105 mtctr r5
106 subi r4,r4,2
107 blelr-
108 sync
10900: lhzu r5,2(r4)
110 sthbrx r5,0,r3
111 bdnz 00b
112 sync
113 blr
114
115_GLOBAL(_insl)
116 sync
117 cmpwi 0,r5,0
118 mtctr r5
119 subi r4,r4,4
120 blelr-
12100: lwbrx r5,0,r3
122 eieio
123 stwu r5,4(r4)
124 bdnz 00b
125 twi 0,r5,0
126 isync
127 blr
128
129_GLOBAL(_outsl)
130 cmpwi 0,r5,0
131 mtctr r5
132 subi r4,r4,4
133 blelr-
134 sync
13500: lwzu r5,4(r4)
136 stwbrx r5,0,r3
137 bdnz 00b
138 sync
139 blr
140
141#ifdef CONFIG_PPC32
142_GLOBAL(__ide_mm_insw)
143#endif
144_GLOBAL(_insw_ns)
145 sync
146 cmpwi 0,r5,0
147 mtctr r5
148 subi r4,r4,2
149 blelr-
15000: lhz r5,0(r3)
151 eieio
152 sthu r5,2(r4)
153 bdnz 00b
154 twi 0,r5,0
155 isync
156 blr
157
158#ifdef CONFIG_PPC32
159_GLOBAL(__ide_mm_outsw)
160#endif
161_GLOBAL(_outsw_ns)
162 cmpwi 0,r5,0
163 mtctr r5
164 subi r4,r4,2
165 blelr-
166 sync
16700: lhzu r5,2(r4)
168 sth r5,0(r3)
169 bdnz 00b
170 sync
171 blr
172
173#ifdef CONFIG_PPC32
174_GLOBAL(__ide_mm_insl)
175#endif
176_GLOBAL(_insl_ns)
177 sync
178 cmpwi 0,r5,0
179 mtctr r5
180 subi r4,r4,4
181 blelr-
18200: lwz r5,0(r3)
183 eieio
184 stwu r5,4(r4)
185 bdnz 00b
186 twi 0,r5,0
187 isync
188 blr
189
190#ifdef CONFIG_PPC32
191_GLOBAL(__ide_mm_outsl)
192#endif
193_GLOBAL(_outsl_ns)
194 cmpwi 0,r5,0
195 mtctr r5
196 subi r4,r4,4
197 blelr-
198 sync
19900: lwzu r5,4(r4)
200 stw r5,0(r3)
201 bdnz 00b
202 sync
203 blr
204
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 3262b73a3a68..397c83eda20e 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -189,27 +189,9 @@ void of_release_dev(struct device *dev)
189int of_device_register(struct of_device *ofdev) 189int of_device_register(struct of_device *ofdev)
190{ 190{
191 int rc; 191 int rc;
192 struct of_device **odprop;
193 192
194 BUG_ON(ofdev->node == NULL); 193 BUG_ON(ofdev->node == NULL);
195 194
196 odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
197 if (!odprop) {
198 struct property *new_prop;
199
200 new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
201 GFP_KERNEL);
202 if (new_prop == NULL)
203 return -ENOMEM;
204 new_prop->name = "linux,device";
205 new_prop->length = sizeof(sizeof(struct of_device *));
206 new_prop->value = (unsigned char *)&new_prop[1];
207 odprop = (struct of_device **)new_prop->value;
208 *odprop = NULL;
209 prom_add_property(ofdev->node, new_prop);
210 }
211 *odprop = ofdev;
212
213 rc = device_register(&ofdev->dev); 195 rc = device_register(&ofdev->dev);
214 if (rc) 196 if (rc)
215 return rc; 197 return rc;
@@ -221,14 +203,8 @@ int of_device_register(struct of_device *ofdev)
221 203
222void of_device_unregister(struct of_device *ofdev) 204void of_device_unregister(struct of_device *ofdev)
223{ 205{
224 struct of_device **odprop;
225
226 device_remove_file(&ofdev->dev, &dev_attr_devspec); 206 device_remove_file(&ofdev->dev, &dev_attr_devspec);
227 207
228 odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
229 if (odprop)
230 *odprop = NULL;
231
232 device_unregister(&ofdev->dev); 208 device_unregister(&ofdev->dev);
233} 209}
234 210
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index c68741fed14b..55f1a25085cd 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -17,6 +17,7 @@
17#include <asm/lppaca.h> 17#include <asm/lppaca.h>
18#include <asm/iseries/it_lp_reg_save.h> 18#include <asm/iseries/it_lp_reg_save.h>
19#include <asm/paca.h> 19#include <asm/paca.h>
20#include <asm/mmu.h>
20 21
21 22
22/* This symbol is provided by the linker - let it fill in the paca 23/* This symbol is provided by the linker - let it fill in the paca
@@ -45,6 +46,17 @@ struct lppaca lppaca[] = {
45 }, 46 },
46}; 47};
47 48
49/*
50 * 3 persistent SLBs are registered here. The buffer will be zero
51 * initially, hence will all be invaild until we actually write them.
52 */
53struct slb_shadow slb_shadow[] __cacheline_aligned = {
54 [0 ... (NR_CPUS-1)] = {
55 .persistent = SLB_NUM_BOLTED,
56 .buffer_length = sizeof(struct slb_shadow),
57 },
58};
59
48/* The Paca is an array with one entry per processor. Each contains an 60/* The Paca is an array with one entry per processor. Each contains an
49 * lppaca, which contains the information shared between the 61 * lppaca, which contains the information shared between the
50 * hypervisor and Linux. 62 * hypervisor and Linux.
@@ -59,7 +71,8 @@ struct lppaca lppaca[] = {
59 .lock_token = 0x8000, \ 71 .lock_token = 0x8000, \
60 .paca_index = (number), /* Paca Index */ \ 72 .paca_index = (number), /* Paca Index */ \
61 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 73 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
62 .hw_cpu_id = 0xffff, 74 .hw_cpu_id = 0xffff, \
75 .slb_shadow_ptr = &slb_shadow[number],
63 76
64#ifdef CONFIG_PPC_ISERIES 77#ifdef CONFIG_PPC_ISERIES
65#define PACA_INIT_ISERIES(number) \ 78#define PACA_INIT_ISERIES(number) \
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 09b1e1bbb29b..9b49f8691d29 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -633,12 +633,12 @@ pcibios_alloc_controller(void)
633static void 633static void
634make_one_node_map(struct device_node* node, u8 pci_bus) 634make_one_node_map(struct device_node* node, u8 pci_bus)
635{ 635{
636 int *bus_range; 636 const int *bus_range;
637 int len; 637 int len;
638 638
639 if (pci_bus >= pci_bus_count) 639 if (pci_bus >= pci_bus_count)
640 return; 640 return;
641 bus_range = (int *) get_property(node, "bus-range", &len); 641 bus_range = get_property(node, "bus-range", &len);
642 if (bus_range == NULL || len < 2 * sizeof(int)) { 642 if (bus_range == NULL || len < 2 * sizeof(int)) {
643 printk(KERN_WARNING "Can't get bus-range for %s, " 643 printk(KERN_WARNING "Can't get bus-range for %s, "
644 "assuming it starts at 0\n", node->full_name); 644 "assuming it starts at 0\n", node->full_name);
@@ -648,13 +648,13 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
648 648
649 for (node=node->child; node != 0;node = node->sibling) { 649 for (node=node->child; node != 0;node = node->sibling) {
650 struct pci_dev* dev; 650 struct pci_dev* dev;
651 unsigned int *class_code, *reg; 651 const unsigned int *class_code, *reg;
652 652
653 class_code = (unsigned int *) get_property(node, "class-code", NULL); 653 class_code = get_property(node, "class-code", NULL);
654 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 654 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
655 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) 655 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
656 continue; 656 continue;
657 reg = (unsigned int *)get_property(node, "reg", NULL); 657 reg = get_property(node, "reg", NULL);
658 if (!reg) 658 if (!reg)
659 continue; 659 continue;
660 dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); 660 dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
@@ -669,7 +669,7 @@ pcibios_make_OF_bus_map(void)
669{ 669{
670 int i; 670 int i;
671 struct pci_controller* hose; 671 struct pci_controller* hose;
672 u8* of_prop_map; 672 struct property *map_prop;
673 673
674 pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); 674 pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
675 if (!pci_to_OF_bus_map) { 675 if (!pci_to_OF_bus_map) {
@@ -691,9 +691,12 @@ pcibios_make_OF_bus_map(void)
691 continue; 691 continue;
692 make_one_node_map(node, hose->first_busno); 692 make_one_node_map(node, hose->first_busno);
693 } 693 }
694 of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL); 694 map_prop = of_find_property(find_path_device("/"),
695 if (of_prop_map) 695 "pci-OF-bus-map", NULL);
696 memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); 696 if (map_prop) {
697 BUG_ON(pci_bus_count > map_prop->length);
698 memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count);
699 }
697#ifdef DEBUG 700#ifdef DEBUG
698 printk("PCI->OF bus map:\n"); 701 printk("PCI->OF bus map:\n");
699 for (i=0; i<pci_bus_count; i++) { 702 for (i=0; i<pci_bus_count; i++) {
@@ -712,7 +715,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
712 struct device_node* sub_node; 715 struct device_node* sub_node;
713 716
714 for (; node != 0;node = node->sibling) { 717 for (; node != 0;node = node->sibling) {
715 unsigned int *class_code; 718 const unsigned int *class_code;
716 719
717 if (filter(node, data)) 720 if (filter(node, data))
718 return node; 721 return node;
@@ -722,7 +725,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
722 * a fake root for all functions of a multi-function device, 725 * a fake root for all functions of a multi-function device,
723 * we go down them as well. 726 * we go down them as well.
724 */ 727 */
725 class_code = (unsigned int *) get_property(node, "class-code", NULL); 728 class_code = get_property(node, "class-code", NULL);
726 if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 729 if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
727 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && 730 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
728 strcmp(node->name, "multifunc-device")) 731 strcmp(node->name, "multifunc-device"))
@@ -737,10 +740,10 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
737static int 740static int
738scan_OF_pci_childs_iterator(struct device_node* node, void* data) 741scan_OF_pci_childs_iterator(struct device_node* node, void* data)
739{ 742{
740 unsigned int *reg; 743 const unsigned int *reg;
741 u8* fdata = (u8*)data; 744 u8* fdata = (u8*)data;
742 745
743 reg = (unsigned int *) get_property(node, "reg", NULL); 746 reg = get_property(node, "reg", NULL);
744 if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] 747 if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
745 && ((reg[0] >> 16) & 0xff) == fdata[0]) 748 && ((reg[0] >> 16) & 0xff) == fdata[0])
746 return 1; 749 return 1;
@@ -841,7 +844,7 @@ find_OF_pci_device_filter(struct device_node* node, void* data)
841int 844int
842pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) 845pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
843{ 846{
844 unsigned int *reg; 847 const unsigned int *reg;
845 struct pci_controller* hose; 848 struct pci_controller* hose;
846 struct pci_dev* dev = NULL; 849 struct pci_dev* dev = NULL;
847 850
@@ -854,7 +857,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
854 if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, 857 if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
855 find_OF_pci_device_filter, (void *)node)) 858 find_OF_pci_device_filter, (void *)node))
856 return -ENODEV; 859 return -ENODEV;
857 reg = (unsigned int *) get_property(node, "reg", NULL); 860 reg = get_property(node, "reg", NULL);
858 if (!reg) 861 if (!reg)
859 return -ENODEV; 862 return -ENODEV;
860 *bus = (reg[0] >> 16) & 0xff; 863 *bus = (reg[0] >> 16) & 0xff;
@@ -885,8 +888,8 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
885 struct device_node *dev, int primary) 888 struct device_node *dev, int primary)
886{ 889{
887 static unsigned int static_lc_ranges[256] __initdata; 890 static unsigned int static_lc_ranges[256] __initdata;
888 unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; 891 const unsigned int *dt_ranges;
889 unsigned int size; 892 unsigned int *lc_ranges, *ranges, *prev, size;
890 int rlen = 0, orig_rlen; 893 int rlen = 0, orig_rlen;
891 int memno = 0; 894 int memno = 0;
892 struct resource *res; 895 struct resource *res;
@@ -897,7 +900,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
897 * that can have more than 3 ranges, fortunately using contiguous 900 * that can have more than 3 ranges, fortunately using contiguous
898 * addresses -- BenH 901 * addresses -- BenH
899 */ 902 */
900 dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); 903 dt_ranges = get_property(dev, "ranges", &rlen);
901 if (!dt_ranges) 904 if (!dt_ranges)
902 return; 905 return;
903 /* Sanity check, though hopefully that never happens */ 906 /* Sanity check, though hopefully that never happens */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 138134c8c17d..c1b1e14775e4 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -185,34 +185,6 @@ static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
185 spin_unlock(&hose_spinlock); 185 spin_unlock(&hose_spinlock);
186} 186}
187 187
188static void add_linux_pci_domain(struct device_node *dev,
189 struct pci_controller *phb)
190{
191 struct property *of_prop;
192 unsigned int size;
193
194 of_prop = (struct property *)
195 get_property(dev, "linux,pci-domain", &size);
196 if (of_prop != NULL)
197 return;
198 WARN_ON(of_prop && size < sizeof(int));
199 if (of_prop && size < sizeof(int))
200 of_prop = NULL;
201 size = sizeof(struct property) + sizeof(int);
202 if (of_prop == NULL) {
203 if (mem_init_done)
204 of_prop = kmalloc(size, GFP_KERNEL);
205 else
206 of_prop = alloc_bootmem(size);
207 }
208 memset(of_prop, 0, sizeof(struct property));
209 of_prop->name = "linux,pci-domain";
210 of_prop->length = sizeof(int);
211 of_prop->value = (unsigned char *)&of_prop[1];
212 *((int *)of_prop->value) = phb->global_number;
213 prom_add_property(dev, of_prop);
214}
215
216struct pci_controller * pcibios_alloc_controller(struct device_node *dev) 188struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
217{ 189{
218 struct pci_controller *phb; 190 struct pci_controller *phb;
@@ -226,22 +198,13 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
226 pci_setup_pci_controller(phb); 198 pci_setup_pci_controller(phb);
227 phb->arch_data = dev; 199 phb->arch_data = dev;
228 phb->is_dynamic = mem_init_done; 200 phb->is_dynamic = mem_init_done;
229 if (dev) { 201 if (dev)
230 PHB_SET_NODE(phb, of_node_to_nid(dev)); 202 PHB_SET_NODE(phb, of_node_to_nid(dev));
231 add_linux_pci_domain(dev, phb);
232 }
233 return phb; 203 return phb;
234} 204}
235 205
236void pcibios_free_controller(struct pci_controller *phb) 206void pcibios_free_controller(struct pci_controller *phb)
237{ 207{
238 if (phb->arch_data) {
239 struct device_node *np = phb->arch_data;
240 int *domain = (int *)get_property(np,
241 "linux,pci-domain", NULL);
242 if (domain)
243 *domain = -1;
244 }
245 if (phb->is_dynamic) 208 if (phb->is_dynamic)
246 kfree(phb); 209 kfree(phb);
247} 210}
@@ -283,10 +246,10 @@ static void __init pcibios_claim_of_setup(void)
283#ifdef CONFIG_PPC_MULTIPLATFORM 246#ifdef CONFIG_PPC_MULTIPLATFORM
284static u32 get_int_prop(struct device_node *np, const char *name, u32 def) 247static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
285{ 248{
286 u32 *prop; 249 const u32 *prop;
287 int len; 250 int len;
288 251
289 prop = (u32 *) get_property(np, name, &len); 252 prop = get_property(np, name, &len);
290 if (prop && len >= 4) 253 if (prop && len >= 4)
291 return *prop; 254 return *prop;
292 return def; 255 return def;
@@ -315,10 +278,11 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
315 u64 base, size; 278 u64 base, size;
316 unsigned int flags; 279 unsigned int flags;
317 struct resource *res; 280 struct resource *res;
318 u32 *addrs, i; 281 const u32 *addrs;
282 u32 i;
319 int proplen; 283 int proplen;
320 284
321 addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); 285 addrs = get_property(node, "assigned-addresses", &proplen);
322 if (!addrs) 286 if (!addrs)
323 return; 287 return;
324 DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); 288 DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
@@ -418,7 +382,7 @@ void __devinit of_scan_bus(struct device_node *node,
418 struct pci_bus *bus) 382 struct pci_bus *bus)
419{ 383{
420 struct device_node *child = NULL; 384 struct device_node *child = NULL;
421 u32 *reg; 385 const u32 *reg;
422 int reglen, devfn; 386 int reglen, devfn;
423 struct pci_dev *dev; 387 struct pci_dev *dev;
424 388
@@ -426,7 +390,7 @@ void __devinit of_scan_bus(struct device_node *node,
426 390
427 while ((child = of_get_next_child(node, child)) != NULL) { 391 while ((child = of_get_next_child(node, child)) != NULL) {
428 DBG(" * %s\n", child->full_name); 392 DBG(" * %s\n", child->full_name);
429 reg = (u32 *) get_property(child, "reg", &reglen); 393 reg = get_property(child, "reg", &reglen);
430 if (reg == NULL || reglen < 20) 394 if (reg == NULL || reglen < 20)
431 continue; 395 continue;
432 devfn = (reg[0] >> 8) & 0xff; 396 devfn = (reg[0] >> 8) & 0xff;
@@ -450,7 +414,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
450 struct pci_dev *dev) 414 struct pci_dev *dev)
451{ 415{
452 struct pci_bus *bus; 416 struct pci_bus *bus;
453 u32 *busrange, *ranges; 417 const u32 *busrange, *ranges;
454 int len, i, mode; 418 int len, i, mode;
455 struct resource *res; 419 struct resource *res;
456 unsigned int flags; 420 unsigned int flags;
@@ -459,13 +423,13 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
459 DBG("of_scan_pci_bridge(%s)\n", node->full_name); 423 DBG("of_scan_pci_bridge(%s)\n", node->full_name);
460 424
461 /* parse bus-range property */ 425 /* parse bus-range property */
462 busrange = (u32 *) get_property(node, "bus-range", &len); 426 busrange = get_property(node, "bus-range", &len);
463 if (busrange == NULL || len != 8) { 427 if (busrange == NULL || len != 8) {
464 printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", 428 printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
465 node->full_name); 429 node->full_name);
466 return; 430 return;
467 } 431 }
468 ranges = (u32 *) get_property(node, "ranges", &len); 432 ranges = get_property(node, "ranges", &len);
469 if (ranges == NULL) { 433 if (ranges == NULL) {
470 printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", 434 printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
471 node->full_name); 435 node->full_name);
@@ -929,13 +893,13 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
929 unsigned int size; 893 unsigned int size;
930 }; 894 };
931 895
932 struct isa_range *range; 896 const struct isa_range *range;
933 unsigned long pci_addr; 897 unsigned long pci_addr;
934 unsigned int isa_addr; 898 unsigned int isa_addr;
935 unsigned int size; 899 unsigned int size;
936 int rlen = 0; 900 int rlen = 0;
937 901
938 range = (struct isa_range *) get_property(isa_node, "ranges", &rlen); 902 range = get_property(isa_node, "ranges", &rlen);
939 if (range == NULL || (rlen < sizeof(struct isa_range))) { 903 if (range == NULL || (rlen < sizeof(struct isa_range))) {
940 printk(KERN_ERR "no ISA ranges or unexpected isa range size," 904 printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
941 "mapping 64k\n"); 905 "mapping 64k\n");
@@ -976,7 +940,8 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
976void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, 940void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
977 struct device_node *dev, int prim) 941 struct device_node *dev, int prim)
978{ 942{
979 unsigned int *ranges, pci_space; 943 const unsigned int *ranges;
944 unsigned int pci_space;
980 unsigned long size; 945 unsigned long size;
981 int rlen = 0; 946 int rlen = 0;
982 int memno = 0; 947 int memno = 0;
@@ -994,7 +959,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
994 * (size depending on dev->n_addr_cells) 959 * (size depending on dev->n_addr_cells)
995 * cells 4+5 or 5+6: the size of the range 960 * cells 4+5 or 5+6: the size of the range
996 */ 961 */
997 ranges = (unsigned int *) get_property(dev, "ranges", &rlen); 962 ranges = get_property(dev, "ranges", &rlen);
998 if (ranges == NULL) 963 if (ranges == NULL)
999 return; 964 return;
1000 hose->io_base_phys = 0; 965 hose->io_base_phys = 0;
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 1c18953514c3..68df018dae0e 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -40,8 +40,8 @@
40static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) 40static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
41{ 41{
42 struct pci_controller *phb = data; 42 struct pci_controller *phb = data;
43 int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); 43 const int *type = get_property(dn, "ibm,pci-config-space-type", NULL);
44 u32 *regs; 44 const u32 *regs;
45 struct pci_dn *pdn; 45 struct pci_dn *pdn;
46 46
47 if (mem_init_done) 47 if (mem_init_done)
@@ -54,14 +54,14 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
54 dn->data = pdn; 54 dn->data = pdn;
55 pdn->node = dn; 55 pdn->node = dn;
56 pdn->phb = phb; 56 pdn->phb = phb;
57 regs = (u32 *)get_property(dn, "reg", NULL); 57 regs = get_property(dn, "reg", NULL);
58 if (regs) { 58 if (regs) {
59 /* First register entry is addr (00BBSS00) */ 59 /* First register entry is addr (00BBSS00) */
60 pdn->busno = (regs[0] >> 16) & 0xff; 60 pdn->busno = (regs[0] >> 16) & 0xff;
61 pdn->devfn = (regs[0] >> 8) & 0xff; 61 pdn->devfn = (regs[0] >> 8) & 0xff;
62 } 62 }
63 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 63 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
64 u32 *busp = (u32 *)get_property(dn, "linux,subbus", NULL); 64 const u32 *busp = get_property(dn, "linux,subbus", NULL);
65 if (busp) 65 if (busp)
66 pdn->bussubno = *busp; 66 pdn->bussubno = *busp;
67 } 67 }
@@ -96,10 +96,11 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
96 96
97 /* We started with a phb, iterate all childs */ 97 /* We started with a phb, iterate all childs */
98 for (dn = start->child; dn; dn = nextdn) { 98 for (dn = start->child; dn; dn = nextdn) {
99 u32 *classp, class; 99 const u32 *classp;
100 u32 class;
100 101
101 nextdn = NULL; 102 nextdn = NULL;
102 classp = (u32 *)get_property(dn, "class-code", NULL); 103 classp = get_property(dn, "class-code", NULL);
103 class = classp ? *classp : 0; 104 class = classp ? *classp : 0;
104 105
105 if (pre && ((ret = pre(dn, data)) != NULL)) 106 if (pre && ((ret = pre(dn, data)) != NULL))
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 39d3bfcabcd2..807193a3c784 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -91,25 +91,10 @@ EXPORT_SYMBOL(__copy_tofrom_user);
91EXPORT_SYMBOL(__clear_user); 91EXPORT_SYMBOL(__clear_user);
92EXPORT_SYMBOL(__strncpy_from_user); 92EXPORT_SYMBOL(__strncpy_from_user);
93EXPORT_SYMBOL(__strnlen_user); 93EXPORT_SYMBOL(__strnlen_user);
94 94#ifdef CONFIG_PPC64
95#ifndef __powerpc64__ 95EXPORT_SYMBOL(copy_4K_page);
96EXPORT_SYMBOL(__ide_mm_insl);
97EXPORT_SYMBOL(__ide_mm_outsw);
98EXPORT_SYMBOL(__ide_mm_insw);
99EXPORT_SYMBOL(__ide_mm_outsl);
100#endif 96#endif
101 97
102EXPORT_SYMBOL(_insb);
103EXPORT_SYMBOL(_outsb);
104EXPORT_SYMBOL(_insw);
105EXPORT_SYMBOL(_outsw);
106EXPORT_SYMBOL(_insl);
107EXPORT_SYMBOL(_outsl);
108EXPORT_SYMBOL(_insw_ns);
109EXPORT_SYMBOL(_outsw_ns);
110EXPORT_SYMBOL(_insl_ns);
111EXPORT_SYMBOL(_outsl_ns);
112
113#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)) 98#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
114EXPORT_SYMBOL(ppc_ide_md); 99EXPORT_SYMBOL(ppc_ide_md);
115#endif 100#endif
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index a1787ffb6319..eb913f80bfb1 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -757,24 +757,9 @@ static int __init early_init_dt_scan_root(unsigned long node,
757static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) 757static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
758{ 758{
759 cell_t *p = *cellp; 759 cell_t *p = *cellp;
760 unsigned long r;
761 760
762 /* Ignore more than 2 cells */ 761 *cellp = p + s;
763 while (s > sizeof(unsigned long) / 4) { 762 return of_read_ulong(p, s);
764 p++;
765 s--;
766 }
767 r = *p++;
768#ifdef CONFIG_PPC64
769 if (s > 1) {
770 r <<= 32;
771 r |= *(p++);
772 s--;
773 }
774#endif
775
776 *cellp = p;
777 return r;
778} 763}
779 764
780 765
@@ -942,11 +927,11 @@ void __init early_init_devtree(void *params)
942int 927int
943prom_n_addr_cells(struct device_node* np) 928prom_n_addr_cells(struct device_node* np)
944{ 929{
945 int* ip; 930 const int *ip;
946 do { 931 do {
947 if (np->parent) 932 if (np->parent)
948 np = np->parent; 933 np = np->parent;
949 ip = (int *) get_property(np, "#address-cells", NULL); 934 ip = get_property(np, "#address-cells", NULL);
950 if (ip != NULL) 935 if (ip != NULL)
951 return *ip; 936 return *ip;
952 } while (np->parent); 937 } while (np->parent);
@@ -958,11 +943,11 @@ EXPORT_SYMBOL(prom_n_addr_cells);
958int 943int
959prom_n_size_cells(struct device_node* np) 944prom_n_size_cells(struct device_node* np)
960{ 945{
961 int* ip; 946 const int* ip;
962 do { 947 do {
963 if (np->parent) 948 if (np->parent)
964 np = np->parent; 949 np = np->parent;
965 ip = (int *) get_property(np, "#size-cells", NULL); 950 ip = get_property(np, "#size-cells", NULL);
966 if (ip != NULL) 951 if (ip != NULL)
967 return *ip; 952 return *ip;
968 } while (np->parent); 953 } while (np->parent);
@@ -1034,7 +1019,7 @@ int device_is_compatible(struct device_node *device, const char *compat)
1034 const char* cp; 1019 const char* cp;
1035 int cplen, l; 1020 int cplen, l;
1036 1021
1037 cp = (char *) get_property(device, "compatible", &cplen); 1022 cp = get_property(device, "compatible", &cplen);
1038 if (cp == NULL) 1023 if (cp == NULL)
1039 return 0; 1024 return 0;
1040 while (cplen > 0) { 1025 while (cplen > 0) {
@@ -1449,7 +1434,7 @@ static int of_finish_dynamic_node(struct device_node *node)
1449{ 1434{
1450 struct device_node *parent = of_get_parent(node); 1435 struct device_node *parent = of_get_parent(node);
1451 int err = 0; 1436 int err = 0;
1452 phandle *ibm_phandle; 1437 const phandle *ibm_phandle;
1453 1438
1454 node->name = get_property(node, "name", NULL); 1439 node->name = get_property(node, "name", NULL);
1455 node->type = get_property(node, "device_type", NULL); 1440 node->type = get_property(node, "device_type", NULL);
@@ -1466,8 +1451,7 @@ static int of_finish_dynamic_node(struct device_node *node)
1466 return -ENODEV; 1451 return -ENODEV;
1467 1452
1468 /* fix up new node's linux_phandle field */ 1453 /* fix up new node's linux_phandle field */
1469 if ((ibm_phandle = (unsigned int *)get_property(node, 1454 if ((ibm_phandle = get_property(node, "ibm,phandle", NULL)))
1470 "ibm,phandle", NULL)))
1471 node->linux_phandle = *ibm_phandle; 1455 node->linux_phandle = *ibm_phandle;
1472 1456
1473out: 1457out:
@@ -1528,7 +1512,7 @@ struct property *of_find_property(struct device_node *np, const char *name,
1528 * Find a property with a given name for a given node 1512 * Find a property with a given name for a given node
1529 * and return the value. 1513 * and return the value.
1530 */ 1514 */
1531void *get_property(struct device_node *np, const char *name, int *lenp) 1515const void *get_property(struct device_node *np, const char *name, int *lenp)
1532{ 1516{
1533 struct property *pp = of_find_property(np,name,lenp); 1517 struct property *pp = of_find_property(np,name,lenp);
1534 return pp ? pp->value : NULL; 1518 return pp ? pp->value : NULL;
@@ -1658,16 +1642,16 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
1658 hardid = get_hard_smp_processor_id(cpu); 1642 hardid = get_hard_smp_processor_id(cpu);
1659 1643
1660 for_each_node_by_type(np, "cpu") { 1644 for_each_node_by_type(np, "cpu") {
1661 u32 *intserv; 1645 const u32 *intserv;
1662 unsigned int plen, t; 1646 unsigned int plen, t;
1663 1647
1664 /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist 1648 /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
1665 * fallback to "reg" property and assume no threads 1649 * fallback to "reg" property and assume no threads
1666 */ 1650 */
1667 intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", 1651 intserv = get_property(np, "ibm,ppc-interrupt-server#s",
1668 &plen); 1652 &plen);
1669 if (intserv == NULL) { 1653 if (intserv == NULL) {
1670 u32 *reg = (u32 *)get_property(np, "reg", NULL); 1654 const u32 *reg = get_property(np, "reg", NULL);
1671 if (reg == NULL) 1655 if (reg == NULL)
1672 continue; 1656 continue;
1673 if (*reg == hardid) { 1657 if (*reg == hardid) {
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 4394e545f9f7..b91761639d96 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2033,16 +2033,22 @@ static void __init fixup_device_tree_maple(void)
2033#endif 2033#endif
2034 2034
2035#ifdef CONFIG_PPC_CHRP 2035#ifdef CONFIG_PPC_CHRP
2036/* Pegasos lacks the "ranges" property in the isa node */ 2036/* Pegasos and BriQ lacks the "ranges" property in the isa node */
2037static void __init fixup_device_tree_chrp(void) 2037static void __init fixup_device_tree_chrp(void)
2038{ 2038{
2039 phandle isa; 2039 phandle isa;
2040 u32 isa_ranges[6]; 2040 u32 isa_ranges[6];
2041 u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
2041 char *name; 2042 char *name;
2042 int rc; 2043 int rc;
2043 2044
2044 name = "/pci@80000000/isa@c"; 2045 name = "/pci@80000000/isa@c";
2045 isa = call_prom("finddevice", 1, 1, ADDR(name)); 2046 isa = call_prom("finddevice", 1, 1, ADDR(name));
2047 if (!PHANDLE_VALID(isa)) {
2048 name = "/pci@ff500000/isa@6";
2049 isa = call_prom("finddevice", 1, 1, ADDR(name));
2050 rloc = 0x01003000; /* IO space; PCI device = 6 */
2051 }
2046 if (!PHANDLE_VALID(isa)) 2052 if (!PHANDLE_VALID(isa))
2047 return; 2053 return;
2048 2054
@@ -2054,7 +2060,7 @@ static void __init fixup_device_tree_chrp(void)
2054 2060
2055 isa_ranges[0] = 0x1; 2061 isa_ranges[0] = 0x1;
2056 isa_ranges[1] = 0x0; 2062 isa_ranges[1] = 0x0;
2057 isa_ranges[2] = 0x01006000; 2063 isa_ranges[2] = rloc;
2058 isa_ranges[3] = 0x0; 2064 isa_ranges[3] = 0x0;
2059 isa_ranges[4] = 0x0; 2065 isa_ranges[4] = 0x0;
2060 isa_ranges[5] = 0x00010000; 2066 isa_ranges[5] = 0x00010000;
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index a10825a5dfe6..603dff3ad62a 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -27,7 +27,7 @@
27 27
28/* Debug utility */ 28/* Debug utility */
29#ifdef DEBUG 29#ifdef DEBUG
30static void of_dump_addr(const char *s, u32 *addr, int na) 30static void of_dump_addr(const char *s, const u32 *addr, int na)
31{ 31{
32 printk("%s", s); 32 printk("%s", s);
33 while(na--) 33 while(na--)
@@ -35,7 +35,7 @@ static void of_dump_addr(const char *s, u32 *addr, int na)
35 printk("\n"); 35 printk("\n");
36} 36}
37#else 37#else
38static void of_dump_addr(const char *s, u32 *addr, int na) { } 38static void of_dump_addr(const char *s, const u32 *addr, int na) { }
39#endif 39#endif
40 40
41 41
@@ -46,9 +46,10 @@ struct of_bus {
46 int (*match)(struct device_node *parent); 46 int (*match)(struct device_node *parent);
47 void (*count_cells)(struct device_node *child, 47 void (*count_cells)(struct device_node *child,
48 int *addrc, int *sizec); 48 int *addrc, int *sizec);
49 u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); 49 u64 (*map)(u32 *addr, const u32 *range,
50 int na, int ns, int pna);
50 int (*translate)(u32 *addr, u64 offset, int na); 51 int (*translate)(u32 *addr, u64 offset, int na);
51 unsigned int (*get_flags)(u32 *addr); 52 unsigned int (*get_flags)(const u32 *addr);
52}; 53};
53 54
54 55
@@ -65,7 +66,8 @@ static void of_bus_default_count_cells(struct device_node *dev,
65 *sizec = prom_n_size_cells(dev); 66 *sizec = prom_n_size_cells(dev);
66} 67}
67 68
68static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) 69static u64 of_bus_default_map(u32 *addr, const u32 *range,
70 int na, int ns, int pna)
69{ 71{
70 u64 cp, s, da; 72 u64 cp, s, da;
71 73
@@ -93,7 +95,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
93 return 0; 95 return 0;
94} 96}
95 97
96static unsigned int of_bus_default_get_flags(u32 *addr) 98static unsigned int of_bus_default_get_flags(const u32 *addr)
97{ 99{
98 return IORESOURCE_MEM; 100 return IORESOURCE_MEM;
99} 101}
@@ -118,7 +120,7 @@ static void of_bus_pci_count_cells(struct device_node *np,
118 *sizec = 2; 120 *sizec = 2;
119} 121}
120 122
121static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) 123static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
122{ 124{
123 u64 cp, s, da; 125 u64 cp, s, da;
124 126
@@ -143,7 +145,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
143 return of_bus_default_translate(addr + 1, offset, na - 1); 145 return of_bus_default_translate(addr + 1, offset, na - 1);
144} 146}
145 147
146static unsigned int of_bus_pci_get_flags(u32 *addr) 148static unsigned int of_bus_pci_get_flags(const u32 *addr)
147{ 149{
148 unsigned int flags = 0; 150 unsigned int flags = 0;
149 u32 w = addr[0]; 151 u32 w = addr[0];
@@ -178,7 +180,7 @@ static void of_bus_isa_count_cells(struct device_node *child,
178 *sizec = 1; 180 *sizec = 1;
179} 181}
180 182
181static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) 183static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
182{ 184{
183 u64 cp, s, da; 185 u64 cp, s, da;
184 186
@@ -203,7 +205,7 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
203 return of_bus_default_translate(addr + 1, offset, na - 1); 205 return of_bus_default_translate(addr + 1, offset, na - 1);
204} 206}
205 207
206static unsigned int of_bus_isa_get_flags(u32 *addr) 208static unsigned int of_bus_isa_get_flags(const u32 *addr)
207{ 209{
208 unsigned int flags = 0; 210 unsigned int flags = 0;
209 u32 w = addr[0]; 211 u32 w = addr[0];
@@ -268,7 +270,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
268 struct of_bus *pbus, u32 *addr, 270 struct of_bus *pbus, u32 *addr,
269 int na, int ns, int pna) 271 int na, int ns, int pna)
270{ 272{
271 u32 *ranges; 273 const u32 *ranges;
272 unsigned int rlen; 274 unsigned int rlen;
273 int rone; 275 int rone;
274 u64 offset = OF_BAD_ADDR; 276 u64 offset = OF_BAD_ADDR;
@@ -285,7 +287,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
285 * to translate addresses that aren't supposed to be translated in 287 * to translate addresses that aren't supposed to be translated in
286 * the first place. --BenH. 288 * the first place. --BenH.
287 */ 289 */
288 ranges = (u32 *)get_property(parent, "ranges", &rlen); 290 ranges = get_property(parent, "ranges", &rlen);
289 if (ranges == NULL || rlen == 0) { 291 if (ranges == NULL || rlen == 0) {
290 offset = of_read_number(addr, na); 292 offset = of_read_number(addr, na);
291 memset(addr, 0, pna * 4); 293 memset(addr, 0, pna * 4);
@@ -328,7 +330,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
328 * that can be mapped to a cpu physical address). This is not really specified 330 * that can be mapped to a cpu physical address). This is not really specified
329 * that way, but this is traditionally the way IBM at least do things 331 * that way, but this is traditionally the way IBM at least do things
330 */ 332 */
331u64 of_translate_address(struct device_node *dev, u32 *in_addr) 333u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
332{ 334{
333 struct device_node *parent = NULL; 335 struct device_node *parent = NULL;
334 struct of_bus *bus, *pbus; 336 struct of_bus *bus, *pbus;
@@ -405,10 +407,10 @@ u64 of_translate_address(struct device_node *dev, u32 *in_addr)
405} 407}
406EXPORT_SYMBOL(of_translate_address); 408EXPORT_SYMBOL(of_translate_address);
407 409
408u32 *of_get_address(struct device_node *dev, int index, u64 *size, 410const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
409 unsigned int *flags) 411 unsigned int *flags)
410{ 412{
411 u32 *prop; 413 const u32 *prop;
412 unsigned int psize; 414 unsigned int psize;
413 struct device_node *parent; 415 struct device_node *parent;
414 struct of_bus *bus; 416 struct of_bus *bus;
@@ -425,7 +427,7 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
425 return NULL; 427 return NULL;
426 428
427 /* Get "reg" or "assigned-addresses" property */ 429 /* Get "reg" or "assigned-addresses" property */
428 prop = (u32 *)get_property(dev, bus->addresses, &psize); 430 prop = get_property(dev, bus->addresses, &psize);
429 if (prop == NULL) 431 if (prop == NULL)
430 return NULL; 432 return NULL;
431 psize /= 4; 433 psize /= 4;
@@ -443,10 +445,10 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
443} 445}
444EXPORT_SYMBOL(of_get_address); 446EXPORT_SYMBOL(of_get_address);
445 447
446u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, 448const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
447 unsigned int *flags) 449 unsigned int *flags)
448{ 450{
449 u32 *prop; 451 const u32 *prop;
450 unsigned int psize; 452 unsigned int psize;
451 struct device_node *parent; 453 struct device_node *parent;
452 struct of_bus *bus; 454 struct of_bus *bus;
@@ -467,7 +469,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
467 return NULL; 469 return NULL;
468 470
469 /* Get "reg" or "assigned-addresses" property */ 471 /* Get "reg" or "assigned-addresses" property */
470 prop = (u32 *)get_property(dev, bus->addresses, &psize); 472 prop = get_property(dev, bus->addresses, &psize);
471 if (prop == NULL) 473 if (prop == NULL)
472 return NULL; 474 return NULL;
473 psize /= 4; 475 psize /= 4;
@@ -485,7 +487,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
485} 487}
486EXPORT_SYMBOL(of_get_pci_address); 488EXPORT_SYMBOL(of_get_pci_address);
487 489
488static int __of_address_to_resource(struct device_node *dev, u32 *addrp, 490static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
489 u64 size, unsigned int flags, 491 u64 size, unsigned int flags,
490 struct resource *r) 492 struct resource *r)
491{ 493{
@@ -516,7 +518,7 @@ static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
516int of_address_to_resource(struct device_node *dev, int index, 518int of_address_to_resource(struct device_node *dev, int index,
517 struct resource *r) 519 struct resource *r)
518{ 520{
519 u32 *addrp; 521 const u32 *addrp;
520 u64 size; 522 u64 size;
521 unsigned int flags; 523 unsigned int flags;
522 524
@@ -530,7 +532,7 @@ EXPORT_SYMBOL_GPL(of_address_to_resource);
530int of_pci_address_to_resource(struct device_node *dev, int bar, 532int of_pci_address_to_resource(struct device_node *dev, int bar,
531 struct resource *r) 533 struct resource *r)
532{ 534{
533 u32 *addrp; 535 const u32 *addrp;
534 u64 size; 536 u64 size;
535 unsigned int flags; 537 unsigned int flags;
536 538
@@ -541,13 +543,14 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
541} 543}
542EXPORT_SYMBOL_GPL(of_pci_address_to_resource); 544EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
543 545
544void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop, 546void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
545 unsigned long *busno, unsigned long *phys, unsigned long *size) 547 unsigned long *busno, unsigned long *phys, unsigned long *size)
546{ 548{
547 u32 *dma_window, cells; 549 const u32 *dma_window;
548 unsigned char *prop; 550 u32 cells;
551 const unsigned char *prop;
549 552
550 dma_window = (u32 *)dma_window_prop; 553 dma_window = dma_window_prop;
551 554
552 /* busno is always one cell */ 555 /* busno is always one cell */
553 *busno = *(dma_window++); 556 *busno = *(dma_window++);
@@ -576,13 +579,13 @@ static struct device_node *of_irq_dflt_pic;
576static struct device_node *of_irq_find_parent(struct device_node *child) 579static struct device_node *of_irq_find_parent(struct device_node *child)
577{ 580{
578 struct device_node *p; 581 struct device_node *p;
579 phandle *parp; 582 const phandle *parp;
580 583
581 if (!of_node_get(child)) 584 if (!of_node_get(child))
582 return NULL; 585 return NULL;
583 586
584 do { 587 do {
585 parp = (phandle *)get_property(child, "interrupt-parent", NULL); 588 parp = get_property(child, "interrupt-parent", NULL);
586 if (parp == NULL) 589 if (parp == NULL)
587 p = of_get_parent(child); 590 p = of_get_parent(child);
588 else { 591 else {
@@ -639,11 +642,11 @@ void of_irq_map_init(unsigned int flags)
639 642
640} 643}
641 644
642int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize, 645int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
643 u32 *addr, struct of_irq *out_irq) 646 const u32 *addr, struct of_irq *out_irq)
644{ 647{
645 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; 648 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
646 u32 *tmp, *imap, *imask; 649 const u32 *tmp, *imap, *imask;
647 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; 650 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
648 int imaplen, match, i; 651 int imaplen, match, i;
649 652
@@ -657,7 +660,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
657 * is none, we are nice and just walk up the tree 660 * is none, we are nice and just walk up the tree
658 */ 661 */
659 do { 662 do {
660 tmp = (u32 *)get_property(ipar, "#interrupt-cells", NULL); 663 tmp = get_property(ipar, "#interrupt-cells", NULL);
661 if (tmp != NULL) { 664 if (tmp != NULL) {
662 intsize = *tmp; 665 intsize = *tmp;
663 break; 666 break;
@@ -681,7 +684,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
681 */ 684 */
682 old = of_node_get(ipar); 685 old = of_node_get(ipar);
683 do { 686 do {
684 tmp = (u32 *)get_property(old, "#address-cells", NULL); 687 tmp = get_property(old, "#address-cells", NULL);
685 tnode = of_get_parent(old); 688 tnode = of_get_parent(old);
686 of_node_put(old); 689 of_node_put(old);
687 old = tnode; 690 old = tnode;
@@ -708,7 +711,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
708 } 711 }
709 712
710 /* Now look for an interrupt-map */ 713 /* Now look for an interrupt-map */
711 imap = (u32 *)get_property(ipar, "interrupt-map", &imaplen); 714 imap = get_property(ipar, "interrupt-map", &imaplen);
712 /* No interrupt map, check for an interrupt parent */ 715 /* No interrupt map, check for an interrupt parent */
713 if (imap == NULL) { 716 if (imap == NULL) {
714 DBG(" -> no map, getting parent\n"); 717 DBG(" -> no map, getting parent\n");
@@ -718,7 +721,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
718 imaplen /= sizeof(u32); 721 imaplen /= sizeof(u32);
719 722
720 /* Look for a mask */ 723 /* Look for a mask */
721 imask = (u32 *)get_property(ipar, "interrupt-map-mask", NULL); 724 imask = get_property(ipar, "interrupt-map-mask", NULL);
722 725
723 /* If we were passed no "reg" property and we attempt to parse 726 /* If we were passed no "reg" property and we attempt to parse
724 * an interrupt-map, then #address-cells must be 0. 727 * an interrupt-map, then #address-cells must be 0.
@@ -765,14 +768,14 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
765 /* Get #interrupt-cells and #address-cells of new 768 /* Get #interrupt-cells and #address-cells of new
766 * parent 769 * parent
767 */ 770 */
768 tmp = (u32 *)get_property(newpar, "#interrupt-cells", 771 tmp = get_property(newpar, "#interrupt-cells",
769 NULL); 772 NULL);
770 if (tmp == NULL) { 773 if (tmp == NULL) {
771 DBG(" -> parent lacks #interrupt-cells !\n"); 774 DBG(" -> parent lacks #interrupt-cells !\n");
772 goto fail; 775 goto fail;
773 } 776 }
774 newintsize = *tmp; 777 newintsize = *tmp;
775 tmp = (u32 *)get_property(newpar, "#address-cells", 778 tmp = get_property(newpar, "#address-cells",
776 NULL); 779 NULL);
777 newaddrsize = (tmp == NULL) ? 0 : *tmp; 780 newaddrsize = (tmp == NULL) ? 0 : *tmp;
778 781
@@ -818,14 +821,14 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);
818static int of_irq_map_oldworld(struct device_node *device, int index, 821static int of_irq_map_oldworld(struct device_node *device, int index,
819 struct of_irq *out_irq) 822 struct of_irq *out_irq)
820{ 823{
821 u32 *ints; 824 const u32 *ints;
822 int intlen; 825 int intlen;
823 826
824 /* 827 /*
825 * Old machines just have a list of interrupt numbers 828 * Old machines just have a list of interrupt numbers
826 * and no interrupt-controller nodes. 829 * and no interrupt-controller nodes.
827 */ 830 */
828 ints = (u32 *) get_property(device, "AAPL,interrupts", &intlen); 831 ints = get_property(device, "AAPL,interrupts", &intlen);
829 if (ints == NULL) 832 if (ints == NULL)
830 return -EINVAL; 833 return -EINVAL;
831 intlen /= sizeof(u32); 834 intlen /= sizeof(u32);
@@ -850,7 +853,8 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
850int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) 853int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
851{ 854{
852 struct device_node *p; 855 struct device_node *p;
853 u32 *intspec, *tmp, intsize, intlen, *addr; 856 const u32 *intspec, *tmp, *addr;
857 u32 intsize, intlen;
854 int res; 858 int res;
855 859
856 DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); 860 DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
@@ -860,13 +864,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
860 return of_irq_map_oldworld(device, index, out_irq); 864 return of_irq_map_oldworld(device, index, out_irq);
861 865
862 /* Get the interrupts property */ 866 /* Get the interrupts property */
863 intspec = (u32 *)get_property(device, "interrupts", &intlen); 867 intspec = get_property(device, "interrupts", &intlen);
864 if (intspec == NULL) 868 if (intspec == NULL)
865 return -EINVAL; 869 return -EINVAL;
866 intlen /= sizeof(u32); 870 intlen /= sizeof(u32);
867 871
868 /* Get the reg property (if any) */ 872 /* Get the reg property (if any) */
869 addr = (u32 *)get_property(device, "reg", NULL); 873 addr = get_property(device, "reg", NULL);
870 874
871 /* Look for the interrupt parent. */ 875 /* Look for the interrupt parent. */
872 p = of_irq_find_parent(device); 876 p = of_irq_find_parent(device);
@@ -874,7 +878,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
874 return -EINVAL; 878 return -EINVAL;
875 879
876 /* Get size of interrupt specifier */ 880 /* Get size of interrupt specifier */
877 tmp = (u32 *)get_property(p, "#interrupt-cells", NULL); 881 tmp = get_property(p, "#interrupt-cells", NULL);
878 if (tmp == NULL) { 882 if (tmp == NULL) {
879 of_node_put(p); 883 of_node_put(p);
880 return -EINVAL; 884 return -EINVAL;
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 9c9ad1fa9cce..2fe82abf1c52 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -246,12 +246,12 @@ struct file_operations ppc_rtas_rmo_buf_ops = {
246 246
247static int ppc_rtas_find_all_sensors(void); 247static int ppc_rtas_find_all_sensors(void);
248static void ppc_rtas_process_sensor(struct seq_file *m, 248static void ppc_rtas_process_sensor(struct seq_file *m,
249 struct individual_sensor *s, int state, int error, char *loc); 249 struct individual_sensor *s, int state, int error, const char *loc);
250static char *ppc_rtas_process_error(int error); 250static char *ppc_rtas_process_error(int error);
251static void get_location_code(struct seq_file *m, 251static void get_location_code(struct seq_file *m,
252 struct individual_sensor *s, char *loc); 252 struct individual_sensor *s, const char *loc);
253static void check_location_string(struct seq_file *m, char *c); 253static void check_location_string(struct seq_file *m, const char *c);
254static void check_location(struct seq_file *m, char *c); 254static void check_location(struct seq_file *m, const char *c);
255 255
256static int __init proc_rtas_init(void) 256static int __init proc_rtas_init(void)
257{ 257{
@@ -446,11 +446,11 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v)
446 for (i=0; i<sensors.quant; i++) { 446 for (i=0; i<sensors.quant; i++) {
447 struct individual_sensor *p = &sensors.sensor[i]; 447 struct individual_sensor *p = &sensors.sensor[i];
448 char rstr[64]; 448 char rstr[64];
449 char *loc; 449 const char *loc;
450 int llen, offs; 450 int llen, offs;
451 451
452 sprintf (rstr, SENSOR_PREFIX"%04d", p->token); 452 sprintf (rstr, SENSOR_PREFIX"%04d", p->token);
453 loc = (char *) get_property(rtas_node, rstr, &llen); 453 loc = get_property(rtas_node, rstr, &llen);
454 454
455 /* A sensor may have multiple instances */ 455 /* A sensor may have multiple instances */
456 for (j = 0, offs = 0; j <= p->quant; j++) { 456 for (j = 0, offs = 0; j <= p->quant; j++) {
@@ -474,10 +474,10 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v)
474 474
475static int ppc_rtas_find_all_sensors(void) 475static int ppc_rtas_find_all_sensors(void)
476{ 476{
477 unsigned int *utmp; 477 const unsigned int *utmp;
478 int len, i; 478 int len, i;
479 479
480 utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len); 480 utmp = get_property(rtas_node, "rtas-sensors", &len);
481 if (utmp == NULL) { 481 if (utmp == NULL) {
482 printk (KERN_ERR "error: could not get rtas-sensors\n"); 482 printk (KERN_ERR "error: could not get rtas-sensors\n");
483 return 1; 483 return 1;
@@ -530,7 +530,7 @@ static char *ppc_rtas_process_error(int error)
530 */ 530 */
531 531
532static void ppc_rtas_process_sensor(struct seq_file *m, 532static void ppc_rtas_process_sensor(struct seq_file *m,
533 struct individual_sensor *s, int state, int error, char *loc) 533 struct individual_sensor *s, int state, int error, const char *loc)
534{ 534{
535 /* Defined return vales */ 535 /* Defined return vales */
536 const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", 536 const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t",
@@ -682,7 +682,7 @@ static void ppc_rtas_process_sensor(struct seq_file *m,
682 682
683/* ****************************************************************** */ 683/* ****************************************************************** */
684 684
685static void check_location(struct seq_file *m, char *c) 685static void check_location(struct seq_file *m, const char *c)
686{ 686{
687 switch (c[0]) { 687 switch (c[0]) {
688 case LOC_PLANAR: 688 case LOC_PLANAR:
@@ -719,7 +719,7 @@ static void check_location(struct seq_file *m, char *c)
719 * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ] 719 * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
720 * the '.' may be an abbrevation 720 * the '.' may be an abbrevation
721 */ 721 */
722static void check_location_string(struct seq_file *m, char *c) 722static void check_location_string(struct seq_file *m, const char *c)
723{ 723{
724 while (*c) { 724 while (*c) {
725 if (isalpha(*c) || *c == '.') 725 if (isalpha(*c) || *c == '.')
@@ -733,7 +733,8 @@ static void check_location_string(struct seq_file *m, char *c)
733 733
734/* ****************************************************************** */ 734/* ****************************************************************** */
735 735
736static void get_location_code(struct seq_file *m, struct individual_sensor *s, char *loc) 736static void get_location_code(struct seq_file *m, struct individual_sensor *s,
737 const char *loc)
737{ 738{
738 if (!loc || !*loc) { 739 if (!loc || !*loc) {
739 seq_printf(m, "---");/* does not have a location */ 740 seq_printf(m, "---");/* does not have a location */
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 77f1e06d208d..6ef80d4e38d3 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -177,10 +177,12 @@ void __init udbg_init_rtas_console(void)
177void rtas_progress(char *s, unsigned short hex) 177void rtas_progress(char *s, unsigned short hex)
178{ 178{
179 struct device_node *root; 179 struct device_node *root;
180 int width, *p; 180 int width;
181 const int *p;
181 char *os; 182 char *os;
182 static int display_character, set_indicator; 183 static int display_character, set_indicator;
183 static int display_width, display_lines, *row_width, form_feed; 184 static int display_width, display_lines, form_feed;
185 const static int *row_width;
184 static DEFINE_SPINLOCK(progress_lock); 186 static DEFINE_SPINLOCK(progress_lock);
185 static int current_line; 187 static int current_line;
186 static int pending_newline = 0; /* did last write end with unprinted newline? */ 188 static int pending_newline = 0; /* did last write end with unprinted newline? */
@@ -191,16 +193,16 @@ void rtas_progress(char *s, unsigned short hex)
191 if (display_width == 0) { 193 if (display_width == 0) {
192 display_width = 0x10; 194 display_width = 0x10;
193 if ((root = find_path_device("/rtas"))) { 195 if ((root = find_path_device("/rtas"))) {
194 if ((p = (unsigned int *)get_property(root, 196 if ((p = get_property(root,
195 "ibm,display-line-length", NULL))) 197 "ibm,display-line-length", NULL)))
196 display_width = *p; 198 display_width = *p;
197 if ((p = (unsigned int *)get_property(root, 199 if ((p = get_property(root,
198 "ibm,form-feed", NULL))) 200 "ibm,form-feed", NULL)))
199 form_feed = *p; 201 form_feed = *p;
200 if ((p = (unsigned int *)get_property(root, 202 if ((p = get_property(root,
201 "ibm,display-number-of-lines", NULL))) 203 "ibm,display-number-of-lines", NULL)))
202 display_lines = *p; 204 display_lines = *p;
203 row_width = (unsigned int *)get_property(root, 205 row_width = get_property(root,
204 "ibm,display-truncation-length", NULL); 206 "ibm,display-truncation-length", NULL);
205 } 207 }
206 display_character = rtas_token("display-character"); 208 display_character = rtas_token("display-character");
@@ -293,10 +295,10 @@ EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */
293 295
294int rtas_token(const char *service) 296int rtas_token(const char *service)
295{ 297{
296 int *tokp; 298 const int *tokp;
297 if (rtas.dev == NULL) 299 if (rtas.dev == NULL)
298 return RTAS_UNKNOWN_SERVICE; 300 return RTAS_UNKNOWN_SERVICE;
299 tokp = (int *) get_property(rtas.dev, service, NULL); 301 tokp = get_property(rtas.dev, service, NULL);
300 return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; 302 return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
301} 303}
302EXPORT_SYMBOL(rtas_token); 304EXPORT_SYMBOL(rtas_token);
@@ -626,6 +628,9 @@ void rtas_os_term(char *str)
626{ 628{
627 int status; 629 int status;
628 630
631 if (panic_timeout)
632 return;
633
629 if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term")) 634 if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
630 return; 635 return;
631 636
@@ -687,15 +692,14 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
687 int i; 692 int i;
688 long state; 693 long state;
689 long rc; 694 long rc;
690 unsigned long dummy; 695 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
691
692 struct rtas_suspend_me_data data; 696 struct rtas_suspend_me_data data;
693 697
694 /* Make sure the state is valid */ 698 /* Make sure the state is valid */
695 rc = plpar_hcall(H_VASI_STATE, 699 rc = plpar_hcall(H_VASI_STATE, retbuf,
696 ((u64)args->args[0] << 32) | args->args[1], 700 ((u64)args->args[0] << 32) | args->args[1]);
697 0, 0, 0, 701
698 &state, &dummy, &dummy); 702 state = retbuf[0];
699 703
700 if (rc) { 704 if (rc) {
701 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); 705 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
@@ -845,15 +849,15 @@ void __init rtas_initialize(void)
845 */ 849 */
846 rtas.dev = of_find_node_by_name(NULL, "rtas"); 850 rtas.dev = of_find_node_by_name(NULL, "rtas");
847 if (rtas.dev) { 851 if (rtas.dev) {
848 u32 *basep, *entryp; 852 const u32 *basep, *entryp, *sizep;
849 u32 *sizep;
850 853
851 basep = (u32 *)get_property(rtas.dev, "linux,rtas-base", NULL); 854 basep = get_property(rtas.dev, "linux,rtas-base", NULL);
852 sizep = (u32 *)get_property(rtas.dev, "rtas-size", NULL); 855 sizep = get_property(rtas.dev, "rtas-size", NULL);
853 if (basep != NULL && sizep != NULL) { 856 if (basep != NULL && sizep != NULL) {
854 rtas.base = *basep; 857 rtas.base = *basep;
855 rtas.size = *sizep; 858 rtas.size = *sizep;
856 entryp = (u32 *)get_property(rtas.dev, "linux,rtas-entry", NULL); 859 entryp = get_property(rtas.dev,
860 "linux,rtas-entry", NULL);
857 if (entryp == NULL) /* Ugh */ 861 if (entryp == NULL) /* Ugh */
858 rtas.entry = rtas.base; 862 rtas.entry = rtas.base;
859 else 863 else
@@ -909,6 +913,11 @@ int __init early_init_dt_scan_rtas(unsigned long node,
909 basep = of_get_flat_dt_prop(node, "get-term-char", NULL); 913 basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
910 if (basep) 914 if (basep)
911 rtas_getchar_token = *basep; 915 rtas_getchar_token = *basep;
916
917 if (rtas_putchar_token != RTAS_UNKNOWN_SERVICE &&
918 rtas_getchar_token != RTAS_UNKNOWN_SERVICE)
919 udbg_init_rtas_console();
920
912#endif 921#endif
913 922
914 /* break now */ 923 /* break now */
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index cda022657324..b4a0de79c060 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -57,7 +57,7 @@ static inline int config_access_valid(struct pci_dn *dn, int where)
57 57
58static int of_device_available(struct device_node * dn) 58static int of_device_available(struct device_node * dn)
59{ 59{
60 char * status; 60 const char *status;
61 61
62 status = get_property(dn, "status", NULL); 62 status = get_property(dn, "status", NULL);
63 63
@@ -81,8 +81,7 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
81 if (!config_access_valid(pdn, where)) 81 if (!config_access_valid(pdn, where))
82 return PCIBIOS_BAD_REGISTER_NUMBER; 82 return PCIBIOS_BAD_REGISTER_NUMBER;
83 83
84 addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | 84 addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
85 (pdn->devfn << 8) | (where & 0xff);
86 buid = pdn->phb->buid; 85 buid = pdn->phb->buid;
87 if (buid) { 86 if (buid) {
88 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, 87 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
@@ -134,8 +133,7 @@ int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
134 if (!config_access_valid(pdn, where)) 133 if (!config_access_valid(pdn, where))
135 return PCIBIOS_BAD_REGISTER_NUMBER; 134 return PCIBIOS_BAD_REGISTER_NUMBER;
136 135
137 addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | 136 addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
138 (pdn->devfn << 8) | (where & 0xff);
139 buid = pdn->phb->buid; 137 buid = pdn->phb->buid;
140 if (buid) { 138 if (buid) {
141 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, 139 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
@@ -178,7 +176,7 @@ struct pci_ops rtas_pci_ops = {
178 176
179int is_python(struct device_node *dev) 177int is_python(struct device_node *dev)
180{ 178{
181 char *model = (char *)get_property(dev, "model", NULL); 179 const char *model = get_property(dev, "model", NULL);
182 180
183 if (model && strstr(model, "Python")) 181 if (model && strstr(model, "Python"))
184 return 1; 182 return 1;
@@ -234,7 +232,7 @@ void __init init_pci_config_tokens (void)
234unsigned long __devinit get_phb_buid (struct device_node *phb) 232unsigned long __devinit get_phb_buid (struct device_node *phb)
235{ 233{
236 int addr_cells; 234 int addr_cells;
237 unsigned int *buid_vals; 235 const unsigned int *buid_vals;
238 unsigned int len; 236 unsigned int len;
239 unsigned long buid; 237 unsigned long buid;
240 238
@@ -247,7 +245,7 @@ unsigned long __devinit get_phb_buid (struct device_node *phb)
247 if (phb->parent->parent) 245 if (phb->parent->parent)
248 return 0; 246 return 0;
249 247
250 buid_vals = (unsigned int *) get_property(phb, "reg", &len); 248 buid_vals = get_property(phb, "reg", &len);
251 if (buid_vals == NULL) 249 if (buid_vals == NULL)
252 return 0; 250 return 0;
253 251
@@ -264,10 +262,10 @@ unsigned long __devinit get_phb_buid (struct device_node *phb)
264static int phb_set_bus_ranges(struct device_node *dev, 262static int phb_set_bus_ranges(struct device_node *dev,
265 struct pci_controller *phb) 263 struct pci_controller *phb)
266{ 264{
267 int *bus_range; 265 const int *bus_range;
268 unsigned int len; 266 unsigned int len;
269 267
270 bus_range = (int *) get_property(dev, "bus-range", &len); 268 bus_range = get_property(dev, "bus-range", &len);
271 if (bus_range == NULL || len < 2 * sizeof(int)) { 269 if (bus_range == NULL || len < 2 * sizeof(int)) {
272 return 1; 270 return 1;
273 } 271 }
@@ -325,15 +323,15 @@ unsigned long __init find_and_init_phbs(void)
325 * in chosen. 323 * in chosen.
326 */ 324 */
327 if (of_chosen) { 325 if (of_chosen) {
328 int *prop; 326 const int *prop;
329 327
330 prop = (int *)get_property(of_chosen, "linux,pci-probe-only", 328 prop = get_property(of_chosen,
331 NULL); 329 "linux,pci-probe-only", NULL);
332 if (prop) 330 if (prop)
333 pci_probe_only = *prop; 331 pci_probe_only = *prop;
334 332
335 prop = (int *)get_property(of_chosen, 333 prop = get_property(of_chosen,
336 "linux,pci-assign-all-buses", NULL); 334 "linux,pci-assign-all-buses", NULL);
337 if (prop) 335 if (prop)
338 pci_assign_all_buses = *prop; 336 pci_assign_all_buses = *prop;
339 } 337 }
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 499c3861074f..0af3fc1bdcc9 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -304,19 +304,21 @@ struct seq_operations cpuinfo_op = {
304void __init check_for_initrd(void) 304void __init check_for_initrd(void)
305{ 305{
306#ifdef CONFIG_BLK_DEV_INITRD 306#ifdef CONFIG_BLK_DEV_INITRD
307 unsigned long *prop; 307 const unsigned int *prop;
308 int len;
308 309
309 DBG(" -> check_for_initrd()\n"); 310 DBG(" -> check_for_initrd()\n");
310 311
311 if (of_chosen) { 312 if (of_chosen) {
312 prop = (unsigned long *)get_property(of_chosen, 313 prop = get_property(of_chosen, "linux,initrd-start", &len);
313 "linux,initrd-start", NULL);
314 if (prop != NULL) { 314 if (prop != NULL) {
315 initrd_start = (unsigned long)__va(*prop); 315 initrd_start = (unsigned long)
316 prop = (unsigned long *)get_property(of_chosen, 316 __va(of_read_ulong(prop, len / 4));
317 "linux,initrd-end", NULL); 317 prop = get_property(of_chosen,
318 "linux,initrd-end", &len);
318 if (prop != NULL) { 319 if (prop != NULL) {
319 initrd_end = (unsigned long)__va(*prop); 320 initrd_end = (unsigned long)
321 __va(of_read_ulong(prop, len / 4));
320 initrd_below_start_ok = 1; 322 initrd_below_start_ok = 1;
321 } else 323 } else
322 initrd_start = 0; 324 initrd_start = 0;
@@ -366,15 +368,14 @@ void __init smp_setup_cpu_maps(void)
366 int cpu = 0; 368 int cpu = 0;
367 369
368 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { 370 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
369 int *intserv; 371 const int *intserv;
370 int j, len = sizeof(u32), nthreads = 1; 372 int j, len = sizeof(u32), nthreads = 1;
371 373
372 intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s", 374 intserv = get_property(dn, "ibm,ppc-interrupt-server#s", &len);
373 &len);
374 if (intserv) 375 if (intserv)
375 nthreads = len / sizeof(int); 376 nthreads = len / sizeof(int);
376 else { 377 else {
377 intserv = (int *) get_property(dn, "reg", NULL); 378 intserv = get_property(dn, "reg", NULL);
378 if (!intserv) 379 if (!intserv)
379 intserv = &cpu; /* assume logical == phys */ 380 intserv = &cpu; /* assume logical == phys */
380 } 381 }
@@ -395,13 +396,12 @@ void __init smp_setup_cpu_maps(void)
395 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) && 396 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
396 (dn = of_find_node_by_path("/rtas"))) { 397 (dn = of_find_node_by_path("/rtas"))) {
397 int num_addr_cell, num_size_cell, maxcpus; 398 int num_addr_cell, num_size_cell, maxcpus;
398 unsigned int *ireg; 399 const unsigned int *ireg;
399 400
400 num_addr_cell = prom_n_addr_cells(dn); 401 num_addr_cell = prom_n_addr_cells(dn);
401 num_size_cell = prom_n_size_cells(dn); 402 num_size_cell = prom_n_size_cells(dn);
402 403
403 ireg = (unsigned int *) 404 ireg = get_property(dn, "ibm,lrdr-capacity", NULL);
404 get_property(dn, "ibm,lrdr-capacity", NULL);
405 405
406 if (!ireg) 406 if (!ireg)
407 goto out; 407 goto out;
@@ -444,6 +444,8 @@ void __init smp_setup_cpu_maps(void)
444 444
445int __initdata do_early_xmon; 445int __initdata do_early_xmon;
446#ifdef CONFIG_XMON 446#ifdef CONFIG_XMON
447extern int xmon_no_auto_backtrace;
448
447static int __init early_xmon(char *p) 449static int __init early_xmon(char *p)
448{ 450{
449 /* ensure xmon is enabled */ 451 /* ensure xmon is enabled */
@@ -452,6 +454,8 @@ static int __init early_xmon(char *p)
452 xmon_init(1); 454 xmon_init(1);
453 if (strncmp(p, "off", 3) == 0) 455 if (strncmp(p, "off", 3) == 0)
454 xmon_init(0); 456 xmon_init(0);
457 if (strncmp(p, "nobt", 4) == 0)
458 xmon_no_auto_backtrace = 1;
455 if (strncmp(p, "early", 5) != 0) 459 if (strncmp(p, "early", 5) != 0)
456 return 0; 460 return 0;
457 } 461 }
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index fd1785e4c9bb..00d6b8addd78 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -56,7 +56,6 @@
56#include <asm/page.h> 56#include <asm/page.h>
57#include <asm/mmu.h> 57#include <asm/mmu.h>
58#include <asm/lmb.h> 58#include <asm/lmb.h>
59#include <asm/iseries/it_lp_naca.h>
60#include <asm/firmware.h> 59#include <asm/firmware.h>
61#include <asm/xmon.h> 60#include <asm/xmon.h>
62#include <asm/udbg.h> 61#include <asm/udbg.h>
@@ -79,10 +78,10 @@ u64 ppc64_pft_size;
79 * before we've read this from the device tree. 78 * before we've read this from the device tree.
80 */ 79 */
81struct ppc64_caches ppc64_caches = { 80struct ppc64_caches ppc64_caches = {
82 .dline_size = 0x80, 81 .dline_size = 0x40,
83 .log_dline_size = 7, 82 .log_dline_size = 6,
84 .iline_size = 0x80, 83 .iline_size = 0x40,
85 .log_iline_size = 7 84 .log_iline_size = 6
86}; 85};
87EXPORT_SYMBOL_GPL(ppc64_caches); 86EXPORT_SYMBOL_GPL(ppc64_caches);
88 87
@@ -107,7 +106,7 @@ static int smt_enabled_cmdline;
107static void check_smt_enabled(void) 106static void check_smt_enabled(void)
108{ 107{
109 struct device_node *dn; 108 struct device_node *dn;
110 char *smt_option; 109 const char *smt_option;
111 110
112 /* Allow the command line to overrule the OF option */ 111 /* Allow the command line to overrule the OF option */
113 if (smt_enabled_cmdline) 112 if (smt_enabled_cmdline)
@@ -116,7 +115,7 @@ static void check_smt_enabled(void)
116 dn = of_find_node_by_path("/options"); 115 dn = of_find_node_by_path("/options");
117 116
118 if (dn) { 117 if (dn) {
119 smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL); 118 smt_option = get_property(dn, "ibm,smt-enabled", NULL);
120 119
121 if (smt_option) { 120 if (smt_option) {
122 if (!strcmp(smt_option, "on")) 121 if (!strcmp(smt_option, "on"))
@@ -293,7 +292,7 @@ static void __init initialize_cache_info(void)
293 */ 292 */
294 293
295 if ( num_cpus == 1 ) { 294 if ( num_cpus == 1 ) {
296 u32 *sizep, *lsizep; 295 const u32 *sizep, *lsizep;
297 u32 size, lsize; 296 u32 size, lsize;
298 const char *dc, *ic; 297 const char *dc, *ic;
299 298
@@ -308,10 +307,10 @@ static void __init initialize_cache_info(void)
308 307
309 size = 0; 308 size = 0;
310 lsize = cur_cpu_spec->dcache_bsize; 309 lsize = cur_cpu_spec->dcache_bsize;
311 sizep = (u32 *)get_property(np, "d-cache-size", NULL); 310 sizep = get_property(np, "d-cache-size", NULL);
312 if (sizep != NULL) 311 if (sizep != NULL)
313 size = *sizep; 312 size = *sizep;
314 lsizep = (u32 *) get_property(np, dc, NULL); 313 lsizep = get_property(np, dc, NULL);
315 if (lsizep != NULL) 314 if (lsizep != NULL)
316 lsize = *lsizep; 315 lsize = *lsizep;
317 if (sizep == 0 || lsizep == 0) 316 if (sizep == 0 || lsizep == 0)
@@ -325,10 +324,10 @@ static void __init initialize_cache_info(void)
325 324
326 size = 0; 325 size = 0;
327 lsize = cur_cpu_spec->icache_bsize; 326 lsize = cur_cpu_spec->icache_bsize;
328 sizep = (u32 *)get_property(np, "i-cache-size", NULL); 327 sizep = get_property(np, "i-cache-size", NULL);
329 if (sizep != NULL) 328 if (sizep != NULL)
330 size = *sizep; 329 size = *sizep;
331 lsizep = (u32 *)get_property(np, ic, NULL); 330 lsizep = get_property(np, ic, NULL);
332 if (lsizep != NULL) 331 if (lsizep != NULL)
333 lsize = *lsizep; 332 lsize = *lsizep;
334 if (sizep == 0 || lsizep == 0) 333 if (sizep == 0 || lsizep == 0)
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index fec228cd0163..406f308ddead 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -60,7 +60,7 @@ static int smt_snooze_cmdline;
60static int __init smt_setup(void) 60static int __init smt_setup(void)
61{ 61{
62 struct device_node *options; 62 struct device_node *options;
63 unsigned int *val; 63 const unsigned int *val;
64 unsigned int cpu; 64 unsigned int cpu;
65 65
66 if (!cpu_has_feature(CPU_FTR_SMT)) 66 if (!cpu_has_feature(CPU_FTR_SMT))
@@ -70,8 +70,7 @@ static int __init smt_setup(void)
70 if (!options) 70 if (!options)
71 return -ENODEV; 71 return -ENODEV;
72 72
73 val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay", 73 val = get_property(options, "ibm,smt-snooze-delay", NULL);
74 NULL);
75 if (!smt_snooze_cmdline && val) { 74 if (!smt_snooze_cmdline && val) {
76 for_each_possible_cpu(cpu) 75 for_each_possible_cpu(cpu)
77 per_cpu(smt_snooze_delay, cpu) = *val; 76 per_cpu(smt_snooze_delay, cpu) = *val;
@@ -231,7 +230,7 @@ static void register_cpu_online(unsigned int cpu)
231 if (cur_cpu_spec->num_pmcs >= 8) 230 if (cur_cpu_spec->num_pmcs >= 8)
232 sysdev_create_file(s, &attr_pmc8); 231 sysdev_create_file(s, &attr_pmc8);
233 232
234 if (cpu_has_feature(CPU_FTR_SMT)) 233 if (cpu_has_feature(CPU_FTR_PURR))
235 sysdev_create_file(s, &attr_purr); 234 sysdev_create_file(s, &attr_purr);
236} 235}
237 236
@@ -273,7 +272,7 @@ static void unregister_cpu_online(unsigned int cpu)
273 if (cur_cpu_spec->num_pmcs >= 8) 272 if (cur_cpu_spec->num_pmcs >= 8)
274 sysdev_remove_file(s, &attr_pmc8); 273 sysdev_remove_file(s, &attr_pmc8);
275 274
276 if (cpu_has_feature(CPU_FTR_SMT)) 275 if (cpu_has_feature(CPU_FTR_PURR))
277 sysdev_remove_file(s, &attr_purr); 276 sysdev_remove_file(s, &attr_purr);
278} 277}
279#endif /* CONFIG_HOTPLUG_CPU */ 278#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index a124499e65d9..7a3c3f791ade 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -860,19 +860,17 @@ EXPORT_SYMBOL(do_settimeofday);
860static int __init get_freq(char *name, int cells, unsigned long *val) 860static int __init get_freq(char *name, int cells, unsigned long *val)
861{ 861{
862 struct device_node *cpu; 862 struct device_node *cpu;
863 unsigned int *fp; 863 const unsigned int *fp;
864 int found = 0; 864 int found = 0;
865 865
866 /* The cpu node should have timebase and clock frequency properties */ 866 /* The cpu node should have timebase and clock frequency properties */
867 cpu = of_find_node_by_type(NULL, "cpu"); 867 cpu = of_find_node_by_type(NULL, "cpu");
868 868
869 if (cpu) { 869 if (cpu) {
870 fp = (unsigned int *)get_property(cpu, name, NULL); 870 fp = get_property(cpu, name, NULL);
871 if (fp) { 871 if (fp) {
872 found = 1; 872 found = 1;
873 *val = 0; 873 *val = of_read_ulong(fp, cells);
874 while (cells--)
875 *val = (*val << 32) | *fp++;
876 } 874 }
877 875
878 of_node_put(cpu); 876 of_node_put(cpu);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 9b352bd0a460..d9f10f2fc372 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -598,6 +598,9 @@ static void parse_fpe(struct pt_regs *regs)
598#define INST_STSWI 0x7c0005aa 598#define INST_STSWI 0x7c0005aa
599#define INST_STSWX 0x7c00052a 599#define INST_STSWX 0x7c00052a
600 600
601#define INST_POPCNTB 0x7c0000f4
602#define INST_POPCNTB_MASK 0xfc0007fe
603
601static int emulate_string_inst(struct pt_regs *regs, u32 instword) 604static int emulate_string_inst(struct pt_regs *regs, u32 instword)
602{ 605{
603 u8 rT = (instword >> 21) & 0x1f; 606 u8 rT = (instword >> 21) & 0x1f;
@@ -666,6 +669,23 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
666 return 0; 669 return 0;
667} 670}
668 671
672static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
673{
674 u32 ra,rs;
675 unsigned long tmp;
676
677 ra = (instword >> 16) & 0x1f;
678 rs = (instword >> 21) & 0x1f;
679
680 tmp = regs->gpr[rs];
681 tmp = tmp - ((tmp >> 1) & 0x5555555555555555ULL);
682 tmp = (tmp & 0x3333333333333333ULL) + ((tmp >> 2) & 0x3333333333333333ULL);
683 tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
684 regs->gpr[ra] = tmp;
685
686 return 0;
687}
688
669static int emulate_instruction(struct pt_regs *regs) 689static int emulate_instruction(struct pt_regs *regs)
670{ 690{
671 u32 instword; 691 u32 instword;
@@ -703,6 +723,11 @@ static int emulate_instruction(struct pt_regs *regs)
703 if ((instword & INST_STRING_GEN_MASK) == INST_STRING) 723 if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
704 return emulate_string_inst(regs, instword); 724 return emulate_string_inst(regs, instword);
705 725
726 /* Emulate the popcntb (Population Count Bytes) instruction. */
727 if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
728 return emulate_popcntb_inst(regs, instword);
729 }
730
706 return -EINVAL; 731 return -EINVAL;
707} 732}
708 733
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index fad8580f9081..cb87e71eec66 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -77,7 +77,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
77 } else 77 } else
78#endif 78#endif
79 { 79 {
80 unsigned char *dma_window; 80 const unsigned char *dma_window;
81 struct iommu_table *tbl; 81 struct iommu_table *tbl;
82 unsigned long offset, size; 82 unsigned long offset, size;
83 83
@@ -217,7 +217,7 @@ static void __devinit vio_dev_release(struct device *dev)
217struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) 217struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
218{ 218{
219 struct vio_dev *viodev; 219 struct vio_dev *viodev;
220 unsigned int *unit_address; 220 const unsigned int *unit_address;
221 221
222 /* we need the 'device_type' property, in order to match with drivers */ 222 /* we need the 'device_type' property, in order to match with drivers */
223 if (of_node->type == NULL) { 223 if (of_node->type == NULL) {
@@ -227,7 +227,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
227 return NULL; 227 return NULL;
228 } 228 }
229 229
230 unit_address = (unsigned int *)get_property(of_node, "reg", NULL); 230 unit_address = get_property(of_node, "reg", NULL);
231 if (unit_address == NULL) { 231 if (unit_address == NULL) {
232 printk(KERN_WARNING "%s: node %s missing 'reg'\n", 232 printk(KERN_WARNING "%s: node %s missing 'reg'\n",
233 __FUNCTION__, 233 __FUNCTION__,
@@ -249,7 +249,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
249 viodev->type = of_node->type; 249 viodev->type = of_node->type;
250 viodev->unit_address = *unit_address; 250 viodev->unit_address = *unit_address;
251 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 251 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
252 unit_address = (unsigned int *)get_property(of_node, 252 unit_address = get_property(of_node,
253 "linux,unit_address", NULL); 253 "linux,unit_address", NULL);
254 if (unit_address != NULL) 254 if (unit_address != NULL)
255 viodev->unit_address = *unit_address; 255 viodev->unit_address = *unit_address;
@@ -423,7 +423,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
423{ 423{
424 const struct vio_dev *vio_dev = to_vio_dev(dev); 424 const struct vio_dev *vio_dev = to_vio_dev(dev);
425 struct device_node *dn = dev->platform_data; 425 struct device_node *dn = dev->platform_data;
426 char *cp; 426 const char *cp;
427 int length; 427 int length;
428 428
429 if (!num_envp) 429 if (!num_envp)
@@ -431,7 +431,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
431 431
432 if (!dn) 432 if (!dn)
433 return -ENODEV; 433 return -ENODEV;
434 cp = (char *)get_property(dn, "compatible", &length); 434 cp = get_property(dn, "compatible", &length);
435 if (!cp) 435 if (!cp)
436 return -ENODEV; 436 return -ENODEV;
437 437
@@ -493,11 +493,11 @@ static struct vio_dev *vio_find_name(const char *kobj_name)
493 */ 493 */
494struct vio_dev *vio_find_node(struct device_node *vnode) 494struct vio_dev *vio_find_node(struct device_node *vnode)
495{ 495{
496 uint32_t *unit_address; 496 const uint32_t *unit_address;
497 char kobj_name[BUS_ID_SIZE]; 497 char kobj_name[BUS_ID_SIZE];
498 498
499 /* construct the kobject name from the device node */ 499 /* construct the kobject name from the device node */
500 unit_address = (uint32_t *)get_property(vnode, "reg", NULL); 500 unit_address = get_property(vnode, "reg", NULL);
501 if (!unit_address) 501 if (!unit_address)
502 return NULL; 502 return NULL;
503 snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); 503 snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index ff7096458249..336dd191f768 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -14,7 +14,6 @@ endif
14obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ 14obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
15 memcpy_64.o usercopy_64.o mem_64.o string.o \ 15 memcpy_64.o usercopy_64.o mem_64.o string.o \
16 strcase.o 16 strcase.o
17obj-$(CONFIG_PPC_ISERIES) += e2a.o
18obj-$(CONFIG_XMON) += sstep.o 17obj-$(CONFIG_XMON) += sstep.o
19 18
20ifeq ($(CONFIG_PPC64),y) 19ifeq ($(CONFIG_PPC64),y)
diff --git a/arch/powerpc/lib/e2a.c b/arch/powerpc/lib/e2a.c
deleted file mode 100644
index 4b72ed8fd50e..000000000000
--- a/arch/powerpc/lib/e2a.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 * EBCDIC to ASCII conversion
3 *
4 * This function moved here from arch/powerpc/platforms/iseries/viopath.c
5 *
6 * (C) Copyright 2000-2004 IBM Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) anyu later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/module.h>
25
26unsigned char e2a(unsigned char x)
27{
28 switch (x) {
29 case 0xF0:
30 return '0';
31 case 0xF1:
32 return '1';
33 case 0xF2:
34 return '2';
35 case 0xF3:
36 return '3';
37 case 0xF4:
38 return '4';
39 case 0xF5:
40 return '5';
41 case 0xF6:
42 return '6';
43 case 0xF7:
44 return '7';
45 case 0xF8:
46 return '8';
47 case 0xF9:
48 return '9';
49 case 0xC1:
50 return 'A';
51 case 0xC2:
52 return 'B';
53 case 0xC3:
54 return 'C';
55 case 0xC4:
56 return 'D';
57 case 0xC5:
58 return 'E';
59 case 0xC6:
60 return 'F';
61 case 0xC7:
62 return 'G';
63 case 0xC8:
64 return 'H';
65 case 0xC9:
66 return 'I';
67 case 0xD1:
68 return 'J';
69 case 0xD2:
70 return 'K';
71 case 0xD3:
72 return 'L';
73 case 0xD4:
74 return 'M';
75 case 0xD5:
76 return 'N';
77 case 0xD6:
78 return 'O';
79 case 0xD7:
80 return 'P';
81 case 0xD8:
82 return 'Q';
83 case 0xD9:
84 return 'R';
85 case 0xE2:
86 return 'S';
87 case 0xE3:
88 return 'T';
89 case 0xE4:
90 return 'U';
91 case 0xE5:
92 return 'V';
93 case 0xE6:
94 return 'W';
95 case 0xE7:
96 return 'X';
97 case 0xE8:
98 return 'Y';
99 case 0xE9:
100 return 'Z';
101 }
102 return ' ';
103}
104EXPORT_SYMBOL(e2a);
105
106unsigned char* strne2a(unsigned char *dest, const unsigned char *src, size_t n)
107{
108 int i;
109
110 n = strnlen(src, n);
111
112 for (i = 0; i < n; i++)
113 dest[i] = e2a(src[i]);
114
115 return dest;
116}
diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c
index 077bed7dc52b..80b482ca30df 100644
--- a/arch/powerpc/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -23,6 +23,7 @@
23#include <asm/hvcall.h> 23#include <asm/hvcall.h>
24#include <asm/iseries/hv_call.h> 24#include <asm/iseries/hv_call.h>
25#include <asm/smp.h> 25#include <asm/smp.h>
26#include <asm/firmware.h>
26 27
27void __spin_yield(raw_spinlock_t *lock) 28void __spin_yield(raw_spinlock_t *lock)
28{ 29{
@@ -39,13 +40,12 @@ void __spin_yield(raw_spinlock_t *lock)
39 rmb(); 40 rmb();
40 if (lock->slock != lock_value) 41 if (lock->slock != lock_value)
41 return; /* something has changed */ 42 return; /* something has changed */
42#ifdef CONFIG_PPC_ISERIES 43 if (firmware_has_feature(FW_FEATURE_ISERIES))
43 HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, 44 HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
44 ((u64)holder_cpu << 32) | yield_count); 45 ((u64)holder_cpu << 32) | yield_count);
45#else 46 else
46 plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), 47 plpar_hcall_norets(H_CONFER,
47 yield_count); 48 get_hard_smp_processor_id(holder_cpu), yield_count);
48#endif
49} 49}
50 50
51/* 51/*
@@ -69,13 +69,12 @@ void __rw_yield(raw_rwlock_t *rw)
69 rmb(); 69 rmb();
70 if (rw->lock != lock_value) 70 if (rw->lock != lock_value)
71 return; /* something has changed */ 71 return; /* something has changed */
72#ifdef CONFIG_PPC_ISERIES 72 if (firmware_has_feature(FW_FEATURE_ISERIES))
73 HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, 73 HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
74 ((u64)holder_cpu << 32) | yield_count); 74 ((u64)holder_cpu << 32) | yield_count);
75#else 75 else
76 plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), 76 plpar_hcall_norets(H_CONFER,
77 yield_count); 77 get_hard_smp_processor_id(holder_cpu), yield_count);
78#endif
79} 78}
80#endif 79#endif
81 80
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index fbe23933f731..6c0f1c7d83e5 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -159,12 +159,12 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
159{ 159{
160 unsigned int hw_cpuid = get_hard_smp_processor_id(cpu); 160 unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
161 struct device_node *cpu_node = NULL; 161 struct device_node *cpu_node = NULL;
162 unsigned int *interrupt_server, *reg; 162 const unsigned int *interrupt_server, *reg;
163 int len; 163 int len;
164 164
165 while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) { 165 while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
166 /* Try interrupt server first */ 166 /* Try interrupt server first */
167 interrupt_server = (unsigned int *)get_property(cpu_node, 167 interrupt_server = get_property(cpu_node,
168 "ibm,ppc-interrupt-server#s", &len); 168 "ibm,ppc-interrupt-server#s", &len);
169 169
170 len = len / sizeof(u32); 170 len = len / sizeof(u32);
@@ -175,8 +175,7 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
175 return cpu_node; 175 return cpu_node;
176 } 176 }
177 } else { 177 } else {
178 reg = (unsigned int *)get_property(cpu_node, 178 reg = get_property(cpu_node, "reg", &len);
179 "reg", &len);
180 if (reg && (len > 0) && (reg[0] == hw_cpuid)) 179 if (reg && (len > 0) && (reg[0] == hw_cpuid))
181 return cpu_node; 180 return cpu_node;
182 } 181 }
@@ -186,9 +185,9 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
186} 185}
187 186
188/* must hold reference to node during call */ 187/* must hold reference to node during call */
189static int *of_get_associativity(struct device_node *dev) 188static const int *of_get_associativity(struct device_node *dev)
190{ 189{
191 return (unsigned int *)get_property(dev, "ibm,associativity", NULL); 190 return get_property(dev, "ibm,associativity", NULL);
192} 191}
193 192
194/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa 193/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
@@ -197,7 +196,7 @@ static int *of_get_associativity(struct device_node *dev)
197static int of_node_to_nid_single(struct device_node *device) 196static int of_node_to_nid_single(struct device_node *device)
198{ 197{
199 int nid = -1; 198 int nid = -1;
200 unsigned int *tmp; 199 const unsigned int *tmp;
201 200
202 if (min_common_depth == -1) 201 if (min_common_depth == -1)
203 goto out; 202 goto out;
@@ -255,7 +254,7 @@ EXPORT_SYMBOL_GPL(of_node_to_nid);
255static int __init find_min_common_depth(void) 254static int __init find_min_common_depth(void)
256{ 255{
257 int depth; 256 int depth;
258 unsigned int *ref_points; 257 const unsigned int *ref_points;
259 struct device_node *rtas_root; 258 struct device_node *rtas_root;
260 unsigned int len; 259 unsigned int len;
261 260
@@ -270,7 +269,7 @@ static int __init find_min_common_depth(void)
270 * configuration (should be all 0's) and the second is for a normal 269 * configuration (should be all 0's) and the second is for a normal
271 * NUMA configuration. 270 * NUMA configuration.
272 */ 271 */
273 ref_points = (unsigned int *)get_property(rtas_root, 272 ref_points = get_property(rtas_root,
274 "ibm,associativity-reference-points", &len); 273 "ibm,associativity-reference-points", &len);
275 274
276 if ((len >= 1) && ref_points) { 275 if ((len >= 1) && ref_points) {
@@ -297,7 +296,7 @@ static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells)
297 of_node_put(memory); 296 of_node_put(memory);
298} 297}
299 298
300static unsigned long __devinit read_n_cells(int n, unsigned int **buf) 299static unsigned long __devinit read_n_cells(int n, const unsigned int **buf)
301{ 300{
302 unsigned long result = 0; 301 unsigned long result = 0;
303 302
@@ -435,15 +434,13 @@ static int __init parse_numa_properties(void)
435 unsigned long size; 434 unsigned long size;
436 int nid; 435 int nid;
437 int ranges; 436 int ranges;
438 unsigned int *memcell_buf; 437 const unsigned int *memcell_buf;
439 unsigned int len; 438 unsigned int len;
440 439
441 memcell_buf = (unsigned int *)get_property(memory, 440 memcell_buf = get_property(memory,
442 "linux,usable-memory", &len); 441 "linux,usable-memory", &len);
443 if (!memcell_buf || len <= 0) 442 if (!memcell_buf || len <= 0)
444 memcell_buf = 443 memcell_buf = get_property(memory, "reg", &len);
445 (unsigned int *)get_property(memory, "reg",
446 &len);
447 if (!memcell_buf || len <= 0) 444 if (!memcell_buf || len <= 0)
448 continue; 445 continue;
449 446
@@ -787,10 +784,10 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
787 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { 784 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
788 unsigned long start, size; 785 unsigned long start, size;
789 int ranges; 786 int ranges;
790 unsigned int *memcell_buf; 787 const unsigned int *memcell_buf;
791 unsigned int len; 788 unsigned int len;
792 789
793 memcell_buf = (unsigned int *)get_property(memory, "reg", &len); 790 memcell_buf = get_property(memory, "reg", &len);
794 if (!memcell_buf || len <= 0) 791 if (!memcell_buf || len <= 0)
795 continue; 792 continue;
796 793
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index de0c8842415c..d3733912adb4 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -22,6 +22,8 @@
22#include <asm/paca.h> 22#include <asm/paca.h>
23#include <asm/cputable.h> 23#include <asm/cputable.h>
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/smp.h>
26#include <linux/compiler.h>
25 27
26#ifdef DEBUG 28#ifdef DEBUG
27#define DBG(fmt...) udbg_printf(fmt) 29#define DBG(fmt...) udbg_printf(fmt)
@@ -50,9 +52,32 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags)
50 return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; 52 return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
51} 53}
52 54
53static inline void create_slbe(unsigned long ea, unsigned long flags, 55static inline void slb_shadow_update(unsigned long esid, unsigned long vsid,
54 unsigned long entry) 56 unsigned long entry)
55{ 57{
58 /*
59 * Clear the ESID first so the entry is not valid while we are
60 * updating it.
61 */
62 get_slb_shadow()->save_area[entry].esid = 0;
63 barrier();
64 get_slb_shadow()->save_area[entry].vsid = vsid;
65 barrier();
66 get_slb_shadow()->save_area[entry].esid = esid;
67
68}
69
70static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
71 unsigned long entry)
72{
73 /*
74 * Updating the shadow buffer before writing the SLB ensures
75 * we don't get a stale entry here if we get preempted by PHYP
76 * between these two statements.
77 */
78 slb_shadow_update(mk_esid_data(ea, entry), mk_vsid_data(ea, flags),
79 entry);
80
56 asm volatile("slbmte %0,%1" : 81 asm volatile("slbmte %0,%1" :
57 : "r" (mk_vsid_data(ea, flags)), 82 : "r" (mk_vsid_data(ea, flags)),
58 "r" (mk_esid_data(ea, entry)) 83 "r" (mk_esid_data(ea, entry))
@@ -77,6 +102,10 @@ void slb_flush_and_rebolt(void)
77 if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) 102 if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
78 ksp_esid_data &= ~SLB_ESID_V; 103 ksp_esid_data &= ~SLB_ESID_V;
79 104
105 /* Only third entry (stack) may change here so only resave that */
106 slb_shadow_update(ksp_esid_data,
107 mk_vsid_data(ksp_esid_data, lflags), 2);
108
80 /* We need to do this all in asm, so we're sure we don't touch 109 /* We need to do this all in asm, so we're sure we don't touch
81 * the stack between the slbia and rebolting it. */ 110 * the stack between the slbia and rebolting it. */
82 asm volatile("isync\n" 111 asm volatile("isync\n"
@@ -209,9 +238,9 @@ void slb_initialize(void)
209 asm volatile("isync":::"memory"); 238 asm volatile("isync":::"memory");
210 asm volatile("slbmte %0,%0"::"r" (0) : "memory"); 239 asm volatile("slbmte %0,%0"::"r" (0) : "memory");
211 asm volatile("isync; slbia; isync":::"memory"); 240 asm volatile("isync; slbia; isync":::"memory");
212 create_slbe(PAGE_OFFSET, lflags, 0); 241 create_shadowed_slbe(PAGE_OFFSET, lflags, 0);
213 242
214 create_slbe(VMALLOC_START, vflags, 1); 243 create_shadowed_slbe(VMALLOC_START, vflags, 1);
215 244
216 /* We don't bolt the stack for the time being - we're in boot, 245 /* We don't bolt the stack for the time being - we're in boot,
217 * so the stack is in the bolted segment. By the time it goes 246 * so the stack is in the bolted segment. By the time it goes
diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c
index f6eef78efd29..b58baa65c4a7 100644
--- a/arch/powerpc/mm/tlb_64.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -146,6 +146,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
146 psize = mmu_huge_psize; 146 psize = mmu_huge_psize;
147#else 147#else
148 BUG(); 148 BUG();
149 psize = pte_pagesize_index(pte); /* shutup gcc */
149#endif 150#endif
150 } else 151 } else
151 psize = pte_pagesize_index(pte); 152 psize = pte_pagesize_index(pte);
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index cf3967a66fb5..969fbb6d8c46 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -60,8 +60,8 @@ static void __init mpc834x_itx_setup_arch(void)
60 60
61 np = of_find_node_by_type(NULL, "cpu"); 61 np = of_find_node_by_type(NULL, "cpu");
62 if (np != 0) { 62 if (np != 0) {
63 unsigned int *fp = 63 const unsigned int *fp =
64 (int *)get_property(np, "clock-frequency", NULL); 64 get_property(np, "clock-frequency", NULL);
65 if (fp != 0) 65 if (fp != 0)
66 loops_per_jiffy = *fp / HZ; 66 loops_per_jiffy = *fp / HZ;
67 else 67 else
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c
index 32df239d1c48..677196187a4e 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c
@@ -57,8 +57,8 @@ static void __init mpc834x_sys_setup_arch(void)
57 57
58 np = of_find_node_by_type(NULL, "cpu"); 58 np = of_find_node_by_type(NULL, "cpu");
59 if (np != 0) { 59 if (np != 0) {
60 unsigned int *fp = 60 const unsigned int *fp =
61 (int *)get_property(np, "clock-frequency", NULL); 61 get_property(np, "clock-frequency", NULL);
62 if (fp != 0) 62 if (fp != 0)
63 loops_per_jiffy = *fp / HZ; 63 loops_per_jiffy = *fp / HZ;
64 else 64 else
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 5d84a9ccd103..4557ac5255c1 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -59,7 +59,7 @@ int __init add_bridge(struct device_node *dev)
59 int len; 59 int len;
60 struct pci_controller *hose; 60 struct pci_controller *hose;
61 struct resource rsrc; 61 struct resource rsrc;
62 int *bus_range; 62 const int *bus_range;
63 int primary = 1, has_address = 0; 63 int primary = 1, has_address = 0;
64 phys_addr_t immr = get_immrbase(); 64 phys_addr_t immr = get_immrbase();
65 65
@@ -69,7 +69,7 @@ int __init add_bridge(struct device_node *dev)
69 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 69 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
70 70
71 /* Get bus range if any */ 71 /* Get bus range if any */
72 bus_range = (int *)get_property(dev, "bus-range", &len); 72 bus_range = get_property(dev, "bus-range", &len);
73 if (bus_range == NULL || len < 2 * sizeof(int)) { 73 if (bus_range == NULL || len < 2 * sizeof(int)) {
74 printk(KERN_WARNING "Can't get bus-range for %s, assume" 74 printk(KERN_WARNING "Can't get bus-range for %s, assume"
75 " bus 0\n", dev->full_name); 75 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 9d2acfbbeccd..cae6b73357d5 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -121,9 +121,9 @@ static void __init mpc85xx_ads_setup_arch(void)
121 121
122 cpu = of_find_node_by_type(NULL, "cpu"); 122 cpu = of_find_node_by_type(NULL, "cpu");
123 if (cpu != 0) { 123 if (cpu != 0) {
124 unsigned int *fp; 124 const unsigned int *fp;
125 125
126 fp = (int *)get_property(cpu, "clock-frequency", NULL); 126 fp = get_property(cpu, "clock-frequency", NULL);
127 if (fp != 0) 127 if (fp != 0)
128 loops_per_jiffy = *fp / HZ; 128 loops_per_jiffy = *fp / HZ;
129 else 129 else
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 1d357d32a29f..4c1fede6470e 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -241,9 +241,9 @@ mpc85xx_cds_setup_arch(void)
241 241
242 cpu = of_find_node_by_type(NULL, "cpu"); 242 cpu = of_find_node_by_type(NULL, "cpu");
243 if (cpu != 0) { 243 if (cpu != 0) {
244 unsigned int *fp; 244 const unsigned int *fp;
245 245
246 fp = (int *)get_property(cpu, "clock-frequency", NULL); 246 fp = get_property(cpu, "clock-frequency", NULL);
247 if (fp != 0) 247 if (fp != 0)
248 loops_per_jiffy = *fp / HZ; 248 loops_per_jiffy = *fp / HZ;
249 else 249 else
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
index 1d51f3242ab1..05930eeb6e7f 100644
--- a/arch/powerpc/platforms/85xx/pci.c
+++ b/arch/powerpc/platforms/85xx/pci.c
@@ -41,7 +41,7 @@ int __init add_bridge(struct device_node *dev)
41 int len; 41 int len;
42 struct pci_controller *hose; 42 struct pci_controller *hose;
43 struct resource rsrc; 43 struct resource rsrc;
44 int *bus_range; 44 const int *bus_range;
45 int primary = 1, has_address = 0; 45 int primary = 1, has_address = 0;
46 phys_addr_t immr = get_immrbase(); 46 phys_addr_t immr = get_immrbase();
47 47
@@ -51,7 +51,7 @@ int __init add_bridge(struct device_node *dev)
51 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 51 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
52 52
53 /* Get bus range if any */ 53 /* Get bus range if any */
54 bus_range = (int *) get_property(dev, "bus-range", &len); 54 bus_range = get_property(dev, "bus-range", &len);
55 if (bus_range == NULL || len < 2 * sizeof(int)) { 55 if (bus_range == NULL || len < 2 * sizeof(int)) {
56 printk(KERN_WARNING "Can't get bus-range for %s, assume" 56 printk(KERN_WARNING "Can't get bus-range for %s, assume"
57 " bus 0\n", dev->full_name); 57 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 5e583cf38786..b637e8157f7b 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -347,9 +347,9 @@ mpc86xx_hpcn_setup_arch(void)
347 347
348 np = of_find_node_by_type(NULL, "cpu"); 348 np = of_find_node_by_type(NULL, "cpu");
349 if (np != 0) { 349 if (np != 0) {
350 unsigned int *fp; 350 const unsigned int *fp;
351 351
352 fp = (int *)get_property(np, "clock-frequency", NULL); 352 fp = get_property(np, "clock-frequency", NULL);
353 if (fp != 0) 353 if (fp != 0)
354 loops_per_jiffy = *fp / HZ; 354 loops_per_jiffy = *fp / HZ;
355 else 355 else
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index a8c8f0a44055..481e18ed5be9 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -153,7 +153,7 @@ int __init add_bridge(struct device_node *dev)
153 int len; 153 int len;
154 struct pci_controller *hose; 154 struct pci_controller *hose;
155 struct resource rsrc; 155 struct resource rsrc;
156 int *bus_range; 156 const int *bus_range;
157 int has_address = 0; 157 int has_address = 0;
158 int primary = 0; 158 int primary = 0;
159 159
@@ -163,7 +163,7 @@ int __init add_bridge(struct device_node *dev)
163 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 163 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
164 164
165 /* Get bus range if any */ 165 /* Get bus range if any */
166 bus_range = (int *) get_property(dev, "bus-range", &len); 166 bus_range = get_property(dev, "bus-range", &len);
167 if (bus_range == NULL || len < 2 * sizeof(int)) 167 if (bus_range == NULL || len < 2 * sizeof(int))
168 printk(KERN_WARNING "Can't get bus-range for %s, assume" 168 printk(KERN_WARNING "Can't get bus-range for %s, assume"
169 " bus 0\n", dev->full_name); 169 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 5cf46dc57895..e58fa953a50b 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_PPC_86xx) += 86xx/
13obj-$(CONFIG_PPC_PSERIES) += pseries/ 13obj-$(CONFIG_PPC_PSERIES) += pseries/
14obj-$(CONFIG_PPC_ISERIES) += iseries/ 14obj-$(CONFIG_PPC_ISERIES) += iseries/
15obj-$(CONFIG_PPC_MAPLE) += maple/ 15obj-$(CONFIG_PPC_MAPLE) += maple/
16obj-$(CONFIG_PPC_PASEMI) += pasemi/
16obj-$(CONFIG_PPC_CELL) += cell/ 17obj-$(CONFIG_PPC_CELL) += cell/
17obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ 18obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
index ce696c1cca75..3f3859d12e00 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -97,7 +97,7 @@ void __init cbe_regs_init(void)
97 struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++]; 97 struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
98 98
99 /* That hack must die die die ! */ 99 /* That hack must die die die ! */
100 struct address_prop { 100 const struct address_prop {
101 unsigned long address; 101 unsigned long address;
102 unsigned int len; 102 unsigned int len;
103 } __attribute__((packed)) *prop; 103 } __attribute__((packed)) *prop;
@@ -114,13 +114,11 @@ void __init cbe_regs_init(void)
114 if (cbe_thread_map[i].cpu_node == cpu) 114 if (cbe_thread_map[i].cpu_node == cpu)
115 cbe_thread_map[i].regs = map; 115 cbe_thread_map[i].regs = map;
116 116
117 prop = (struct address_prop *)get_property(cpu, "pervasive", 117 prop = get_property(cpu, "pervasive", NULL);
118 NULL);
119 if (prop != NULL) 118 if (prop != NULL)
120 map->pmd_regs = ioremap(prop->address, prop->len); 119 map->pmd_regs = ioremap(prop->address, prop->len);
121 120
122 prop = (struct address_prop *)get_property(cpu, "iic", 121 prop = get_property(cpu, "iic", NULL);
123 NULL);
124 if (prop != NULL) 122 if (prop != NULL)
125 map->iic_regs = ioremap(prop->address, prop->len); 123 map->iic_regs = ioremap(prop->address, prop->len);
126 } 124 }
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index d7bbb61109f9..6b57a47c5d37 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -89,17 +89,17 @@ static struct irq_chip iic_chip = {
89/* Get an IRQ number from the pending state register of the IIC */ 89/* Get an IRQ number from the pending state register of the IIC */
90static unsigned int iic_get_irq(struct pt_regs *regs) 90static unsigned int iic_get_irq(struct pt_regs *regs)
91{ 91{
92 struct cbe_iic_pending_bits pending; 92 struct cbe_iic_pending_bits pending;
93 struct iic *iic; 93 struct iic *iic;
94 94
95 iic = &__get_cpu_var(iic); 95 iic = &__get_cpu_var(iic);
96 *(unsigned long *) &pending = 96 *(unsigned long *) &pending =
97 in_be64((unsigned long __iomem *) &iic->regs->pending_destr); 97 in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
98 iic->eoi_stack[++iic->eoi_ptr] = pending.prio; 98 iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
99 BUG_ON(iic->eoi_ptr > 15); 99 BUG_ON(iic->eoi_ptr > 15);
100 if (pending.flags & CBE_IIC_IRQ_VALID) 100 if (pending.flags & CBE_IIC_IRQ_VALID)
101 return irq_linear_revmap(iic->host, 101 return irq_linear_revmap(iic->host,
102 iic_pending_to_hwnum(pending)); 102 iic_pending_to_hwnum(pending));
103 return NO_IRQ; 103 return NO_IRQ;
104} 104}
105 105
@@ -250,16 +250,15 @@ static int __init setup_iic(void)
250 struct resource r0, r1; 250 struct resource r0, r1;
251 struct irq_host *host; 251 struct irq_host *host;
252 int found = 0; 252 int found = 0;
253 u32 *np; 253 const u32 *np;
254 254
255 for (dn = NULL; 255 for (dn = NULL;
256 (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) { 256 (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
257 if (!device_is_compatible(dn, 257 if (!device_is_compatible(dn,
258 "IBM,CBEA-Internal-Interrupt-Controller")) 258 "IBM,CBEA-Internal-Interrupt-Controller"))
259 continue; 259 continue;
260 np = (u32 *)get_property(dn, "ibm,interrupt-server-ranges", 260 np = get_property(dn, "ibm,interrupt-server-ranges", NULL);
261 NULL); 261 if (np == NULL) {
262 if (np == NULL) {
263 printk(KERN_WARNING "IIC: CPU association not found\n"); 262 printk(KERN_WARNING "IIC: CPU association not found\n");
264 of_node_put(dn); 263 of_node_put(dn);
265 return -ENODEV; 264 return -ENODEV;
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index a35004e14c69..d2b20eba5b87 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -308,15 +308,16 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
308 308
309static void iommu_devnode_setup(struct device_node *d) 309static void iommu_devnode_setup(struct device_node *d)
310{ 310{
311 unsigned int *ioid; 311 const unsigned int *ioid;
312 unsigned long *dma_window, map_start, map_size, token; 312 unsigned long map_start, map_size, token;
313 const unsigned long *dma_window;
313 struct cell_iommu *iommu; 314 struct cell_iommu *iommu;
314 315
315 ioid = (unsigned int *)get_property(d, "ioid", NULL); 316 ioid = get_property(d, "ioid", NULL);
316 if (!ioid) 317 if (!ioid)
317 pr_debug("No ioid entry found !\n"); 318 pr_debug("No ioid entry found !\n");
318 319
319 dma_window = (unsigned long *)get_property(d, "ibm,dma-window", NULL); 320 dma_window = get_property(d, "ibm,dma-window", NULL);
320 if (!dma_window) 321 if (!dma_window)
321 pr_debug("No ibm,dma-window entry found !\n"); 322 pr_debug("No ibm,dma-window entry found !\n");
322 323
@@ -371,8 +372,9 @@ static int cell_map_iommu_hardcoded(int num_nodes)
371 372
372static int cell_map_iommu(void) 373static int cell_map_iommu(void)
373{ 374{
374 unsigned int num_nodes = 0, *node_id; 375 unsigned int num_nodes = 0;
375 unsigned long *base, *mmio_base; 376 const unsigned int *node_id;
377 const unsigned long *base, *mmio_base;
376 struct device_node *dn; 378 struct device_node *dn;
377 struct cell_iommu *iommu = NULL; 379 struct cell_iommu *iommu = NULL;
378 380
@@ -381,7 +383,7 @@ static int cell_map_iommu(void)
381 for(dn = of_find_node_by_type(NULL, "cpu"); 383 for(dn = of_find_node_by_type(NULL, "cpu");
382 dn; 384 dn;
383 dn = of_find_node_by_type(dn, "cpu")) { 385 dn = of_find_node_by_type(dn, "cpu")) {
384 node_id = (unsigned int *)get_property(dn, "node-id", NULL); 386 node_id = get_property(dn, "node-id", NULL);
385 387
386 if (num_nodes < *node_id) 388 if (num_nodes < *node_id)
387 num_nodes = *node_id; 389 num_nodes = *node_id;
@@ -396,9 +398,9 @@ static int cell_map_iommu(void)
396 dn; 398 dn;
397 dn = of_find_node_by_type(dn, "cpu")) { 399 dn = of_find_node_by_type(dn, "cpu")) {
398 400
399 node_id = (unsigned int *)get_property(dn, "node-id", NULL); 401 node_id = get_property(dn, "node-id", NULL);
400 base = (unsigned long *)get_property(dn, "ioc-cache", NULL); 402 base = get_property(dn, "ioc-cache", NULL);
401 mmio_base = (unsigned long *)get_property(dn, "ioc-translation", NULL); 403 mmio_base = get_property(dn, "ioc-translation", NULL);
402 404
403 if (!base || !mmio_base || !node_id) 405 if (!base || !mmio_base || !node_id)
404 return cell_map_iommu_hardcoded(num_nodes); 406 return cell_map_iommu_hardcoded(num_nodes);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 282987d6d4a2..22c228a49c33 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -150,10 +150,6 @@ static int __init cell_probe(void)
150 !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) 150 !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
151 return 0; 151 return 0;
152 152
153#ifdef CONFIG_UDBG_RTAS_CONSOLE
154 udbg_init_rtas_console();
155#endif
156
157 hpte_init_native(); 153 hpte_init_native();
158 154
159 return 1; 155 return 1;
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index 46aef0640742..1c0acbad7425 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -57,7 +57,7 @@
57 */ 57 */
58static cpumask_t of_spin_map; 58static cpumask_t of_spin_map;
59 59
60extern void pSeries_secondary_smp_init(unsigned long); 60extern void generic_secondary_smp_init(unsigned long);
61 61
62/** 62/**
63 * smp_startup_cpu() - start the given cpu 63 * smp_startup_cpu() - start the given cpu
@@ -74,7 +74,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
74{ 74{
75 int status; 75 int status;
76 unsigned long start_here = __pa((u32)*((unsigned long *) 76 unsigned long start_here = __pa((u32)*((unsigned long *)
77 pSeries_secondary_smp_init)); 77 generic_secondary_smp_init));
78 unsigned int pcpu; 78 unsigned int pcpu;
79 int start_cpu; 79 int start_cpu;
80 80
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 15217bb0402f..742a03282b44 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -240,7 +240,7 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc,
240static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic) 240static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
241{ 241{
242 unsigned int virq; 242 unsigned int virq;
243 u32 *imap, *tmp; 243 const u32 *imap, *tmp;
244 int imaplen, intsize, unit; 244 int imaplen, intsize, unit;
245 struct device_node *iic; 245 struct device_node *iic;
246 struct irq_host *iic_host; 246 struct irq_host *iic_host;
@@ -258,25 +258,25 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
258#endif 258#endif
259 259
260 /* Now do the horrible hacks */ 260 /* Now do the horrible hacks */
261 tmp = (u32 *)get_property(pic->of_node, "#interrupt-cells", NULL); 261 tmp = get_property(pic->of_node, "#interrupt-cells", NULL);
262 if (tmp == NULL) 262 if (tmp == NULL)
263 return NO_IRQ; 263 return NO_IRQ;
264 intsize = *tmp; 264 intsize = *tmp;
265 imap = (u32 *)get_property(pic->of_node, "interrupt-map", &imaplen); 265 imap = get_property(pic->of_node, "interrupt-map", &imaplen);
266 if (imap == NULL || imaplen < (intsize + 1)) 266 if (imap == NULL || imaplen < (intsize + 1))
267 return NO_IRQ; 267 return NO_IRQ;
268 iic = of_find_node_by_phandle(imap[intsize]); 268 iic = of_find_node_by_phandle(imap[intsize]);
269 if (iic == NULL) 269 if (iic == NULL)
270 return NO_IRQ; 270 return NO_IRQ;
271 imap += intsize + 1; 271 imap += intsize + 1;
272 tmp = (u32 *)get_property(iic, "#interrupt-cells", NULL); 272 tmp = get_property(iic, "#interrupt-cells", NULL);
273 if (tmp == NULL) 273 if (tmp == NULL)
274 return NO_IRQ; 274 return NO_IRQ;
275 intsize = *tmp; 275 intsize = *tmp;
276 /* Assume unit is last entry of interrupt specifier */ 276 /* Assume unit is last entry of interrupt specifier */
277 unit = imap[intsize - 1]; 277 unit = imap[intsize - 1];
278 /* Ok, we have a unit, now let's try to get the node */ 278 /* Ok, we have a unit, now let's try to get the node */
279 tmp = (u32 *)get_property(iic, "ibm,interrupt-server-ranges", NULL); 279 tmp = get_property(iic, "ibm,interrupt-server-ranges", NULL);
280 if (tmp == NULL) { 280 if (tmp == NULL) {
281 of_node_put(iic); 281 of_node_put(iic);
282 return NO_IRQ; 282 return NO_IRQ;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index d06042deb021..3bd36d46ab4a 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -488,10 +488,10 @@ int spu_irq_class_1_bottom(struct spu *spu)
488 488
489static int __init find_spu_node_id(struct device_node *spe) 489static int __init find_spu_node_id(struct device_node *spe)
490{ 490{
491 unsigned int *id; 491 const unsigned int *id;
492 struct device_node *cpu; 492 struct device_node *cpu;
493 cpu = spe->parent->parent; 493 cpu = spe->parent->parent;
494 id = (unsigned int *)get_property(cpu, "node-id", NULL); 494 id = get_property(cpu, "node-id", NULL);
495 return id ? *id : 0; 495 return id ? *id : 0;
496} 496}
497 497
@@ -500,7 +500,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
500{ 500{
501 static DEFINE_MUTEX(add_spumem_mutex); 501 static DEFINE_MUTEX(add_spumem_mutex);
502 502
503 struct address_prop { 503 const struct address_prop {
504 unsigned long address; 504 unsigned long address;
505 unsigned int len; 505 unsigned int len;
506 } __attribute__((packed)) *p; 506 } __attribute__((packed)) *p;
@@ -511,7 +511,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
511 struct zone *zone; 511 struct zone *zone;
512 int ret; 512 int ret;
513 513
514 p = (void*)get_property(spe, prop, &proplen); 514 p = get_property(spe, prop, &proplen);
515 WARN_ON(proplen != sizeof (*p)); 515 WARN_ON(proplen != sizeof (*p));
516 516
517 start_pfn = p->address >> PAGE_SHIFT; 517 start_pfn = p->address >> PAGE_SHIFT;
@@ -531,12 +531,12 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
531static void __iomem * __init map_spe_prop(struct spu *spu, 531static void __iomem * __init map_spe_prop(struct spu *spu,
532 struct device_node *n, const char *name) 532 struct device_node *n, const char *name)
533{ 533{
534 struct address_prop { 534 const struct address_prop {
535 unsigned long address; 535 unsigned long address;
536 unsigned int len; 536 unsigned int len;
537 } __attribute__((packed)) *prop; 537 } __attribute__((packed)) *prop;
538 538
539 void *p; 539 const void *p;
540 int proplen; 540 int proplen;
541 void* ret = NULL; 541 void* ret = NULL;
542 int err = 0; 542 int err = 0;
@@ -570,14 +570,14 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
570{ 570{
571 struct irq_host *host; 571 struct irq_host *host;
572 unsigned int isrc; 572 unsigned int isrc;
573 u32 *tmp; 573 const u32 *tmp;
574 574
575 host = iic_get_irq_host(spu->node); 575 host = iic_get_irq_host(spu->node);
576 if (host == NULL) 576 if (host == NULL)
577 return -ENODEV; 577 return -ENODEV;
578 578
579 /* Get the interrupt source from the device-tree */ 579 /* Get the interrupt source from the device-tree */
580 tmp = (u32 *)get_property(np, "isrc", NULL); 580 tmp = get_property(np, "isrc", NULL);
581 if (!tmp) 581 if (!tmp)
582 return -ENODEV; 582 return -ENODEV;
583 spu->isrc = isrc = tmp[0]; 583 spu->isrc = isrc = tmp[0];
@@ -593,7 +593,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
593 593
594static int __init spu_map_device(struct spu *spu, struct device_node *node) 594static int __init spu_map_device(struct spu *spu, struct device_node *node)
595{ 595{
596 char *prop; 596 const char *prop;
597 int ret; 597 int ret;
598 598
599 ret = -ENODEV; 599 ret = -ENODEV;
diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
index 150f67d6f90c..0dd4a64757d9 100644
--- a/arch/powerpc/platforms/chrp/nvram.c
+++ b/arch/powerpc/platforms/chrp/nvram.c
@@ -67,13 +67,14 @@ static void chrp_nvram_write(int addr, unsigned char val)
67void __init chrp_nvram_init(void) 67void __init chrp_nvram_init(void)
68{ 68{
69 struct device_node *nvram; 69 struct device_node *nvram;
70 unsigned int *nbytes_p, proplen; 70 const unsigned int *nbytes_p;
71 unsigned int proplen;
71 72
72 nvram = of_find_node_by_type(NULL, "nvram"); 73 nvram = of_find_node_by_type(NULL, "nvram");
73 if (nvram == NULL) 74 if (nvram == NULL)
74 return; 75 return;
75 76
76 nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); 77 nbytes_p = get_property(nvram, "#bytes", &proplen);
77 if (nbytes_p == NULL || proplen != sizeof(unsigned int)) 78 if (nbytes_p == NULL || proplen != sizeof(unsigned int))
78 return; 79 return;
79 80
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 6802cdc3168a..0f4340506c75 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -214,11 +214,11 @@ void __init
214chrp_find_bridges(void) 214chrp_find_bridges(void)
215{ 215{
216 struct device_node *dev; 216 struct device_node *dev;
217 int *bus_range; 217 const int *bus_range;
218 int len, index = -1; 218 int len, index = -1;
219 struct pci_controller *hose; 219 struct pci_controller *hose;
220 unsigned int *dma; 220 const unsigned int *dma;
221 char *model, *machine; 221 const char *model, *machine;
222 int is_longtrail = 0, is_mot = 0, is_pegasos = 0; 222 int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
223 struct device_node *root = find_path_device("/"); 223 struct device_node *root = find_path_device("/");
224 struct resource r; 224 struct resource r;
@@ -246,7 +246,7 @@ chrp_find_bridges(void)
246 dev->full_name); 246 dev->full_name);
247 continue; 247 continue;
248 } 248 }
249 bus_range = (int *) get_property(dev, "bus-range", &len); 249 bus_range = get_property(dev, "bus-range", &len);
250 if (bus_range == NULL || len < 2 * sizeof(int)) { 250 if (bus_range == NULL || len < 2 * sizeof(int)) {
251 printk(KERN_WARNING "Can't get bus-range for %s\n", 251 printk(KERN_WARNING "Can't get bus-range for %s\n",
252 dev->full_name); 252 dev->full_name);
@@ -257,7 +257,7 @@ chrp_find_bridges(void)
257 else 257 else
258 printk(KERN_INFO "PCI buses %d..%d", 258 printk(KERN_INFO "PCI buses %d..%d",
259 bus_range[0], bus_range[1]); 259 bus_range[0], bus_range[1]);
260 printk(" controlled by %s", dev->type); 260 printk(" controlled by %s", dev->full_name);
261 if (!is_longtrail) 261 if (!is_longtrail)
262 printk(" at %llx", (unsigned long long)r.start); 262 printk(" at %llx", (unsigned long long)r.start);
263 printk("\n"); 263 printk("\n");
@@ -289,6 +289,19 @@ chrp_find_bridges(void)
289 setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); 289 setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
290 } else if (is_pegasos == 2) { 290 } else if (is_pegasos == 2) {
291 setup_peg2(hose, dev); 291 setup_peg2(hose, dev);
292 } else if (!strncmp(model, "IBM,CPC710", 10)) {
293 setup_indirect_pci(hose,
294 r.start + 0x000f8000,
295 r.start + 0x000f8010);
296 if (index == 0) {
297 dma = get_property(dev, "system-dma-base",&len);
298 if (dma && len >= sizeof(*dma)) {
299 dma = (unsigned int *)
300 (((unsigned long)dma) +
301 len - sizeof(*dma));
302 pci_dram_offset = *dma;
303 }
304 }
292 } else { 305 } else {
293 printk("No methods for %s (model %s), using RTAS\n", 306 printk("No methods for %s (model %s), using RTAS\n",
294 dev->full_name, model); 307 dev->full_name, model);
@@ -299,15 +312,35 @@ chrp_find_bridges(void)
299 312
300 /* check the first bridge for a property that we can 313 /* check the first bridge for a property that we can
301 use to set pci_dram_offset */ 314 use to set pci_dram_offset */
302 dma = (unsigned int *) 315 dma = get_property(dev, "ibm,dma-ranges", &len);
303 get_property(dev, "ibm,dma-ranges", &len);
304 if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { 316 if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
305 pci_dram_offset = dma[2] - dma[3]; 317 pci_dram_offset = dma[2] - dma[3];
306 printk("pci_dram_offset = %lx\n", pci_dram_offset); 318 printk("pci_dram_offset = %lx\n", pci_dram_offset);
307 } 319 }
308 } 320 }
321}
322
323/* SL82C105 IDE Control/Status Register */
324#define SL82C105_IDECSR 0x40
325
326/* Fixup for Winbond ATA quirk, required for briq */
327void chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105)
328{
329 u8 progif;
309 330
310 /* Do not fixup interrupts from OF tree on pegasos */ 331 /* If non-briq machines need that fixup too, please speak up */
311 if (is_pegasos) 332 if (!machine_is(chrp) || _chrp_type != _CHRP_briq)
312 ppc_md.pcibios_fixup = NULL; 333 return;
334
335 if ((sl82c105->class & 5) != 5) {
336 printk("W83C553: Switching SL82C105 IDE to PCI native mode\n");
337 /* Enable SL82C105 PCI native IDE mode */
338 pci_read_config_byte(sl82c105, PCI_CLASS_PROG, &progif);
339 pci_write_config_byte(sl82c105, PCI_CLASS_PROG, progif | 0x05);
340 sl82c105->class |= 0x05;
341 /* Disable SL82C105 second port */
342 pci_write_config_word(sl82c105, SL82C105_IDECSR, 0x0003);
343 }
313} 344}
345DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
346 chrp_pci_fixup_winbond_ata);
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 9c08ff322290..488dbd9b51ae 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -74,6 +74,9 @@ extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
74 74
75extern unsigned long loops_per_jiffy; 75extern unsigned long loops_per_jiffy;
76 76
77/* To be replaced by RTAS when available */
78static unsigned int *briq_SPOR;
79
77#ifdef CONFIG_SMP 80#ifdef CONFIG_SMP
78extern struct smp_ops_t chrp_smp_ops; 81extern struct smp_ops_t chrp_smp_ops;
79#endif 82#endif
@@ -92,6 +95,15 @@ static const char *gg2_cachemodes[4] = {
92 "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" 95 "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
93}; 96};
94 97
98static const char *chrp_names[] = {
99 "Unknown",
100 "","","",
101 "Motorola",
102 "IBM or Longtrail",
103 "Genesi Pegasos",
104 "Total Impact Briq"
105};
106
95void chrp_show_cpuinfo(struct seq_file *m) 107void chrp_show_cpuinfo(struct seq_file *m)
96{ 108{
97 int i, sdramen; 109 int i, sdramen;
@@ -214,8 +226,7 @@ static void __init pegasos_set_l2cr(void)
214 /* Enable L2 cache if needed */ 226 /* Enable L2 cache if needed */
215 np = find_type_devices("cpu"); 227 np = find_type_devices("cpu");
216 if (np != NULL) { 228 if (np != NULL) {
217 unsigned int *l2cr = (unsigned int *) 229 const unsigned int *l2cr = get_property(np, "l2cr", NULL);
218 get_property (np, "l2cr", NULL);
219 if (l2cr == NULL) { 230 if (l2cr == NULL) {
220 printk ("Pegasos l2cr : no cpu l2cr property found\n"); 231 printk ("Pegasos l2cr : no cpu l2cr property found\n");
221 return; 232 return;
@@ -229,10 +240,18 @@ static void __init pegasos_set_l2cr(void)
229 } 240 }
230} 241}
231 242
243static void briq_restart(char *cmd)
244{
245 local_irq_disable();
246 if (briq_SPOR)
247 out_be32(briq_SPOR, 0);
248 for(;;);
249}
250
232void __init chrp_setup_arch(void) 251void __init chrp_setup_arch(void)
233{ 252{
234 struct device_node *root = find_path_device ("/"); 253 struct device_node *root = find_path_device ("/");
235 char *machine = NULL; 254 const char *machine = NULL;
236 255
237 /* init to some ~sane value until calibrate_delay() runs */ 256 /* init to some ~sane value until calibrate_delay() runs */
238 loops_per_jiffy = 50000000/HZ; 257 loops_per_jiffy = 50000000/HZ;
@@ -245,11 +264,16 @@ void __init chrp_setup_arch(void)
245 _chrp_type = _CHRP_IBM; 264 _chrp_type = _CHRP_IBM;
246 } else if (machine && strncmp(machine, "MOT", 3) == 0) { 265 } else if (machine && strncmp(machine, "MOT", 3) == 0) {
247 _chrp_type = _CHRP_Motorola; 266 _chrp_type = _CHRP_Motorola;
267 } else if (machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0) {
268 _chrp_type = _CHRP_briq;
269 /* Map the SPOR register on briq and change the restart hook */
270 briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4);
271 ppc_md.restart = briq_restart;
248 } else { 272 } else {
249 /* Let's assume it is an IBM chrp if all else fails */ 273 /* Let's assume it is an IBM chrp if all else fails */
250 _chrp_type = _CHRP_IBM; 274 _chrp_type = _CHRP_IBM;
251 } 275 }
252 printk("chrp type = %x\n", _chrp_type); 276 printk("chrp type = %x [%s]\n", _chrp_type, chrp_names[_chrp_type]);
253 277
254 rtas_initialize(); 278 rtas_initialize();
255 if (rtas_token("display-character") >= 0) 279 if (rtas_token("display-character") >= 0)
@@ -328,7 +352,7 @@ static void __init chrp_find_openpic(void)
328 struct device_node *np, *root; 352 struct device_node *np, *root;
329 int len, i, j; 353 int len, i, j;
330 int isu_size, idu_size; 354 int isu_size, idu_size;
331 unsigned int *iranges, *opprop = NULL; 355 const unsigned int *iranges, *opprop = NULL;
332 int oplen = 0; 356 int oplen = 0;
333 unsigned long opaddr; 357 unsigned long opaddr;
334 int na = 1; 358 int na = 1;
@@ -338,8 +362,7 @@ static void __init chrp_find_openpic(void)
338 return; 362 return;
339 root = of_find_node_by_path("/"); 363 root = of_find_node_by_path("/");
340 if (root) { 364 if (root) {
341 opprop = (unsigned int *) get_property 365 opprop = get_property(root, "platform-open-pic", &oplen);
342 (root, "platform-open-pic", &oplen);
343 na = prom_n_addr_cells(root); 366 na = prom_n_addr_cells(root);
344 } 367 }
345 if (opprop && oplen >= na * sizeof(unsigned int)) { 368 if (opprop && oplen >= na * sizeof(unsigned int)) {
@@ -356,7 +379,7 @@ static void __init chrp_find_openpic(void)
356 379
357 printk(KERN_INFO "OpenPIC at %lx\n", opaddr); 380 printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
358 381
359 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); 382 iranges = get_property(np, "interrupt-ranges", &len);
360 if (iranges == NULL) 383 if (iranges == NULL)
361 len = 0; /* non-distributed mpic */ 384 len = 0; /* non-distributed mpic */
362 else 385 else
@@ -442,8 +465,8 @@ static void __init chrp_find_8259(void)
442 * from anyway 465 * from anyway
443 */ 466 */
444 for (np = find_devices("pci"); np != NULL; np = np->next) { 467 for (np = find_devices("pci"); np != NULL; np = np->next) {
445 unsigned int *addrp = (unsigned int *) 468 const unsigned int *addrp = get_property(np,
446 get_property(np, "8259-interrupt-acknowledge", NULL); 469 "8259-interrupt-acknowledge", NULL);
447 470
448 if (addrp == NULL) 471 if (addrp == NULL)
449 continue; 472 continue;
@@ -502,7 +525,7 @@ void __init
502chrp_init2(void) 525chrp_init2(void)
503{ 526{
504 struct device_node *device; 527 struct device_node *device;
505 unsigned int *p = NULL; 528 const unsigned int *p = NULL;
506 529
507#ifdef CONFIG_NVRAM 530#ifdef CONFIG_NVRAM
508 chrp_nvram_init(); 531 chrp_nvram_init();
@@ -520,8 +543,7 @@ chrp_init2(void)
520 */ 543 */
521 device = find_devices("rtas"); 544 device = find_devices("rtas");
522 if (device) 545 if (device)
523 p = (unsigned int *) get_property 546 p = get_property(device, "rtas-event-scan-rate", NULL);
524 (device, "rtas-event-scan-rate", NULL);
525 if (p && *p) { 547 if (p && *p) {
526 /* 548 /*
527 * Arrange to call chrp_event_scan at least *p times 549 * Arrange to call chrp_event_scan at least *p times
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index 5d393eb94935..e4f2b9df5e17 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -95,7 +95,7 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
95{ 95{
96 struct pci_controller *hose; 96 struct pci_controller *hose;
97 struct device_node *node; 97 struct device_node *node;
98 unsigned int *interrupt; 98 const unsigned int *interrupt;
99 int busnr; 99 int busnr;
100 int len; 100 int len;
101 u8 slot; 101 u8 slot;
@@ -112,7 +112,7 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
112 if (!node) 112 if (!node)
113 printk(KERN_ERR "No pci node found\n"); 113 printk(KERN_ERR "No pci node found\n");
114 114
115 interrupt = (unsigned int *) get_property(node, "interrupt-map", &len); 115 interrupt = get_property(node, "interrupt-map", &len);
116 slot = find_slot_by_devfn(interrupt, dev->devfn); 116 slot = find_slot_by_devfn(interrupt, dev->devfn);
117 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 117 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
118 if (pin == 0 || pin > 4) 118 if (pin == 0 || pin > 4)
@@ -141,9 +141,9 @@ static void __init mpc7448_hpc2_setup_arch(void)
141 141
142 cpu = of_find_node_by_type(NULL, "cpu"); 142 cpu = of_find_node_by_type(NULL, "cpu");
143 if (cpu != 0) { 143 if (cpu != 0) {
144 unsigned int *fp; 144 const unsigned int *fp;
145 145
146 fp = (int *)get_property(cpu, "clock-frequency", NULL); 146 fp = get_property(cpu, "clock-frequency", NULL);
147 if (fp != 0) 147 if (fp != 0)
148 loops_per_jiffy = *fp / HZ; 148 loops_per_jiffy = *fp / HZ;
149 else 149 else
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
index 3d957a30c8c2..887b68804e6d 100644
--- a/arch/powerpc/platforms/iseries/Kconfig
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -3,13 +3,17 @@ menu "iSeries device drivers"
3 depends on PPC_ISERIES 3 depends on PPC_ISERIES
4 4
5config VIOCONS 5config VIOCONS
6 tristate "iSeries Virtual Console Support" 6 tristate "iSeries Virtual Console Support (Obsolete)"
7 help
8 This is the old virtual console driver for legacy iSeries.
9 You should use the iSeries Hypervisor Virtual Console
10 support instead.
7 11
8config VIODASD 12config VIODASD
9 tristate "iSeries Virtual I/O disk support" 13 tristate "iSeries Virtual I/O disk support"
10 help 14 help
11 If you are running on an iSeries system and you want to use 15 If you are running on an iSeries system and you want to use
12 virtual disks created and managed by OS/400, say Y. 16 virtual disks created and managed by OS/400, say Y.
13 17
14config VIOCD 18config VIOCD
15 tristate "iSeries Virtual I/O CD support" 19 tristate "iSeries Virtual I/O CD support"
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index d194140c1ebf..e305deee7f44 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2005-2006 Michael Ellerman, IBM Corporation 2 * Copyright (C) 2005-2006 Michael Ellerman, IBM Corporation
3 * Copyright (C) 2000-2004, IBM Corporation
3 * 4 *
4 * Description: 5 * Description:
5 * This file contains all the routines to build a flattened device 6 * This file contains all the routines to build a flattened device
@@ -33,13 +34,13 @@
33#include <asm/iseries/hv_types.h> 34#include <asm/iseries/hv_types.h>
34#include <asm/iseries/hv_lp_config.h> 35#include <asm/iseries/hv_lp_config.h>
35#include <asm/iseries/hv_call_xm.h> 36#include <asm/iseries/hv_call_xm.h>
36#include <asm/iseries/it_exp_vpd_panel.h>
37#include <asm/udbg.h> 37#include <asm/udbg.h>
38 38
39#include "processor_vpd.h" 39#include "processor_vpd.h"
40#include "call_hpt.h" 40#include "call_hpt.h"
41#include "call_pci.h" 41#include "call_pci.h"
42#include "pci.h" 42#include "pci.h"
43#include "it_exp_vpd_panel.h"
43 44
44#ifdef DEBUG 45#ifdef DEBUG
45#define DBG(fmt...) udbg_printf(fmt) 46#define DBG(fmt...) udbg_printf(fmt)
@@ -76,6 +77,43 @@ static char __initdata device_type_pci[] = "pci";
76static char __initdata device_type_vdevice[] = "vdevice"; 77static char __initdata device_type_vdevice[] = "vdevice";
77static char __initdata device_type_vscsi[] = "vscsi"; 78static char __initdata device_type_vscsi[] = "vscsi";
78 79
80
81/* EBCDIC to ASCII conversion routines */
82
83static unsigned char __init e2a(unsigned char x)
84{
85 switch (x) {
86 case 0x81 ... 0x89:
87 return x - 0x81 + 'a';
88 case 0x91 ... 0x99:
89 return x - 0x91 + 'j';
90 case 0xA2 ... 0xA9:
91 return x - 0xA2 + 's';
92 case 0xC1 ... 0xC9:
93 return x - 0xC1 + 'A';
94 case 0xD1 ... 0xD9:
95 return x - 0xD1 + 'J';
96 case 0xE2 ... 0xE9:
97 return x - 0xE2 + 'S';
98 case 0xF0 ... 0xF9:
99 return x - 0xF0 + '0';
100 }
101 return ' ';
102}
103
104static unsigned char * __init strne2a(unsigned char *dest,
105 const unsigned char *src, size_t n)
106{
107 int i;
108
109 n = strnlen(src, n);
110
111 for (i = 0; i < n; i++)
112 dest[i] = e2a(src[i]);
113
114 return dest;
115}
116
79static struct iseries_flat_dt * __init dt_init(void) 117static struct iseries_flat_dt * __init dt_init(void)
80{ 118{
81 struct iseries_flat_dt *dt; 119 struct iseries_flat_dt *dt;
@@ -298,7 +336,8 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
298 dt_prop_u32(dt, "#address-cells", 1); 336 dt_prop_u32(dt, "#address-cells", 1);
299 dt_prop_u32(dt, "#size-cells", 0); 337 dt_prop_u32(dt, "#size-cells", 0);
300 338
301 dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, NULL, 1); 339 dt_do_vdevice(dt, "vty", reg, -1, device_type_serial,
340 "IBM,iSeries-vty", 1);
302 reg++; 341 reg++;
303 342
304 dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi, 343 dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi,
diff --git a/arch/powerpc/platforms/iseries/hvlpconfig.c b/arch/powerpc/platforms/iseries/hvlpconfig.c
index 663a1affb4bb..f0475f0b1853 100644
--- a/arch/powerpc/platforms/iseries/hvlpconfig.c
+++ b/arch/powerpc/platforms/iseries/hvlpconfig.c
@@ -18,9 +18,22 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <asm/iseries/hv_lp_config.h> 20#include <asm/iseries/hv_lp_config.h>
21#include "it_lp_naca.h"
21 22
22HvLpIndex HvLpConfig_getLpIndex_outline(void) 23HvLpIndex HvLpConfig_getLpIndex_outline(void)
23{ 24{
24 return HvLpConfig_getLpIndex(); 25 return HvLpConfig_getLpIndex();
25} 26}
26EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline); 27EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline);
28
29HvLpIndex HvLpConfig_getLpIndex(void)
30{
31 return itLpNaca.xLpIndex;
32}
33EXPORT_SYMBOL(HvLpConfig_getLpIndex);
34
35HvLpIndex HvLpConfig_getPrimaryLpIndex(void)
36{
37 return itLpNaca.xPrimaryLpIndex;
38}
39EXPORT_SYMBOL_GPL(HvLpConfig_getPrimaryLpIndex);
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index e3bd2015f2c9..f4cbbcf8773a 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -88,6 +88,23 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
88} 88}
89 89
90/* 90/*
91 * Structure passed to HvCallXm_getTceTableParms
92 */
93struct iommu_table_cb {
94 unsigned long itc_busno; /* Bus number for this tce table */
95 unsigned long itc_start; /* Will be NULL for secondary */
96 unsigned long itc_totalsize; /* Size (in pages) of whole table */
97 unsigned long itc_offset; /* Index into real tce table of the
98 start of our section */
99 unsigned long itc_size; /* Size (in pages) of our section */
100 unsigned long itc_index; /* Index of this tce table */
101 unsigned short itc_maxtables; /* Max num of tables for partition */
102 unsigned char itc_virtbus; /* Flag to indicate virtual bus */
103 unsigned char itc_slotno; /* IOA Tce Slot Index */
104 unsigned char itc_rsvd[4];
105};
106
107/*
91 * Call Hv with the architected data structure to get TCE table info. 108 * Call Hv with the architected data structure to get TCE table info.
92 * info. Put the returned data into the Linux representation of the 109 * info. Put the returned data into the Linux representation of the
93 * TCE table data. 110 * TCE table data.
@@ -162,7 +179,7 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
162{ 179{
163 struct iommu_table *tbl; 180 struct iommu_table *tbl;
164 struct pci_dn *pdn = PCI_DN(dn); 181 struct pci_dn *pdn = PCI_DN(dn);
165 u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL); 182 const u32 *lsn = get_property(dn, "linux,logical-slot-number", NULL);
166 183
167 BUG_ON(lsn == NULL); 184 BUG_ON(lsn == NULL);
168 185
diff --git a/include/asm-powerpc/iseries/it_exp_vpd_panel.h b/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h
index 304a609ae21a..6de9097b7f57 100644
--- a/include/asm-powerpc/iseries/it_exp_vpd_panel.h
+++ b/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h
@@ -15,8 +15,8 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18#ifndef _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H 18#ifndef _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H
19#define _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H 19#define _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H
20 20
21/* 21/*
22 * This struct maps the panel information 22 * This struct maps the panel information
@@ -48,4 +48,4 @@ struct ItExtVpdPanel {
48 48
49extern struct ItExtVpdPanel xItExtVpdPanel; 49extern struct ItExtVpdPanel xItExtVpdPanel;
50 50
51#endif /* _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H */ 51#endif /* _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H */
diff --git a/include/asm-powerpc/iseries/it_lp_naca.h b/arch/powerpc/platforms/iseries/it_lp_naca.h
index 4fdcf052927f..9bbf58986819 100644
--- a/include/asm-powerpc/iseries/it_lp_naca.h
+++ b/arch/powerpc/platforms/iseries/it_lp_naca.h
@@ -15,8 +15,8 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18#ifndef _ASM_POWERPC_ISERIES_IT_LP_NACA_H 18#ifndef _PLATFORMS_ISERIES_IT_LP_NACA_H
19#define _ASM_POWERPC_ISERIES_IT_LP_NACA_H 19#define _PLATFORMS_ISERIES_IT_LP_NACA_H
20 20
21#include <linux/types.h> 21#include <linux/types.h>
22 22
@@ -77,4 +77,4 @@ extern struct ItLpNaca itLpNaca;
77#define ITLPNACA_HWSYNCEDTBS 0x20 /* Hardware synced TBs */ 77#define ITLPNACA_HWSYNCEDTBS 0x20 /* Hardware synced TBs */
78#define ITLPNACA_HMTINT 0x10 /* Utilize MHT for interrupts */ 78#define ITLPNACA_HMTINT 0x10 /* Utilize MHT for interrupts */
79 79
80#endif /* _ASM_POWERPC_ISERIES_IT_LP_NACA_H */ 80#endif /* _PLATFORMS_ISERIES_IT_LP_NACA_H */
diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c
index a7769445d6c7..8162049bb04d 100644
--- a/arch/powerpc/platforms/iseries/lpardata.c
+++ b/arch/powerpc/platforms/iseries/lpardata.c
@@ -13,12 +13,10 @@
13#include <asm/processor.h> 13#include <asm/processor.h>
14#include <asm/ptrace.h> 14#include <asm/ptrace.h>
15#include <asm/abs_addr.h> 15#include <asm/abs_addr.h>
16#include <asm/iseries/it_lp_naca.h>
17#include <asm/lppaca.h> 16#include <asm/lppaca.h>
18#include <asm/iseries/it_lp_reg_save.h> 17#include <asm/iseries/it_lp_reg_save.h>
19#include <asm/paca.h> 18#include <asm/paca.h>
20#include <asm/iseries/lpar_map.h> 19#include <asm/iseries/lpar_map.h>
21#include <asm/iseries/it_exp_vpd_panel.h>
22#include <asm/iseries/it_lp_queue.h> 20#include <asm/iseries/it_lp_queue.h>
23 21
24#include "naca.h" 22#include "naca.h"
@@ -27,6 +25,8 @@
27#include "ipl_parms.h" 25#include "ipl_parms.h"
28#include "processor_vpd.h" 26#include "processor_vpd.h"
29#include "release_data.h" 27#include "release_data.h"
28#include "it_exp_vpd_panel.h"
29#include "it_lp_naca.h"
30 30
31/* The HvReleaseData is the root of the information shared between 31/* The HvReleaseData is the root of the information shared between
32 * the hypervisor and Linux. 32 * the hypervisor and Linux.
@@ -127,14 +127,12 @@ struct ItLpNaca itLpNaca = {
127 (u64)instruction_access_slb_iSeries /* 0x480 I-SLB */ 127 (u64)instruction_access_slb_iSeries /* 0x480 I-SLB */
128 } 128 }
129}; 129};
130EXPORT_SYMBOL(itLpNaca);
131 130
132/* May be filled in by the hypervisor so cannot end up in the BSS */ 131/* May be filled in by the hypervisor so cannot end up in the BSS */
133struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); 132struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
134 133
135/* May be filled in by the hypervisor so cannot end up in the BSS */ 134/* May be filled in by the hypervisor so cannot end up in the BSS */
136struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data"))); 135struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
137EXPORT_SYMBOL(xItExtVpdPanel);
138 136
139#define maxPhysicalProcessors 32 137#define maxPhysicalProcessors 32
140 138
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
index 2a9f81ea27d6..98c1c2440aad 100644
--- a/arch/powerpc/platforms/iseries/lpevents.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -20,7 +20,7 @@
20#include <asm/iseries/it_lp_queue.h> 20#include <asm/iseries/it_lp_queue.h>
21#include <asm/iseries/hv_lp_event.h> 21#include <asm/iseries/hv_lp_event.h>
22#include <asm/iseries/hv_call_event.h> 22#include <asm/iseries/hv_call_event.h>
23#include <asm/iseries/it_lp_naca.h> 23#include "it_lp_naca.h"
24 24
25/* 25/*
26 * The LpQueue is used to pass event data from the hypervisor to 26 * The LpQueue is used to pass event data from the hypervisor to
diff --git a/arch/powerpc/platforms/iseries/main_store.h b/arch/powerpc/platforms/iseries/main_store.h
index 74f6889f834f..1a7a3f50e40b 100644
--- a/arch/powerpc/platforms/iseries/main_store.h
+++ b/arch/powerpc/platforms/iseries/main_store.h
@@ -61,9 +61,9 @@ struct IoHriMainStoreSegment4 {
61}; 61};
62 62
63/* Main Store VPD for Power4 */ 63/* Main Store VPD for Power4 */
64struct IoHriMainStoreChipInfo1 { 64struct __attribute((packed)) IoHriMainStoreChipInfo1 {
65 u32 chipMfgID __attribute((packed)); 65 u32 chipMfgID;
66 char chipECLevel[4] __attribute((packed)); 66 char chipECLevel[4];
67}; 67};
68 68
69struct IoHriMainStoreVpdIdData { 69struct IoHriMainStoreVpdIdData {
@@ -73,72 +73,72 @@ struct IoHriMainStoreVpdIdData {
73 char serialNumber[12]; 73 char serialNumber[12];
74}; 74};
75 75
76struct IoHriMainStoreVpdFruData { 76struct __attribute((packed)) IoHriMainStoreVpdFruData {
77 char fruLabel[8] __attribute((packed)); 77 char fruLabel[8];
78 u8 numberOfSlots __attribute((packed)); 78 u8 numberOfSlots;
79 u8 pluggingType __attribute((packed)); 79 u8 pluggingType;
80 u16 slotMapIndex __attribute((packed)); 80 u16 slotMapIndex;
81}; 81};
82 82
83struct IoHriMainStoreAdrRangeBlock { 83struct __attribute((packed)) IoHriMainStoreAdrRangeBlock {
84 void *blockStart __attribute((packed)); 84 void *blockStart;
85 void *blockEnd __attribute((packed)); 85 void *blockEnd;
86 u32 blockProcChipId __attribute((packed)); 86 u32 blockProcChipId;
87}; 87};
88 88
89#define MaxAreaAdrRangeBlocks 4 89#define MaxAreaAdrRangeBlocks 4
90 90
91struct IoHriMainStoreArea4 { 91struct __attribute((packed)) IoHriMainStoreArea4 {
92 u32 msVpdFormat __attribute((packed)); 92 u32 msVpdFormat;
93 u8 containedVpdType __attribute((packed)); 93 u8 containedVpdType;
94 u8 reserved1 __attribute((packed)); 94 u8 reserved1;
95 u16 reserved2 __attribute((packed)); 95 u16 reserved2;
96 96
97 u64 msExists __attribute((packed)); 97 u64 msExists;
98 u64 msFunctional __attribute((packed)); 98 u64 msFunctional;
99 99
100 u32 memorySize __attribute((packed)); 100 u32 memorySize;
101 u32 procNodeId __attribute((packed)); 101 u32 procNodeId;
102 102
103 u32 numAdrRangeBlocks __attribute((packed)); 103 u32 numAdrRangeBlocks;
104 struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks] __attribute((packed)); 104 struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks];
105 105
106 struct IoHriMainStoreChipInfo1 chipInfo0 __attribute((packed)); 106 struct IoHriMainStoreChipInfo1 chipInfo0;
107 struct IoHriMainStoreChipInfo1 chipInfo1 __attribute((packed)); 107 struct IoHriMainStoreChipInfo1 chipInfo1;
108 struct IoHriMainStoreChipInfo1 chipInfo2 __attribute((packed)); 108 struct IoHriMainStoreChipInfo1 chipInfo2;
109 struct IoHriMainStoreChipInfo1 chipInfo3 __attribute((packed)); 109 struct IoHriMainStoreChipInfo1 chipInfo3;
110 struct IoHriMainStoreChipInfo1 chipInfo4 __attribute((packed)); 110 struct IoHriMainStoreChipInfo1 chipInfo4;
111 struct IoHriMainStoreChipInfo1 chipInfo5 __attribute((packed)); 111 struct IoHriMainStoreChipInfo1 chipInfo5;
112 struct IoHriMainStoreChipInfo1 chipInfo6 __attribute((packed)); 112 struct IoHriMainStoreChipInfo1 chipInfo6;
113 struct IoHriMainStoreChipInfo1 chipInfo7 __attribute((packed)); 113 struct IoHriMainStoreChipInfo1 chipInfo7;
114 114
115 void *msRamAreaArray __attribute((packed)); 115 void *msRamAreaArray;
116 u32 msRamAreaArrayNumEntries __attribute((packed)); 116 u32 msRamAreaArrayNumEntries;
117 u32 msRamAreaArrayEntrySize __attribute((packed)); 117 u32 msRamAreaArrayEntrySize;
118 118
119 u32 numaDimmExists __attribute((packed)); 119 u32 numaDimmExists;
120 u32 numaDimmFunctional __attribute((packed)); 120 u32 numaDimmFunctional;
121 void *numaDimmArray __attribute((packed)); 121 void *numaDimmArray;
122 u32 numaDimmArrayNumEntries __attribute((packed)); 122 u32 numaDimmArrayNumEntries;
123 u32 numaDimmArrayEntrySize __attribute((packed)); 123 u32 numaDimmArrayEntrySize;
124 124
125 struct IoHriMainStoreVpdIdData idData __attribute((packed)); 125 struct IoHriMainStoreVpdIdData idData;
126 126
127 u64 powerData __attribute((packed)); 127 u64 powerData;
128 u64 cardAssemblyPartNum __attribute((packed)); 128 u64 cardAssemblyPartNum;
129 u64 chipSerialNum __attribute((packed)); 129 u64 chipSerialNum;
130 130
131 u64 reserved3 __attribute((packed)); 131 u64 reserved3;
132 char reserved4[16] __attribute((packed)); 132 char reserved4[16];
133 133
134 struct IoHriMainStoreVpdFruData fruData __attribute((packed)); 134 struct IoHriMainStoreVpdFruData fruData;
135 135
136 u8 vpdPortNum __attribute((packed)); 136 u8 vpdPortNum;
137 u8 reserved5 __attribute((packed)); 137 u8 reserved5;
138 u8 frameId __attribute((packed)); 138 u8 frameId;
139 u8 rackUnit __attribute((packed)); 139 u8 rackUnit;
140 char asciiKeywordVpd[256] __attribute((packed)); 140 char asciiKeywordVpd[256];
141 u32 reserved6 __attribute((packed)); 141 u32 reserved6;
142}; 142};
143 143
144 144
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 35bcc98111f5..3eb12065df23 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -34,6 +34,7 @@
34#include <asm/pci-bridge.h> 34#include <asm/pci-bridge.h>
35#include <asm/iommu.h> 35#include <asm/iommu.h>
36#include <asm/abs_addr.h> 36#include <asm/abs_addr.h>
37#include <asm/firmware.h>
37 38
38#include <asm/iseries/hv_call_xm.h> 39#include <asm/iseries/hv_call_xm.h>
39#include <asm/iseries/mf.h> 40#include <asm/iseries/mf.h>
@@ -176,12 +177,12 @@ void iSeries_pcibios_init(void)
176 } 177 }
177 while ((node = of_get_next_child(root, node)) != NULL) { 178 while ((node = of_get_next_child(root, node)) != NULL) {
178 HvBusNumber bus; 179 HvBusNumber bus;
179 u32 *busp; 180 const u32 *busp;
180 181
181 if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) 182 if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
182 continue; 183 continue;
183 184
184 busp = (u32 *)get_property(node, "bus-range", NULL); 185 busp = get_property(node, "bus-range", NULL);
185 if (busp == NULL) 186 if (busp == NULL)
186 continue; 187 continue;
187 bus = *busp; 188 bus = *busp;
@@ -221,10 +222,9 @@ void __init iSeries_pci_final_fixup(void)
221 222
222 if (node != NULL) { 223 if (node != NULL) {
223 struct pci_dn *pdn = PCI_DN(node); 224 struct pci_dn *pdn = PCI_DN(node);
224 u32 *agent; 225 const u32 *agent;
225 226
226 agent = (u32 *)get_property(node, "linux,agent-id", 227 agent = get_property(node, "linux,agent-id", NULL);
227 NULL);
228 if ((pdn != NULL) && (agent != NULL)) { 228 if ((pdn != NULL) && (agent != NULL)) {
229 u8 irq = iSeries_allocate_IRQ(pdn->busno, 0, 229 u8 irq = iSeries_allocate_IRQ(pdn->busno, 0,
230 pdn->bussubno); 230 pdn->bussubno);
@@ -271,46 +271,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev)
271} 271}
272 272
273/* 273/*
274 * I/0 Memory copy MUST use mmio commands on iSeries
275 * To do; For performance, include the hv call directly
276 */
277void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
278{
279 u8 ByteValue = c;
280 long NumberOfBytes = Count;
281
282 while (NumberOfBytes > 0) {
283 iSeries_Write_Byte(ByteValue, dest++);
284 -- NumberOfBytes;
285 }
286}
287EXPORT_SYMBOL(iSeries_memset_io);
288
289void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
290{
291 char *src = source;
292 long NumberOfBytes = count;
293
294 while (NumberOfBytes > 0) {
295 iSeries_Write_Byte(*src++, dest++);
296 -- NumberOfBytes;
297 }
298}
299EXPORT_SYMBOL(iSeries_memcpy_toio);
300
301void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
302{
303 char *dst = dest;
304 long NumberOfBytes = count;
305
306 while (NumberOfBytes > 0) {
307 *dst++ = iSeries_Read_Byte(src++);
308 -- NumberOfBytes;
309 }
310}
311EXPORT_SYMBOL(iSeries_memcpy_fromio);
312
313/*
314 * Look down the chain to find the matching Device Device 274 * Look down the chain to find the matching Device Device
315 */ 275 */
316static struct device_node *find_Device_Node(int bus, int devfn) 276static struct device_node *find_Device_Node(int bus, int devfn)
@@ -492,7 +452,7 @@ static inline struct device_node *xlate_iomm_address(
492 * iSeries_Read_Word = Read Word (16 bit) 452 * iSeries_Read_Word = Read Word (16 bit)
493 * iSeries_Read_Long = Read Long (32 bit) 453 * iSeries_Read_Long = Read Long (32 bit)
494 */ 454 */
495u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) 455static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
496{ 456{
497 u64 BarOffset; 457 u64 BarOffset;
498 u64 dsa; 458 u64 dsa;
@@ -519,9 +479,8 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
519 479
520 return (u8)ret.value; 480 return (u8)ret.value;
521} 481}
522EXPORT_SYMBOL(iSeries_Read_Byte);
523 482
524u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) 483static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
525{ 484{
526 u64 BarOffset; 485 u64 BarOffset;
527 u64 dsa; 486 u64 dsa;
@@ -549,9 +508,8 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
549 508
550 return swab16((u16)ret.value); 509 return swab16((u16)ret.value);
551} 510}
552EXPORT_SYMBOL(iSeries_Read_Word);
553 511
554u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) 512static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
555{ 513{
556 u64 BarOffset; 514 u64 BarOffset;
557 u64 dsa; 515 u64 dsa;
@@ -579,7 +537,6 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
579 537
580 return swab32((u32)ret.value); 538 return swab32((u32)ret.value);
581} 539}
582EXPORT_SYMBOL(iSeries_Read_Long);
583 540
584/* 541/*
585 * Write MM I/O Instructions for the iSeries 542 * Write MM I/O Instructions for the iSeries
@@ -588,7 +545,7 @@ EXPORT_SYMBOL(iSeries_Read_Long);
588 * iSeries_Write_Word = Write Word(16 bit) 545 * iSeries_Write_Word = Write Word(16 bit)
589 * iSeries_Write_Long = Write Long(32 bit) 546 * iSeries_Write_Long = Write Long(32 bit)
590 */ 547 */
591void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) 548static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
592{ 549{
593 u64 BarOffset; 550 u64 BarOffset;
594 u64 dsa; 551 u64 dsa;
@@ -613,9 +570,8 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
613 rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); 570 rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
614 } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); 571 } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
615} 572}
616EXPORT_SYMBOL(iSeries_Write_Byte);
617 573
618void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) 574static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
619{ 575{
620 u64 BarOffset; 576 u64 BarOffset;
621 u64 dsa; 577 u64 dsa;
@@ -640,9 +596,8 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
640 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); 596 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
641 } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); 597 } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
642} 598}
643EXPORT_SYMBOL(iSeries_Write_Word);
644 599
645void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) 600static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
646{ 601{
647 u64 BarOffset; 602 u64 BarOffset;
648 u64 dsa; 603 u64 dsa;
@@ -667,4 +622,224 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
667 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); 622 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
668 } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); 623 } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
669} 624}
670EXPORT_SYMBOL(iSeries_Write_Long); 625
626extern unsigned char __raw_readb(const volatile void __iomem *addr)
627{
628 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
629
630 return *(volatile unsigned char __force *)addr;
631}
632EXPORT_SYMBOL(__raw_readb);
633
634extern unsigned short __raw_readw(const volatile void __iomem *addr)
635{
636 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
637
638 return *(volatile unsigned short __force *)addr;
639}
640EXPORT_SYMBOL(__raw_readw);
641
642extern unsigned int __raw_readl(const volatile void __iomem *addr)
643{
644 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
645
646 return *(volatile unsigned int __force *)addr;
647}
648EXPORT_SYMBOL(__raw_readl);
649
650extern unsigned long __raw_readq(const volatile void __iomem *addr)
651{
652 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
653
654 return *(volatile unsigned long __force *)addr;
655}
656EXPORT_SYMBOL(__raw_readq);
657
658extern void __raw_writeb(unsigned char v, volatile void __iomem *addr)
659{
660 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
661
662 *(volatile unsigned char __force *)addr = v;
663}
664EXPORT_SYMBOL(__raw_writeb);
665
666extern void __raw_writew(unsigned short v, volatile void __iomem *addr)
667{
668 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
669
670 *(volatile unsigned short __force *)addr = v;
671}
672EXPORT_SYMBOL(__raw_writew);
673
674extern void __raw_writel(unsigned int v, volatile void __iomem *addr)
675{
676 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
677
678 *(volatile unsigned int __force *)addr = v;
679}
680EXPORT_SYMBOL(__raw_writel);
681
682extern void __raw_writeq(unsigned long v, volatile void __iomem *addr)
683{
684 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
685
686 *(volatile unsigned long __force *)addr = v;
687}
688EXPORT_SYMBOL(__raw_writeq);
689
690int in_8(const volatile unsigned char __iomem *addr)
691{
692 if (firmware_has_feature(FW_FEATURE_ISERIES))
693 return iSeries_Read_Byte(addr);
694 return __in_8(addr);
695}
696EXPORT_SYMBOL(in_8);
697
698void out_8(volatile unsigned char __iomem *addr, int val)
699{
700 if (firmware_has_feature(FW_FEATURE_ISERIES))
701 iSeries_Write_Byte(val, addr);
702 else
703 __out_8(addr, val);
704}
705EXPORT_SYMBOL(out_8);
706
707int in_le16(const volatile unsigned short __iomem *addr)
708{
709 if (firmware_has_feature(FW_FEATURE_ISERIES))
710 return iSeries_Read_Word(addr);
711 return __in_le16(addr);
712}
713EXPORT_SYMBOL(in_le16);
714
715int in_be16(const volatile unsigned short __iomem *addr)
716{
717 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
718
719 return __in_be16(addr);
720}
721EXPORT_SYMBOL(in_be16);
722
723void out_le16(volatile unsigned short __iomem *addr, int val)
724{
725 if (firmware_has_feature(FW_FEATURE_ISERIES))
726 iSeries_Write_Word(val, addr);
727 else
728 __out_le16(addr, val);
729}
730EXPORT_SYMBOL(out_le16);
731
732void out_be16(volatile unsigned short __iomem *addr, int val)
733{
734 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
735
736 __out_be16(addr, val);
737}
738EXPORT_SYMBOL(out_be16);
739
740unsigned in_le32(const volatile unsigned __iomem *addr)
741{
742 if (firmware_has_feature(FW_FEATURE_ISERIES))
743 return iSeries_Read_Long(addr);
744 return __in_le32(addr);
745}
746EXPORT_SYMBOL(in_le32);
747
748unsigned in_be32(const volatile unsigned __iomem *addr)
749{
750 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
751
752 return __in_be32(addr);
753}
754EXPORT_SYMBOL(in_be32);
755
756void out_le32(volatile unsigned __iomem *addr, int val)
757{
758 if (firmware_has_feature(FW_FEATURE_ISERIES))
759 iSeries_Write_Long(val, addr);
760 else
761 __out_le32(addr, val);
762}
763EXPORT_SYMBOL(out_le32);
764
765void out_be32(volatile unsigned __iomem *addr, int val)
766{
767 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
768
769 __out_be32(addr, val);
770}
771EXPORT_SYMBOL(out_be32);
772
773unsigned long in_le64(const volatile unsigned long __iomem *addr)
774{
775 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
776
777 return __in_le64(addr);
778}
779EXPORT_SYMBOL(in_le64);
780
781unsigned long in_be64(const volatile unsigned long __iomem *addr)
782{
783 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
784
785 return __in_be64(addr);
786}
787EXPORT_SYMBOL(in_be64);
788
789void out_le64(volatile unsigned long __iomem *addr, unsigned long val)
790{
791 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
792
793 __out_le64(addr, val);
794}
795EXPORT_SYMBOL(out_le64);
796
797void out_be64(volatile unsigned long __iomem *addr, unsigned long val)
798{
799 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
800
801 __out_be64(addr, val);
802}
803EXPORT_SYMBOL(out_be64);
804
805void memset_io(volatile void __iomem *addr, int c, unsigned long n)
806{
807 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
808 volatile char __iomem *d = addr;
809
810 while (n-- > 0) {
811 iSeries_Write_Byte(c, d++);
812 }
813 } else
814 eeh_memset_io(addr, c, n);
815}
816EXPORT_SYMBOL(memset_io);
817
818void memcpy_fromio(void *dest, const volatile void __iomem *src,
819 unsigned long n)
820{
821 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
822 char *d = dest;
823 const volatile char __iomem *s = src;
824
825 while (n-- > 0) {
826 *d++ = iSeries_Read_Byte(s++);
827 }
828 } else
829 eeh_memcpy_fromio(dest, src, n);
830}
831EXPORT_SYMBOL(memcpy_fromio);
832
833void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
834{
835 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
836 const char *s = src;
837 volatile char __iomem *d = dest;
838
839 while (n-- > 0) {
840 iSeries_Write_Byte(*s++, d++);
841 }
842 } else
843 eeh_memcpy_toio(dest, src, n);
844}
845EXPORT_SYMBOL(memcpy_toio);
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index c9605d773a77..7f1953066ff8 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -59,6 +59,7 @@
59#include "irq.h" 59#include "irq.h"
60#include "vpd_areas.h" 60#include "vpd_areas.h"
61#include "processor_vpd.h" 61#include "processor_vpd.h"
62#include "it_lp_naca.h"
62#include "main_store.h" 63#include "main_store.h"
63#include "call_sm.h" 64#include "call_sm.h"
64#include "call_hpt.h" 65#include "call_hpt.h"
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 622a30149b48..9baa4ee82592 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -41,8 +41,8 @@
41 41
42#include <asm/system.h> 42#include <asm/system.h>
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <asm/prom.h>
44#include <asm/iseries/hv_types.h> 45#include <asm/iseries/hv_types.h>
45#include <asm/iseries/it_exp_vpd_panel.h>
46#include <asm/iseries/hv_lp_event.h> 46#include <asm/iseries/hv_lp_event.h>
47#include <asm/iseries/hv_lp_config.h> 47#include <asm/iseries/hv_lp_config.h>
48#include <asm/iseries/mf.h> 48#include <asm/iseries/mf.h>
@@ -116,6 +116,8 @@ static int proc_viopath_show(struct seq_file *m, void *v)
116 dma_addr_t handle; 116 dma_addr_t handle;
117 HvLpEvent_Rc hvrc; 117 HvLpEvent_Rc hvrc;
118 DECLARE_MUTEX_LOCKED(Semaphore); 118 DECLARE_MUTEX_LOCKED(Semaphore);
119 struct device_node *node;
120 const char *sysid;
119 121
120 buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL); 122 buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL);
121 if (!buf) 123 if (!buf)
@@ -143,20 +145,26 @@ static int proc_viopath_show(struct seq_file *m, void *v)
143 145
144 buf[HW_PAGE_SIZE-1] = '\0'; 146 buf[HW_PAGE_SIZE-1] = '\0';
145 seq_printf(m, "%s", buf); 147 seq_printf(m, "%s", buf);
146 seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
147 seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n",
148 e2a(xItExtVpdPanel.mfgID[2]),
149 e2a(xItExtVpdPanel.mfgID[3]),
150 e2a(xItExtVpdPanel.systemSerial[1]),
151 e2a(xItExtVpdPanel.systemSerial[2]),
152 e2a(xItExtVpdPanel.systemSerial[3]),
153 e2a(xItExtVpdPanel.systemSerial[4]),
154 e2a(xItExtVpdPanel.systemSerial[5]));
155 148
156 dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE, 149 dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE,
157 DMA_FROM_DEVICE); 150 DMA_FROM_DEVICE);
158 kfree(buf); 151 kfree(buf);
159 152
153 seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
154
155 node = of_find_node_by_path("/");
156 sysid = NULL;
157 if (node != NULL)
158 sysid = get_property(node, "system-id", NULL);
159
160 if (sysid == NULL)
161 seq_printf(m, "SRLNBR=<UNKNOWN>\n");
162 else
163 /* Skip "IBM," on front of serial number, see dt.c */
164 seq_printf(m, "SRLNBR=%s\n", sysid + 4);
165
166 of_node_put(node);
167
160 return 0; 168 return 0;
161} 169}
162 170
diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
index 23a6d1e5b429..9f83878a0c2e 100644
--- a/arch/powerpc/platforms/iseries/vpdinfo.c
+++ b/arch/powerpc/platforms/iseries/vpdinfo.c
@@ -188,7 +188,7 @@ static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
188{ 188{
189 u8 *TagPtr = VpdData; 189 u8 *TagPtr = VpdData;
190 int DataLen = VpdDataLen - 3; 190 int DataLen = VpdDataLen - 3;
191 u8 PhbId; 191 u8 PhbId = 0xff;
192 192
193 while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { 193 while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
194 int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); 194 int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
@@ -205,15 +205,16 @@ static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
205 } 205 }
206} 206}
207 207
208static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, 208static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
209 u8 *frame, char card[4]) 209 u8 *frame, char card[4])
210{ 210{
211 int status = 0;
211 int BusVpdLen = 0; 212 int BusVpdLen = 0;
212 u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); 213 u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
213 214
214 if (BusVpdPtr == NULL) { 215 if (BusVpdPtr == NULL) {
215 printk("PCI: Bus VPD Buffer allocation failure.\n"); 216 printk("PCI: Bus VPD Buffer allocation failure.\n");
216 return; 217 return 0;
217 } 218 }
218 BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr), 219 BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
219 BUS_VPDSIZE); 220 BUS_VPDSIZE);
@@ -228,8 +229,10 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
228 goto out_free; 229 goto out_free;
229 } 230 }
230 iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card); 231 iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
232 status = 1;
231out_free: 233out_free:
232 kfree(BusVpdPtr); 234 kfree(BusVpdPtr);
235 return status;
233} 236}
234 237
235/* 238/*
@@ -246,7 +249,7 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
246 struct device_node *DevNode = PciDev->sysdata; 249 struct device_node *DevNode = PciDev->sysdata;
247 struct pci_dn *pdn; 250 struct pci_dn *pdn;
248 u16 bus; 251 u16 bus;
249 u8 frame; 252 u8 frame = 0;
250 char card[4]; 253 char card[4];
251 HvSubBusNumber subbus; 254 HvSubBusNumber subbus;
252 HvAgentId agent; 255 HvAgentId agent;
@@ -262,10 +265,11 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
262 subbus = pdn->bussubno; 265 subbus = pdn->bussubno;
263 agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), 266 agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
264 ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); 267 ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
265 iSeries_Get_Location_Code(bus, agent, &frame, card);
266 268
267 printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", 269 if (iSeries_Get_Location_Code(bus, agent, &frame, card)) {
268 count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, 270 printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
269 frame, card); 271 "Card %4s 0x%04X\n", count, bus,
270 printk("0x%04X\n", (int)(PciDev->class >> 8)); 272 PCI_SLOT(PciDev->devfn), PciDev->vendor, frame,
273 card, (int)(PciDev->class >> 8));
274 }
271} 275}
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 63a1670d3bfd..c3aa46b8e2b9 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -38,16 +38,16 @@ static struct pci_controller *u3_agp, *u3_ht;
38static int __init fixup_one_level_bus_range(struct device_node *node, int higher) 38static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
39{ 39{
40 for (; node != 0;node = node->sibling) { 40 for (; node != 0;node = node->sibling) {
41 int * bus_range; 41 const int *bus_range;
42 unsigned int *class_code; 42 const unsigned int *class_code;
43 int len; 43 int len;
44 44
45 /* For PCI<->PCI bridges or CardBus bridges, we go down */ 45 /* For PCI<->PCI bridges or CardBus bridges, we go down */
46 class_code = (unsigned int *) get_property(node, "class-code", NULL); 46 class_code = get_property(node, "class-code", NULL);
47 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 47 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
48 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) 48 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
49 continue; 49 continue;
50 bus_range = (int *) get_property(node, "bus-range", &len); 50 bus_range = get_property(node, "bus-range", &len);
51 if (bus_range != NULL && len > 2 * sizeof(int)) { 51 if (bus_range != NULL && len > 2 * sizeof(int)) {
52 if (bus_range[1] > higher) 52 if (bus_range[1] > higher)
53 higher = bus_range[1]; 53 higher = bus_range[1];
@@ -65,30 +65,36 @@ static int __init fixup_one_level_bus_range(struct device_node *node, int higher
65 */ 65 */
66static void __init fixup_bus_range(struct device_node *bridge) 66static void __init fixup_bus_range(struct device_node *bridge)
67{ 67{
68 int * bus_range; 68 int *bus_range;
69 struct property *prop;
69 int len; 70 int len;
70 71
71 /* Lookup the "bus-range" property for the hose */ 72 /* Lookup the "bus-range" property for the hose */
72 bus_range = (int *) get_property(bridge, "bus-range", &len); 73 prop = of_find_property(bridge, "bus-range", &len);
73 if (bus_range == NULL || len < 2 * sizeof(int)) { 74 if (prop == NULL || prop->value == NULL || len < 2 * sizeof(int)) {
74 printk(KERN_WARNING "Can't get bus-range for %s\n", 75 printk(KERN_WARNING "Can't get bus-range for %s\n",
75 bridge->full_name); 76 bridge->full_name);
76 return; 77 return;
77 } 78 }
79 bus_range = (int *)prop->value;
78 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); 80 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
79} 81}
80 82
81 83
82#define U3_AGP_CFA0(devfn, off) \ 84static unsigned long u3_agp_cfa0(u8 devfn, u8 off)
83 ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ 85{
84 | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ 86 return (1 << (unsigned long)PCI_SLOT(devfn)) |
85 | (((unsigned long)(off)) & 0xFCUL)) 87 ((unsigned long)PCI_FUNC(devfn) << 8) |
88 ((unsigned long)off & 0xFCUL);
89}
86 90
87#define U3_AGP_CFA1(bus, devfn, off) \ 91static unsigned long u3_agp_cfa1(u8 bus, u8 devfn, u8 off)
88 ((((unsigned long)(bus)) << 16) \ 92{
89 |(((unsigned long)(devfn)) << 8) \ 93 return ((unsigned long)bus << 16) |
90 |(((unsigned long)(off)) & 0xFCUL) \ 94 ((unsigned long)devfn << 8) |
91 |1UL) 95 ((unsigned long)off & 0xFCUL) |
96 1UL;
97}
92 98
93static unsigned long u3_agp_cfg_access(struct pci_controller* hose, 99static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
94 u8 bus, u8 dev_fn, u8 offset) 100 u8 bus, u8 dev_fn, u8 offset)
@@ -98,9 +104,9 @@ static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
98 if (bus == hose->first_busno) { 104 if (bus == hose->first_busno) {
99 if (dev_fn < (11 << 3)) 105 if (dev_fn < (11 << 3))
100 return 0; 106 return 0;
101 caddr = U3_AGP_CFA0(dev_fn, offset); 107 caddr = u3_agp_cfa0(dev_fn, offset);
102 } else 108 } else
103 caddr = U3_AGP_CFA1(bus, dev_fn, offset); 109 caddr = u3_agp_cfa1(bus, dev_fn, offset);
104 110
105 /* Uninorth will return garbage if we don't read back the value ! */ 111 /* Uninorth will return garbage if we don't read back the value ! */
106 do { 112 do {
@@ -182,13 +188,15 @@ static struct pci_ops u3_agp_pci_ops =
182 u3_agp_write_config 188 u3_agp_write_config
183}; 189};
184 190
191static unsigned long u3_ht_cfa0(u8 devfn, u8 off)
192{
193 return (devfn << 8) | off;
194}
185 195
186#define U3_HT_CFA0(devfn, off) \ 196static unsigned long u3_ht_cfa1(u8 bus, u8 devfn, u8 off)
187 ((((unsigned long)devfn) << 8) | offset) 197{
188#define U3_HT_CFA1(bus, devfn, off) \ 198 return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL;
189 (U3_HT_CFA0(devfn, off) \ 199}
190 + (((unsigned long)bus) << 16) \
191 + 0x01000000UL)
192 200
193static unsigned long u3_ht_cfg_access(struct pci_controller* hose, 201static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
194 u8 bus, u8 devfn, u8 offset) 202 u8 bus, u8 devfn, u8 offset)
@@ -196,9 +204,9 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
196 if (bus == hose->first_busno) { 204 if (bus == hose->first_busno) {
197 if (PCI_SLOT(devfn) == 0) 205 if (PCI_SLOT(devfn) == 0)
198 return 0; 206 return 0;
199 return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset); 207 return ((unsigned long)hose->cfg_data) + u3_ht_cfa0(devfn, offset);
200 } else 208 } else
201 return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); 209 return ((unsigned long)hose->cfg_data) + u3_ht_cfa1(bus, devfn, offset);
202} 210}
203 211
204static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, 212static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
@@ -211,6 +219,9 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
211 if (hose == NULL) 219 if (hose == NULL)
212 return PCIBIOS_DEVICE_NOT_FOUND; 220 return PCIBIOS_DEVICE_NOT_FOUND;
213 221
222 if (offset > 0xff)
223 return PCIBIOS_BAD_REGISTER_NUMBER;
224
214 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); 225 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
215 if (!addr) 226 if (!addr)
216 return PCIBIOS_DEVICE_NOT_FOUND; 227 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -243,6 +254,9 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
243 if (hose == NULL) 254 if (hose == NULL)
244 return PCIBIOS_DEVICE_NOT_FOUND; 255 return PCIBIOS_DEVICE_NOT_FOUND;
245 256
257 if (offset > 0xff)
258 return PCIBIOS_BAD_REGISTER_NUMBER;
259
246 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); 260 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
247 if (!addr) 261 if (!addr)
248 return PCIBIOS_DEVICE_NOT_FOUND; 262 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -314,12 +328,12 @@ static int __init add_bridge(struct device_node *dev)
314 int len; 328 int len;
315 struct pci_controller *hose; 329 struct pci_controller *hose;
316 char* disp_name; 330 char* disp_name;
317 int *bus_range; 331 const int *bus_range;
318 int primary = 1; 332 int primary = 1;
319 333
320 DBG("Adding PCI host bridge %s\n", dev->full_name); 334 DBG("Adding PCI host bridge %s\n", dev->full_name);
321 335
322 bus_range = (int *) get_property(dev, "bus-range", &len); 336 bus_range = get_property(dev, "bus-range", &len);
323 if (bus_range == NULL || len < 2 * sizeof(int)) { 337 if (bus_range == NULL || len < 2 * sizeof(int)) {
324 printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", 338 printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
325 dev->full_name); 339 dev->full_name);
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 57567dfb9819..fe6b9bff61b9 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -99,8 +99,7 @@ static unsigned long maple_find_nvram_base(void)
99static void maple_restart(char *cmd) 99static void maple_restart(char *cmd)
100{ 100{
101 unsigned int maple_nvram_base; 101 unsigned int maple_nvram_base;
102 unsigned int maple_nvram_offset; 102 const unsigned int *maple_nvram_offset, *maple_nvram_command;
103 unsigned int maple_nvram_command;
104 struct device_node *sp; 103 struct device_node *sp;
105 104
106 maple_nvram_base = maple_find_nvram_base(); 105 maple_nvram_base = maple_find_nvram_base();
@@ -113,14 +112,12 @@ static void maple_restart(char *cmd)
113 printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); 112 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
114 goto fail; 113 goto fail;
115 } 114 }
116 maple_nvram_offset = *(unsigned int*) get_property(sp, 115 maple_nvram_offset = get_property(sp, "restart-addr", NULL);
117 "restart-addr", NULL); 116 maple_nvram_command = get_property(sp, "restart-value", NULL);
118 maple_nvram_command = *(unsigned int*) get_property(sp,
119 "restart-value", NULL);
120 of_node_put(sp); 117 of_node_put(sp);
121 118
122 /* send command */ 119 /* send command */
123 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); 120 outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset);
124 for (;;) ; 121 for (;;) ;
125 fail: 122 fail:
126 printk(KERN_EMERG "Maple: Manual Restart Required\n"); 123 printk(KERN_EMERG "Maple: Manual Restart Required\n");
@@ -129,8 +126,7 @@ static void maple_restart(char *cmd)
129static void maple_power_off(void) 126static void maple_power_off(void)
130{ 127{
131 unsigned int maple_nvram_base; 128 unsigned int maple_nvram_base;
132 unsigned int maple_nvram_offset; 129 const unsigned int *maple_nvram_offset, *maple_nvram_command;
133 unsigned int maple_nvram_command;
134 struct device_node *sp; 130 struct device_node *sp;
135 131
136 maple_nvram_base = maple_find_nvram_base(); 132 maple_nvram_base = maple_find_nvram_base();
@@ -143,14 +139,12 @@ static void maple_power_off(void)
143 printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); 139 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
144 goto fail; 140 goto fail;
145 } 141 }
146 maple_nvram_offset = *(unsigned int*) get_property(sp, 142 maple_nvram_offset = get_property(sp, "power-off-addr", NULL);
147 "power-off-addr", NULL); 143 maple_nvram_command = get_property(sp, "power-off-value", NULL);
148 maple_nvram_command = *(unsigned int*) get_property(sp,
149 "power-off-value", NULL);
150 of_node_put(sp); 144 of_node_put(sp);
151 145
152 /* send command */ 146 /* send command */
153 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); 147 outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset);
154 for (;;) ; 148 for (;;) ;
155 fail: 149 fail:
156 printk(KERN_EMERG "Maple: Manual Power-Down Required\n"); 150 printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
@@ -211,7 +205,7 @@ static void __init maple_init_early(void)
211static void __init maple_init_IRQ(void) 205static void __init maple_init_IRQ(void)
212{ 206{
213 struct device_node *root, *np, *mpic_node = NULL; 207 struct device_node *root, *np, *mpic_node = NULL;
214 unsigned int *opprop; 208 const unsigned int *opprop;
215 unsigned long openpic_addr = 0; 209 unsigned long openpic_addr = 0;
216 int naddr, n, i, opplen, has_isus = 0; 210 int naddr, n, i, opplen, has_isus = 0;
217 struct mpic *mpic; 211 struct mpic *mpic;
@@ -241,8 +235,7 @@ static void __init maple_init_IRQ(void)
241 /* Find address list in /platform-open-pic */ 235 /* Find address list in /platform-open-pic */
242 root = of_find_node_by_path("/"); 236 root = of_find_node_by_path("/");
243 naddr = prom_n_addr_cells(root); 237 naddr = prom_n_addr_cells(root);
244 opprop = (unsigned int *) get_property(root, "platform-open-pic", 238 opprop = get_property(root, "platform-open-pic", &opplen);
245 &opplen);
246 if (opprop != 0) { 239 if (opprop != 0) {
247 openpic_addr = of_read_number(opprop, naddr); 240 openpic_addr = of_read_number(opprop, naddr);
248 has_isus = (opplen > naddr); 241 has_isus = (opplen > naddr);
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
new file mode 100644
index 000000000000..1be1a993c5f5
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/Makefile
@@ -0,0 +1 @@
obj-y += setup.o pci.o time.o
diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h
new file mode 100644
index 000000000000..fd71d72736b2
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/pasemi.h
@@ -0,0 +1,8 @@
1#ifndef _PASEMI_PASEMI_H
2#define _PASEMI_PASEMI_H
3
4extern unsigned long pas_get_boot_time(void);
5extern void pas_pci_init(void);
6extern void pas_pcibios_fixup(void);
7
8#endif /* _PASEMI_PASEMI_H */
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
new file mode 100644
index 000000000000..4679c5230413
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -0,0 +1,198 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Authors: Kip Walker, PA Semi
5 * Olof Johansson, PA Semi
6 *
7 * Maintained by: Olof Johansson <olof@lixom.net>
8 *
9 * Based on arch/powerpc/platforms/maple/pci.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25
26#include <linux/kernel.h>
27#include <linux/pci.h>
28
29#include <asm/pci-bridge.h>
30#include <asm/machdep.h>
31
32#include <asm/ppc-pci.h>
33
34#define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off))
35
36#define CONFIG_OFFSET_VALID(off) ((off) < 4096)
37
38static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose,
39 u8 bus, u8 devfn, int offset)
40{
41 return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
42}
43
44static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
45 int offset, int len, u32 *val)
46{
47 struct pci_controller *hose;
48 unsigned long addr;
49
50 hose = pci_bus_to_host(bus);
51 if (!hose)
52 return PCIBIOS_DEVICE_NOT_FOUND;
53
54 if (!CONFIG_OFFSET_VALID(offset))
55 return PCIBIOS_BAD_REGISTER_NUMBER;
56
57 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
58
59 /*
60 * Note: the caller has already checked that offset is
61 * suitably aligned and that len is 1, 2 or 4.
62 */
63 switch (len) {
64 case 1:
65 *val = in_8((u8 *)addr);
66 break;
67 case 2:
68 *val = in_le16((u16 *)addr);
69 break;
70 default:
71 *val = in_le32((u32 *)addr);
72 break;
73 }
74
75 return PCIBIOS_SUCCESSFUL;
76}
77
78static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
79 int offset, int len, u32 val)
80{
81 struct pci_controller *hose;
82 unsigned long addr;
83
84 hose = pci_bus_to_host(bus);
85 if (!hose)
86 return PCIBIOS_DEVICE_NOT_FOUND;
87
88 if (!CONFIG_OFFSET_VALID(offset))
89 return PCIBIOS_BAD_REGISTER_NUMBER;
90
91 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
92
93 /*
94 * Note: the caller has already checked that offset is
95 * suitably aligned and that len is 1, 2 or 4.
96 */
97 switch (len) {
98 case 1:
99 out_8((u8 *)addr, val);
100 (void) in_8((u8 *)addr);
101 break;
102 case 2:
103 out_le16((u16 *)addr, val);
104 (void) in_le16((u16 *)addr);
105 break;
106 default:
107 out_le32((u32 *)addr, val);
108 (void) in_le32((u32 *)addr);
109 break;
110 }
111 return PCIBIOS_SUCCESSFUL;
112}
113
114static struct pci_ops pa_pxp_ops = {
115 pa_pxp_read_config,
116 pa_pxp_write_config,
117};
118
119static void __init setup_pa_pxp(struct pci_controller *hose)
120{
121 hose->ops = &pa_pxp_ops;
122 hose->cfg_data = ioremap(0xe0000000, 0x10000000);
123}
124
125static int __init add_bridge(struct device_node *dev)
126{
127 struct pci_controller *hose;
128
129 pr_debug("Adding PCI host bridge %s\n", dev->full_name);
130
131 hose = pcibios_alloc_controller(dev);
132 if (!hose)
133 return -ENOMEM;
134
135 hose->first_busno = 0;
136 hose->last_busno = 0xff;
137
138 setup_pa_pxp(hose);
139
140 printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
141
142 /* Interpret the "ranges" property */
143 /* This also maps the I/O region and sets isa_io/mem_base */
144 pci_process_bridge_OF_ranges(hose, dev, 1);
145 pci_setup_phb_io(hose, 1);
146
147 return 0;
148}
149
150
151void __init pas_pcibios_fixup(void)
152{
153 struct pci_dev *dev = NULL;
154
155 for_each_pci_dev(dev)
156 pci_read_irq_line(dev);
157}
158
159static void __init pas_fixup_phb_resources(void)
160{
161 struct pci_controller *hose, *tmp;
162
163 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
164 unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
165 hose->io_resource.start += offset;
166 hose->io_resource.end += offset;
167 printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
168 hose->global_number,
169 hose->io_resource.start, hose->io_resource.end);
170 }
171}
172
173
174void __init pas_pci_init(void)
175{
176 struct device_node *np, *root;
177
178 root = of_find_node_by_path("/");
179 if (!root) {
180 printk(KERN_CRIT "pas_pci_init: can't find root "
181 "of device tree\n");
182 return;
183 }
184
185 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
186 if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np))
187 of_node_get(np);
188
189 of_node_put(root);
190
191 pas_fixup_phb_resources();
192
193 /* Setup the linkage between OF nodes and PHBs */
194 pci_devs_phb_init();
195
196 /* Use the common resource allocation mechanism */
197 pci_probe_only = 1;
198}
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
new file mode 100644
index 000000000000..628482671c15
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -0,0 +1,188 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Authors: Kip Walker, PA Semi
5 * Olof Johansson, PA Semi
6 *
7 * Maintained by: Olof Johansson <olof@lixom.net>
8 *
9 * Based on arch/powerpc/platforms/maple/setup.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/config.h>
26#include <linux/errno.h>
27#include <linux/kernel.h>
28#include <linux/delay.h>
29#include <linux/console.h>
30
31#include <asm/prom.h>
32#include <asm/system.h>
33#include <asm/iommu.h>
34#include <asm/machdep.h>
35#include <asm/mpic.h>
36#include <asm/smp.h>
37#include <asm/time.h>
38
39#include "pasemi.h"
40
41static void pas_restart(char *cmd)
42{
43 printk("restart unimplemented, looping...\n");
44 for (;;) ;
45}
46
47static void pas_power_off(void)
48{
49 printk("power off unimplemented, looping...\n");
50 for (;;) ;
51}
52
53static void pas_halt(void)
54{
55 pas_power_off();
56}
57
58#ifdef CONFIG_SMP
59struct smp_ops_t pas_smp_ops = {
60 .probe = smp_mpic_probe,
61 .message_pass = smp_mpic_message_pass,
62 .kick_cpu = smp_generic_kick_cpu,
63 .setup_cpu = smp_mpic_setup_cpu,
64 .give_timebase = smp_generic_give_timebase,
65 .take_timebase = smp_generic_take_timebase,
66};
67#endif /* CONFIG_SMP */
68
69void __init pas_setup_arch(void)
70{
71#ifdef CONFIG_SMP
72 /* Setup SMP callback */
73 smp_ops = &pas_smp_ops;
74#endif
75 /* Lookup PCI hosts */
76 pas_pci_init();
77
78#ifdef CONFIG_DUMMY_CONSOLE
79 conswitchp = &dummy_con;
80#endif
81
82 printk(KERN_DEBUG "Using default idle loop\n");
83}
84
85static void iommu_dev_setup_null(struct pci_dev *dev) { }
86static void iommu_bus_setup_null(struct pci_bus *bus) { }
87
88static void __init pas_init_early(void)
89{
90 /* No iommu code yet */
91 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
92 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
93 pci_direct_iommu_init();
94}
95
96/* No legacy IO on our parts */
97static int pas_check_legacy_ioport(unsigned int baseport)
98{
99 return -ENODEV;
100}
101
102static __init void pas_init_IRQ(void)
103{
104 struct device_node *np;
105 struct device_node *root, *mpic_node;
106 unsigned long openpic_addr;
107 const unsigned int *opprop;
108 int naddr, opplen;
109 struct mpic *mpic;
110
111 mpic_node = NULL;
112
113 for_each_node_by_type(np, "interrupt-controller")
114 if (device_is_compatible(np, "open-pic")) {
115 mpic_node = np;
116 break;
117 }
118 if (!mpic_node)
119 for_each_node_by_type(np, "open-pic") {
120 mpic_node = np;
121 break;
122 }
123 if (!mpic_node) {
124 printk(KERN_ERR
125 "Failed to locate the MPIC interrupt controller\n");
126 return;
127 }
128
129 /* Find address list in /platform-open-pic */
130 root = of_find_node_by_path("/");
131 naddr = prom_n_addr_cells(root);
132 opprop = get_property(root, "platform-open-pic", &opplen);
133 if (!opprop) {
134 printk(KERN_ERR "No platform-open-pic property.\n");
135 of_node_put(root);
136 return;
137 }
138 openpic_addr = of_read_number(opprop, naddr);
139 printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
140 of_node_put(root);
141
142 mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0,
143 " PAS-OPIC ");
144 BUG_ON(!mpic);
145
146 mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
147 mpic_init(mpic);
148 of_node_put(mpic_node);
149 of_node_put(root);
150}
151
152static void __init pas_progress(char *s, unsigned short hex)
153{
154 printk("[%04x] : %s\n", hex, s ? s : "");
155}
156
157
158/*
159 * Called very early, MMU is off, device-tree isn't unflattened
160 */
161static int __init pas_probe(void)
162{
163 unsigned long root = of_get_flat_dt_root();
164
165 if (!of_flat_dt_is_compatible(root, "PA6T-1682M"))
166 return 0;
167
168 hpte_init_native();
169
170 return 1;
171}
172
173define_machine(pas) {
174 .name = "PA Semi PA6T-1682M",
175 .probe = pas_probe,
176 .setup_arch = pas_setup_arch,
177 .init_early = pas_init_early,
178 .init_IRQ = pas_init_IRQ,
179 .get_irq = mpic_get_irq,
180 .pcibios_fixup = pas_pcibios_fixup,
181 .restart = pas_restart,
182 .power_off = pas_power_off,
183 .halt = pas_halt,
184 .get_boot_time = pas_get_boot_time,
185 .calibrate_decr = generic_calibrate_decr,
186 .check_legacy_ioport = pas_check_legacy_ioport,
187 .progress = pas_progress,
188};
diff --git a/arch/powerpc/platforms/pasemi/time.c b/arch/powerpc/platforms/pasemi/time.c
new file mode 100644
index 000000000000..9bd410b8fec6
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/time.c
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/config.h>
21#include <linux/time.h>
22
23#include <asm/time.h>
24
25unsigned long __init pas_get_boot_time(void)
26{
27 /* Let's just return a fake date right now */
28 return mktime(2006, 1, 1, 12, 0, 0);
29}
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
index d66415491055..afa593a8544a 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -60,7 +60,8 @@ int pmac_has_backlight_type(const char *type)
60 struct device_node* bk_node = find_devices("backlight"); 60 struct device_node* bk_node = find_devices("backlight");
61 61
62 if (bk_node) { 62 if (bk_node) {
63 char *prop = get_property(bk_node, "backlight-control", NULL); 63 const char *prop = get_property(bk_node,
64 "backlight-control", NULL);
64 if (prop && strncmp(prop, type, strlen(type)) == 0) 65 if (prop && strncmp(prop, type, strlen(type)) == 0)
65 return 1; 66 return 1;
66 } 67 }
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 62926248bdb8..c2b6b4134f68 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -421,7 +421,7 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
421 421
422static u32 read_gpio(struct device_node *np) 422static u32 read_gpio(struct device_node *np)
423{ 423{
424 u32 *reg = (u32 *)get_property(np, "reg", NULL); 424 const u32 *reg = get_property(np, "reg", NULL);
425 u32 offset; 425 u32 offset;
426 426
427 if (reg == NULL) 427 if (reg == NULL)
@@ -497,7 +497,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
497 "frequency-gpio"); 497 "frequency-gpio");
498 struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, 498 struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
499 "slewing-done"); 499 "slewing-done");
500 u32 *value; 500 const u32 *value;
501 501
502 /* 502 /*
503 * Check to see if it's GPIO driven or PMU only 503 * Check to see if it's GPIO driven or PMU only
@@ -519,15 +519,15 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
519 */ 519 */
520 if (frequency_gpio && slew_done_gpio) { 520 if (frequency_gpio && slew_done_gpio) {
521 int lenp, rc; 521 int lenp, rc;
522 u32 *freqs, *ratio; 522 const u32 *freqs, *ratio;
523 523
524 freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); 524 freqs = get_property(cpunode, "bus-frequencies", &lenp);
525 lenp /= sizeof(u32); 525 lenp /= sizeof(u32);
526 if (freqs == NULL || lenp != 2) { 526 if (freqs == NULL || lenp != 2) {
527 printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); 527 printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
528 return 1; 528 return 1;
529 } 529 }
530 ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); 530 ratio = get_property(cpunode, "processor-to-bus-ratio*2", NULL);
531 if (ratio == NULL) { 531 if (ratio == NULL) {
532 printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); 532 printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
533 return 1; 533 return 1;
@@ -562,7 +562,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
562 /* If we use the PMU, look for the min & max frequencies in the 562 /* If we use the PMU, look for the min & max frequencies in the
563 * device-tree 563 * device-tree
564 */ 564 */
565 value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); 565 value = get_property(cpunode, "min-clock-frequency", NULL);
566 if (!value) 566 if (!value)
567 return 1; 567 return 1;
568 low_freq = (*value) / 1000; 568 low_freq = (*value) / 1000;
@@ -571,7 +571,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
571 if (low_freq < 100000) 571 if (low_freq < 100000)
572 low_freq *= 10; 572 low_freq *= 10;
573 573
574 value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); 574 value = get_property(cpunode, "max-clock-frequency", NULL);
575 if (!value) 575 if (!value)
576 return 1; 576 return 1;
577 hi_freq = (*value) / 1000; 577 hi_freq = (*value) / 1000;
@@ -611,13 +611,14 @@ static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
611static int pmac_cpufreq_init_750FX(struct device_node *cpunode) 611static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
612{ 612{
613 struct device_node *volt_gpio_np; 613 struct device_node *volt_gpio_np;
614 u32 pvr, *value; 614 u32 pvr;
615 const u32 *value;
615 616
616 if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) 617 if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
617 return 1; 618 return 1;
618 619
619 hi_freq = cur_freq; 620 hi_freq = cur_freq;
620 value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); 621 value = get_property(cpunode, "reduced-clock-frequency", NULL);
621 if (!value) 622 if (!value)
622 return 1; 623 return 1;
623 low_freq = (*value) / 1000; 624 low_freq = (*value) / 1000;
@@ -650,7 +651,7 @@ static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
650static int __init pmac_cpufreq_setup(void) 651static int __init pmac_cpufreq_setup(void)
651{ 652{
652 struct device_node *cpunode; 653 struct device_node *cpunode;
653 u32 *value; 654 const u32 *value;
654 655
655 if (strstr(cmd_line, "nocpufreq")) 656 if (strstr(cmd_line, "nocpufreq"))
656 return 0; 657 return 0;
@@ -661,7 +662,7 @@ static int __init pmac_cpufreq_setup(void)
661 goto out; 662 goto out;
662 663
663 /* Get current cpu clock freq */ 664 /* Get current cpu clock freq */
664 value = (u32 *)get_property(cpunode, "clock-frequency", NULL); 665 value = get_property(cpunode, "clock-frequency", NULL);
665 if (!value) 666 if (!value)
666 goto out; 667 goto out;
667 cur_freq = (*value) / 1000; 668 cur_freq = (*value) / 1000;
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 7b1156ea5341..d30466d74194 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -89,7 +89,7 @@ static DEFINE_MUTEX(g5_switch_mutex);
89 89
90#ifdef CONFIG_PMAC_SMU 90#ifdef CONFIG_PMAC_SMU
91 91
92static u32 *g5_pmode_data; 92static const u32 *g5_pmode_data;
93static int g5_pmode_max; 93static int g5_pmode_max;
94 94
95static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ 95static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
@@ -391,7 +391,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
391 unsigned int psize, ssize; 391 unsigned int psize, ssize;
392 unsigned long max_freq; 392 unsigned long max_freq;
393 char *freq_method, *volt_method; 393 char *freq_method, *volt_method;
394 u32 *valp, pvr_hi; 394 const u32 *valp;
395 u32 pvr_hi;
395 int use_volts_vdnap = 0; 396 int use_volts_vdnap = 0;
396 int use_volts_smu = 0; 397 int use_volts_smu = 0;
397 int rc = -ENODEV; 398 int rc = -ENODEV;
@@ -409,8 +410,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
409 /* Get first CPU node */ 410 /* Get first CPU node */
410 for (cpunode = NULL; 411 for (cpunode = NULL;
411 (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { 412 (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
412 u32 *reg = 413 const u32 *reg = get_property(cpunode, "reg", NULL);
413 (u32 *)get_property(cpunode, "reg", NULL);
414 if (reg == NULL || (*reg) != 0) 414 if (reg == NULL || (*reg) != 0)
415 continue; 415 continue;
416 if (!strcmp(cpunode->type, "cpu")) 416 if (!strcmp(cpunode->type, "cpu"))
@@ -422,7 +422,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
422 } 422 }
423 423
424 /* Check 970FX for now */ 424 /* Check 970FX for now */
425 valp = (u32 *)get_property(cpunode, "cpu-version", NULL); 425 valp = get_property(cpunode, "cpu-version", NULL);
426 if (!valp) { 426 if (!valp) {
427 DBG("No cpu-version property !\n"); 427 DBG("No cpu-version property !\n");
428 goto bail_noprops; 428 goto bail_noprops;
@@ -434,7 +434,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
434 } 434 }
435 435
436 /* Look for the powertune data in the device-tree */ 436 /* Look for the powertune data in the device-tree */
437 g5_pmode_data = (u32 *)get_property(cpunode, "power-mode-data",&psize); 437 g5_pmode_data = get_property(cpunode, "power-mode-data",&psize);
438 if (!g5_pmode_data) { 438 if (!g5_pmode_data) {
439 DBG("No power-mode-data !\n"); 439 DBG("No power-mode-data !\n");
440 goto bail_noprops; 440 goto bail_noprops;
@@ -442,7 +442,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
442 g5_pmode_max = psize / sizeof(u32) - 1; 442 g5_pmode_max = psize / sizeof(u32) - 1;
443 443
444 if (use_volts_smu) { 444 if (use_volts_smu) {
445 struct smu_sdbp_header *shdr; 445 const struct smu_sdbp_header *shdr;
446 446
447 /* Look for the FVT table */ 447 /* Look for the FVT table */
448 shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL); 448 shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
@@ -493,7 +493,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
493 * half freq in this version. So far, I haven't yet seen a machine 493 * half freq in this version. So far, I haven't yet seen a machine
494 * supporting anything else. 494 * supporting anything else.
495 */ 495 */
496 valp = (u32 *)get_property(cpunode, "clock-frequency", NULL); 496 valp = get_property(cpunode, "clock-frequency", NULL);
497 if (!valp) 497 if (!valp)
498 return -ENODEV; 498 return -ENODEV;
499 max_freq = (*valp)/1000; 499 max_freq = (*valp)/1000;
@@ -541,8 +541,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
541static int __init g5_pm72_cpufreq_init(struct device_node *cpus) 541static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
542{ 542{
543 struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; 543 struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
544 u8 *eeprom = NULL; 544 const u8 *eeprom = NULL;
545 u32 *valp; 545 const u32 *valp;
546 u64 max_freq, min_freq, ih, il; 546 u64 max_freq, min_freq, ih, il;
547 int has_volt = 1, rc = 0; 547 int has_volt = 1, rc = 0;
548 548
@@ -563,7 +563,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
563 /* Lookup the cpuid eeprom node */ 563 /* Lookup the cpuid eeprom node */
564 cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0"); 564 cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
565 if (cpuid != NULL) 565 if (cpuid != NULL)
566 eeprom = (u8 *)get_property(cpuid, "cpuid", NULL); 566 eeprom = get_property(cpuid, "cpuid", NULL);
567 if (eeprom == NULL) { 567 if (eeprom == NULL) {
568 printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n"); 568 printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n");
569 rc = -ENODEV; 569 rc = -ENODEV;
@@ -573,7 +573,8 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
573 /* Lookup the i2c hwclock */ 573 /* Lookup the i2c hwclock */
574 for (hwclock = NULL; 574 for (hwclock = NULL;
575 (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){ 575 (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){
576 char *loc = get_property(hwclock, "hwctrl-location", NULL); 576 const char *loc = get_property(hwclock,
577 "hwctrl-location", NULL);
577 if (loc == NULL) 578 if (loc == NULL)
578 continue; 579 continue;
579 if (strcmp(loc, "CPU CLOCK")) 580 if (strcmp(loc, "CPU CLOCK"))
@@ -637,7 +638,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
637 */ 638 */
638 639
639 /* Get max frequency from device-tree */ 640 /* Get max frequency from device-tree */
640 valp = (u32 *)get_property(cpunode, "clock-frequency", NULL); 641 valp = get_property(cpunode, "clock-frequency", NULL);
641 if (!valp) { 642 if (!valp) {
642 printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n"); 643 printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n");
643 rc = -ENODEV; 644 rc = -ENODEV;
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index f8313bf9a9f7..13fcaf5b1796 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -1058,8 +1058,8 @@ core99_reset_cpu(struct device_node *node, long param, long value)
1058 if (np == NULL) 1058 if (np == NULL)
1059 return -ENODEV; 1059 return -ENODEV;
1060 for (np = np->child; np != NULL; np = np->sibling) { 1060 for (np = np->child; np != NULL; np = np->sibling) {
1061 u32 *num = (u32 *)get_property(np, "reg", NULL); 1061 u32 *num = get_property(np, "reg", NULL);
1062 u32 *rst = (u32 *)get_property(np, "soft-reset", NULL); 1062 u32 *rst = get_property(np, "soft-reset", NULL);
1063 if (num == NULL || rst == NULL) 1063 if (num == NULL || rst == NULL)
1064 continue; 1064 continue;
1065 if (param == *num) { 1065 if (param == *num) {
@@ -1087,7 +1087,7 @@ core99_usb_enable(struct device_node *node, long param, long value)
1087{ 1087{
1088 struct macio_chip *macio; 1088 struct macio_chip *macio;
1089 unsigned long flags; 1089 unsigned long flags;
1090 char *prop; 1090 const char *prop;
1091 int number; 1091 int number;
1092 u32 reg; 1092 u32 reg;
1093 1093
@@ -1096,7 +1096,7 @@ core99_usb_enable(struct device_node *node, long param, long value)
1096 macio->type != macio_intrepid) 1096 macio->type != macio_intrepid)
1097 return -ENODEV; 1097 return -ENODEV;
1098 1098
1099 prop = (char *)get_property(node, "AAPL,clock-id", NULL); 1099 prop = get_property(node, "AAPL,clock-id", NULL);
1100 if (!prop) 1100 if (!prop)
1101 return -ENODEV; 1101 return -ENODEV;
1102 if (strncmp(prop, "usb0u048", 8) == 0) 1102 if (strncmp(prop, "usb0u048", 8) == 0)
@@ -1507,8 +1507,8 @@ static long g5_reset_cpu(struct device_node *node, long param, long value)
1507 if (np == NULL) 1507 if (np == NULL)
1508 return -ENODEV; 1508 return -ENODEV;
1509 for (np = np->child; np != NULL; np = np->sibling) { 1509 for (np = np->child; np != NULL; np = np->sibling) {
1510 u32 *num = (u32 *)get_property(np, "reg", NULL); 1510 const u32 *num = get_property(np, "reg", NULL);
1511 u32 *rst = (u32 *)get_property(np, "soft-reset", NULL); 1511 const u32 *rst = get_property(np, "soft-reset", NULL);
1512 if (num == NULL || rst == NULL) 1512 if (num == NULL || rst == NULL)
1513 continue; 1513 continue;
1514 if (param == *num) { 1514 if (param == *num) {
@@ -2408,7 +2408,7 @@ static int __init probe_motherboard(void)
2408 */ 2408 */
2409 dt = find_devices("device-tree"); 2409 dt = find_devices("device-tree");
2410 if (dt != NULL) 2410 if (dt != NULL)
2411 model = (const char *) get_property(dt, "model", NULL); 2411 model = get_property(dt, "model", NULL);
2412 for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { 2412 for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
2413 if (strcmp(model, pmac_mb_defs[i].model_string) == 0) { 2413 if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
2414 pmac_mb = pmac_mb_defs[i]; 2414 pmac_mb = pmac_mb_defs[i];
@@ -2536,7 +2536,7 @@ found:
2536 */ 2536 */
2537static void __init probe_uninorth(void) 2537static void __init probe_uninorth(void)
2538{ 2538{
2539 u32 *addrp; 2539 const u32 *addrp;
2540 phys_addr_t address; 2540 phys_addr_t address;
2541 unsigned long actrl; 2541 unsigned long actrl;
2542 2542
@@ -2555,7 +2555,7 @@ static void __init probe_uninorth(void)
2555 if (uninorth_node == NULL) 2555 if (uninorth_node == NULL)
2556 return; 2556 return;
2557 2557
2558 addrp = (u32 *)get_property(uninorth_node, "reg", NULL); 2558 addrp = get_property(uninorth_node, "reg", NULL);
2559 if (addrp == NULL) 2559 if (addrp == NULL)
2560 return; 2560 return;
2561 address = of_translate_address(uninorth_node, addrp); 2561 address = of_translate_address(uninorth_node, addrp);
@@ -2596,7 +2596,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2596 struct device_node* node; 2596 struct device_node* node;
2597 int i; 2597 int i;
2598 volatile u32 __iomem *base; 2598 volatile u32 __iomem *base;
2599 u32 *addrp, *revp; 2599 const u32 *addrp, *revp;
2600 phys_addr_t addr; 2600 phys_addr_t addr;
2601 u64 size; 2601 u64 size;
2602 2602
@@ -2639,7 +2639,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2639 return; 2639 return;
2640 } 2640 }
2641 if (type == macio_keylargo || type == macio_keylargo2) { 2641 if (type == macio_keylargo || type == macio_keylargo2) {
2642 u32 *did = (u32 *)get_property(node, "device-id", NULL); 2642 const u32 *did = get_property(node, "device-id", NULL);
2643 if (*did == 0x00000025) 2643 if (*did == 0x00000025)
2644 type = macio_pangea; 2644 type = macio_pangea;
2645 if (*did == 0x0000003e) 2645 if (*did == 0x0000003e)
@@ -2652,7 +2652,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2652 macio_chips[i].base = base; 2652 macio_chips[i].base = base;
2653 macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; 2653 macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
2654 macio_chips[i].name = macio_names[type]; 2654 macio_chips[i].name = macio_names[type];
2655 revp = (u32 *)get_property(node, "revision-id", NULL); 2655 revp = get_property(node, "revision-id", NULL);
2656 if (revp) 2656 if (revp)
2657 macio_chips[i].rev = *revp; 2657 macio_chips[i].rev = *revp;
2658 printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n", 2658 printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
@@ -2695,15 +2695,15 @@ static void __init
2695initial_serial_shutdown(struct device_node *np) 2695initial_serial_shutdown(struct device_node *np)
2696{ 2696{
2697 int len; 2697 int len;
2698 struct slot_names_prop { 2698 const struct slot_names_prop {
2699 int count; 2699 int count;
2700 char name[1]; 2700 char name[1];
2701 } *slots; 2701 } *slots;
2702 char *conn; 2702 const char *conn;
2703 int port_type = PMAC_SCC_ASYNC; 2703 int port_type = PMAC_SCC_ASYNC;
2704 int modem = 0; 2704 int modem = 0;
2705 2705
2706 slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); 2706 slots = get_property(np, "slot-names", &len);
2707 conn = get_property(np, "AAPL,connector", &len); 2707 conn = get_property(np, "AAPL,connector", &len);
2708 if (conn && (strcmp(conn, "infrared") == 0)) 2708 if (conn && (strcmp(conn, "infrared") == 0))
2709 port_type = PMAC_SCC_IRDA; 2709 port_type = PMAC_SCC_IRDA;
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 8677f50c2586..c2c7cf75dd5f 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -477,7 +477,8 @@ static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
477static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) 477static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
478{ 478{
479 struct pmac_i2c_host_kw *host; 479 struct pmac_i2c_host_kw *host;
480 u32 *psteps, *prate, *addrp, steps; 480 const u32 *psteps, *prate, *addrp;
481 u32 steps;
481 482
482 host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL); 483 host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL);
483 if (host == NULL) { 484 if (host == NULL) {
@@ -490,7 +491,7 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
490 * on all i2c keywest nodes so far ... we would have to fallback 491 * on all i2c keywest nodes so far ... we would have to fallback
491 * to macio parsing if that wasn't the case 492 * to macio parsing if that wasn't the case
492 */ 493 */
493 addrp = (u32 *)get_property(np, "AAPL,address", NULL); 494 addrp = get_property(np, "AAPL,address", NULL);
494 if (addrp == NULL) { 495 if (addrp == NULL) {
495 printk(KERN_ERR "low_i2c: Can't find address for %s\n", 496 printk(KERN_ERR "low_i2c: Can't find address for %s\n",
496 np->full_name); 497 np->full_name);
@@ -504,13 +505,13 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
504 host->timeout_timer.function = kw_i2c_timeout; 505 host->timeout_timer.function = kw_i2c_timeout;
505 host->timeout_timer.data = (unsigned long)host; 506 host->timeout_timer.data = (unsigned long)host;
506 507
507 psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); 508 psteps = get_property(np, "AAPL,address-step", NULL);
508 steps = psteps ? (*psteps) : 0x10; 509 steps = psteps ? (*psteps) : 0x10;
509 for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) 510 for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
510 steps >>= 1; 511 steps >>= 1;
511 /* Select interface rate */ 512 /* Select interface rate */
512 host->speed = KW_I2C_MODE_25KHZ; 513 host->speed = KW_I2C_MODE_25KHZ;
513 prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); 514 prate = get_property(np, "AAPL,i2c-rate", NULL);
514 if (prate) switch(*prate) { 515 if (prate) switch(*prate) {
515 case 100: 516 case 100:
516 host->speed = KW_I2C_MODE_100KHZ; 517 host->speed = KW_I2C_MODE_100KHZ;
@@ -618,8 +619,8 @@ static void __init kw_i2c_probe(void)
618 } else { 619 } else {
619 for (child = NULL; 620 for (child = NULL;
620 (child = of_get_next_child(np, child)) != NULL;) { 621 (child = of_get_next_child(np, child)) != NULL;) {
621 u32 *reg = 622 const u32 *reg = get_property(child,
622 (u32 *)get_property(child, "reg", NULL); 623 "reg", NULL);
623 if (reg == NULL) 624 if (reg == NULL)
624 continue; 625 continue;
625 kw_i2c_add(host, np, child, *reg); 626 kw_i2c_add(host, np, child, *reg);
@@ -881,7 +882,7 @@ static void __init smu_i2c_probe(void)
881{ 882{
882 struct device_node *controller, *busnode; 883 struct device_node *controller, *busnode;
883 struct pmac_i2c_bus *bus; 884 struct pmac_i2c_bus *bus;
884 u32 *reg; 885 const u32 *reg;
885 int sz; 886 int sz;
886 887
887 if (!smu_present()) 888 if (!smu_present())
@@ -904,7 +905,7 @@ static void __init smu_i2c_probe(void)
904 if (strcmp(busnode->type, "i2c") && 905 if (strcmp(busnode->type, "i2c") &&
905 strcmp(busnode->type, "i2c-bus")) 906 strcmp(busnode->type, "i2c-bus"))
906 continue; 907 continue;
907 reg = (u32 *)get_property(busnode, "reg", NULL); 908 reg = get_property(busnode, "reg", NULL);
908 if (reg == NULL) 909 if (reg == NULL)
909 continue; 910 continue;
910 911
@@ -948,9 +949,8 @@ struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node)
948 list_for_each_entry(bus, &pmac_i2c_busses, link) { 949 list_for_each_entry(bus, &pmac_i2c_busses, link) {
949 if (p == bus->busnode) { 950 if (p == bus->busnode) {
950 if (prev && bus->flags & pmac_i2c_multibus) { 951 if (prev && bus->flags & pmac_i2c_multibus) {
951 u32 *reg; 952 const u32 *reg;
952 reg = (u32 *)get_property(prev, "reg", 953 reg = get_property(prev, "reg", NULL);
953 NULL);
954 if (!reg) 954 if (!reg)
955 continue; 955 continue;
956 if (((*reg) >> 8) != bus->channel) 956 if (((*reg) >> 8) != bus->channel)
@@ -971,7 +971,7 @@ EXPORT_SYMBOL_GPL(pmac_i2c_find_bus);
971 971
972u8 pmac_i2c_get_dev_addr(struct device_node *device) 972u8 pmac_i2c_get_dev_addr(struct device_node *device)
973{ 973{
974 u32 *reg = (u32 *)get_property(device, "reg", NULL); 974 const u32 *reg = get_property(device, "reg", NULL);
975 975
976 if (reg == NULL) 976 if (reg == NULL)
977 return 0; 977 return 0;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 205d04471161..9923adc5248e 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -66,16 +66,16 @@ struct device_node *k2_skiplist[2];
66static int __init fixup_one_level_bus_range(struct device_node *node, int higher) 66static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
67{ 67{
68 for (; node != 0;node = node->sibling) { 68 for (; node != 0;node = node->sibling) {
69 int * bus_range; 69 const int * bus_range;
70 unsigned int *class_code; 70 const unsigned int *class_code;
71 int len; 71 int len;
72 72
73 /* For PCI<->PCI bridges or CardBus bridges, we go down */ 73 /* For PCI<->PCI bridges or CardBus bridges, we go down */
74 class_code = (unsigned int *) get_property(node, "class-code", NULL); 74 class_code = get_property(node, "class-code", NULL);
75 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 75 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
76 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) 76 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
77 continue; 77 continue;
78 bus_range = (int *) get_property(node, "bus-range", &len); 78 bus_range = get_property(node, "bus-range", &len);
79 if (bus_range != NULL && len > 2 * sizeof(int)) { 79 if (bus_range != NULL && len > 2 * sizeof(int)) {
80 if (bus_range[1] > higher) 80 if (bus_range[1] > higher)
81 higher = bus_range[1]; 81 higher = bus_range[1];
@@ -93,13 +93,15 @@ static int __init fixup_one_level_bus_range(struct device_node *node, int higher
93 */ 93 */
94static void __init fixup_bus_range(struct device_node *bridge) 94static void __init fixup_bus_range(struct device_node *bridge)
95{ 95{
96 int * bus_range; 96 int *bus_range, len;
97 int len; 97 struct property *prop;
98 98
99 /* Lookup the "bus-range" property for the hose */ 99 /* Lookup the "bus-range" property for the hose */
100 bus_range = (int *) get_property(bridge, "bus-range", &len); 100 prop = of_find_property(bridge, "bus-range", &len);
101 if (bus_range == NULL || len < 2 * sizeof(int)) 101 if (prop == NULL || prop->length < 2 * sizeof(int))
102 return; 102 return;
103
104 bus_range = (int *)prop->value;
103 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); 105 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
104} 106}
105 107
@@ -237,7 +239,7 @@ static struct pci_ops macrisc_pci_ops =
237static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) 239static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
238{ 240{
239 struct device_node *np; 241 struct device_node *np;
240 u32 *vendor, *device; 242 const u32 *vendor, *device;
241 243
242 if (offset >= 0x100) 244 if (offset >= 0x100)
243 return PCIBIOS_BAD_REGISTER_NUMBER; 245 return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -245,8 +247,8 @@ static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
245 if (np == NULL) 247 if (np == NULL)
246 return PCIBIOS_DEVICE_NOT_FOUND; 248 return PCIBIOS_DEVICE_NOT_FOUND;
247 249
248 vendor = (u32 *)get_property(np, "vendor-id", NULL); 250 vendor = get_property(np, "vendor-id", NULL);
249 device = (u32 *)get_property(np, "device-id", NULL); 251 device = get_property(np, "device-id", NULL);
250 if (vendor == NULL || device == NULL) 252 if (vendor == NULL || device == NULL)
251 return PCIBIOS_DEVICE_NOT_FOUND; 253 return PCIBIOS_DEVICE_NOT_FOUND;
252 254
@@ -686,20 +688,21 @@ static void __init fixup_nec_usb2(void)
686 688
687 for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) { 689 for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
688 struct pci_controller *hose; 690 struct pci_controller *hose;
689 u32 data, *prop; 691 u32 data;
692 const u32 *prop;
690 u8 bus, devfn; 693 u8 bus, devfn;
691 694
692 prop = (u32 *)get_property(nec, "vendor-id", NULL); 695 prop = get_property(nec, "vendor-id", NULL);
693 if (prop == NULL) 696 if (prop == NULL)
694 continue; 697 continue;
695 if (0x1033 != *prop) 698 if (0x1033 != *prop)
696 continue; 699 continue;
697 prop = (u32 *)get_property(nec, "device-id", NULL); 700 prop = get_property(nec, "device-id", NULL);
698 if (prop == NULL) 701 if (prop == NULL)
699 continue; 702 continue;
700 if (0x0035 != *prop) 703 if (0x0035 != *prop)
701 continue; 704 continue;
702 prop = (u32 *)get_property(nec, "reg", NULL); 705 prop = get_property(nec, "reg", NULL);
703 if (prop == NULL) 706 if (prop == NULL)
704 continue; 707 continue;
705 devfn = (prop[0] >> 8) & 0xff; 708 devfn = (prop[0] >> 8) & 0xff;
@@ -898,7 +901,7 @@ static int __init add_bridge(struct device_node *dev)
898 struct pci_controller *hose; 901 struct pci_controller *hose;
899 struct resource rsrc; 902 struct resource rsrc;
900 char *disp_name; 903 char *disp_name;
901 int *bus_range; 904 const int *bus_range;
902 int primary = 1, has_address = 0; 905 int primary = 1, has_address = 0;
903 906
904 DBG("Adding PCI host bridge %s\n", dev->full_name); 907 DBG("Adding PCI host bridge %s\n", dev->full_name);
@@ -907,7 +910,7 @@ static int __init add_bridge(struct device_node *dev)
907 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 910 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
908 911
909 /* Get bus range if any */ 912 /* Get bus range if any */
910 bus_range = (int *) get_property(dev, "bus-range", &len); 913 bus_range = get_property(dev, "bus-range", &len);
911 if (bus_range == NULL || len < 2 * sizeof(int)) { 914 if (bus_range == NULL || len < 2 * sizeof(int)) {
912 printk(KERN_WARNING "Can't get bus-range for %s, assume" 915 printk(KERN_WARNING "Can't get bus-range for %s, assume"
913 " bus 0\n", dev->full_name); 916 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index aacfa59595d1..ee3b223ab17a 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -114,7 +114,7 @@ static void macio_gpio_init_one(struct macio_chip *macio)
114 * we just create them all 114 * we just create them all
115 */ 115 */
116 for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) { 116 for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) {
117 u32 *reg = (u32 *)get_property(gp, "reg", NULL); 117 const u32 *reg = get_property(gp, "reg", NULL);
118 unsigned long offset; 118 unsigned long offset;
119 if (reg == NULL) 119 if (reg == NULL)
120 continue; 120 continue;
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index b117adbf9571..7651f278615a 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -813,14 +813,15 @@ struct pmf_function *__pmf_find_function(struct device_node *target,
813 struct pmf_device *dev; 813 struct pmf_device *dev;
814 struct pmf_function *func, *result = NULL; 814 struct pmf_function *func, *result = NULL;
815 char fname[64]; 815 char fname[64];
816 u32 *prop, ph; 816 const u32 *prop;
817 u32 ph;
817 818
818 /* 819 /*
819 * Look for a "platform-*" function reference. If we can't find 820 * Look for a "platform-*" function reference. If we can't find
820 * one, then we fallback to a direct call attempt 821 * one, then we fallback to a direct call attempt
821 */ 822 */
822 snprintf(fname, 63, "platform-%s", name); 823 snprintf(fname, 63, "platform-%s", name);
823 prop = (u32 *)get_property(target, fname, NULL); 824 prop = get_property(target, fname, NULL);
824 if (prop == NULL) 825 if (prop == NULL)
825 goto find_it; 826 goto find_it;
826 ph = *prop; 827 ph = *prop;
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 31a9da769fa2..824a618396ab 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -116,7 +116,7 @@ extern struct smp_ops_t core99_smp_ops;
116static void pmac_show_cpuinfo(struct seq_file *m) 116static void pmac_show_cpuinfo(struct seq_file *m)
117{ 117{
118 struct device_node *np; 118 struct device_node *np;
119 char *pp; 119 const char *pp;
120 int plen; 120 int plen;
121 int mbmodel; 121 int mbmodel;
122 unsigned int mbflags; 122 unsigned int mbflags;
@@ -134,12 +134,12 @@ static void pmac_show_cpuinfo(struct seq_file *m)
134 seq_printf(m, "machine\t\t: "); 134 seq_printf(m, "machine\t\t: ");
135 np = of_find_node_by_path("/"); 135 np = of_find_node_by_path("/");
136 if (np != NULL) { 136 if (np != NULL) {
137 pp = (char *) get_property(np, "model", NULL); 137 pp = get_property(np, "model", NULL);
138 if (pp != NULL) 138 if (pp != NULL)
139 seq_printf(m, "%s\n", pp); 139 seq_printf(m, "%s\n", pp);
140 else 140 else
141 seq_printf(m, "PowerMac\n"); 141 seq_printf(m, "PowerMac\n");
142 pp = (char *) get_property(np, "compatible", &plen); 142 pp = get_property(np, "compatible", &plen);
143 if (pp != NULL) { 143 if (pp != NULL) {
144 seq_printf(m, "motherboard\t:"); 144 seq_printf(m, "motherboard\t:");
145 while (plen > 0) { 145 while (plen > 0) {
@@ -163,10 +163,8 @@ static void pmac_show_cpuinfo(struct seq_file *m)
163 if (np == NULL) 163 if (np == NULL)
164 np = of_find_node_by_type(NULL, "cache"); 164 np = of_find_node_by_type(NULL, "cache");
165 if (np != NULL) { 165 if (np != NULL) {
166 unsigned int *ic = (unsigned int *) 166 const unsigned int *ic = get_property(np, "i-cache-size", NULL);
167 get_property(np, "i-cache-size", NULL); 167 const unsigned int *dc = get_property(np, "d-cache-size", NULL);
168 unsigned int *dc = (unsigned int *)
169 get_property(np, "d-cache-size", NULL);
170 seq_printf(m, "L2 cache\t:"); 168 seq_printf(m, "L2 cache\t:");
171 has_l2cache = 1; 169 has_l2cache = 1;
172 if (get_property(np, "cache-unified", NULL) != 0 && dc) { 170 if (get_property(np, "cache-unified", NULL) != 0 && dc) {
@@ -254,7 +252,7 @@ static void __init l2cr_init(void)
254 if (np == 0) 252 if (np == 0)
255 np = find_type_devices("cpu"); 253 np = find_type_devices("cpu");
256 if (np != 0) { 254 if (np != 0) {
257 unsigned int *l2cr = (unsigned int *) 255 const unsigned int *l2cr =
258 get_property(np, "l2cr-value", NULL); 256 get_property(np, "l2cr-value", NULL);
259 if (l2cr != 0) { 257 if (l2cr != 0) {
260 ppc_override_l2cr = 1; 258 ppc_override_l2cr = 1;
@@ -277,7 +275,7 @@ static void __init l2cr_init(void)
277static void __init pmac_setup_arch(void) 275static void __init pmac_setup_arch(void)
278{ 276{
279 struct device_node *cpu, *ic; 277 struct device_node *cpu, *ic;
280 int *fp; 278 const int *fp;
281 unsigned long pvr; 279 unsigned long pvr;
282 280
283 pvr = PVR_VER(mfspr(SPRN_PVR)); 281 pvr = PVR_VER(mfspr(SPRN_PVR));
@@ -287,7 +285,7 @@ static void __init pmac_setup_arch(void)
287 loops_per_jiffy = 50000000 / HZ; 285 loops_per_jiffy = 50000000 / HZ;
288 cpu = of_find_node_by_type(NULL, "cpu"); 286 cpu = of_find_node_by_type(NULL, "cpu");
289 if (cpu != NULL) { 287 if (cpu != NULL) {
290 fp = (int *) get_property(cpu, "clock-frequency", NULL); 288 fp = get_property(cpu, "clock-frequency", NULL);
291 if (fp != NULL) { 289 if (fp != NULL) {
292 if (pvr >= 0x30 && pvr < 0x80) 290 if (pvr >= 0x30 && pvr < 0x80)
293 /* PPC970 etc. */ 291 /* PPC970 etc. */
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 827b7121ffb8..653eeb64d1e2 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -548,7 +548,7 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
548 struct device_node *cc = NULL; 548 struct device_node *cc = NULL;
549 struct device_node *p; 549 struct device_node *p;
550 const char *name = NULL; 550 const char *name = NULL;
551 u32 *reg; 551 const u32 *reg;
552 int ok; 552 int ok;
553 553
554 /* Look for the clock chip */ 554 /* Look for the clock chip */
@@ -562,7 +562,7 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
562 pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc); 562 pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc);
563 if (pmac_tb_clock_chip_host == NULL) 563 if (pmac_tb_clock_chip_host == NULL)
564 continue; 564 continue;
565 reg = (u32 *)get_property(cc, "reg", NULL); 565 reg = get_property(cc, "reg", NULL);
566 if (reg == NULL) 566 if (reg == NULL)
567 continue; 567 continue;
568 switch (*reg) { 568 switch (*reg) {
@@ -707,8 +707,7 @@ static void __init smp_core99_setup(int ncpus)
707 core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ 707 core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */
708 cpu = of_find_node_by_type(NULL, "cpu"); 708 cpu = of_find_node_by_type(NULL, "cpu");
709 if (cpu != NULL) { 709 if (cpu != NULL) {
710 tbprop = (u32 *)get_property(cpu, "timebase-enable", 710 tbprop = get_property(cpu, "timebase-enable", NULL);
711 NULL);
712 if (tbprop) 711 if (tbprop)
713 core99_tb_gpio = *tbprop; 712 core99_tb_gpio = *tbprop;
714 of_node_put(cpu); 713 of_node_put(cpu);
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index 37e5b1eff911..ce1a235855f7 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -68,11 +68,11 @@ static unsigned char scc_inittab[] = {
68 68
69void udbg_scc_init(int force_scc) 69void udbg_scc_init(int force_scc)
70{ 70{
71 u32 *reg; 71 const u32 *reg;
72 unsigned long addr; 72 unsigned long addr;
73 struct device_node *stdout = NULL, *escc = NULL, *macio = NULL; 73 struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
74 struct device_node *ch, *ch_def = NULL, *ch_a = NULL; 74 struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
75 char *path; 75 const char *path;
76 int i, x; 76 int i, x;
77 77
78 escc = of_find_node_by_name(NULL, "escc"); 78 escc = of_find_node_by_name(NULL, "escc");
@@ -81,7 +81,7 @@ void udbg_scc_init(int force_scc)
81 macio = of_get_parent(escc); 81 macio = of_get_parent(escc);
82 if (macio == NULL) 82 if (macio == NULL)
83 goto bail; 83 goto bail;
84 path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 84 path = get_property(of_chosen, "linux,stdout-path", NULL);
85 if (path != NULL) 85 if (path != NULL)
86 stdout = of_find_node_by_path(path); 86 stdout = of_find_node_by_path(path);
87 for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) { 87 for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) {
@@ -96,13 +96,13 @@ void udbg_scc_init(int force_scc)
96 ch = ch_def ? ch_def : ch_a; 96 ch = ch_def ? ch_def : ch_a;
97 97
98 /* Get address within mac-io ASIC */ 98 /* Get address within mac-io ASIC */
99 reg = (u32 *)get_property(escc, "reg", NULL); 99 reg = get_property(escc, "reg", NULL);
100 if (reg == NULL) 100 if (reg == NULL)
101 goto bail; 101 goto bail;
102 addr = reg[0]; 102 addr = reg[0];
103 103
104 /* Get address of mac-io PCI itself */ 104 /* Get address of mac-io PCI itself */
105 reg = (u32 *)get_property(macio, "assigned-addresses", NULL); 105 reg = get_property(macio, "assigned-addresses", NULL);
106 if (reg == NULL) 106 if (reg == NULL)
107 goto bail; 107 goto bail;
108 addr += reg[2]; 108 addr += reg[2];
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index e5e0ff466904..997243a91be8 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o
12 12
13obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o 13obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
14obj-$(CONFIG_HVCS) += hvcserver.o 14obj-$(CONFIG_HVCS) += hvcserver.o
15obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 32eaddfa5470..84bc8f7e17ef 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -449,7 +449,11 @@ EXPORT_SYMBOL(eeh_check_failure);
449/* ------------------------------------------------------------- */ 449/* ------------------------------------------------------------- */
450/* The code below deals with error recovery */ 450/* The code below deals with error recovery */
451 451
452/** Return negative value if a permanent error, else return 452/**
453 * eeh_slot_availability - returns error status of slot
454 * @pdn pci device node
455 *
456 * Return negative value if a permanent error, else return
453 * a number of milliseconds to wait until the PCI slot is 457 * a number of milliseconds to wait until the PCI slot is
454 * ready to be used. 458 * ready to be used.
455 */ 459 */
@@ -474,11 +478,42 @@ eeh_slot_availability(struct pci_dn *pdn)
474 478
475 printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n", 479 printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n",
476 rc, rets[0], rets[1], rets[2]); 480 rc, rets[0], rets[1], rets[2]);
477 return -1; 481 return -2;
482}
483
484/**
485 * rtas_pci_enable - enable MMIO or DMA transfers for this slot
486 * @pdn pci device node
487 */
488
489int
490rtas_pci_enable(struct pci_dn *pdn, int function)
491{
492 int config_addr;
493 int rc;
494
495 /* Use PE configuration address, if present */
496 config_addr = pdn->eeh_config_addr;
497 if (pdn->eeh_pe_config_addr)
498 config_addr = pdn->eeh_pe_config_addr;
499
500 rc = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
501 config_addr,
502 BUID_HI(pdn->phb->buid),
503 BUID_LO(pdn->phb->buid),
504 function);
505
506 if (rc)
507 printk(KERN_WARNING "EEH: Cannot enable function %d, err=%d dn=%s\n",
508 function, rc, pdn->node->full_name);
509
510 return rc;
478} 511}
479 512
480/** rtas_pci_slot_reset raises/lowers the pci #RST line 513/**
481 * state: 1/0 to raise/lower the #RST 514 * rtas_pci_slot_reset - raises/lowers the pci #RST line
515 * @pdn pci device node
516 * @state: 1/0 to raise/lower the #RST
482 * 517 *
483 * Clear the EEH-frozen condition on a slot. This routine 518 * Clear the EEH-frozen condition on a slot. This routine
484 * asserts the PCI #RST line if the 'state' argument is '1', 519 * asserts the PCI #RST line if the 'state' argument is '1',
@@ -511,24 +546,21 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
511 BUID_HI(pdn->phb->buid), 546 BUID_HI(pdn->phb->buid),
512 BUID_LO(pdn->phb->buid), 547 BUID_LO(pdn->phb->buid),
513 state); 548 state);
514 if (rc) { 549 if (rc)
515 printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n", 550 printk (KERN_WARNING "EEH: Unable to reset the failed slot,"
551 " (%d) #RST=%d dn=%s\n",
516 rc, state, pdn->node->full_name); 552 rc, state, pdn->node->full_name);
517 return;
518 }
519} 553}
520 554
521/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second 555/**
522 * dn -- device node to be reset. 556 * rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
557 * @pdn: pci device node to be reset.
523 * 558 *
524 * Return 0 if success, else a non-zero value. 559 * Return 0 if success, else a non-zero value.
525 */ 560 */
526 561
527int 562static void __rtas_set_slot_reset(struct pci_dn *pdn)
528rtas_set_slot_reset(struct pci_dn *pdn)
529{ 563{
530 int i, rc;
531
532 rtas_pci_slot_reset (pdn, 1); 564 rtas_pci_slot_reset (pdn, 1);
533 565
534 /* The PCI bus requires that the reset be held high for at least 566 /* The PCI bus requires that the reset be held high for at least
@@ -549,17 +581,33 @@ rtas_set_slot_reset(struct pci_dn *pdn)
549 * up traffic. */ 581 * up traffic. */
550#define PCI_BUS_SETTLE_TIME_MSEC 1800 582#define PCI_BUS_SETTLE_TIME_MSEC 1800
551 msleep (PCI_BUS_SETTLE_TIME_MSEC); 583 msleep (PCI_BUS_SETTLE_TIME_MSEC);
584}
585
586int rtas_set_slot_reset(struct pci_dn *pdn)
587{
588 int i, rc;
589
590 __rtas_set_slot_reset(pdn);
552 591
553 /* Now double check with the firmware to make sure the device is 592 /* Now double check with the firmware to make sure the device is
554 * ready to be used; if not, wait for recovery. */ 593 * ready to be used; if not, wait for recovery. */
555 for (i=0; i<10; i++) { 594 for (i=0; i<10; i++) {
556 rc = eeh_slot_availability (pdn); 595 rc = eeh_slot_availability (pdn);
557 if (rc < 0)
558 printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name);
559 if (rc == 0) 596 if (rc == 0)
560 return 0; 597 return 0;
561 if (rc < 0) 598
599 if (rc == -2) {
600 printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n",
601 i, pdn->node->full_name);
602 __rtas_set_slot_reset(pdn);
603 continue;
604 }
605
606 if (rc < 0) {
607 printk (KERN_ERR "EEH: unrecoverable slot failure %s\n",
608 pdn->node->full_name);
562 return -1; 609 return -1;
610 }
563 611
564 msleep (rc+100); 612 msleep (rc+100);
565 } 613 }
@@ -582,6 +630,8 @@ rtas_set_slot_reset(struct pci_dn *pdn)
582 630
583/** 631/**
584 * __restore_bars - Restore the Base Address Registers 632 * __restore_bars - Restore the Base Address Registers
633 * @pdn: pci device node
634 *
585 * Loads the PCI configuration space base address registers, 635 * Loads the PCI configuration space base address registers,
586 * the expansion ROM base address, the latency timer, and etc. 636 * the expansion ROM base address, the latency timer, and etc.
587 * from the saved values in the device node. 637 * from the saved values in the device node.
@@ -691,11 +741,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
691{ 741{
692 struct eeh_early_enable_info *info = data; 742 struct eeh_early_enable_info *info = data;
693 int ret; 743 int ret;
694 char *status = get_property(dn, "status", NULL); 744 const char *status = get_property(dn, "status", NULL);
695 u32 *class_code = (u32 *)get_property(dn, "class-code", NULL); 745 const u32 *class_code = get_property(dn, "class-code", NULL);
696 u32 *vendor_id = (u32 *)get_property(dn, "vendor-id", NULL); 746 const u32 *vendor_id = get_property(dn, "vendor-id", NULL);
697 u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); 747 const u32 *device_id = get_property(dn, "device-id", NULL);
698 u32 *regs; 748 const u32 *regs;
699 int enable; 749 int enable;
700 struct pci_dn *pdn = PCI_DN(dn); 750 struct pci_dn *pdn = PCI_DN(dn);
701 751
@@ -737,7 +787,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
737 787
738 /* Ok... see if this device supports EEH. Some do, some don't, 788 /* Ok... see if this device supports EEH. Some do, some don't,
739 * and the only way to find out is to check each and every one. */ 789 * and the only way to find out is to check each and every one. */
740 regs = (u32 *)get_property(dn, "reg", NULL); 790 regs = get_property(dn, "reg", NULL);
741 if (regs) { 791 if (regs) {
742 /* First register entry is addr (00BBSS00) */ 792 /* First register entry is addr (00BBSS00) */
743 /* Try to enable eeh */ 793 /* Try to enable eeh */
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index c37a8497c60f..b6b462d3c604 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -157,6 +157,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
157 if (!piar) 157 if (!piar)
158 return NULL; 158 return NULL;
159 159
160 pci_dev_get(dev);
160 piar->addr_lo = alo; 161 piar->addr_lo = alo;
161 piar->addr_hi = ahi; 162 piar->addr_hi = ahi;
162 piar->pcidev = dev; 163 piar->pcidev = dev;
@@ -178,7 +179,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
178 struct device_node *dn; 179 struct device_node *dn;
179 struct pci_dn *pdn; 180 struct pci_dn *pdn;
180 int i; 181 int i;
181 int inserted = 0;
182 182
183 dn = pci_device_to_OF_node(dev); 183 dn = pci_device_to_OF_node(dev);
184 if (!dn) { 184 if (!dn) {
@@ -197,9 +197,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
197 return; 197 return;
198 } 198 }
199 199
200 /* The cache holds a reference to the device... */
201 pci_dev_get(dev);
202
203 /* Walk resources on this device, poke them into the tree */ 200 /* Walk resources on this device, poke them into the tree */
204 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 201 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
205 unsigned long start = pci_resource_start(dev,i); 202 unsigned long start = pci_resource_start(dev,i);
@@ -212,12 +209,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
212 if (start == 0 || ~start == 0 || end == 0 || ~end == 0) 209 if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
213 continue; 210 continue;
214 pci_addr_cache_insert(dev, start, end, flags); 211 pci_addr_cache_insert(dev, start, end, flags);
215 inserted = 1;
216 } 212 }
217
218 /* If there was nothing to add, the cache has no reference... */
219 if (!inserted)
220 pci_dev_put(dev);
221} 213}
222 214
223/** 215/**
@@ -240,7 +232,6 @@ void pci_addr_cache_insert_device(struct pci_dev *dev)
240static inline void __pci_addr_cache_remove_device(struct pci_dev *dev) 232static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
241{ 233{
242 struct rb_node *n; 234 struct rb_node *n;
243 int removed = 0;
244 235
245restart: 236restart:
246 n = rb_first(&pci_io_addr_cache_root.rb_root); 237 n = rb_first(&pci_io_addr_cache_root.rb_root);
@@ -250,16 +241,12 @@ restart:
250 241
251 if (piar->pcidev == dev) { 242 if (piar->pcidev == dev) {
252 rb_erase(n, &pci_io_addr_cache_root.rb_root); 243 rb_erase(n, &pci_io_addr_cache_root.rb_root);
253 removed = 1; 244 pci_dev_put(piar->pcidev);
254 kfree(piar); 245 kfree(piar);
255 goto restart; 246 goto restart;
256 } 247 }
257 n = rb_next(n); 248 n = rb_next(n);
258 } 249 }
259
260 /* The cache no longer holds its reference to this device... */
261 if (removed)
262 pci_dev_put(dev);
263} 250}
264 251
265/** 252/**
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index aaad2c0afcbf..c2bc9904f1cb 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -77,8 +77,12 @@ static int irq_in_use(unsigned int irq)
77} 77}
78 78
79/* ------------------------------------------------------- */ 79/* ------------------------------------------------------- */
80/** eeh_report_error - report an EEH error to each device, 80/**
81 * collect up and merge the device responses. 81 * eeh_report_error - report pci error to each device driver
82 *
83 * Report an EEH error to each device driver, collect up and
84 * merge the device driver responses. Cumulative response
85 * passed back in "userdata".
82 */ 86 */
83 87
84static void eeh_report_error(struct pci_dev *dev, void *userdata) 88static void eeh_report_error(struct pci_dev *dev, void *userdata)
@@ -96,24 +100,49 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
96 PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED; 100 PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
97 disable_irq_nosync(dev->irq); 101 disable_irq_nosync(dev->irq);
98 } 102 }
99 if (!driver->err_handler) 103 if (!driver->err_handler ||
100 return; 104 !driver->err_handler->error_detected)
101 if (!driver->err_handler->error_detected)
102 return; 105 return;
103 106
104 rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen); 107 rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
105 if (*res == PCI_ERS_RESULT_NONE) *res = rc; 108 if (*res == PCI_ERS_RESULT_NONE) *res = rc;
106 if (*res == PCI_ERS_RESULT_NEED_RESET) return;
107 if (*res == PCI_ERS_RESULT_DISCONNECT && 109 if (*res == PCI_ERS_RESULT_DISCONNECT &&
108 rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; 110 rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
109} 111}
110 112
111/** eeh_report_reset -- tell this device that the pci slot 113/**
112 * has been reset. 114 * eeh_report_mmio_enabled - tell drivers that MMIO has been enabled
115 *
116 * Report an EEH error to each device driver, collect up and
117 * merge the device driver responses. Cumulative response
118 * passed back in "userdata".
119 */
120
121static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
122{
123 enum pci_ers_result rc, *res = userdata;
124 struct pci_driver *driver = dev->driver;
125
126 // dev->error_state = pci_channel_mmio_enabled;
127
128 if (!driver ||
129 !driver->err_handler ||
130 !driver->err_handler->mmio_enabled)
131 return;
132
133 rc = driver->err_handler->mmio_enabled (dev);
134 if (*res == PCI_ERS_RESULT_NONE) *res = rc;
135 if (*res == PCI_ERS_RESULT_DISCONNECT &&
136 rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
137}
138
139/**
140 * eeh_report_reset - tell device that slot has been reset
113 */ 141 */
114 142
115static void eeh_report_reset(struct pci_dev *dev, void *userdata) 143static void eeh_report_reset(struct pci_dev *dev, void *userdata)
116{ 144{
145 enum pci_ers_result rc, *res = userdata;
117 struct pci_driver *driver = dev->driver; 146 struct pci_driver *driver = dev->driver;
118 struct device_node *dn = pci_device_to_OF_node(dev); 147 struct device_node *dn = pci_device_to_OF_node(dev);
119 148
@@ -124,14 +153,20 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata)
124 PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; 153 PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
125 enable_irq(dev->irq); 154 enable_irq(dev->irq);
126 } 155 }
127 if (!driver->err_handler) 156 if (!driver->err_handler ||
128 return; 157 !driver->err_handler->slot_reset)
129 if (!driver->err_handler->slot_reset)
130 return; 158 return;
131 159
132 driver->err_handler->slot_reset(dev); 160 rc = driver->err_handler->slot_reset(dev);
161 if (*res == PCI_ERS_RESULT_NONE) *res = rc;
162 if (*res == PCI_ERS_RESULT_DISCONNECT &&
163 rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
133} 164}
134 165
166/**
167 * eeh_report_resume - tell device to resume normal operations
168 */
169
135static void eeh_report_resume(struct pci_dev *dev, void *userdata) 170static void eeh_report_resume(struct pci_dev *dev, void *userdata)
136{ 171{
137 struct pci_driver *driver = dev->driver; 172 struct pci_driver *driver = dev->driver;
@@ -148,6 +183,13 @@ static void eeh_report_resume(struct pci_dev *dev, void *userdata)
148 driver->err_handler->resume(dev); 183 driver->err_handler->resume(dev);
149} 184}
150 185
186/**
187 * eeh_report_failure - tell device driver that device is dead.
188 *
189 * This informs the device driver that the device is permanently
190 * dead, and that no further recovery attempts will be made on it.
191 */
192
151static void eeh_report_failure(struct pci_dev *dev, void *userdata) 193static void eeh_report_failure(struct pci_dev *dev, void *userdata)
152{ 194{
153 struct pci_driver *driver = dev->driver; 195 struct pci_driver *driver = dev->driver;
@@ -190,11 +232,11 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)
190 232
191/** 233/**
192 * eeh_reset_device() -- perform actual reset of a pci slot 234 * eeh_reset_device() -- perform actual reset of a pci slot
193 * Args: bus: pointer to the pci bus structure corresponding 235 * @bus: pointer to the pci bus structure corresponding
194 * to the isolated slot. A non-null value will 236 * to the isolated slot. A non-null value will
195 * cause all devices under the bus to be removed 237 * cause all devices under the bus to be removed
196 * and then re-added. 238 * and then re-added.
197 * pe_dn: pointer to a "Partionable Endpoint" device node. 239 * @pe_dn: pointer to a "Partionable Endpoint" device node.
198 * This is the top-level structure on which pci 240 * This is the top-level structure on which pci
199 * bus resets can be performed. 241 * bus resets can be performed.
200 */ 242 */
@@ -268,14 +310,14 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
268 310
269 if (!frozen_dn) { 311 if (!frozen_dn) {
270 312
271 location = (char *) get_property(event->dn, "ibm,loc-code", NULL); 313 location = get_property(event->dn, "ibm,loc-code", NULL);
272 location = location ? location : "unknown"; 314 location = location ? location : "unknown";
273 printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " 315 printk(KERN_ERR "EEH: Error: Cannot find partition endpoint "
274 "for location=%s pci addr=%s\n", 316 "for location=%s pci addr=%s\n",
275 location, pci_name(event->dev)); 317 location, pci_name(event->dev));
276 return NULL; 318 return NULL;
277 } 319 }
278 location = (char *) get_property(frozen_dn, "ibm,loc-code", NULL); 320 location = get_property(frozen_dn, "ibm,loc-code", NULL);
279 location = location ? location : "unknown"; 321 location = location ? location : "unknown";
280 322
281 /* There are two different styles for coming up with the PE. 323 /* There are two different styles for coming up with the PE.
@@ -347,23 +389,43 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
347 goto hard_fail; 389 goto hard_fail;
348 } 390 }
349 391
350 /* If any device called out for a reset, then reset the slot */ 392 /* If all devices reported they can proceed, then re-enable MMIO */
351 if (result == PCI_ERS_RESULT_NEED_RESET) { 393 if (result == PCI_ERS_RESULT_CAN_RECOVER) {
352 rc = eeh_reset_device(frozen_pdn, NULL); 394 rc = rtas_pci_enable(frozen_pdn, EEH_THAW_MMIO);
353 if (rc) 395
354 goto hard_fail; 396 if (rc) {
355 pci_walk_bus(frozen_bus, eeh_report_reset, NULL); 397 result = PCI_ERS_RESULT_NEED_RESET;
398 } else {
399 result = PCI_ERS_RESULT_NONE;
400 pci_walk_bus(frozen_bus, eeh_report_mmio_enabled, &result);
401 }
356 } 402 }
357 403
358 /* If all devices reported they can proceed, the re-enable PIO */ 404 /* If all devices reported they can proceed, then re-enable DMA */
359 if (result == PCI_ERS_RESULT_CAN_RECOVER) { 405 if (result == PCI_ERS_RESULT_CAN_RECOVER) {
360 /* XXX Not supported; we brute-force reset the device */ 406 rc = rtas_pci_enable(frozen_pdn, EEH_THAW_DMA);
407
408 if (rc)
409 result = PCI_ERS_RESULT_NEED_RESET;
410 }
411
412 /* If any device has a hard failure, then shut off everything. */
413 if (result == PCI_ERS_RESULT_DISCONNECT)
414 goto hard_fail;
415
416 /* If any device called out for a reset, then reset the slot */
417 if (result == PCI_ERS_RESULT_NEED_RESET) {
361 rc = eeh_reset_device(frozen_pdn, NULL); 418 rc = eeh_reset_device(frozen_pdn, NULL);
362 if (rc) 419 if (rc)
363 goto hard_fail; 420 goto hard_fail;
364 pci_walk_bus(frozen_bus, eeh_report_reset, NULL); 421 result = PCI_ERS_RESULT_NONE;
422 pci_walk_bus(frozen_bus, eeh_report_reset, &result);
365 } 423 }
366 424
425 /* All devices should claim they have recovered by now. */
426 if (result != PCI_ERS_RESULT_RECOVERED)
427 goto hard_fail;
428
367 /* Tell all device drivers that they can resume operations */ 429 /* Tell all device drivers that they can resume operations */
368 pci_walk_bus(frozen_bus, eeh_report_resume, NULL); 430 pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
369 431
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index 45ccc687e57c..137077451316 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -124,11 +124,11 @@ int eeh_send_failure_event (struct device_node *dn,
124{ 124{
125 unsigned long flags; 125 unsigned long flags;
126 struct eeh_event *event; 126 struct eeh_event *event;
127 char *location; 127 const char *location;
128 128
129 if (!mem_init_done) { 129 if (!mem_init_done) {
130 printk(KERN_ERR "EEH: event during early boot not handled\n"); 130 printk(KERN_ERR "EEH: event during early boot not handled\n");
131 location = (char *) get_property(dn, "ibm,loc-code", NULL); 131 location = get_property(dn, "ibm,loc-code", NULL);
132 printk(KERN_ERR "EEH: device node = %s\n", dn->full_name); 132 printk(KERN_ERR "EEH: device node = %s\n", dn->full_name);
133 printk(KERN_ERR "EEH: PCI location = %s\n", location); 133 printk(KERN_ERR "EEH: PCI location = %s\n", location);
134 return 1; 134 return 1;
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index c01d8f0cbe6d..1c7b2baa5f73 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -68,7 +68,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
68void __init fw_feature_init(void) 68void __init fw_feature_init(void)
69{ 69{
70 struct device_node *dn; 70 struct device_node *dn;
71 char *hypertas, *s; 71 const char *hypertas, *s;
72 int len, i; 72 int len, i;
73 73
74 DBG(" -> fw_feature_init()\n"); 74 DBG(" -> fw_feature_init()\n");
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index c9ff547f9d25..c00cfed7af2c 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -1,7 +1,6 @@
1/* 1/*
2 * This file contains the generic code to perform a call to the 2 * This file contains the generic code to perform a call to the
3 * pSeries LPAR hypervisor. 3 * pSeries LPAR hypervisor.
4 * NOTE: this file will go away when we move to inline this work.
5 * 4 *
6 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
@@ -11,217 +10,153 @@
11#include <asm/hvcall.h> 10#include <asm/hvcall.h>
12#include <asm/processor.h> 11#include <asm/processor.h>
13#include <asm/ppc_asm.h> 12#include <asm/ppc_asm.h>
13#include <asm/asm-offsets.h>
14 14
15#define STK_PARM(i) (48 + ((i)-3)*8) 15#define STK_PARM(i) (48 + ((i)-3)*8)
16 16
17 .text 17#ifdef CONFIG_HCALL_STATS
18 18/*
19/* long plpar_hcall(unsigned long opcode, R3 19 * precall must preserve all registers. use unused STK_PARM()
20 unsigned long arg1, R4 20 * areas to save snapshots and opcode.
21 unsigned long arg2, R5
22 unsigned long arg3, R6
23 unsigned long arg4, R7
24 unsigned long *out1, R8
25 unsigned long *out2, R9
26 unsigned long *out3); R10
27 */ 21 */
28_GLOBAL(plpar_hcall) 22#define HCALL_INST_PRECALL \
29 HMT_MEDIUM 23 std r3,STK_PARM(r3)(r1); /* save opcode */ \
30 24 mftb r0; /* get timebase and */ \
31 mfcr r0 25 std r0,STK_PARM(r5)(r1); /* save for later */ \
32 26BEGIN_FTR_SECTION; \
33 std r8,STK_PARM(r8)(r1) /* Save out ptrs */ 27 mfspr r0,SPRN_PURR; /* get PURR and */ \
34 std r9,STK_PARM(r9)(r1) 28 std r0,STK_PARM(r6)(r1); /* save for later */ \
35 std r10,STK_PARM(r10)(r1) 29END_FTR_SECTION_IFCLR(CPU_FTR_PURR);
36 30
37 stw r0,8(r1) 31/*
38 32 * postcall is performed immediately before function return which
39 HVSC /* invoke the hypervisor */ 33 * allows liberal use of volatile registers.
40 34 */
41 lwz r0,8(r1) 35#define HCALL_INST_POSTCALL \
42 36 ld r4,STK_PARM(r3)(r1); /* validate opcode */ \
43 ld r8,STK_PARM(r8)(r1) /* Fetch r4-r6 ret args */ 37 cmpldi cr7,r4,MAX_HCALL_OPCODE; \
44 ld r9,STK_PARM(r9)(r1) 38 bgt- cr7,1f; \
45 ld r10,STK_PARM(r10)(r1) 39 \
46 std r4,0(r8) 40 /* get time and PURR snapshots after hcall */ \
47 std r5,0(r9) 41 mftb r7; /* timebase after */ \
48 std r6,0(r10) 42BEGIN_FTR_SECTION; \
49 43 mfspr r8,SPRN_PURR; /* PURR after */ \
50 mtcrf 0xff,r0 44 ld r6,STK_PARM(r6)(r1); /* PURR before */ \
51 blr /* return r3 = status */ 45 subf r6,r6,r8; /* delta */ \
46END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
47 ld r5,STK_PARM(r5)(r1); /* timebase before */ \
48 subf r5,r5,r7; /* time delta */ \
49 \
50 /* calculate address of stat structure r4 = opcode */ \
51 srdi r4,r4,2; /* index into array */ \
52 mulli r4,r4,HCALL_STAT_SIZE; \
53 LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \
54 add r4,r4,r7; \
55 ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \
56 add r4,r4,r7; \
57 \
58 /* update stats */ \
59 ld r7,HCALL_STAT_CALLS(r4); /* count */ \
60 addi r7,r7,1; \
61 std r7,HCALL_STAT_CALLS(r4); \
62 ld r7,HCALL_STAT_TB(r4); /* timebase */ \
63 add r7,r7,r5; \
64 std r7,HCALL_STAT_TB(r4); \
65BEGIN_FTR_SECTION; \
66 ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
67 add r7,r7,r6; \
68 std r7,HCALL_STAT_PURR(r4); \
69END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
701:
71#else
72#define HCALL_INST_PRECALL
73#define HCALL_INST_POSTCALL
74#endif
52 75
76 .text
53 77
54/* Simple interface with no output values (other than status) */
55_GLOBAL(plpar_hcall_norets) 78_GLOBAL(plpar_hcall_norets)
56 HMT_MEDIUM 79 HMT_MEDIUM
57 80
58 mfcr r0 81 mfcr r0
59 stw r0,8(r1) 82 stw r0,8(r1)
60 83
61 HVSC /* invoke the hypervisor */ 84 HCALL_INST_PRECALL
62
63 lwz r0,8(r1)
64 mtcrf 0xff,r0
65 blr /* return r3 = status */
66
67
68/* long plpar_hcall_8arg_2ret(unsigned long opcode, R3
69 unsigned long arg1, R4
70 unsigned long arg2, R5
71 unsigned long arg3, R6
72 unsigned long arg4, R7
73 unsigned long arg5, R8
74 unsigned long arg6, R9
75 unsigned long arg7, R10
76 unsigned long arg8, 112(R1)
77 unsigned long *out1); 120(R1)
78 */
79_GLOBAL(plpar_hcall_8arg_2ret)
80 HMT_MEDIUM
81
82 mfcr r0
83 ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */
84 stw r0,8(r1)
85 85
86 HVSC /* invoke the hypervisor */ 86 HVSC /* invoke the hypervisor */
87 87
88 HCALL_INST_POSTCALL
89
88 lwz r0,8(r1) 90 lwz r0,8(r1)
89 ld r10,STK_PARM(r12)(r1) /* Fetch r4 ret arg */
90 std r4,0(r10)
91 mtcrf 0xff,r0 91 mtcrf 0xff,r0
92 blr /* return r3 = status */ 92 blr /* return r3 = status */
93 93
94 94_GLOBAL(plpar_hcall)
95/* long plpar_hcall_4out(unsigned long opcode, R3
96 unsigned long arg1, R4
97 unsigned long arg2, R5
98 unsigned long arg3, R6
99 unsigned long arg4, R7
100 unsigned long *out1, R8
101 unsigned long *out2, R9
102 unsigned long *out3, R10
103 unsigned long *out4); 112(R1)
104 */
105_GLOBAL(plpar_hcall_4out)
106 HMT_MEDIUM 95 HMT_MEDIUM
107 96
108 mfcr r0 97 mfcr r0
109 stw r0,8(r1) 98 stw r0,8(r1)
110 99
111 std r8,STK_PARM(r8)(r1) /* Save out ptrs */ 100 HCALL_INST_PRECALL
112 std r9,STK_PARM(r9)(r1)
113 std r10,STK_PARM(r10)(r1)
114
115 HVSC /* invoke the hypervisor */
116
117 lwz r0,8(r1)
118 101
119 ld r8,STK_PARM(r8)(r1) /* Fetch r4-r7 ret args */ 102 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
120 ld r9,STK_PARM(r9)(r1)
121 ld r10,STK_PARM(r10)(r1)
122 ld r11,STK_PARM(r11)(r1)
123 std r4,0(r8)
124 std r5,0(r9)
125 std r6,0(r10)
126 std r7,0(r11)
127 103
128 mtcrf 0xff,r0 104 mr r4,r5
129 blr /* return r3 = status */ 105 mr r5,r6
130 106 mr r6,r7
131/* plpar_hcall_7arg_7ret(unsigned long opcode, R3 107 mr r7,r8
132 unsigned long arg1, R4 108 mr r8,r9
133 unsigned long arg2, R5 109 mr r9,r10
134 unsigned long arg3, R6
135 unsigned long arg4, R7
136 unsigned long arg5, R8
137 unsigned long arg6, R9
138 unsigned long arg7, R10
139 unsigned long *out1, 112(R1)
140 unsigned long *out2, 110(R1)
141 unsigned long *out3, 108(R1)
142 unsigned long *out4, 106(R1)
143 unsigned long *out5, 104(R1)
144 unsigned long *out6, 102(R1)
145 unsigned long *out7); 100(R1)
146*/
147_GLOBAL(plpar_hcall_7arg_7ret)
148 HMT_MEDIUM
149
150 mfcr r0
151 stw r0,8(r1)
152 110
153 HVSC /* invoke the hypervisor */ 111 HVSC /* invoke the hypervisor */
154 112
155 lwz r0,8(r1) 113 ld r12,STK_PARM(r4)(r1)
114 std r4, 0(r12)
115 std r5, 8(r12)
116 std r6, 16(r12)
117 std r7, 24(r12)
156 118
157 ld r11,STK_PARM(r11)(r1) /* Fetch r4 ret arg */ 119 HCALL_INST_POSTCALL
158 std r4,0(r11)
159 ld r11,STK_PARM(r12)(r1) /* Fetch r5 ret arg */
160 std r5,0(r11)
161 ld r11,STK_PARM(r13)(r1) /* Fetch r6 ret arg */
162 std r6,0(r11)
163 ld r11,STK_PARM(r14)(r1) /* Fetch r7 ret arg */
164 std r7,0(r11)
165 ld r11,STK_PARM(r15)(r1) /* Fetch r8 ret arg */
166 std r8,0(r11)
167 ld r11,STK_PARM(r16)(r1) /* Fetch r9 ret arg */
168 std r9,0(r11)
169 ld r11,STK_PARM(r17)(r1) /* Fetch r10 ret arg */
170 std r10,0(r11)
171 120
121 lwz r0,8(r1)
172 mtcrf 0xff,r0 122 mtcrf 0xff,r0
173 123
174 blr /* return r3 = status */ 124 blr /* return r3 = status */
175 125
176/* plpar_hcall_9arg_9ret(unsigned long opcode, R3 126_GLOBAL(plpar_hcall9)
177 unsigned long arg1, R4
178 unsigned long arg2, R5
179 unsigned long arg3, R6
180 unsigned long arg4, R7
181 unsigned long arg5, R8
182 unsigned long arg6, R9
183 unsigned long arg7, R10
184 unsigned long arg8, 112(R1)
185 unsigned long arg9, 110(R1)
186 unsigned long *out1, 108(R1)
187 unsigned long *out2, 106(R1)
188 unsigned long *out3, 104(R1)
189 unsigned long *out4, 102(R1)
190 unsigned long *out5, 100(R1)
191 unsigned long *out6, 98(R1)
192 unsigned long *out7); 96(R1)
193 unsigned long *out8, 94(R1)
194 unsigned long *out9, 92(R1)
195*/
196_GLOBAL(plpar_hcall_9arg_9ret)
197 HMT_MEDIUM 127 HMT_MEDIUM
198 128
199 mfcr r0 129 mfcr r0
200 stw r0,8(r1) 130 stw r0,8(r1)
201 131
202 ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ 132 HCALL_INST_PRECALL
203 ld r12,STK_PARM(r12)(r1) /* put arg9 in R12 */ 133
134 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
135
136 mr r4,r5
137 mr r5,r6
138 mr r6,r7
139 mr r7,r8
140 mr r8,r9
141 mr r9,r10
142 ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */
143 ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */
144 ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */
204 145
205 HVSC /* invoke the hypervisor */ 146 HVSC /* invoke the hypervisor */
206 147
207 ld r0,STK_PARM(r13)(r1) /* Fetch r4 ret arg */ 148 ld r12,STK_PARM(r4)(r1)
208 stdx r4,r0,r0 149 std r4, 0(r12)
209 ld r0,STK_PARM(r14)(r1) /* Fetch r5 ret arg */ 150 std r5, 8(r12)
210 stdx r5,r0,r0 151 std r6, 16(r12)
211 ld r0,STK_PARM(r15)(r1) /* Fetch r6 ret arg */ 152 std r7, 24(r12)
212 stdx r6,r0,r0 153 std r8, 32(r12)
213 ld r0,STK_PARM(r16)(r1) /* Fetch r7 ret arg */ 154 std r9, 40(r12)
214 stdx r7,r0,r0 155 std r10,48(r12)
215 ld r0,STK_PARM(r17)(r1) /* Fetch r8 ret arg */ 156 std r11,56(r12)
216 stdx r8,r0,r0 157 std r12,64(r12)
217 ld r0,STK_PARM(r18)(r1) /* Fetch r9 ret arg */ 158
218 stdx r9,r0,r0 159 HCALL_INST_POSTCALL
219 ld r0,STK_PARM(r19)(r1) /* Fetch r10 ret arg */
220 stdx r10,r0,r0
221 ld r0,STK_PARM(r20)(r1) /* Fetch r11 ret arg */
222 stdx r11,r0,r0
223 ld r0,STK_PARM(r21)(r1) /* Fetch r12 ret arg */
224 stdx r12,r0,r0
225 160
226 lwz r0,8(r1) 161 lwz r0,8(r1)
227 mtcrf 0xff,r0 162 mtcrf 0xff,r0
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
new file mode 100644
index 000000000000..641e6511cf06
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (C) 2006 Mike Kravetz IBM Corporation
3 *
4 * Hypervisor Call Instrumentation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/percpu.h>
23#include <linux/debugfs.h>
24#include <linux/seq_file.h>
25#include <linux/cpumask.h>
26#include <asm/hvcall.h>
27#include <asm/firmware.h>
28#include <asm/cputable.h>
29
30DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
31
32/*
33 * Routines for displaying the statistics in debugfs
34 */
35static void *hc_start(struct seq_file *m, loff_t *pos)
36{
37 if ((int)*pos < HCALL_STAT_ARRAY_SIZE)
38 return (void *)(unsigned long)(*pos + 1);
39
40 return NULL;
41}
42
43static void *hc_next(struct seq_file *m, void *p, loff_t * pos)
44{
45 ++*pos;
46
47 return hc_start(m, pos);
48}
49
50static void hc_stop(struct seq_file *m, void *p)
51{
52}
53
54static int hc_show(struct seq_file *m, void *p)
55{
56 unsigned long h_num = (unsigned long)p;
57 struct hcall_stats *hs = (struct hcall_stats *)m->private;
58
59 if (hs[h_num].num_calls) {
60 if (!cpu_has_feature(CPU_FTR_PURR))
61 seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2,
62 hs[h_num].num_calls,
63 hs[h_num].tb_total,
64 hs[h_num].purr_total);
65 else
66 seq_printf(m, "%lu %lu %lu\n", h_num<<2,
67 hs[h_num].num_calls,
68 hs[h_num].tb_total);
69 }
70
71 return 0;
72}
73
74static struct seq_operations hcall_inst_seq_ops = {
75 .start = hc_start,
76 .next = hc_next,
77 .stop = hc_stop,
78 .show = hc_show
79};
80
81static int hcall_inst_seq_open(struct inode *inode, struct file *file)
82{
83 int rc;
84 struct seq_file *seq;
85
86 rc = seq_open(file, &hcall_inst_seq_ops);
87 seq = file->private_data;
88 seq->private = file->f_dentry->d_inode->u.generic_ip;
89
90 return rc;
91}
92
93static struct file_operations hcall_inst_seq_fops = {
94 .open = hcall_inst_seq_open,
95 .read = seq_read,
96 .llseek = seq_lseek,
97 .release = seq_release,
98};
99
100#define HCALL_ROOT_DIR "hcall_inst"
101#define CPU_NAME_BUF_SIZE 32
102
103static int __init hcall_inst_init(void)
104{
105 struct dentry *hcall_root;
106 struct dentry *hcall_file;
107 char cpu_name_buf[CPU_NAME_BUF_SIZE];
108 int cpu;
109
110 if (!firmware_has_feature(FW_FEATURE_LPAR))
111 return 0;
112
113 hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL);
114 if (!hcall_root)
115 return -ENOMEM;
116
117 for_each_possible_cpu(cpu) {
118 snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu);
119 hcall_file = debugfs_create_file(cpu_name_buf, S_IRUGO,
120 hcall_root,
121 per_cpu(hcall_stats, cpu),
122 &hcall_inst_seq_fops);
123 if (!hcall_file)
124 return -ENOMEM;
125 }
126
127 return 0;
128}
129__initcall(hcall_inst_init);
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index a72a987f1d4d..3f6a89b09816 100644
--- a/arch/powerpc/platforms/pseries/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -27,6 +27,7 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <asm/hvcall.h> 28#include <asm/hvcall.h>
29#include <asm/hvconsole.h> 29#include <asm/hvconsole.h>
30#include "plpar_wrappers.h"
30 31
31/** 32/**
32 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper 33 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
@@ -40,9 +41,9 @@ int hvc_get_chars(uint32_t vtermno, char *buf, int count)
40{ 41{
41 unsigned long got; 42 unsigned long got;
42 43
43 if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got, 44 if (plpar_get_term_char(vtermno, &got, buf) == H_SUCCESS)
44 (unsigned long *)buf, (unsigned long *)buf+1) == H_SUCCESS)
45 return got; 45 return got;
46
46 return 0; 47 return 0;
47} 48}
48 49
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index d67af2c65754..bbf2e34dc358 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -267,13 +267,12 @@ static void iommu_table_setparms(struct pci_controller *phb,
267 struct iommu_table *tbl) 267 struct iommu_table *tbl)
268{ 268{
269 struct device_node *node; 269 struct device_node *node;
270 unsigned long *basep; 270 const unsigned long *basep, *sizep;
271 unsigned int *sizep;
272 271
273 node = (struct device_node *)phb->arch_data; 272 node = (struct device_node *)phb->arch_data;
274 273
275 basep = (unsigned long *)get_property(node, "linux,tce-base", NULL); 274 basep = get_property(node, "linux,tce-base", NULL);
276 sizep = (unsigned int *)get_property(node, "linux,tce-size", NULL); 275 sizep = get_property(node, "linux,tce-size", NULL);
277 if (basep == NULL || sizep == NULL) { 276 if (basep == NULL || sizep == NULL) {
278 printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has " 277 printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has "
279 "missing tce entries !\n", dn->full_name); 278 "missing tce entries !\n", dn->full_name);
@@ -315,7 +314,7 @@ static void iommu_table_setparms(struct pci_controller *phb,
315static void iommu_table_setparms_lpar(struct pci_controller *phb, 314static void iommu_table_setparms_lpar(struct pci_controller *phb,
316 struct device_node *dn, 315 struct device_node *dn,
317 struct iommu_table *tbl, 316 struct iommu_table *tbl,
318 unsigned char *dma_window) 317 const void *dma_window)
319{ 318{
320 unsigned long offset, size; 319 unsigned long offset, size;
321 320
@@ -415,7 +414,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
415 struct iommu_table *tbl; 414 struct iommu_table *tbl;
416 struct device_node *dn, *pdn; 415 struct device_node *dn, *pdn;
417 struct pci_dn *ppci; 416 struct pci_dn *ppci;
418 unsigned char *dma_window = NULL; 417 const void *dma_window = NULL;
419 418
420 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); 419 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
421 420
@@ -519,7 +518,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
519{ 518{
520 struct device_node *pdn, *dn; 519 struct device_node *pdn, *dn;
521 struct iommu_table *tbl; 520 struct iommu_table *tbl;
522 unsigned char *dma_window = NULL; 521 const void *dma_window = NULL;
523 struct pci_dn *pci; 522 struct pci_dn *pci;
524 523
525 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); 524 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 3aeb40699042..1820a0b0a8c6 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -48,13 +48,11 @@
48#define DBG_LOW(fmt...) do { } while(0) 48#define DBG_LOW(fmt...) do { } while(0)
49#endif 49#endif
50 50
51/* in pSeries_hvCall.S */ 51/* in hvCall.S */
52EXPORT_SYMBOL(plpar_hcall); 52EXPORT_SYMBOL(plpar_hcall);
53EXPORT_SYMBOL(plpar_hcall_4out); 53EXPORT_SYMBOL(plpar_hcall9);
54EXPORT_SYMBOL(plpar_hcall_norets); 54EXPORT_SYMBOL(plpar_hcall_norets);
55EXPORT_SYMBOL(plpar_hcall_8arg_2ret); 55
56EXPORT_SYMBOL(plpar_hcall_7arg_7ret);
57EXPORT_SYMBOL(plpar_hcall_9arg_9ret);
58extern void pSeries_find_serial_port(void); 56extern void pSeries_find_serial_port(void);
59 57
60 58
@@ -204,20 +202,20 @@ void __init udbg_init_debug_lpar(void)
204void __init find_udbg_vterm(void) 202void __init find_udbg_vterm(void)
205{ 203{
206 struct device_node *stdout_node; 204 struct device_node *stdout_node;
207 u32 *termno; 205 const u32 *termno;
208 char *name; 206 const char *name;
209 int add_console; 207 int add_console;
210 208
211 /* find the boot console from /chosen/stdout */ 209 /* find the boot console from /chosen/stdout */
212 if (!of_chosen) 210 if (!of_chosen)
213 return; 211 return;
214 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 212 name = get_property(of_chosen, "linux,stdout-path", NULL);
215 if (name == NULL) 213 if (name == NULL)
216 return; 214 return;
217 stdout_node = of_find_node_by_path(name); 215 stdout_node = of_find_node_by_path(name);
218 if (!stdout_node) 216 if (!stdout_node)
219 return; 217 return;
220 name = (char *)get_property(stdout_node, "name", NULL); 218 name = get_property(stdout_node, "name", NULL);
221 if (!name) { 219 if (!name) {
222 printk(KERN_WARNING "stdout node missing 'name' property!\n"); 220 printk(KERN_WARNING "stdout node missing 'name' property!\n");
223 goto out; 221 goto out;
@@ -228,7 +226,7 @@ void __init find_udbg_vterm(void)
228 /* Check if it's a virtual terminal */ 226 /* Check if it's a virtual terminal */
229 if (strncmp(name, "vty", 3) != 0) 227 if (strncmp(name, "vty", 3) != 0)
230 goto out; 228 goto out;
231 termno = (u32 *)get_property(stdout_node, "reg", NULL); 229 termno = get_property(stdout_node, "reg", NULL);
232 if (termno == NULL) 230 if (termno == NULL)
233 goto out; 231 goto out;
234 vtermno = termno[0]; 232 vtermno = termno[0];
@@ -254,18 +252,34 @@ out:
254void vpa_init(int cpu) 252void vpa_init(int cpu)
255{ 253{
256 int hwcpu = get_hard_smp_processor_id(cpu); 254 int hwcpu = get_hard_smp_processor_id(cpu);
257 unsigned long vpa = __pa(&lppaca[cpu]); 255 unsigned long addr;
258 long ret; 256 long ret;
259 257
260 if (cpu_has_feature(CPU_FTR_ALTIVEC)) 258 if (cpu_has_feature(CPU_FTR_ALTIVEC))
261 lppaca[cpu].vmxregs_in_use = 1; 259 lppaca[cpu].vmxregs_in_use = 1;
262 260
263 ret = register_vpa(hwcpu, vpa); 261 addr = __pa(&lppaca[cpu]);
262 ret = register_vpa(hwcpu, addr);
264 263
265 if (ret) 264 if (ret) {
266 printk(KERN_ERR "WARNING: vpa_init: VPA registration for " 265 printk(KERN_ERR "WARNING: vpa_init: VPA registration for "
267 "cpu %d (hw %d) of area %lx returns %ld\n", 266 "cpu %d (hw %d) of area %lx returns %ld\n",
268 cpu, hwcpu, vpa, ret); 267 cpu, hwcpu, addr, ret);
268 return;
269 }
270 /*
271 * PAPR says this feature is SLB-Buffer but firmware never
272 * reports that. All SPLPAR support SLB shadow buffer.
273 */
274 addr = __pa(&slb_shadow[cpu]);
275 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
276 ret = register_slb_shadow(hwcpu, addr);
277 if (ret)
278 printk(KERN_ERR
279 "WARNING: vpa_init: SLB shadow buffer "
280 "registration for cpu %d (hw %d) of area %lx "
281 "returns %ld\n", cpu, hwcpu, addr, ret);
282 }
269} 283}
270 284
271long pSeries_lpar_hpte_insert(unsigned long hpte_group, 285long pSeries_lpar_hpte_insert(unsigned long hpte_group,
@@ -277,7 +291,6 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
277 unsigned long flags; 291 unsigned long flags;
278 unsigned long slot; 292 unsigned long slot;
279 unsigned long hpte_v, hpte_r; 293 unsigned long hpte_v, hpte_r;
280 unsigned long dummy0, dummy1;
281 294
282 if (!(vflags & HPTE_V_BOLTED)) 295 if (!(vflags & HPTE_V_BOLTED))
283 DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " 296 DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
@@ -302,8 +315,7 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
302 if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) 315 if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
303 hpte_r &= ~_PAGE_COHERENT; 316 hpte_r &= ~_PAGE_COHERENT;
304 317
305 lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v, 318 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
306 hpte_r, &slot, &dummy0, &dummy1);
307 if (unlikely(lpar_rc == H_PTEG_FULL)) { 319 if (unlikely(lpar_rc == H_PTEG_FULL)) {
308 if (!(vflags & HPTE_V_BOLTED)) 320 if (!(vflags & HPTE_V_BOLTED))
309 DBG_LOW(" full\n"); 321 DBG_LOW(" full\n");
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 18abfb1f4e24..64163cecdf93 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -123,13 +123,14 @@ static ssize_t pSeries_nvram_get_size(void)
123int __init pSeries_nvram_init(void) 123int __init pSeries_nvram_init(void)
124{ 124{
125 struct device_node *nvram; 125 struct device_node *nvram;
126 unsigned int *nbytes_p, proplen; 126 const unsigned int *nbytes_p;
127 unsigned int proplen;
127 128
128 nvram = of_find_node_by_type(NULL, "nvram"); 129 nvram = of_find_node_by_type(NULL, "nvram");
129 if (nvram == NULL) 130 if (nvram == NULL)
130 return -ENODEV; 131 return -ENODEV;
131 132
132 nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); 133 nbytes_p = get_property(nvram, "#bytes", &proplen);
133 if (nbytes_p == NULL || proplen != sizeof(unsigned int)) 134 if (nbytes_p == NULL || proplen != sizeof(unsigned int))
134 return -EIO; 135 return -EIO;
135 136
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index e97e67f5e079..410a6bcc4ca0 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -60,7 +60,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
60static void __devinit check_s7a(void) 60static void __devinit check_s7a(void)
61{ 61{
62 struct device_node *root; 62 struct device_node *root;
63 char *model; 63 const char *model;
64 64
65 s7a_workaround = 0; 65 s7a_workaround = 0;
66 root = of_find_node_by_path("/"); 66 root = of_find_node_by_path("/");
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index 3bd1b3e06003..3eb7b294d92f 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -5,20 +5,17 @@
5 5
6static inline long poll_pending(void) 6static inline long poll_pending(void)
7{ 7{
8 unsigned long dummy; 8 return plpar_hcall_norets(H_POLL_PENDING);
9 return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0, &dummy, &dummy, &dummy);
10} 9}
11 10
12static inline long prod_processor(void) 11static inline long prod_processor(void)
13{ 12{
14 plpar_hcall_norets(H_PROD); 13 return plpar_hcall_norets(H_PROD);
15 return 0;
16} 14}
17 15
18static inline long cede_processor(void) 16static inline long cede_processor(void)
19{ 17{
20 plpar_hcall_norets(H_CEDE); 18 return plpar_hcall_norets(H_CEDE);
21 return 0;
22} 19}
23 20
24static inline long vpa_call(unsigned long flags, unsigned long cpu, 21static inline long vpa_call(unsigned long flags, unsigned long cpu,
@@ -40,23 +37,59 @@ static inline long register_vpa(unsigned long cpu, unsigned long vpa)
40 return vpa_call(0x1, cpu, vpa); 37 return vpa_call(0x1, cpu, vpa);
41} 38}
42 39
40static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa)
41{
42 return vpa_call(0x7, cpu, vpa);
43}
44
45static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
46{
47 return vpa_call(0x3, cpu, vpa);
48}
49
43extern void vpa_init(int cpu); 50extern void vpa_init(int cpu);
44 51
52static inline long plpar_pte_enter(unsigned long flags,
53 unsigned long hpte_group, unsigned long hpte_v,
54 unsigned long hpte_r, unsigned long *slot)
55{
56 long rc;
57 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
58
59 rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
60
61 *slot = retbuf[0];
62
63 return rc;
64}
65
45static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex, 66static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
46 unsigned long avpn, unsigned long *old_pteh_ret, 67 unsigned long avpn, unsigned long *old_pteh_ret,
47 unsigned long *old_ptel_ret) 68 unsigned long *old_ptel_ret)
48{ 69{
49 unsigned long dummy; 70 long rc;
50 return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0, old_pteh_ret, 71 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
51 old_ptel_ret, &dummy); 72
73 rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
74
75 *old_pteh_ret = retbuf[0];
76 *old_ptel_ret = retbuf[1];
77
78 return rc;
52} 79}
53 80
54static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, 81static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
55 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) 82 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
56{ 83{
57 unsigned long dummy; 84 long rc;
58 return plpar_hcall(H_READ, flags, ptex, 0, 0, old_pteh_ret, 85 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
59 old_ptel_ret, &dummy); 86
87 rc = plpar_hcall(H_READ, retbuf, flags, ptex);
88
89 *old_pteh_ret = retbuf[0];
90 *old_ptel_ret = retbuf[1];
91
92 return rc;
60} 93}
61 94
62static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, 95static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
@@ -68,9 +101,14 @@ static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
68static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba, 101static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
69 unsigned long *tce_ret) 102 unsigned long *tce_ret)
70{ 103{
71 unsigned long dummy; 104 long rc;
72 return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0, tce_ret, &dummy, 105 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
73 &dummy); 106
107 rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
108
109 *tce_ret = retbuf[0];
110
111 return rc;
74} 112}
75 113
76static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba, 114static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
@@ -94,9 +132,17 @@ static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
94static inline long plpar_get_term_char(unsigned long termno, 132static inline long plpar_get_term_char(unsigned long termno,
95 unsigned long *len_ret, char *buf_ret) 133 unsigned long *len_ret, char *buf_ret)
96{ 134{
135 long rc;
136 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
97 unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */ 137 unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */
98 return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0, len_ret, 138
99 lbuf + 0, lbuf + 1); 139 rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno);
140
141 *len_ret = retbuf[0];
142 lbuf[0] = retbuf[1];
143 lbuf[1] = retbuf[2];
144
145 return rc;
100} 146}
101 147
102static inline long plpar_put_term_char(unsigned long termno, unsigned long len, 148static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
@@ -107,4 +153,31 @@ static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
107 lbuf[1]); 153 lbuf[1]);
108} 154}
109 155
156static inline long plpar_eoi(unsigned long xirr)
157{
158 return plpar_hcall_norets(H_EOI, xirr);
159}
160
161static inline long plpar_cppr(unsigned long cppr)
162{
163 return plpar_hcall_norets(H_CPPR, cppr);
164}
165
166static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
167{
168 return plpar_hcall_norets(H_IPI, servernum, mfrr);
169}
170
171static inline long plpar_xirr(unsigned long *xirr_ret)
172{
173 long rc;
174 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
175
176 rc = plpar_hcall(H_XIRR, retbuf);
177
178 *xirr_ret = retbuf[0];
179
180 return rc;
181}
182
110#endif /* _PSERIES_PLPAR_WRAPPERS_H */ 183#endif /* _PSERIES_PLPAR_WRAPPERS_H */
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index c7ffde1a614e..903115d67fdc 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -79,7 +79,7 @@ static void request_ras_irqs(struct device_node *np,
79{ 79{
80 int i, index, count = 0; 80 int i, index, count = 0;
81 struct of_irq oirq; 81 struct of_irq oirq;
82 u32 *opicprop; 82 const u32 *opicprop;
83 unsigned int opicplen; 83 unsigned int opicplen;
84 unsigned int virqs[16]; 84 unsigned int virqs[16];
85 85
@@ -87,7 +87,7 @@ static void request_ras_irqs(struct device_node *np,
87 * map those interrupts using the default interrupt host and default 87 * map those interrupts using the default interrupt host and default
88 * trigger 88 * trigger
89 */ 89 */
90 opicprop = (u32 *)get_property(np, "open-pic-interrupt", &opicplen); 90 opicprop = get_property(np, "open-pic-interrupt", &opicplen);
91 if (opicprop) { 91 if (opicprop) {
92 opicplen /= sizeof(u32); 92 opicplen /= sizeof(u32);
93 for (i = 0; i < opicplen; i++) { 93 for (i = 0; i < opicplen; i++) {
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index 2e4e04042d85..8ca2612221d6 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -359,11 +359,11 @@ static int enable_surveillance(int timeout)
359static int get_eventscan_parms(void) 359static int get_eventscan_parms(void)
360{ 360{
361 struct device_node *node; 361 struct device_node *node;
362 int *ip; 362 const int *ip;
363 363
364 node = of_find_node_by_path("/rtas"); 364 node = of_find_node_by_path("/rtas");
365 365
366 ip = (int *)get_property(node, "rtas-event-scan-rate", NULL); 366 ip = get_property(node, "rtas-event-scan-rate", NULL);
367 if (ip == NULL) { 367 if (ip == NULL) {
368 printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n"); 368 printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n");
369 of_node_put(node); 369 of_node_put(node);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 31867a701fcb..a6398fbe530d 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -133,9 +133,9 @@ void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc,
133static void __init pseries_mpic_init_IRQ(void) 133static void __init pseries_mpic_init_IRQ(void)
134{ 134{
135 struct device_node *np, *old, *cascade = NULL; 135 struct device_node *np, *old, *cascade = NULL;
136 unsigned int *addrp; 136 const unsigned int *addrp;
137 unsigned long intack = 0; 137 unsigned long intack = 0;
138 unsigned int *opprop; 138 const unsigned int *opprop;
139 unsigned long openpic_addr = 0; 139 unsigned long openpic_addr = 0;
140 unsigned int cascade_irq; 140 unsigned int cascade_irq;
141 int naddr, n, i, opplen; 141 int naddr, n, i, opplen;
@@ -143,7 +143,7 @@ static void __init pseries_mpic_init_IRQ(void)
143 143
144 np = of_find_node_by_path("/"); 144 np = of_find_node_by_path("/");
145 naddr = prom_n_addr_cells(np); 145 naddr = prom_n_addr_cells(np);
146 opprop = (unsigned int *) get_property(np, "platform-open-pic", &opplen); 146 opprop = get_property(np, "platform-open-pic", &opplen);
147 if (opprop != 0) { 147 if (opprop != 0) {
148 openpic_addr = of_read_number(opprop, naddr); 148 openpic_addr = of_read_number(opprop, naddr);
149 printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); 149 printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
@@ -192,7 +192,7 @@ static void __init pseries_mpic_init_IRQ(void)
192 break; 192 break;
193 if (strcmp(np->name, "pci") != 0) 193 if (strcmp(np->name, "pci") != 0)
194 continue; 194 continue;
195 addrp = (u32 *)get_property(np, "8259-interrupt-acknowledge", 195 addrp = get_property(np, "8259-interrupt-acknowledge",
196 NULL); 196 NULL);
197 if (addrp == NULL) 197 if (addrp == NULL)
198 continue; 198 continue;
@@ -223,23 +223,37 @@ static void pseries_lpar_enable_pmcs(void)
223} 223}
224 224
225#ifdef CONFIG_KEXEC 225#ifdef CONFIG_KEXEC
226static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary) 226static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
227{
228 mpic_teardown_this_cpu(secondary);
229}
230
231static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
232{ 227{
233 /* Don't risk a hypervisor call if we're crashing */ 228 /* Don't risk a hypervisor call if we're crashing */
234 if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { 229 if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
235 unsigned long vpa = __pa(get_lppaca()); 230 unsigned long addr;
236 231
237 if (unregister_vpa(hard_smp_processor_id(), vpa)) { 232 addr = __pa(get_slb_shadow());
233 if (unregister_slb_shadow(hard_smp_processor_id(), addr))
234 printk("SLB shadow buffer deregistration of "
235 "cpu %u (hw_cpu_id %d) failed\n",
236 smp_processor_id(),
237 hard_smp_processor_id());
238
239 addr = __pa(get_lppaca());
240 if (unregister_vpa(hard_smp_processor_id(), addr)) {
238 printk("VPA deregistration of cpu %u (hw_cpu_id %d) " 241 printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
239 "failed\n", smp_processor_id(), 242 "failed\n", smp_processor_id(),
240 hard_smp_processor_id()); 243 hard_smp_processor_id());
241 } 244 }
242 } 245 }
246}
247
248static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary)
249{
250 pseries_kexec_cpu_down(crash_shutdown, secondary);
251 mpic_teardown_this_cpu(secondary);
252}
253
254static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
255{
256 pseries_kexec_cpu_down(crash_shutdown, secondary);
243 xics_teardown_cpu(secondary); 257 xics_teardown_cpu(secondary);
244} 258}
245#endif /* CONFIG_KEXEC */ 259#endif /* CONFIG_KEXEC */
@@ -247,11 +261,11 @@ static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
247static void __init pseries_discover_pic(void) 261static void __init pseries_discover_pic(void)
248{ 262{
249 struct device_node *np; 263 struct device_node *np;
250 char *typep; 264 const char *typep;
251 265
252 for (np = NULL; (np = of_find_node_by_name(np, 266 for (np = NULL; (np = of_find_node_by_name(np,
253 "interrupt-controller"));) { 267 "interrupt-controller"));) {
254 typep = (char *)get_property(np, "compatible", NULL); 268 typep = get_property(np, "compatible", NULL);
255 if (strstr(typep, "open-pic")) { 269 if (strstr(typep, "open-pic")) {
256 pSeries_mpic_node = of_node_get(np); 270 pSeries_mpic_node = of_node_get(np);
257 ppc_md.init_IRQ = pseries_mpic_init_IRQ; 271 ppc_md.init_IRQ = pseries_mpic_init_IRQ;
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index ac61098ff401..c6624b8a0e77 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -62,7 +62,7 @@
62 */ 62 */
63static cpumask_t of_spin_map; 63static cpumask_t of_spin_map;
64 64
65extern void pSeries_secondary_smp_init(unsigned long); 65extern void generic_secondary_smp_init(unsigned long);
66 66
67#ifdef CONFIG_HOTPLUG_CPU 67#ifdef CONFIG_HOTPLUG_CPU
68 68
@@ -145,9 +145,9 @@ static int pSeries_add_processor(struct device_node *np)
145 unsigned int cpu; 145 unsigned int cpu;
146 cpumask_t candidate_map, tmp = CPU_MASK_NONE; 146 cpumask_t candidate_map, tmp = CPU_MASK_NONE;
147 int err = -ENOSPC, len, nthreads, i; 147 int err = -ENOSPC, len, nthreads, i;
148 u32 *intserv; 148 const u32 *intserv;
149 149
150 intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len); 150 intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
151 if (!intserv) 151 if (!intserv)
152 return 0; 152 return 0;
153 153
@@ -205,9 +205,9 @@ static void pSeries_remove_processor(struct device_node *np)
205{ 205{
206 unsigned int cpu; 206 unsigned int cpu;
207 int len, nthreads, i; 207 int len, nthreads, i;
208 u32 *intserv; 208 const u32 *intserv;
209 209
210 intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len); 210 intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
211 if (!intserv) 211 if (!intserv)
212 return; 212 return;
213 213
@@ -270,7 +270,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
270{ 270{
271 int status; 271 int status;
272 unsigned long start_here = __pa((u32)*((unsigned long *) 272 unsigned long start_here = __pa((u32)*((unsigned long *)
273 pSeries_secondary_smp_init)); 273 generic_secondary_smp_init));
274 unsigned int pcpu; 274 unsigned int pcpu;
275 int start_cpu; 275 int start_cpu;
276 276
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index e98863025721..253972e5479f 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -34,6 +34,7 @@
34#include <asm/i8259.h> 34#include <asm/i8259.h>
35 35
36#include "xics.h" 36#include "xics.h"
37#include "plpar_wrappers.h"
37 38
38#define XICS_IPI 2 39#define XICS_IPI 2
39#define XICS_IRQ_SPURIOUS 0 40#define XICS_IRQ_SPURIOUS 0
@@ -110,27 +111,6 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
110/* LPAR low level accessors */ 111/* LPAR low level accessors */
111 112
112 113
113static inline long plpar_eoi(unsigned long xirr)
114{
115 return plpar_hcall_norets(H_EOI, xirr);
116}
117
118static inline long plpar_cppr(unsigned long cppr)
119{
120 return plpar_hcall_norets(H_CPPR, cppr);
121}
122
123static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
124{
125 return plpar_hcall_norets(H_IPI, servernum, mfrr);
126}
127
128static inline long plpar_xirr(unsigned long *xirr_ret)
129{
130 unsigned long dummy;
131 return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
132}
133
134static inline unsigned int lpar_xirr_info_get(int n_cpu) 114static inline unsigned int lpar_xirr_info_get(int n_cpu)
135{ 115{
136 unsigned long lpar_rc; 116 unsigned long lpar_rc;
@@ -590,14 +570,14 @@ static void __init xics_init_one_node(struct device_node *np,
590 unsigned int *indx) 570 unsigned int *indx)
591{ 571{
592 unsigned int ilen; 572 unsigned int ilen;
593 u32 *ireg; 573 const u32 *ireg;
594 574
595 /* This code does the theorically broken assumption that the interrupt 575 /* This code does the theorically broken assumption that the interrupt
596 * server numbers are the same as the hard CPU numbers. 576 * server numbers are the same as the hard CPU numbers.
597 * This happens to be the case so far but we are playing with fire... 577 * This happens to be the case so far but we are playing with fire...
598 * should be fixed one of these days. -BenH. 578 * should be fixed one of these days. -BenH.
599 */ 579 */
600 ireg = (u32 *)get_property(np, "ibm,interrupt-server-ranges", NULL); 580 ireg = get_property(np, "ibm,interrupt-server-ranges", NULL);
601 581
602 /* Do that ever happen ? we'll know soon enough... but even good'old 582 /* Do that ever happen ? we'll know soon enough... but even good'old
603 * f80 does have that property .. 583 * f80 does have that property ..
@@ -609,7 +589,7 @@ static void __init xics_init_one_node(struct device_node *np,
609 */ 589 */
610 *indx = *ireg; 590 *indx = *ireg;
611 } 591 }
612 ireg = (u32 *)get_property(np, "reg", &ilen); 592 ireg = get_property(np, "reg", &ilen);
613 if (!ireg) 593 if (!ireg)
614 panic("xics_init_IRQ: can't find interrupt reg property"); 594 panic("xics_init_IRQ: can't find interrupt reg property");
615 595
@@ -635,7 +615,7 @@ static void __init xics_setup_8259_cascade(void)
635{ 615{
636 struct device_node *np, *old, *found = NULL; 616 struct device_node *np, *old, *found = NULL;
637 int cascade, naddr; 617 int cascade, naddr;
638 u32 *addrp; 618 const u32 *addrp;
639 unsigned long intack = 0; 619 unsigned long intack = 0;
640 620
641 for_each_node_by_type(np, "interrupt-controller") 621 for_each_node_by_type(np, "interrupt-controller")
@@ -661,7 +641,7 @@ static void __init xics_setup_8259_cascade(void)
661 break; 641 break;
662 if (strcmp(np->name, "pci") != 0) 642 if (strcmp(np->name, "pci") != 0)
663 continue; 643 continue;
664 addrp = (u32 *)get_property(np, "8259-interrupt-acknowledge", NULL); 644 addrp = get_property(np, "8259-interrupt-acknowledge", NULL);
665 if (addrp == NULL) 645 if (addrp == NULL)
666 continue; 646 continue;
667 naddr = prom_n_addr_cells(np); 647 naddr = prom_n_addr_cells(np);
@@ -680,7 +660,8 @@ void __init xics_init_IRQ(void)
680{ 660{
681 int i; 661 int i;
682 struct device_node *np; 662 struct device_node *np;
683 u32 *ireg, ilen, indx = 0; 663 u32 ilen, indx = 0;
664 const u32 *ireg;
684 int found = 0; 665 int found = 0;
685 666
686 ppc64_boot_msg(0x20, "XICS Init"); 667 ppc64_boot_msg(0x20, "XICS Init");
@@ -705,18 +686,17 @@ void __init xics_init_IRQ(void)
705 for (np = of_find_node_by_type(NULL, "cpu"); 686 for (np = of_find_node_by_type(NULL, "cpu");
706 np; 687 np;
707 np = of_find_node_by_type(np, "cpu")) { 688 np = of_find_node_by_type(np, "cpu")) {
708 ireg = (u32 *)get_property(np, "reg", &ilen); 689 ireg = get_property(np, "reg", &ilen);
709 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { 690 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) {
710 ireg = (u32 *)get_property(np, 691 ireg = get_property(np,
711 "ibm,ppc-interrupt-gserver#s", 692 "ibm,ppc-interrupt-gserver#s", &ilen);
712 &ilen);
713 i = ilen / sizeof(int); 693 i = ilen / sizeof(int);
714 if (ireg && i > 0) { 694 if (ireg && i > 0) {
715 default_server = ireg[0]; 695 default_server = ireg[0];
716 /* take last element */ 696 /* take last element */
717 default_distrib_server = ireg[i-1]; 697 default_distrib_server = ireg[i-1];
718 } 698 }
719 ireg = (u32 *)get_property(np, 699 ireg = get_property(np,
720 "ibm,interrupt-server#-size", NULL); 700 "ibm,interrupt-server#-size", NULL);
721 if (ireg) 701 if (ireg)
722 interrupt_server_size = *ireg; 702 interrupt_server_size = *ireg;
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ef10bcf2d943..92ba378b7990 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -41,7 +41,7 @@ phys_addr_t get_immrbase(void)
41 soc = of_find_node_by_type(NULL, "soc"); 41 soc = of_find_node_by_type(NULL, "soc");
42 if (soc) { 42 if (soc) {
43 unsigned int size; 43 unsigned int size;
44 void *prop = get_property(soc, "reg", &size); 44 const void *prop = get_property(soc, "reg", &size);
45 immrbase = of_translate_address(soc, prop); 45 immrbase = of_translate_address(soc, prop);
46 of_node_put(soc); 46 of_node_put(soc);
47 }; 47 };
@@ -85,7 +85,7 @@ static int __init gfar_mdio_of_init(void)
85 mdio_data.irq[k] = -1; 85 mdio_data.irq[k] = -1;
86 86
87 while ((child = of_get_next_child(np, child)) != NULL) { 87 while ((child = of_get_next_child(np, child)) != NULL) {
88 u32 *id = get_property(child, "reg", NULL); 88 const u32 *id = get_property(child, "reg", NULL);
89 mdio_data.irq[*id] = irq_of_parse_and_map(child, 0); 89 mdio_data.irq[*id] = irq_of_parse_and_map(child, 0);
90 } 90 }
91 91
@@ -124,10 +124,10 @@ static int __init gfar_of_init(void)
124 struct resource r[4]; 124 struct resource r[4];
125 struct device_node *phy, *mdio; 125 struct device_node *phy, *mdio;
126 struct gianfar_platform_data gfar_data; 126 struct gianfar_platform_data gfar_data;
127 unsigned int *id; 127 const unsigned int *id;
128 char *model; 128 const char *model;
129 void *mac_addr; 129 const void *mac_addr;
130 phandle *ph; 130 const phandle *ph;
131 int n_res = 1; 131 int n_res = 1;
132 132
133 memset(r, 0, sizeof(r)); 133 memset(r, 0, sizeof(r));
@@ -193,7 +193,7 @@ static int __init gfar_of_init(void)
193 FSL_GIANFAR_DEV_HAS_VLAN | 193 FSL_GIANFAR_DEV_HAS_VLAN |
194 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; 194 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
195 195
196 ph = (phandle *) get_property(np, "phy-handle", NULL); 196 ph = get_property(np, "phy-handle", NULL);
197 phy = of_find_node_by_phandle(*ph); 197 phy = of_find_node_by_phandle(*ph);
198 198
199 if (phy == NULL) { 199 if (phy == NULL) {
@@ -203,7 +203,7 @@ static int __init gfar_of_init(void)
203 203
204 mdio = of_get_parent(phy); 204 mdio = of_get_parent(phy);
205 205
206 id = (u32 *) get_property(phy, "reg", NULL); 206 id = get_property(phy, "reg", NULL);
207 ret = of_address_to_resource(mdio, 0, &res); 207 ret = of_address_to_resource(mdio, 0, &res);
208 if (ret) { 208 if (ret) {
209 of_node_put(phy); 209 of_node_put(phy);
@@ -247,7 +247,7 @@ static int __init fsl_i2c_of_init(void)
247 i++) { 247 i++) {
248 struct resource r[2]; 248 struct resource r[2];
249 struct fsl_i2c_platform_data i2c_data; 249 struct fsl_i2c_platform_data i2c_data;
250 unsigned char *flags = NULL; 250 const unsigned char *flags = NULL;
251 251
252 memset(&r, 0, sizeof(r)); 252 memset(&r, 0, sizeof(r));
253 memset(&i2c_data, 0, sizeof(i2c_data)); 253 memset(&i2c_data, 0, sizeof(i2c_data));
@@ -298,7 +298,7 @@ static int __init mpc83xx_wdt_init(void)
298 struct resource r; 298 struct resource r;
299 struct device_node *soc, *np; 299 struct device_node *soc, *np;
300 struct platform_device *dev; 300 struct platform_device *dev;
301 unsigned int *freq; 301 const unsigned int *freq;
302 int ret; 302 int ret;
303 303
304 np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); 304 np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
@@ -315,7 +315,7 @@ static int __init mpc83xx_wdt_init(void)
315 goto nosoc; 315 goto nosoc;
316 } 316 }
317 317
318 freq = (unsigned int *)get_property(soc, "bus-frequency", NULL); 318 freq = get_property(soc, "bus-frequency", NULL);
319 if (!freq) { 319 if (!freq) {
320 ret = -ENODEV; 320 ret = -ENODEV;
321 goto err; 321 goto err;
@@ -355,7 +355,7 @@ nodev:
355arch_initcall(mpc83xx_wdt_init); 355arch_initcall(mpc83xx_wdt_init);
356#endif 356#endif
357 357
358static enum fsl_usb2_phy_modes determine_usb_phy(char * phy_type) 358static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
359{ 359{
360 if (!phy_type) 360 if (!phy_type)
361 return FSL_USB2_PHY_NONE; 361 return FSL_USB2_PHY_NONE;
@@ -383,7 +383,7 @@ static int __init fsl_usb_of_init(void)
383 i++) { 383 i++) {
384 struct resource r[2]; 384 struct resource r[2];
385 struct fsl_usb2_platform_data usb_data; 385 struct fsl_usb2_platform_data usb_data;
386 unsigned char *prop = NULL; 386 const unsigned char *prop = NULL;
387 387
388 memset(&r, 0, sizeof(r)); 388 memset(&r, 0, sizeof(r));
389 memset(&usb_data, 0, sizeof(usb_data)); 389 memset(&usb_data, 0, sizeof(usb_data));
@@ -431,7 +431,7 @@ static int __init fsl_usb_of_init(void)
431 i++) { 431 i++) {
432 struct resource r[2]; 432 struct resource r[2];
433 struct fsl_usb2_platform_data usb_data; 433 struct fsl_usb2_platform_data usb_data;
434 unsigned char *prop = NULL; 434 const unsigned char *prop = NULL;
435 435
436 memset(&r, 0, sizeof(r)); 436 memset(&r, 0, sizeof(r));
437 memset(&usb_data, 0, sizeof(usb_data)); 437 memset(&usb_data, 0, sizeof(usb_data));
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index c433d3f39edd..5a3dd480d2fd 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -2,6 +2,8 @@
2#define __PPC_FSL_SOC_H 2#define __PPC_FSL_SOC_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <asm/mmu.h>
6
5extern phys_addr_t get_immrbase(void); 7extern phys_addr_t get_immrbase(void);
6 8
7#endif 9#endif
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 9855820b9548..26a6a3becd66 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -224,7 +224,7 @@ static struct irq_host_ops i8259_host_ops = {
224 .xlate = i8259_host_xlate, 224 .xlate = i8259_host_xlate,
225}; 225};
226 226
227/**** 227/**
228 * i8259_init - Initialize the legacy controller 228 * i8259_init - Initialize the legacy controller
229 * @node: device node of the legacy PIC (can be NULL, but then, it will match 229 * @node: device node of the legacy PIC (can be NULL, but then, it will match
230 * all interrupts, so beware) 230 * all interrupts, so beware)
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 70e707785d49..0251b7c68d0e 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -210,7 +210,7 @@ static struct ipic_info ipic_info[] = {
210 .prio_mask = 4, 210 .prio_mask = 4,
211 }, 211 },
212 [64] = { 212 [64] = {
213 .pend = IPIC_SIPNR_H, 213 .pend = IPIC_SIPNR_L,
214 .mask = IPIC_SIMSR_L, 214 .mask = IPIC_SIMSR_L,
215 .prio = IPIC_SMPRR_A, 215 .prio = IPIC_SMPRR_A,
216 .force = IPIC_SIFCR_L, 216 .force = IPIC_SIFCR_L,
@@ -218,7 +218,7 @@ static struct ipic_info ipic_info[] = {
218 .prio_mask = 0, 218 .prio_mask = 0,
219 }, 219 },
220 [65] = { 220 [65] = {
221 .pend = IPIC_SIPNR_H, 221 .pend = IPIC_SIPNR_L,
222 .mask = IPIC_SIMSR_L, 222 .mask = IPIC_SIMSR_L,
223 .prio = IPIC_SMPRR_A, 223 .prio = IPIC_SMPRR_A,
224 .force = IPIC_SIFCR_L, 224 .force = IPIC_SIFCR_L,
@@ -226,7 +226,7 @@ static struct ipic_info ipic_info[] = {
226 .prio_mask = 1, 226 .prio_mask = 1,
227 }, 227 },
228 [66] = { 228 [66] = {
229 .pend = IPIC_SIPNR_H, 229 .pend = IPIC_SIPNR_L,
230 .mask = IPIC_SIMSR_L, 230 .mask = IPIC_SIMSR_L,
231 .prio = IPIC_SMPRR_A, 231 .prio = IPIC_SMPRR_A,
232 .force = IPIC_SIFCR_L, 232 .force = IPIC_SIFCR_L,
@@ -234,7 +234,7 @@ static struct ipic_info ipic_info[] = {
234 .prio_mask = 2, 234 .prio_mask = 2,
235 }, 235 },
236 [67] = { 236 [67] = {
237 .pend = IPIC_SIPNR_H, 237 .pend = IPIC_SIPNR_L,
238 .mask = IPIC_SIMSR_L, 238 .mask = IPIC_SIMSR_L,
239 .prio = IPIC_SMPRR_A, 239 .prio = IPIC_SMPRR_A,
240 .force = IPIC_SIFCR_L, 240 .force = IPIC_SIFCR_L,
@@ -242,7 +242,7 @@ static struct ipic_info ipic_info[] = {
242 .prio_mask = 3, 242 .prio_mask = 3,
243 }, 243 },
244 [68] = { 244 [68] = {
245 .pend = IPIC_SIPNR_H, 245 .pend = IPIC_SIPNR_L,
246 .mask = IPIC_SIMSR_L, 246 .mask = IPIC_SIMSR_L,
247 .prio = IPIC_SMPRR_B, 247 .prio = IPIC_SMPRR_B,
248 .force = IPIC_SIFCR_L, 248 .force = IPIC_SIFCR_L,
@@ -250,7 +250,7 @@ static struct ipic_info ipic_info[] = {
250 .prio_mask = 0, 250 .prio_mask = 0,
251 }, 251 },
252 [69] = { 252 [69] = {
253 .pend = IPIC_SIPNR_H, 253 .pend = IPIC_SIPNR_L,
254 .mask = IPIC_SIMSR_L, 254 .mask = IPIC_SIMSR_L,
255 .prio = IPIC_SMPRR_B, 255 .prio = IPIC_SMPRR_B,
256 .force = IPIC_SIFCR_L, 256 .force = IPIC_SIFCR_L,
@@ -258,7 +258,7 @@ static struct ipic_info ipic_info[] = {
258 .prio_mask = 1, 258 .prio_mask = 1,
259 }, 259 },
260 [70] = { 260 [70] = {
261 .pend = IPIC_SIPNR_H, 261 .pend = IPIC_SIPNR_L,
262 .mask = IPIC_SIMSR_L, 262 .mask = IPIC_SIMSR_L,
263 .prio = IPIC_SMPRR_B, 263 .prio = IPIC_SMPRR_B,
264 .force = IPIC_SIFCR_L, 264 .force = IPIC_SIFCR_L,
@@ -266,7 +266,7 @@ static struct ipic_info ipic_info[] = {
266 .prio_mask = 2, 266 .prio_mask = 2,
267 }, 267 },
268 [71] = { 268 [71] = {
269 .pend = IPIC_SIPNR_H, 269 .pend = IPIC_SIPNR_L,
270 .mask = IPIC_SIMSR_L, 270 .mask = IPIC_SIMSR_L,
271 .prio = IPIC_SMPRR_B, 271 .prio = IPIC_SMPRR_B,
272 .force = IPIC_SIFCR_L, 272 .force = IPIC_SIFCR_L,
@@ -274,91 +274,91 @@ static struct ipic_info ipic_info[] = {
274 .prio_mask = 3, 274 .prio_mask = 3,
275 }, 275 },
276 [72] = { 276 [72] = {
277 .pend = IPIC_SIPNR_H, 277 .pend = IPIC_SIPNR_L,
278 .mask = IPIC_SIMSR_L, 278 .mask = IPIC_SIMSR_L,
279 .prio = 0, 279 .prio = 0,
280 .force = IPIC_SIFCR_L, 280 .force = IPIC_SIFCR_L,
281 .bit = 8, 281 .bit = 8,
282 }, 282 },
283 [73] = { 283 [73] = {
284 .pend = IPIC_SIPNR_H, 284 .pend = IPIC_SIPNR_L,
285 .mask = IPIC_SIMSR_L, 285 .mask = IPIC_SIMSR_L,
286 .prio = 0, 286 .prio = 0,
287 .force = IPIC_SIFCR_L, 287 .force = IPIC_SIFCR_L,
288 .bit = 9, 288 .bit = 9,
289 }, 289 },
290 [74] = { 290 [74] = {
291 .pend = IPIC_SIPNR_H, 291 .pend = IPIC_SIPNR_L,
292 .mask = IPIC_SIMSR_L, 292 .mask = IPIC_SIMSR_L,
293 .prio = 0, 293 .prio = 0,
294 .force = IPIC_SIFCR_L, 294 .force = IPIC_SIFCR_L,
295 .bit = 10, 295 .bit = 10,
296 }, 296 },
297 [75] = { 297 [75] = {
298 .pend = IPIC_SIPNR_H, 298 .pend = IPIC_SIPNR_L,
299 .mask = IPIC_SIMSR_L, 299 .mask = IPIC_SIMSR_L,
300 .prio = 0, 300 .prio = 0,
301 .force = IPIC_SIFCR_L, 301 .force = IPIC_SIFCR_L,
302 .bit = 11, 302 .bit = 11,
303 }, 303 },
304 [76] = { 304 [76] = {
305 .pend = IPIC_SIPNR_H, 305 .pend = IPIC_SIPNR_L,
306 .mask = IPIC_SIMSR_L, 306 .mask = IPIC_SIMSR_L,
307 .prio = 0, 307 .prio = 0,
308 .force = IPIC_SIFCR_L, 308 .force = IPIC_SIFCR_L,
309 .bit = 12, 309 .bit = 12,
310 }, 310 },
311 [77] = { 311 [77] = {
312 .pend = IPIC_SIPNR_H, 312 .pend = IPIC_SIPNR_L,
313 .mask = IPIC_SIMSR_L, 313 .mask = IPIC_SIMSR_L,
314 .prio = 0, 314 .prio = 0,
315 .force = IPIC_SIFCR_L, 315 .force = IPIC_SIFCR_L,
316 .bit = 13, 316 .bit = 13,
317 }, 317 },
318 [78] = { 318 [78] = {
319 .pend = IPIC_SIPNR_H, 319 .pend = IPIC_SIPNR_L,
320 .mask = IPIC_SIMSR_L, 320 .mask = IPIC_SIMSR_L,
321 .prio = 0, 321 .prio = 0,
322 .force = IPIC_SIFCR_L, 322 .force = IPIC_SIFCR_L,
323 .bit = 14, 323 .bit = 14,
324 }, 324 },
325 [79] = { 325 [79] = {
326 .pend = IPIC_SIPNR_H, 326 .pend = IPIC_SIPNR_L,
327 .mask = IPIC_SIMSR_L, 327 .mask = IPIC_SIMSR_L,
328 .prio = 0, 328 .prio = 0,
329 .force = IPIC_SIFCR_L, 329 .force = IPIC_SIFCR_L,
330 .bit = 15, 330 .bit = 15,
331 }, 331 },
332 [80] = { 332 [80] = {
333 .pend = IPIC_SIPNR_H, 333 .pend = IPIC_SIPNR_L,
334 .mask = IPIC_SIMSR_L, 334 .mask = IPIC_SIMSR_L,
335 .prio = 0, 335 .prio = 0,
336 .force = IPIC_SIFCR_L, 336 .force = IPIC_SIFCR_L,
337 .bit = 16, 337 .bit = 16,
338 }, 338 },
339 [84] = { 339 [84] = {
340 .pend = IPIC_SIPNR_H, 340 .pend = IPIC_SIPNR_L,
341 .mask = IPIC_SIMSR_L, 341 .mask = IPIC_SIMSR_L,
342 .prio = 0, 342 .prio = 0,
343 .force = IPIC_SIFCR_L, 343 .force = IPIC_SIFCR_L,
344 .bit = 20, 344 .bit = 20,
345 }, 345 },
346 [85] = { 346 [85] = {
347 .pend = IPIC_SIPNR_H, 347 .pend = IPIC_SIPNR_L,
348 .mask = IPIC_SIMSR_L, 348 .mask = IPIC_SIMSR_L,
349 .prio = 0, 349 .prio = 0,
350 .force = IPIC_SIFCR_L, 350 .force = IPIC_SIFCR_L,
351 .bit = 21, 351 .bit = 21,
352 }, 352 },
353 [90] = { 353 [90] = {
354 .pend = IPIC_SIPNR_H, 354 .pend = IPIC_SIPNR_L,
355 .mask = IPIC_SIMSR_L, 355 .mask = IPIC_SIMSR_L,
356 .prio = 0, 356 .prio = 0,
357 .force = IPIC_SIFCR_L, 357 .force = IPIC_SIFCR_L,
358 .bit = 26, 358 .bit = 26,
359 }, 359 },
360 [91] = { 360 [91] = {
361 .pend = IPIC_SIPNR_H, 361 .pend = IPIC_SIPNR_L,
362 .mask = IPIC_SIMSR_L, 362 .mask = IPIC_SIMSR_L,
363 .prio = 0, 363 .prio = 0,
364 .force = IPIC_SIFCR_L, 364 .force = IPIC_SIFCR_L,
diff --git a/arch/powerpc/sysdev/mmio_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c
index 615350d46b52..ff23f5a4d4b9 100644
--- a/arch/powerpc/sysdev/mmio_nvram.c
+++ b/arch/powerpc/sysdev/mmio_nvram.c
@@ -80,7 +80,7 @@ static ssize_t mmio_nvram_get_size(void)
80int __init mmio_nvram_init(void) 80int __init mmio_nvram_init(void)
81{ 81{
82 struct device_node *nvram_node; 82 struct device_node *nvram_node;
83 unsigned long *buffer; 83 const unsigned long *buffer;
84 int proplen; 84 int proplen;
85 unsigned long nvram_addr; 85 unsigned long nvram_addr;
86 int ret; 86 int ret;
@@ -91,7 +91,7 @@ int __init mmio_nvram_init(void)
91 goto out; 91 goto out;
92 92
93 ret = -EIO; 93 ret = -EIO;
94 buffer = (unsigned long *)get_property(nvram_node, "reg", &proplen); 94 buffer = get_property(nvram_node, "reg", &proplen);
95 if (proplen != 2*sizeof(unsigned long)) 95 if (proplen != 2*sizeof(unsigned long))
96 goto out; 96 goto out;
97 97
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 2ab06ed3ae73..c28f69bef8e2 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -194,7 +194,7 @@ int __init tsi108_setup_pci(struct device_node *dev)
194 int len; 194 int len;
195 struct pci_controller *hose; 195 struct pci_controller *hose;
196 struct resource rsrc; 196 struct resource rsrc;
197 int *bus_range; 197 const int *bus_range;
198 int primary = 0, has_address = 0; 198 int primary = 0, has_address = 0;
199 199
200 /* PCI Config mapping */ 200 /* PCI Config mapping */
@@ -207,7 +207,7 @@ int __init tsi108_setup_pci(struct device_node *dev)
207 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 207 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
208 208
209 /* Get bus range if any */ 209 /* Get bus range if any */
210 bus_range = (int *)get_property(dev, "bus-range", &len); 210 bus_range = get_property(dev, "bus-range", &len);
211 if (bus_range == NULL || len < 2 * sizeof(int)) { 211 if (bus_range == NULL || len < 2 * sizeof(int)) {
212 printk(KERN_WARNING "Can't get bus-range for %s, assume" 212 printk(KERN_WARNING "Can't get bus-range for %s, assume"
213 " bus 0\n", dev->full_name); 213 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 179b10ced8c7..8adad1444a51 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -137,10 +137,14 @@ static void bootcmds(void);
137static void proccall(void); 137static void proccall(void);
138void dump_segments(void); 138void dump_segments(void);
139static void symbol_lookup(void); 139static void symbol_lookup(void);
140static void xmon_show_stack(unsigned long sp, unsigned long lr,
141 unsigned long pc);
140static void xmon_print_symbol(unsigned long address, const char *mid, 142static void xmon_print_symbol(unsigned long address, const char *mid,
141 const char *after); 143 const char *after);
142static const char *getvecname(unsigned long vec); 144static const char *getvecname(unsigned long vec);
143 145
146int xmon_no_auto_backtrace;
147
144extern int print_insn_powerpc(unsigned long, unsigned long, int); 148extern int print_insn_powerpc(unsigned long, unsigned long, int);
145 149
146extern void xmon_enter(void); 150extern void xmon_enter(void);
@@ -736,6 +740,12 @@ cmds(struct pt_regs *excp)
736 740
737 last_cmd = NULL; 741 last_cmd = NULL;
738 xmon_regs = excp; 742 xmon_regs = excp;
743
744 if (!xmon_no_auto_backtrace) {
745 xmon_no_auto_backtrace = 1;
746 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
747 }
748
739 for(;;) { 749 for(;;) {
740#ifdef CONFIG_SMP 750#ifdef CONFIG_SMP
741 printf("%x:", smp_processor_id()); 751 printf("%x:", smp_processor_id());
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index a04cdf01596b..8fa10cf661a8 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1204,7 +1204,7 @@ config PCI_DOMAINS
1204 default PCI 1204 default PCI
1205 1205
1206config MPC83xx_PCI2 1206config MPC83xx_PCI2
1207 bool " Supprt for 2nd PCI host controller" 1207 bool "Support for 2nd PCI host controller"
1208 depends on PCI && MPC834x 1208 depends on PCI && MPC834x
1209 default y if MPC834x_SYS 1209 default y if MPC834x_SYS
1210 1210
@@ -1223,12 +1223,12 @@ config PCI_8260
1223 default y 1223 default y
1224 1224
1225config 8260_PCI9 1225config 8260_PCI9
1226 bool " Enable workaround for MPC826x erratum PCI 9" 1226 bool "Enable workaround for MPC826x erratum PCI 9"
1227 depends on PCI_8260 && !ADS8272 1227 depends on PCI_8260 && !ADS8272
1228 default y 1228 default y
1229 1229
1230choice 1230choice
1231 prompt " IDMA channel for PCI 9 workaround" 1231 prompt "IDMA channel for PCI 9 workaround"
1232 depends on 8260_PCI9 1232 depends on 8260_PCI9
1233 1233
1234config 8260_PCI9_IDMA1 1234config 8260_PCI9_IDMA1
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 2fa0075f2b5f..50b4bbd06804 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -768,91 +768,6 @@ _GLOBAL(_outsb)
768 bdnz 00b 768 bdnz 00b
769 blr 769 blr
770 770
771_GLOBAL(_insw)
772 cmpwi 0,r5,0
773 mtctr r5
774 subi r4,r4,2
775 blelr-
77600: lhbrx r5,0,r3
77701: eieio
77802: sthu r5,2(r4)
779 ISYNC_8xx
780 .section .fixup,"ax"
78103: blr
782 .text
783 .section __ex_table, "a"
784 .align 2
785 .long 00b, 03b
786 .long 01b, 03b
787 .long 02b, 03b
788 .text
789 bdnz 00b
790 blr
791
792_GLOBAL(_outsw)
793 cmpwi 0,r5,0
794 mtctr r5
795 subi r4,r4,2
796 blelr-
79700: lhzu r5,2(r4)
79801: eieio
79902: sthbrx r5,0,r3
800 ISYNC_8xx
801 .section .fixup,"ax"
80203: blr
803 .text
804 .section __ex_table, "a"
805 .align 2
806 .long 00b, 03b
807 .long 01b, 03b
808 .long 02b, 03b
809 .text
810 bdnz 00b
811 blr
812
813_GLOBAL(_insl)
814 cmpwi 0,r5,0
815 mtctr r5
816 subi r4,r4,4
817 blelr-
81800: lwbrx r5,0,r3
81901: eieio
82002: stwu r5,4(r4)
821 ISYNC_8xx
822 .section .fixup,"ax"
82303: blr
824 .text
825 .section __ex_table, "a"
826 .align 2
827 .long 00b, 03b
828 .long 01b, 03b
829 .long 02b, 03b
830 .text
831 bdnz 00b
832 blr
833
834_GLOBAL(_outsl)
835 cmpwi 0,r5,0
836 mtctr r5
837 subi r4,r4,4
838 blelr-
83900: lwzu r5,4(r4)
84001: stwbrx r5,0,r3
84102: eieio
842 ISYNC_8xx
843 .section .fixup,"ax"
84403: blr
845 .text
846 .section __ex_table, "a"
847 .align 2
848 .long 00b, 03b
849 .long 01b, 03b
850 .long 02b, 03b
851 .text
852 bdnz 00b
853 blr
854
855_GLOBAL(__ide_mm_insw)
856_GLOBAL(_insw_ns) 771_GLOBAL(_insw_ns)
857 cmpwi 0,r5,0 772 cmpwi 0,r5,0
858 mtctr r5 773 mtctr r5
@@ -874,7 +789,6 @@ _GLOBAL(_insw_ns)
874 bdnz 00b 789 bdnz 00b
875 blr 790 blr
876 791
877_GLOBAL(__ide_mm_outsw)
878_GLOBAL(_outsw_ns) 792_GLOBAL(_outsw_ns)
879 cmpwi 0,r5,0 793 cmpwi 0,r5,0
880 mtctr r5 794 mtctr r5
@@ -896,7 +810,6 @@ _GLOBAL(_outsw_ns)
896 bdnz 00b 810 bdnz 00b
897 blr 811 blr
898 812
899_GLOBAL(__ide_mm_insl)
900_GLOBAL(_insl_ns) 813_GLOBAL(_insl_ns)
901 cmpwi 0,r5,0 814 cmpwi 0,r5,0
902 mtctr r5 815 mtctr r5
@@ -918,7 +831,6 @@ _GLOBAL(_insl_ns)
918 bdnz 00b 831 bdnz 00b
919 blr 832 blr
920 833
921_GLOBAL(__ide_mm_outsl)
922_GLOBAL(_outsl_ns) 834_GLOBAL(_outsl_ns)
923 cmpwi 0,r5,0 835 cmpwi 0,r5,0
924 mtctr r5 836 mtctr r5
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index d1735401384c..c8b65ca8a350 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -115,17 +115,8 @@ EXPORT_SYMBOL(outw);
115EXPORT_SYMBOL(outl); 115EXPORT_SYMBOL(outl);
116EXPORT_SYMBOL(outsl);*/ 116EXPORT_SYMBOL(outsl);*/
117 117
118EXPORT_SYMBOL(__ide_mm_insl);
119EXPORT_SYMBOL(__ide_mm_outsw);
120EXPORT_SYMBOL(__ide_mm_insw);
121EXPORT_SYMBOL(__ide_mm_outsl);
122
123EXPORT_SYMBOL(_insb); 118EXPORT_SYMBOL(_insb);
124EXPORT_SYMBOL(_outsb); 119EXPORT_SYMBOL(_outsb);
125EXPORT_SYMBOL(_insw);
126EXPORT_SYMBOL(_outsw);
127EXPORT_SYMBOL(_insl);
128EXPORT_SYMBOL(_outsl);
129EXPORT_SYMBOL(_insw_ns); 120EXPORT_SYMBOL(_insw_ns);
130EXPORT_SYMBOL(_outsw_ns); 121EXPORT_SYMBOL(_outsw_ns);
131EXPORT_SYMBOL(_insl_ns); 122EXPORT_SYMBOL(_insl_ns);
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index a74f46d9826f..5458ac5da7c3 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -127,11 +127,8 @@ void machine_restart(char *cmd)
127 ppc_md.restart(cmd); 127 ppc_md.restart(cmd);
128} 128}
129 129
130void machine_power_off(void) 130static void ppc_generic_power_off(void)
131{ 131{
132#ifdef CONFIG_NVRAM
133 nvram_sync();
134#endif
135 ppc_md.power_off(); 132 ppc_md.power_off();
136} 133}
137 134
@@ -143,7 +140,17 @@ void machine_halt(void)
143 ppc_md.halt(); 140 ppc_md.halt();
144} 141}
145 142
146void (*pm_power_off)(void) = machine_power_off; 143void (*pm_power_off)(void) = ppc_generic_power_off;
144
145void machine_power_off(void)
146{
147#ifdef CONFIG_NVRAM
148 nvram_sync();
149#endif
150 if (pm_power_off)
151 pm_power_off();
152 ppc_generic_power_off();
153}
147 154
148#ifdef CONFIG_TAU 155#ifdef CONFIG_TAU
149extern u32 cpu_temp(unsigned long cpu); 156extern u32 cpu_temp(unsigned long cpu);
diff --git a/arch/ppc/platforms/85xx/sbc8560.h b/arch/ppc/platforms/85xx/sbc8560.h
index c7d61cf3a449..e5e156f60100 100644
--- a/arch/ppc/platforms/85xx/sbc8560.h
+++ b/arch/ppc/platforms/85xx/sbc8560.h
@@ -14,6 +14,7 @@
14#define __MACH_SBC8560_H__ 14#define __MACH_SBC8560_H__
15 15
16#include <platforms/85xx/sbc85xx.h> 16#include <platforms/85xx/sbc85xx.h>
17#include <asm/irq.h>
17 18
18#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET) 19#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
19 20
diff --git a/arch/ppc/platforms/85xx/sbc85xx.h b/arch/ppc/platforms/85xx/sbc85xx.h
index 21ea7a55639b..51df4dc04e22 100644
--- a/arch/ppc/platforms/85xx/sbc85xx.h
+++ b/arch/ppc/platforms/85xx/sbc85xx.h
@@ -49,4 +49,22 @@ extern void sbc8560_init_IRQ(void) __init;
49 49
50#define MPC85XX_PCI1_IO_SIZE 0x01000000 50#define MPC85XX_PCI1_IO_SIZE 0x01000000
51 51
52/* FCC1 Clock Source Configuration. These can be
53 * redefined in the board specific file.
54 * Can only choose from CLK9-12 */
55#define F1_RXCLK 12
56#define F1_TXCLK 11
57
58/* FCC2 Clock Source Configuration. These can be
59 * redefined in the board specific file.
60 * Can only choose from CLK13-16 */
61#define F2_RXCLK 13
62#define F2_TXCLK 14
63
64/* FCC3 Clock Source Configuration. These can be
65 * redefined in the board specific file.
66 * Can only choose from CLK13-16 */
67#define F3_RXCLK 15
68#define F3_TXCLK 16
69
52#endif /* __PLATFORMS_85XX_SBC85XX_H__ */ 70#endif /* __PLATFORMS_85XX_SBC85XX_H__ */
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c
index 974581ea4849..5475709ce07b 100644
--- a/arch/ppc/syslib/m8260_pci_erratum9.c
+++ b/arch/ppc/syslib/m8260_pci_erratum9.c
@@ -339,20 +339,6 @@ void insl(unsigned port, void *buf, int nl)
339 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0); 339 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
340} 340}
341 341
342void insw_ns(unsigned port, void *buf, int ns)
343{
344 u8 *addr = (u8 *)(port + _IO_BASE);
345
346 idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
347}
348
349void insl_ns(unsigned port, void *buf, int nl)
350{
351 u8 *addr = (u8 *)(port + _IO_BASE);
352
353 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
354}
355
356void *memcpy_fromio(void *dest, unsigned long src, size_t count) 342void *memcpy_fromio(void *dest, unsigned long src, size_t count)
357{ 343{
358 unsigned long pa = iopa((unsigned long) src); 344 unsigned long pa = iopa((unsigned long) src);
@@ -373,8 +359,6 @@ EXPORT_SYMBOL(inl);
373EXPORT_SYMBOL(insb); 359EXPORT_SYMBOL(insb);
374EXPORT_SYMBOL(insw); 360EXPORT_SYMBOL(insw);
375EXPORT_SYMBOL(insl); 361EXPORT_SYMBOL(insl);
376EXPORT_SYMBOL(insw_ns);
377EXPORT_SYMBOL(insl_ns);
378EXPORT_SYMBOL(memcpy_fromio); 362EXPORT_SYMBOL(memcpy_fromio);
379 363
380#endif /* ifdef CONFIG_8260_PCI9 */ 364#endif /* ifdef CONFIG_8260_PCI9 */
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index f7e92986952a..d74a883e5bde 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -15,6 +15,7 @@
15#include <asm/processor.h> 15#include <asm/processor.h>
16#include <asm/delay.h> 16#include <asm/delay.h>
17#include <asm/btext.h> 17#include <asm/btext.h>
18#include <asm/ibm4xx.h>
18 19
19static volatile unsigned char *sccc, *sccd; 20static volatile unsigned char *sccc, *sccd;
20unsigned int TXRDY, RXRDY, DLAB; 21unsigned int TXRDY, RXRDY, DLAB;
@@ -57,23 +58,30 @@ static struct sysrq_key_op sysrq_xmon_op =
57void 58void
58xmon_map_scc(void) 59xmon_map_scc(void)
59{ 60{
60#ifdef CONFIG_PPC_PREP 61#if defined(CONFIG_GEMINI)
61 volatile unsigned char *base;
62
63#elif defined(CONFIG_GEMINI)
64 /* should already be mapped by the kernel boot */ 62 /* should already be mapped by the kernel boot */
65 sccc = (volatile unsigned char *) 0xffeffb0d;
66 sccd = (volatile unsigned char *) 0xffeffb08; 63 sccd = (volatile unsigned char *) 0xffeffb08;
67 TXRDY = 0x20;
68 RXRDY = 1;
69 DLAB = 0x80;
70#elif defined(CONFIG_405GP) 64#elif defined(CONFIG_405GP)
71 sccc = (volatile unsigned char *)0xef600305;
72 sccd = (volatile unsigned char *)0xef600300; 65 sccd = (volatile unsigned char *)0xef600300;
66#elif defined(CONFIG_440EP)
67 sccd = (volatile unsigned char *) ioremap(PPC440EP_UART0_ADDR, 8);
68#elif defined(CONFIG_440SP)
69 sccd = (volatile unsigned char *) ioremap64(PPC440SP_UART0_ADDR, 8);
70#elif defined(CONFIG_440SPE)
71 sccd = (volatile unsigned char *) ioremap64(PPC440SPE_UART0_ADDR, 8);
72#elif defined(CONFIG_44x)
73 /* This is the default for 44x platforms. Any boards that have a
74 different UART address need to be put in cases before this or the
75 port will be mapped incorrectly */
76 sccd = (volatile unsigned char *) ioremap64(PPC440GP_UART0_ADDR, 8);
77#endif /* platform */
78
79#ifndef CONFIG_PPC_PREP
80 sccc = sccd + 5;
73 TXRDY = 0x20; 81 TXRDY = 0x20;
74 RXRDY = 1; 82 RXRDY = 1;
75 DLAB = 0x80; 83 DLAB = 0x80;
76#endif /* platform */ 84#endif
77 85
78 register_sysrq_key('x', &sysrq_xmon_op); 86 register_sysrq_key('x', &sysrq_xmon_op);
79} 87}
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 37d234f93394..b1a91744fd2d 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -153,6 +153,12 @@ static int xmon_trace[NR_CPUS];
153#define SSTEP 1 /* stepping because of 's' command */ 153#define SSTEP 1 /* stepping because of 's' command */
154#define BRSTEP 2 /* stepping over breakpoint */ 154#define BRSTEP 2 /* stepping over breakpoint */
155 155
156#ifdef CONFIG_4xx
157#define MSR_SSTEP_ENABLE 0x200
158#else
159#define MSR_SSTEP_ENABLE 0x400
160#endif
161
156static struct pt_regs *xmon_regs[NR_CPUS]; 162static struct pt_regs *xmon_regs[NR_CPUS];
157 163
158extern inline void sync(void) 164extern inline void sync(void)
@@ -211,6 +217,14 @@ static void get_tb(unsigned *p)
211 p[1] = lo; 217 p[1] = lo;
212} 218}
213 219
220static inline void xmon_enable_sstep(struct pt_regs *regs)
221{
222 regs->msr |= MSR_SSTEP_ENABLE;
223#ifdef CONFIG_4xx
224 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
225#endif
226}
227
214int xmon(struct pt_regs *excp) 228int xmon(struct pt_regs *excp)
215{ 229{
216 struct pt_regs regs; 230 struct pt_regs regs;
@@ -254,10 +268,10 @@ int xmon(struct pt_regs *excp)
254 cmd = cmds(excp); 268 cmd = cmds(excp);
255 if (cmd == 's') { 269 if (cmd == 's') {
256 xmon_trace[smp_processor_id()] = SSTEP; 270 xmon_trace[smp_processor_id()] = SSTEP;
257 excp->msr |= 0x400; 271 xmon_enable_sstep(excp);
258 } else if (at_breakpoint(excp->nip)) { 272 } else if (at_breakpoint(excp->nip)) {
259 xmon_trace[smp_processor_id()] = BRSTEP; 273 xmon_trace[smp_processor_id()] = BRSTEP;
260 excp->msr |= 0x400; 274 xmon_enable_sstep(excp);
261 } else { 275 } else {
262 xmon_trace[smp_processor_id()] = 0; 276 xmon_trace[smp_processor_id()] = 0;
263 insert_bpts(); 277 insert_bpts();
@@ -298,7 +312,7 @@ xmon_bpt(struct pt_regs *regs)
298 remove_bpts(); 312 remove_bpts();
299 excprint(regs); 313 excprint(regs);
300 xmon_trace[smp_processor_id()] = BRSTEP; 314 xmon_trace[smp_processor_id()] = BRSTEP;
301 regs->msr |= 0x400; 315 xmon_enable_sstep(regs);
302 } else { 316 } else {
303 xmon(regs); 317 xmon(regs);
304 } 318 }
@@ -385,7 +399,7 @@ insert_bpts(void)
385 } 399 }
386 store_inst((void *) bp->address); 400 store_inst((void *) bp->address);
387 } 401 }
388#if !defined(CONFIG_8xx) 402#if ! (defined(CONFIG_8xx) || defined(CONFIG_4xx))
389 if (dabr.enabled) 403 if (dabr.enabled)
390 set_dabr(dabr.address); 404 set_dabr(dabr.address);
391 if (iabr.enabled) 405 if (iabr.enabled)
@@ -400,7 +414,7 @@ remove_bpts(void)
400 struct bpt *bp; 414 struct bpt *bp;
401 unsigned instr; 415 unsigned instr;
402 416
403#if !defined(CONFIG_8xx) 417#if ! (defined(CONFIG_8xx) || defined(CONFIG_4xx))
404 set_dabr(0); 418 set_dabr(0);
405 set_iabr(0); 419 set_iabr(0);
406#endif 420#endif
@@ -677,7 +691,7 @@ bpt_cmds(void)
677 691
678 cmd = inchar(); 692 cmd = inchar();
679 switch (cmd) { 693 switch (cmd) {
680#if !defined(CONFIG_8xx) 694#if ! (defined(CONFIG_8xx) || defined(CONFIG_4xx))
681 case 'd': 695 case 'd':
682 mode = 7; 696 mode = 7;
683 cmd = inchar(); 697 cmd = inchar();
@@ -792,7 +806,7 @@ backtrace(struct pt_regs *excp)
792 for (; sp != 0; sp = stack[0]) { 806 for (; sp != 0; sp = stack[0]) {
793 if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) 807 if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
794 break; 808 break;
795 printf("[%.8lx] ", stack); 809 printf("[%.8lx] ", stack[0]);
796 xmon_print_symbol(stack[1], " ", "\n"); 810 xmon_print_symbol(stack[1], " ", "\n");
797 if (stack[1] == (unsigned) &ret_from_except 811 if (stack[1] == (unsigned) &ret_from_except
798 || stack[1] == (unsigned) &ret_from_except_full 812 || stack[1] == (unsigned) &ret_from_except_full
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2f4f70c4dbb2..b216ca659cdf 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -460,8 +460,7 @@ config S390_HYPFS_FS
460 information in an s390 hypervisor environment. 460 information in an s390 hypervisor environment.
461 461
462config KEXEC 462config KEXEC
463 bool "kexec system call (EXPERIMENTAL)" 463 bool "kexec system call"
464 depends on EXPERIMENTAL
465 help 464 help
466 kexec is a system call that implements the ability to shutdown your 465 kexec is a system call that implements the ability to shutdown your
467 current kernel, and to start another kernel. It is like a reboot 466 current kernel, and to start another kernel. It is like a reboot
@@ -487,8 +486,22 @@ source "drivers/net/Kconfig"
487 486
488source "fs/Kconfig" 487source "fs/Kconfig"
489 488
489menu "Instrumentation Support"
490
490source "arch/s390/oprofile/Kconfig" 491source "arch/s390/oprofile/Kconfig"
491 492
493config KPROBES
494 bool "Kprobes (EXPERIMENTAL)"
495 depends on EXPERIMENTAL && MODULES
496 help
497 Kprobes allows you to trap at almost any kernel address and
498 execute a callback function. register_kprobe() establishes
499 a probepoint and specifies the callback. Kprobes is useful
500 for kernel debugging, non-intrusive instrumentation and testing.
501 If in doubt, say "N".
502
503endmenu
504
492source "arch/s390/Kconfig.debug" 505source "arch/s390/Kconfig.debug"
493 506
494source "security/Kconfig" 507source "security/Kconfig"
diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h
index 71d65eb30650..0429481dea63 100644
--- a/arch/s390/appldata/appldata.h
+++ b/arch/s390/appldata/appldata.h
@@ -29,22 +29,6 @@
29#define CTL_APPLDATA_NET_SUM 2125 29#define CTL_APPLDATA_NET_SUM 2125
30#define CTL_APPLDATA_PROC 2126 30#define CTL_APPLDATA_PROC 2126
31 31
32#ifndef CONFIG_64BIT
33
34#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */
35#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */
36#define APPLDATA_GEN_EVENT_RECORD 0x02
37#define APPLDATA_START_CONFIG_REC 0x03
38
39#else
40
41#define APPLDATA_START_INTERVAL_REC 0x80
42#define APPLDATA_STOP_REC 0x81
43#define APPLDATA_GEN_EVENT_RECORD 0x82
44#define APPLDATA_START_CONFIG_REC 0x83
45
46#endif /* CONFIG_64BIT */
47
48#define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x) 32#define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x)
49#define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) 33#define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x)
50#define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) 34#define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x)
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index a0a94e0ef8d1..b69ed742f981 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -14,20 +14,20 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <asm/uaccess.h>
18#include <asm/io.h>
19#include <asm/smp.h>
20#include <linux/interrupt.h> 17#include <linux/interrupt.h>
21#include <linux/proc_fs.h> 18#include <linux/proc_fs.h>
22#include <linux/page-flags.h> 19#include <linux/page-flags.h>
23#include <linux/swap.h> 20#include <linux/swap.h>
24#include <linux/pagemap.h> 21#include <linux/pagemap.h>
25#include <linux/sysctl.h> 22#include <linux/sysctl.h>
26#include <asm/timer.h>
27//#include <linux/kernel_stat.h>
28#include <linux/notifier.h> 23#include <linux/notifier.h>
29#include <linux/cpu.h> 24#include <linux/cpu.h>
30#include <linux/workqueue.h> 25#include <linux/workqueue.h>
26#include <asm/appldata.h>
27#include <asm/timer.h>
28#include <asm/uaccess.h>
29#include <asm/io.h>
30#include <asm/smp.h>
31 31
32#include "appldata.h" 32#include "appldata.h"
33 33
@@ -39,34 +39,6 @@
39 39
40#define TOD_MICRO 0x01000 /* nr. of TOD clock units 40#define TOD_MICRO 0x01000 /* nr. of TOD clock units
41 for 1 microsecond */ 41 for 1 microsecond */
42
43/*
44 * Parameter list for DIAGNOSE X'DC'
45 */
46#ifndef CONFIG_64BIT
47struct appldata_parameter_list {
48 u16 diag; /* The DIAGNOSE code X'00DC' */
49 u8 function; /* The function code for the DIAGNOSE */
50 u8 parlist_length; /* Length of the parameter list */
51 u32 product_id_addr; /* Address of the 16-byte product ID */
52 u16 reserved;
53 u16 buffer_length; /* Length of the application data buffer */
54 u32 buffer_addr; /* Address of the application data buffer */
55};
56#else
57struct appldata_parameter_list {
58 u16 diag;
59 u8 function;
60 u8 parlist_length;
61 u32 unused01;
62 u16 reserved;
63 u16 buffer_length;
64 u32 unused02;
65 u64 product_id_addr;
66 u64 buffer_addr;
67};
68#endif /* CONFIG_64BIT */
69
70/* 42/*
71 * /proc entries (sysctl) 43 * /proc entries (sysctl)
72 */ 44 */
@@ -181,46 +153,17 @@ static void appldata_work_fn(void *data)
181int appldata_diag(char record_nr, u16 function, unsigned long buffer, 153int appldata_diag(char record_nr, u16 function, unsigned long buffer,
182 u16 length, char *mod_lvl) 154 u16 length, char *mod_lvl)
183{ 155{
184 unsigned long ry; 156 struct appldata_product_id id = {
185 struct appldata_product_id {
186 char prod_nr[7]; /* product nr. */
187 char prod_fn[2]; /* product function */
188 char record_nr; /* record nr. */
189 char version_nr[2]; /* version */
190 char release_nr[2]; /* release */
191 char mod_lvl[2]; /* modification lvl. */
192 } appldata_product_id = {
193 /* all strings are EBCDIC, record_nr is byte */
194 .prod_nr = {0xD3, 0xC9, 0xD5, 0xE4, 157 .prod_nr = {0xD3, 0xC9, 0xD5, 0xE4,
195 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */ 158 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */
196 .prod_fn = {0xD5, 0xD3}, /* "NL" */ 159 .prod_fn = 0xD5D3, /* "NL" */
197 .record_nr = record_nr, 160 .record_nr = record_nr,
198 .version_nr = {0xF2, 0xF6}, /* "26" */ 161 .version_nr = 0xF2F6, /* "26" */
199 .release_nr = {0xF0, 0xF1}, /* "01" */ 162 .release_nr = 0xF0F1, /* "01" */
200 .mod_lvl = {mod_lvl[0], mod_lvl[1]}, 163 .mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1],
201 };
202 struct appldata_parameter_list appldata_parameter_list = {
203 .diag = 0xDC,
204 .function = function,
205 .parlist_length =
206 sizeof(appldata_parameter_list),
207 .buffer_length = length,
208 .product_id_addr =
209 (unsigned long) &appldata_product_id,
210 .buffer_addr = virt_to_phys((void *) buffer)
211 }; 164 };
212 165
213 if (!MACHINE_IS_VM) 166 return appldata_asm(&id, function, (void *) buffer, length);
214 return -ENOSYS;
215 ry = -1;
216 asm volatile(
217 "diag %1,%0,0xDC\n\t"
218 : "=d" (ry)
219 : "d" (&appldata_parameter_list),
220 "m" (appldata_parameter_list),
221 "m" (appldata_product_id)
222 : "cc");
223 return (int) ry;
224} 167}
225/************************ timer, work, DIAG <END> ****************************/ 168/************************ timer, work, DIAG <END> ****************************/
226 169
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index 161acc5c8a1b..76a15523ae9e 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -16,6 +16,7 @@
16#include <linux/kernel_stat.h> 16#include <linux/kernel_stat.h>
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <asm/appldata.h>
19#include <asm/smp.h> 20#include <asm/smp.h>
20 21
21#include "appldata.h" 22#include "appldata.h"
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 5713c7e5bd16..15c9eec02928 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -16,9 +16,9 @@
16 * 16 *
17 */ 17 */
18 18
19#include <crypto/algapi.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/crypto.h>
22#include "crypt_s390.h" 22#include "crypt_s390.h"
23 23
24#define AES_MIN_KEY_SIZE 16 24#define AES_MIN_KEY_SIZE 16
@@ -34,13 +34,16 @@ int has_aes_256 = 0;
34struct s390_aes_ctx { 34struct s390_aes_ctx {
35 u8 iv[AES_BLOCK_SIZE]; 35 u8 iv[AES_BLOCK_SIZE];
36 u8 key[AES_MAX_KEY_SIZE]; 36 u8 key[AES_MAX_KEY_SIZE];
37 long enc;
38 long dec;
37 int key_len; 39 int key_len;
38}; 40};
39 41
40static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 42static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
41 unsigned int key_len, u32 *flags) 43 unsigned int key_len)
42{ 44{
43 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); 45 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
46 u32 *flags = &tfm->crt_flags;
44 47
45 switch (key_len) { 48 switch (key_len) {
46 case 16: 49 case 16:
@@ -110,133 +113,206 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
110 } 113 }
111} 114}
112 115
113static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
114 const u8 *in, unsigned int nbytes)
115{
116 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
117 int ret;
118 116
119 /* only use complete blocks */ 117static struct crypto_alg aes_alg = {
120 nbytes &= ~(AES_BLOCK_SIZE - 1); 118 .cra_name = "aes",
119 .cra_driver_name = "aes-s390",
120 .cra_priority = CRYPT_S390_PRIORITY,
121 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
122 .cra_blocksize = AES_BLOCK_SIZE,
123 .cra_ctxsize = sizeof(struct s390_aes_ctx),
124 .cra_module = THIS_MODULE,
125 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
126 .cra_u = {
127 .cipher = {
128 .cia_min_keysize = AES_MIN_KEY_SIZE,
129 .cia_max_keysize = AES_MAX_KEY_SIZE,
130 .cia_setkey = aes_set_key,
131 .cia_encrypt = aes_encrypt,
132 .cia_decrypt = aes_decrypt,
133 }
134 }
135};
136
137static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
138 unsigned int key_len)
139{
140 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
121 141
122 switch (sctx->key_len) { 142 switch (key_len) {
123 case 16: 143 case 16:
124 ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes); 144 sctx->enc = KM_AES_128_ENCRYPT;
125 BUG_ON((ret < 0) || (ret != nbytes)); 145 sctx->dec = KM_AES_128_DECRYPT;
126 break; 146 break;
127 case 24: 147 case 24:
128 ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes); 148 sctx->enc = KM_AES_192_ENCRYPT;
129 BUG_ON((ret < 0) || (ret != nbytes)); 149 sctx->dec = KM_AES_192_DECRYPT;
130 break; 150 break;
131 case 32: 151 case 32:
132 ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes); 152 sctx->enc = KM_AES_256_ENCRYPT;
133 BUG_ON((ret < 0) || (ret != nbytes)); 153 sctx->dec = KM_AES_256_DECRYPT;
134 break; 154 break;
135 } 155 }
136 return nbytes; 156
157 return aes_set_key(tfm, in_key, key_len);
137} 158}
138 159
139static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, 160static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
140 const u8 *in, unsigned int nbytes) 161 struct blkcipher_walk *walk)
141{ 162{
142 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 163 int ret = blkcipher_walk_virt(desc, walk);
143 int ret; 164 unsigned int nbytes;
144 165
145 /* only use complete blocks */ 166 while ((nbytes = walk->nbytes)) {
146 nbytes &= ~(AES_BLOCK_SIZE - 1); 167 /* only use complete blocks */
168 unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
169 u8 *out = walk->dst.virt.addr;
170 u8 *in = walk->src.virt.addr;
147 171
148 switch (sctx->key_len) { 172 ret = crypt_s390_km(func, param, out, in, n);
149 case 16: 173 BUG_ON((ret < 0) || (ret != n));
150 ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes); 174
151 BUG_ON((ret < 0) || (ret != nbytes)); 175 nbytes &= AES_BLOCK_SIZE - 1;
152 break; 176 ret = blkcipher_walk_done(desc, walk, nbytes);
153 case 24:
154 ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
155 BUG_ON((ret < 0) || (ret != nbytes));
156 break;
157 case 32:
158 ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
159 BUG_ON((ret < 0) || (ret != nbytes));
160 break;
161 } 177 }
162 return nbytes; 178
179 return ret;
163} 180}
164 181
165static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, 182static int ecb_aes_encrypt(struct blkcipher_desc *desc,
166 const u8 *in, unsigned int nbytes) 183 struct scatterlist *dst, struct scatterlist *src,
184 unsigned int nbytes)
167{ 185{
168 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 186 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
169 int ret; 187 struct blkcipher_walk walk;
170 188
171 /* only use complete blocks */ 189 blkcipher_walk_init(&walk, dst, src, nbytes);
172 nbytes &= ~(AES_BLOCK_SIZE - 1); 190 return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
191}
173 192
174 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); 193static int ecb_aes_decrypt(struct blkcipher_desc *desc,
175 switch (sctx->key_len) { 194 struct scatterlist *dst, struct scatterlist *src,
195 unsigned int nbytes)
196{
197 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
198 struct blkcipher_walk walk;
199
200 blkcipher_walk_init(&walk, dst, src, nbytes);
201 return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk);
202}
203
204static struct crypto_alg ecb_aes_alg = {
205 .cra_name = "ecb(aes)",
206 .cra_driver_name = "ecb-aes-s390",
207 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
208 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
209 .cra_blocksize = AES_BLOCK_SIZE,
210 .cra_ctxsize = sizeof(struct s390_aes_ctx),
211 .cra_type = &crypto_blkcipher_type,
212 .cra_module = THIS_MODULE,
213 .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list),
214 .cra_u = {
215 .blkcipher = {
216 .min_keysize = AES_MIN_KEY_SIZE,
217 .max_keysize = AES_MAX_KEY_SIZE,
218 .setkey = ecb_aes_set_key,
219 .encrypt = ecb_aes_encrypt,
220 .decrypt = ecb_aes_decrypt,
221 }
222 }
223};
224
225static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
226 unsigned int key_len)
227{
228 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
229
230 switch (key_len) {
176 case 16: 231 case 16:
177 ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes); 232 sctx->enc = KMC_AES_128_ENCRYPT;
178 BUG_ON((ret < 0) || (ret != nbytes)); 233 sctx->dec = KMC_AES_128_DECRYPT;
179 break; 234 break;
180 case 24: 235 case 24:
181 ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes); 236 sctx->enc = KMC_AES_192_ENCRYPT;
182 BUG_ON((ret < 0) || (ret != nbytes)); 237 sctx->dec = KMC_AES_192_DECRYPT;
183 break; 238 break;
184 case 32: 239 case 32:
185 ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes); 240 sctx->enc = KMC_AES_256_ENCRYPT;
186 BUG_ON((ret < 0) || (ret != nbytes)); 241 sctx->dec = KMC_AES_256_DECRYPT;
187 break; 242 break;
188 } 243 }
189 memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
190 244
191 return nbytes; 245 return aes_set_key(tfm, in_key, key_len);
192} 246}
193 247
194static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, 248static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
195 const u8 *in, unsigned int nbytes) 249 struct blkcipher_walk *walk)
196{ 250{
197 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 251 int ret = blkcipher_walk_virt(desc, walk);
198 int ret; 252 unsigned int nbytes = walk->nbytes;
199 253
200 /* only use complete blocks */ 254 if (!nbytes)
201 nbytes &= ~(AES_BLOCK_SIZE - 1); 255 goto out;
202 256
203 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); 257 memcpy(param, walk->iv, AES_BLOCK_SIZE);
204 switch (sctx->key_len) { 258 do {
205 case 16: 259 /* only use complete blocks */
206 ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes); 260 unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
207 BUG_ON((ret < 0) || (ret != nbytes)); 261 u8 *out = walk->dst.virt.addr;
208 break; 262 u8 *in = walk->src.virt.addr;
209 case 24: 263
210 ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes); 264 ret = crypt_s390_kmc(func, param, out, in, n);
211 BUG_ON((ret < 0) || (ret != nbytes)); 265 BUG_ON((ret < 0) || (ret != n));
212 break; 266
213 case 32: 267 nbytes &= AES_BLOCK_SIZE - 1;
214 ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes); 268 ret = blkcipher_walk_done(desc, walk, nbytes);
215 BUG_ON((ret < 0) || (ret != nbytes)); 269 } while ((nbytes = walk->nbytes));
216 break; 270 memcpy(walk->iv, param, AES_BLOCK_SIZE);
217 } 271
218 return nbytes; 272out:
273 return ret;
219} 274}
220 275
276static int cbc_aes_encrypt(struct blkcipher_desc *desc,
277 struct scatterlist *dst, struct scatterlist *src,
278 unsigned int nbytes)
279{
280 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
281 struct blkcipher_walk walk;
221 282
222static struct crypto_alg aes_alg = { 283 blkcipher_walk_init(&walk, dst, src, nbytes);
223 .cra_name = "aes", 284 return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
224 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 285}
286
287static int cbc_aes_decrypt(struct blkcipher_desc *desc,
288 struct scatterlist *dst, struct scatterlist *src,
289 unsigned int nbytes)
290{
291 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
292 struct blkcipher_walk walk;
293
294 blkcipher_walk_init(&walk, dst, src, nbytes);
295 return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
296}
297
298static struct crypto_alg cbc_aes_alg = {
299 .cra_name = "cbc(aes)",
300 .cra_driver_name = "cbc-aes-s390",
301 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
302 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
225 .cra_blocksize = AES_BLOCK_SIZE, 303 .cra_blocksize = AES_BLOCK_SIZE,
226 .cra_ctxsize = sizeof(struct s390_aes_ctx), 304 .cra_ctxsize = sizeof(struct s390_aes_ctx),
305 .cra_type = &crypto_blkcipher_type,
227 .cra_module = THIS_MODULE, 306 .cra_module = THIS_MODULE,
228 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), 307 .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
229 .cra_u = { 308 .cra_u = {
230 .cipher = { 309 .blkcipher = {
231 .cia_min_keysize = AES_MIN_KEY_SIZE, 310 .min_keysize = AES_MIN_KEY_SIZE,
232 .cia_max_keysize = AES_MAX_KEY_SIZE, 311 .max_keysize = AES_MAX_KEY_SIZE,
233 .cia_setkey = aes_set_key, 312 .ivsize = AES_BLOCK_SIZE,
234 .cia_encrypt = aes_encrypt, 313 .setkey = cbc_aes_set_key,
235 .cia_decrypt = aes_decrypt, 314 .encrypt = cbc_aes_encrypt,
236 .cia_encrypt_ecb = aes_encrypt_ecb, 315 .decrypt = cbc_aes_decrypt,
237 .cia_decrypt_ecb = aes_decrypt_ecb,
238 .cia_encrypt_cbc = aes_encrypt_cbc,
239 .cia_decrypt_cbc = aes_decrypt_cbc,
240 } 316 }
241 } 317 }
242}; 318};
@@ -256,13 +332,40 @@ static int __init aes_init(void)
256 return -ENOSYS; 332 return -ENOSYS;
257 333
258 ret = crypto_register_alg(&aes_alg); 334 ret = crypto_register_alg(&aes_alg);
259 if (ret != 0) 335 if (ret != 0) {
260 printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n"); 336 printk(KERN_INFO "crypt_s390: aes-s390 couldn't be loaded.\n");
337 goto aes_err;
338 }
339
340 ret = crypto_register_alg(&ecb_aes_alg);
341 if (ret != 0) {
342 printk(KERN_INFO
343 "crypt_s390: ecb-aes-s390 couldn't be loaded.\n");
344 goto ecb_aes_err;
345 }
346
347 ret = crypto_register_alg(&cbc_aes_alg);
348 if (ret != 0) {
349 printk(KERN_INFO
350 "crypt_s390: cbc-aes-s390 couldn't be loaded.\n");
351 goto cbc_aes_err;
352 }
353
354out:
261 return ret; 355 return ret;
356
357cbc_aes_err:
358 crypto_unregister_alg(&ecb_aes_alg);
359ecb_aes_err:
360 crypto_unregister_alg(&aes_alg);
361aes_err:
362 goto out;
262} 363}
263 364
264static void __exit aes_fini(void) 365static void __exit aes_fini(void)
265{ 366{
367 crypto_unregister_alg(&cbc_aes_alg);
368 crypto_unregister_alg(&ecb_aes_alg);
266 crypto_unregister_alg(&aes_alg); 369 crypto_unregister_alg(&aes_alg);
267} 370}
268 371
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h
index d1c259a7fe33..efd836c2e4a6 100644
--- a/arch/s390/crypto/crypt_s390.h
+++ b/arch/s390/crypto/crypt_s390.h
@@ -20,6 +20,9 @@
20#define CRYPT_S390_OP_MASK 0xFF00 20#define CRYPT_S390_OP_MASK 0xFF00
21#define CRYPT_S390_FUNC_MASK 0x00FF 21#define CRYPT_S390_FUNC_MASK 0x00FF
22 22
23#define CRYPT_S390_PRIORITY 300
24#define CRYPT_S390_COMPOSITE_PRIORITY 400
25
23/* s930 cryptographic operations */ 26/* s930 cryptographic operations */
24enum crypt_s390_operations { 27enum crypt_s390_operations {
25 CRYPT_S390_KM = 0x0100, 28 CRYPT_S390_KM = 0x0100,
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
index b3f7496a79b4..2aba04852fe3 100644
--- a/arch/s390/crypto/des_s390.c
+++ b/arch/s390/crypto/des_s390.c
@@ -13,9 +13,10 @@
13 * (at your option) any later version. 13 * (at your option) any later version.
14 * 14 *
15 */ 15 */
16
17#include <crypto/algapi.h>
16#include <linux/init.h> 18#include <linux/init.h>
17#include <linux/module.h> 19#include <linux/module.h>
18#include <linux/crypto.h>
19 20
20#include "crypt_s390.h" 21#include "crypt_s390.h"
21#include "crypto_des.h" 22#include "crypto_des.h"
@@ -45,9 +46,10 @@ struct crypt_s390_des3_192_ctx {
45}; 46};
46 47
47static int des_setkey(struct crypto_tfm *tfm, const u8 *key, 48static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
48 unsigned int keylen, u32 *flags) 49 unsigned int keylen)
49{ 50{
50 struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); 51 struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
52 u32 *flags = &tfm->crt_flags;
51 int ret; 53 int ret;
52 54
53 /* test if key is valid (not a weak key) */ 55 /* test if key is valid (not a weak key) */
@@ -71,85 +73,159 @@ static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
71 crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE); 73 crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
72} 74}
73 75
74static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out, 76static struct crypto_alg des_alg = {
75 const u8 *in, unsigned int nbytes) 77 .cra_name = "des",
78 .cra_driver_name = "des-s390",
79 .cra_priority = CRYPT_S390_PRIORITY,
80 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
81 .cra_blocksize = DES_BLOCK_SIZE,
82 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
83 .cra_module = THIS_MODULE,
84 .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
85 .cra_u = {
86 .cipher = {
87 .cia_min_keysize = DES_KEY_SIZE,
88 .cia_max_keysize = DES_KEY_SIZE,
89 .cia_setkey = des_setkey,
90 .cia_encrypt = des_encrypt,
91 .cia_decrypt = des_decrypt,
92 }
93 }
94};
95
96static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
97 void *param, struct blkcipher_walk *walk)
76{ 98{
77 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); 99 int ret = blkcipher_walk_virt(desc, walk);
78 int ret; 100 unsigned int nbytes;
101
102 while ((nbytes = walk->nbytes)) {
103 /* only use complete blocks */
104 unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
105 u8 *out = walk->dst.virt.addr;
106 u8 *in = walk->src.virt.addr;
79 107
80 /* only use complete blocks */ 108 ret = crypt_s390_km(func, param, out, in, n);
81 nbytes &= ~(DES_BLOCK_SIZE - 1); 109 BUG_ON((ret < 0) || (ret != n));
82 ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes);
83 BUG_ON((ret < 0) || (ret != nbytes));
84 110
85 return nbytes; 111 nbytes &= DES_BLOCK_SIZE - 1;
112 ret = blkcipher_walk_done(desc, walk, nbytes);
113 }
114
115 return ret;
86} 116}
87 117
88static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out, 118static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
89 const u8 *in, unsigned int nbytes) 119 void *param, struct blkcipher_walk *walk)
90{ 120{
91 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); 121 int ret = blkcipher_walk_virt(desc, walk);
92 int ret; 122 unsigned int nbytes = walk->nbytes;
123
124 if (!nbytes)
125 goto out;
126
127 memcpy(param, walk->iv, DES_BLOCK_SIZE);
128 do {
129 /* only use complete blocks */
130 unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
131 u8 *out = walk->dst.virt.addr;
132 u8 *in = walk->src.virt.addr;
93 133
94 /* only use complete blocks */ 134 ret = crypt_s390_kmc(func, param, out, in, n);
95 nbytes &= ~(DES_BLOCK_SIZE - 1); 135 BUG_ON((ret < 0) || (ret != n));
96 ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes);
97 BUG_ON((ret < 0) || (ret != nbytes));
98 136
99 return nbytes; 137 nbytes &= DES_BLOCK_SIZE - 1;
138 ret = blkcipher_walk_done(desc, walk, nbytes);
139 } while ((nbytes = walk->nbytes));
140 memcpy(walk->iv, param, DES_BLOCK_SIZE);
141
142out:
143 return ret;
100} 144}
101 145
102static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out, 146static int ecb_des_encrypt(struct blkcipher_desc *desc,
103 const u8 *in, unsigned int nbytes) 147 struct scatterlist *dst, struct scatterlist *src,
148 unsigned int nbytes)
104{ 149{
105 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); 150 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
106 int ret; 151 struct blkcipher_walk walk;
107 152
108 /* only use complete blocks */ 153 blkcipher_walk_init(&walk, dst, src, nbytes);
109 nbytes &= ~(DES_BLOCK_SIZE - 1); 154 return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, sctx->key, &walk);
155}
110 156
111 memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE); 157static int ecb_des_decrypt(struct blkcipher_desc *desc,
112 ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes); 158 struct scatterlist *dst, struct scatterlist *src,
113 BUG_ON((ret < 0) || (ret != nbytes)); 159 unsigned int nbytes)
160{
161 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
162 struct blkcipher_walk walk;
114 163
115 memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE); 164 blkcipher_walk_init(&walk, dst, src, nbytes);
116 return nbytes; 165 return ecb_desall_crypt(desc, KM_DEA_DECRYPT, sctx->key, &walk);
117} 166}
118 167
119static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out, 168static struct crypto_alg ecb_des_alg = {
120 const u8 *in, unsigned int nbytes) 169 .cra_name = "ecb(des)",
170 .cra_driver_name = "ecb-des-s390",
171 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
172 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
173 .cra_blocksize = DES_BLOCK_SIZE,
174 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
175 .cra_type = &crypto_blkcipher_type,
176 .cra_module = THIS_MODULE,
177 .cra_list = LIST_HEAD_INIT(ecb_des_alg.cra_list),
178 .cra_u = {
179 .blkcipher = {
180 .min_keysize = DES_KEY_SIZE,
181 .max_keysize = DES_KEY_SIZE,
182 .setkey = des_setkey,
183 .encrypt = ecb_des_encrypt,
184 .decrypt = ecb_des_decrypt,
185 }
186 }
187};
188
189static int cbc_des_encrypt(struct blkcipher_desc *desc,
190 struct scatterlist *dst, struct scatterlist *src,
191 unsigned int nbytes)
121{ 192{
122 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); 193 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
123 int ret; 194 struct blkcipher_walk walk;
124 195
125 /* only use complete blocks */ 196 blkcipher_walk_init(&walk, dst, src, nbytes);
126 nbytes &= ~(DES_BLOCK_SIZE - 1); 197 return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, sctx->iv, &walk);
198}
127 199
128 memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE); 200static int cbc_des_decrypt(struct blkcipher_desc *desc,
129 ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes); 201 struct scatterlist *dst, struct scatterlist *src,
130 BUG_ON((ret < 0) || (ret != nbytes)); 202 unsigned int nbytes)
203{
204 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
205 struct blkcipher_walk walk;
131 206
132 return nbytes; 207 blkcipher_walk_init(&walk, dst, src, nbytes);
208 return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, sctx->iv, &walk);
133} 209}
134 210
135static struct crypto_alg des_alg = { 211static struct crypto_alg cbc_des_alg = {
136 .cra_name = "des", 212 .cra_name = "cbc(des)",
137 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 213 .cra_driver_name = "cbc-des-s390",
214 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
215 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
138 .cra_blocksize = DES_BLOCK_SIZE, 216 .cra_blocksize = DES_BLOCK_SIZE,
139 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), 217 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
218 .cra_type = &crypto_blkcipher_type,
140 .cra_module = THIS_MODULE, 219 .cra_module = THIS_MODULE,
141 .cra_list = LIST_HEAD_INIT(des_alg.cra_list), 220 .cra_list = LIST_HEAD_INIT(cbc_des_alg.cra_list),
142 .cra_u = { 221 .cra_u = {
143 .cipher = { 222 .blkcipher = {
144 .cia_min_keysize = DES_KEY_SIZE, 223 .min_keysize = DES_KEY_SIZE,
145 .cia_max_keysize = DES_KEY_SIZE, 224 .max_keysize = DES_KEY_SIZE,
146 .cia_setkey = des_setkey, 225 .ivsize = DES_BLOCK_SIZE,
147 .cia_encrypt = des_encrypt, 226 .setkey = des_setkey,
148 .cia_decrypt = des_decrypt, 227 .encrypt = cbc_des_encrypt,
149 .cia_encrypt_ecb = des_encrypt_ecb, 228 .decrypt = cbc_des_decrypt,
150 .cia_decrypt_ecb = des_decrypt_ecb,
151 .cia_encrypt_cbc = des_encrypt_cbc,
152 .cia_decrypt_cbc = des_decrypt_cbc,
153 } 229 }
154 } 230 }
155}; 231};
@@ -167,11 +243,12 @@ static struct crypto_alg des_alg = {
167 * 243 *
168 */ 244 */
169static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key, 245static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key,
170 unsigned int keylen, u32 *flags) 246 unsigned int keylen)
171{ 247{
172 int i, ret; 248 int i, ret;
173 struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm); 249 struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
174 const u8* temp_key = key; 250 const u8 *temp_key = key;
251 u32 *flags = &tfm->crt_flags;
175 252
176 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { 253 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
177 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; 254 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
@@ -202,89 +279,111 @@ static void des3_128_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
202 DES3_128_BLOCK_SIZE); 279 DES3_128_BLOCK_SIZE);
203} 280}
204 281
205static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc, 282static struct crypto_alg des3_128_alg = {
206 u8 *out, const u8 *in, 283 .cra_name = "des3_ede128",
207 unsigned int nbytes) 284 .cra_driver_name = "des3_ede128-s390",
208{ 285 .cra_priority = CRYPT_S390_PRIORITY,
209 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); 286 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
210 int ret; 287 .cra_blocksize = DES3_128_BLOCK_SIZE,
288 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
289 .cra_module = THIS_MODULE,
290 .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
291 .cra_u = {
292 .cipher = {
293 .cia_min_keysize = DES3_128_KEY_SIZE,
294 .cia_max_keysize = DES3_128_KEY_SIZE,
295 .cia_setkey = des3_128_setkey,
296 .cia_encrypt = des3_128_encrypt,
297 .cia_decrypt = des3_128_decrypt,
298 }
299 }
300};
211 301
212 /* only use complete blocks */ 302static int ecb_des3_128_encrypt(struct blkcipher_desc *desc,
213 nbytes &= ~(DES3_128_BLOCK_SIZE - 1); 303 struct scatterlist *dst,
214 ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes); 304 struct scatterlist *src, unsigned int nbytes)
215 BUG_ON((ret < 0) || (ret != nbytes)); 305{
306 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
307 struct blkcipher_walk walk;
216 308
217 return nbytes; 309 blkcipher_walk_init(&walk, dst, src, nbytes);
310 return ecb_desall_crypt(desc, KM_TDEA_128_ENCRYPT, sctx->key, &walk);
218} 311}
219 312
220static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc, 313static int ecb_des3_128_decrypt(struct blkcipher_desc *desc,
221 u8 *out, const u8 *in, 314 struct scatterlist *dst,
222 unsigned int nbytes) 315 struct scatterlist *src, unsigned int nbytes)
223{ 316{
224 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); 317 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
225 int ret; 318 struct blkcipher_walk walk;
226 319
227 /* only use complete blocks */ 320 blkcipher_walk_init(&walk, dst, src, nbytes);
228 nbytes &= ~(DES3_128_BLOCK_SIZE - 1); 321 return ecb_desall_crypt(desc, KM_TDEA_128_DECRYPT, sctx->key, &walk);
229 ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes);
230 BUG_ON((ret < 0) || (ret != nbytes));
231
232 return nbytes;
233} 322}
234 323
235static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc, 324static struct crypto_alg ecb_des3_128_alg = {
236 u8 *out, const u8 *in, 325 .cra_name = "ecb(des3_ede128)",
237 unsigned int nbytes) 326 .cra_driver_name = "ecb-des3_ede128-s390",
238{ 327 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
239 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); 328 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
240 int ret; 329 .cra_blocksize = DES3_128_BLOCK_SIZE,
241 330 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
242 /* only use complete blocks */ 331 .cra_type = &crypto_blkcipher_type,
243 nbytes &= ~(DES3_128_BLOCK_SIZE - 1); 332 .cra_module = THIS_MODULE,
333 .cra_list = LIST_HEAD_INIT(
334 ecb_des3_128_alg.cra_list),
335 .cra_u = {
336 .blkcipher = {
337 .min_keysize = DES3_128_KEY_SIZE,
338 .max_keysize = DES3_128_KEY_SIZE,
339 .setkey = des3_128_setkey,
340 .encrypt = ecb_des3_128_encrypt,
341 .decrypt = ecb_des3_128_decrypt,
342 }
343 }
344};
244 345
245 memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE); 346static int cbc_des3_128_encrypt(struct blkcipher_desc *desc,
246 ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes); 347 struct scatterlist *dst,
247 BUG_ON((ret < 0) || (ret != nbytes)); 348 struct scatterlist *src, unsigned int nbytes)
349{
350 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
351 struct blkcipher_walk walk;
248 352
249 memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE); 353 blkcipher_walk_init(&walk, dst, src, nbytes);
250 return nbytes; 354 return cbc_desall_crypt(desc, KMC_TDEA_128_ENCRYPT, sctx->iv, &walk);
251} 355}
252 356
253static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc, 357static int cbc_des3_128_decrypt(struct blkcipher_desc *desc,
254 u8 *out, const u8 *in, 358 struct scatterlist *dst,
255 unsigned int nbytes) 359 struct scatterlist *src, unsigned int nbytes)
256{ 360{
257 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); 361 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
258 int ret; 362 struct blkcipher_walk walk;
259
260 /* only use complete blocks */
261 nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
262
263 memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
264 ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes);
265 BUG_ON((ret < 0) || (ret != nbytes));
266 363
267 return nbytes; 364 blkcipher_walk_init(&walk, dst, src, nbytes);
365 return cbc_desall_crypt(desc, KMC_TDEA_128_DECRYPT, sctx->iv, &walk);
268} 366}
269 367
270static struct crypto_alg des3_128_alg = { 368static struct crypto_alg cbc_des3_128_alg = {
271 .cra_name = "des3_ede128", 369 .cra_name = "cbc(des3_ede128)",
272 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 370 .cra_driver_name = "cbc-des3_ede128-s390",
371 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
372 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
273 .cra_blocksize = DES3_128_BLOCK_SIZE, 373 .cra_blocksize = DES3_128_BLOCK_SIZE,
274 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx), 374 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
375 .cra_type = &crypto_blkcipher_type,
275 .cra_module = THIS_MODULE, 376 .cra_module = THIS_MODULE,
276 .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list), 377 .cra_list = LIST_HEAD_INIT(
378 cbc_des3_128_alg.cra_list),
277 .cra_u = { 379 .cra_u = {
278 .cipher = { 380 .blkcipher = {
279 .cia_min_keysize = DES3_128_KEY_SIZE, 381 .min_keysize = DES3_128_KEY_SIZE,
280 .cia_max_keysize = DES3_128_KEY_SIZE, 382 .max_keysize = DES3_128_KEY_SIZE,
281 .cia_setkey = des3_128_setkey, 383 .ivsize = DES3_128_BLOCK_SIZE,
282 .cia_encrypt = des3_128_encrypt, 384 .setkey = des3_128_setkey,
283 .cia_decrypt = des3_128_decrypt, 385 .encrypt = cbc_des3_128_encrypt,
284 .cia_encrypt_ecb = des3_128_encrypt_ecb, 386 .decrypt = cbc_des3_128_decrypt,
285 .cia_decrypt_ecb = des3_128_decrypt_ecb,
286 .cia_encrypt_cbc = des3_128_encrypt_cbc,
287 .cia_decrypt_cbc = des3_128_decrypt_cbc,
288 } 387 }
289 } 388 }
290}; 389};
@@ -303,11 +402,12 @@ static struct crypto_alg des3_128_alg = {
303 * 402 *
304 */ 403 */
305static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, 404static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
306 unsigned int keylen, u32 *flags) 405 unsigned int keylen)
307{ 406{
308 int i, ret; 407 int i, ret;
309 struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); 408 struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
310 const u8* temp_key = key; 409 const u8 *temp_key = key;
410 u32 *flags = &tfm->crt_flags;
311 411
312 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 412 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
313 memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], 413 memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
@@ -341,89 +441,111 @@ static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
341 DES3_192_BLOCK_SIZE); 441 DES3_192_BLOCK_SIZE);
342} 442}
343 443
344static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc, 444static struct crypto_alg des3_192_alg = {
345 u8 *out, const u8 *in, 445 .cra_name = "des3_ede",
346 unsigned int nbytes) 446 .cra_driver_name = "des3_ede-s390",
347{ 447 .cra_priority = CRYPT_S390_PRIORITY,
348 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); 448 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
349 int ret; 449 .cra_blocksize = DES3_192_BLOCK_SIZE,
450 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
451 .cra_module = THIS_MODULE,
452 .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
453 .cra_u = {
454 .cipher = {
455 .cia_min_keysize = DES3_192_KEY_SIZE,
456 .cia_max_keysize = DES3_192_KEY_SIZE,
457 .cia_setkey = des3_192_setkey,
458 .cia_encrypt = des3_192_encrypt,
459 .cia_decrypt = des3_192_decrypt,
460 }
461 }
462};
350 463
351 /* only use complete blocks */ 464static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
352 nbytes &= ~(DES3_192_BLOCK_SIZE - 1); 465 struct scatterlist *dst,
353 ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes); 466 struct scatterlist *src, unsigned int nbytes)
354 BUG_ON((ret < 0) || (ret != nbytes)); 467{
468 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
469 struct blkcipher_walk walk;
355 470
356 return nbytes; 471 blkcipher_walk_init(&walk, dst, src, nbytes);
472 return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, sctx->key, &walk);
357} 473}
358 474
359static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc, 475static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
360 u8 *out, const u8 *in, 476 struct scatterlist *dst,
361 unsigned int nbytes) 477 struct scatterlist *src, unsigned int nbytes)
362{ 478{
363 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); 479 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
364 int ret; 480 struct blkcipher_walk walk;
365
366 /* only use complete blocks */
367 nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
368 ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes);
369 BUG_ON((ret < 0) || (ret != nbytes));
370 481
371 return nbytes; 482 blkcipher_walk_init(&walk, dst, src, nbytes);
483 return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, sctx->key, &walk);
372} 484}
373 485
374static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc, 486static struct crypto_alg ecb_des3_192_alg = {
375 u8 *out, const u8 *in, 487 .cra_name = "ecb(des3_ede)",
376 unsigned int nbytes) 488 .cra_driver_name = "ecb-des3_ede-s390",
377{ 489 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
378 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); 490 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
379 int ret; 491 .cra_blocksize = DES3_192_BLOCK_SIZE,
380 492 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
381 /* only use complete blocks */ 493 .cra_type = &crypto_blkcipher_type,
382 nbytes &= ~(DES3_192_BLOCK_SIZE - 1); 494 .cra_module = THIS_MODULE,
495 .cra_list = LIST_HEAD_INIT(
496 ecb_des3_192_alg.cra_list),
497 .cra_u = {
498 .blkcipher = {
499 .min_keysize = DES3_192_KEY_SIZE,
500 .max_keysize = DES3_192_KEY_SIZE,
501 .setkey = des3_192_setkey,
502 .encrypt = ecb_des3_192_encrypt,
503 .decrypt = ecb_des3_192_decrypt,
504 }
505 }
506};
383 507
384 memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE); 508static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
385 ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes); 509 struct scatterlist *dst,
386 BUG_ON((ret < 0) || (ret != nbytes)); 510 struct scatterlist *src, unsigned int nbytes)
511{
512 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
513 struct blkcipher_walk walk;
387 514
388 memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE); 515 blkcipher_walk_init(&walk, dst, src, nbytes);
389 return nbytes; 516 return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, sctx->iv, &walk);
390} 517}
391 518
392static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc, 519static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
393 u8 *out, const u8 *in, 520 struct scatterlist *dst,
394 unsigned int nbytes) 521 struct scatterlist *src, unsigned int nbytes)
395{ 522{
396 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); 523 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
397 int ret; 524 struct blkcipher_walk walk;
398 525
399 /* only use complete blocks */ 526 blkcipher_walk_init(&walk, dst, src, nbytes);
400 nbytes &= ~(DES3_192_BLOCK_SIZE - 1); 527 return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, sctx->iv, &walk);
401
402 memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
403 ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes);
404 BUG_ON((ret < 0) || (ret != nbytes));
405
406 return nbytes;
407} 528}
408 529
409static struct crypto_alg des3_192_alg = { 530static struct crypto_alg cbc_des3_192_alg = {
410 .cra_name = "des3_ede", 531 .cra_name = "cbc(des3_ede)",
411 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 532 .cra_driver_name = "cbc-des3_ede-s390",
533 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
534 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
412 .cra_blocksize = DES3_192_BLOCK_SIZE, 535 .cra_blocksize = DES3_192_BLOCK_SIZE,
413 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), 536 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
537 .cra_type = &crypto_blkcipher_type,
414 .cra_module = THIS_MODULE, 538 .cra_module = THIS_MODULE,
415 .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list), 539 .cra_list = LIST_HEAD_INIT(
540 cbc_des3_192_alg.cra_list),
416 .cra_u = { 541 .cra_u = {
417 .cipher = { 542 .blkcipher = {
418 .cia_min_keysize = DES3_192_KEY_SIZE, 543 .min_keysize = DES3_192_KEY_SIZE,
419 .cia_max_keysize = DES3_192_KEY_SIZE, 544 .max_keysize = DES3_192_KEY_SIZE,
420 .cia_setkey = des3_192_setkey, 545 .ivsize = DES3_192_BLOCK_SIZE,
421 .cia_encrypt = des3_192_encrypt, 546 .setkey = des3_192_setkey,
422 .cia_decrypt = des3_192_decrypt, 547 .encrypt = cbc_des3_192_encrypt,
423 .cia_encrypt_ecb = des3_192_encrypt_ecb, 548 .decrypt = cbc_des3_192_decrypt,
424 .cia_decrypt_ecb = des3_192_decrypt_ecb,
425 .cia_encrypt_cbc = des3_192_encrypt_cbc,
426 .cia_decrypt_cbc = des3_192_decrypt_cbc,
427 } 549 }
428 } 550 }
429}; 551};
@@ -437,22 +559,69 @@ static int init(void)
437 !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)) 559 !crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
438 return -ENOSYS; 560 return -ENOSYS;
439 561
440 ret |= (crypto_register_alg(&des_alg) == 0) ? 0:1; 562 ret = crypto_register_alg(&des_alg);
441 ret |= (crypto_register_alg(&des3_128_alg) == 0) ? 0:2; 563 if (ret)
442 ret |= (crypto_register_alg(&des3_192_alg) == 0) ? 0:4; 564 goto des_err;
443 if (ret) { 565 ret = crypto_register_alg(&ecb_des_alg);
444 crypto_unregister_alg(&des3_192_alg); 566 if (ret)
445 crypto_unregister_alg(&des3_128_alg); 567 goto ecb_des_err;
446 crypto_unregister_alg(&des_alg); 568 ret = crypto_register_alg(&cbc_des_alg);
447 return -EEXIST; 569 if (ret)
448 } 570 goto cbc_des_err;
449 return 0; 571
572 ret = crypto_register_alg(&des3_128_alg);
573 if (ret)
574 goto des3_128_err;
575 ret = crypto_register_alg(&ecb_des3_128_alg);
576 if (ret)
577 goto ecb_des3_128_err;
578 ret = crypto_register_alg(&cbc_des3_128_alg);
579 if (ret)
580 goto cbc_des3_128_err;
581
582 ret = crypto_register_alg(&des3_192_alg);
583 if (ret)
584 goto des3_192_err;
585 ret = crypto_register_alg(&ecb_des3_192_alg);
586 if (ret)
587 goto ecb_des3_192_err;
588 ret = crypto_register_alg(&cbc_des3_192_alg);
589 if (ret)
590 goto cbc_des3_192_err;
591
592out:
593 return ret;
594
595cbc_des3_192_err:
596 crypto_unregister_alg(&ecb_des3_192_alg);
597ecb_des3_192_err:
598 crypto_unregister_alg(&des3_192_alg);
599des3_192_err:
600 crypto_unregister_alg(&cbc_des3_128_alg);
601cbc_des3_128_err:
602 crypto_unregister_alg(&ecb_des3_128_alg);
603ecb_des3_128_err:
604 crypto_unregister_alg(&des3_128_alg);
605des3_128_err:
606 crypto_unregister_alg(&cbc_des_alg);
607cbc_des_err:
608 crypto_unregister_alg(&ecb_des_alg);
609ecb_des_err:
610 crypto_unregister_alg(&des_alg);
611des_err:
612 goto out;
450} 613}
451 614
452static void __exit fini(void) 615static void __exit fini(void)
453{ 616{
617 crypto_unregister_alg(&cbc_des3_192_alg);
618 crypto_unregister_alg(&ecb_des3_192_alg);
454 crypto_unregister_alg(&des3_192_alg); 619 crypto_unregister_alg(&des3_192_alg);
620 crypto_unregister_alg(&cbc_des3_128_alg);
621 crypto_unregister_alg(&ecb_des3_128_alg);
455 crypto_unregister_alg(&des3_128_alg); 622 crypto_unregister_alg(&des3_128_alg);
623 crypto_unregister_alg(&cbc_des_alg);
624 crypto_unregister_alg(&ecb_des_alg);
456 crypto_unregister_alg(&des_alg); 625 crypto_unregister_alg(&des_alg);
457} 626}
458 627
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c
index 9d34a35b1aa5..49ca8690ee39 100644
--- a/arch/s390/crypto/sha1_s390.c
+++ b/arch/s390/crypto/sha1_s390.c
@@ -126,6 +126,8 @@ static void sha1_final(struct crypto_tfm *tfm, u8 *out)
126 126
127static struct crypto_alg alg = { 127static struct crypto_alg alg = {
128 .cra_name = "sha1", 128 .cra_name = "sha1",
129 .cra_driver_name = "sha1-s390",
130 .cra_priority = CRYPT_S390_PRIORITY,
129 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 131 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
130 .cra_blocksize = SHA1_BLOCK_SIZE, 132 .cra_blocksize = SHA1_BLOCK_SIZE,
131 .cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx), 133 .cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx),
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index f573df30f31d..8e4e67503fe7 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -127,6 +127,8 @@ static void sha256_final(struct crypto_tfm *tfm, u8 *out)
127 127
128static struct crypto_alg alg = { 128static struct crypto_alg alg = {
129 .cra_name = "sha256", 129 .cra_name = "sha256",
130 .cra_driver_name = "sha256-s390",
131 .cra_priority = CRYPT_S390_PRIORITY,
130 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 132 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
131 .cra_blocksize = SHA256_BLOCK_SIZE, 133 .cra_blocksize = SHA256_BLOCK_SIZE,
132 .cra_ctxsize = sizeof(struct s390_sha256_ctx), 134 .cra_ctxsize = sizeof(struct s390_sha256_ctx),
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index f1d4591eddbb..35da53986b1b 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -428,6 +428,7 @@ CONFIG_S390_TAPE_34XX=m
428# CONFIG_VMLOGRDR is not set 428# CONFIG_VMLOGRDR is not set
429# CONFIG_VMCP is not set 429# CONFIG_VMCP is not set
430# CONFIG_MONREADER is not set 430# CONFIG_MONREADER is not set
431CONFIG_MONWRITER=m
431 432
432# 433#
433# Cryptographic devices 434# Cryptographic devices
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h
index ea5567be00fc..f3dbd91965c6 100644
--- a/arch/s390/hypfs/hypfs.h
+++ b/arch/s390/hypfs/hypfs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * fs/hypfs/hypfs.h 2 * arch/s390/hypfs/hypfs.h
3 * Hypervisor filesystem for Linux on s390. 3 * Hypervisor filesystem for Linux on s390.
4 * 4 *
5 * Copyright (C) IBM Corp. 2006 5 * Copyright (C) IBM Corp. 2006
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 1785bce2b919..75144efbb92b 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * fs/hypfs/hypfs_diag.c 2 * arch/s390/hypfs/hypfs_diag.c
3 * Hypervisor filesystem for Linux on s390. Diag 204 and 224 3 * Hypervisor filesystem for Linux on s390. Diag 204 and 224
4 * implementation. 4 * implementation.
5 * 5 *
@@ -432,12 +432,14 @@ static int diag204_probe(void)
432 432
433 buf = diag204_get_buffer(INFO_EXT, &pages); 433 buf = diag204_get_buffer(INFO_EXT, &pages);
434 if (!IS_ERR(buf)) { 434 if (!IS_ERR(buf)) {
435 if (diag204(SUBC_STIB7 | INFO_EXT, pages, buf) >= 0) { 435 if (diag204((unsigned long)SUBC_STIB7 |
436 (unsigned long)INFO_EXT, pages, buf) >= 0) {
436 diag204_store_sc = SUBC_STIB7; 437 diag204_store_sc = SUBC_STIB7;
437 diag204_info_type = INFO_EXT; 438 diag204_info_type = INFO_EXT;
438 goto out; 439 goto out;
439 } 440 }
440 if (diag204(SUBC_STIB6 | INFO_EXT, pages, buf) >= 0) { 441 if (diag204((unsigned long)SUBC_STIB6 |
442 (unsigned long)INFO_EXT, pages, buf) >= 0) {
441 diag204_store_sc = SUBC_STIB7; 443 diag204_store_sc = SUBC_STIB7;
442 diag204_info_type = INFO_EXT; 444 diag204_info_type = INFO_EXT;
443 goto out; 445 goto out;
@@ -452,7 +454,8 @@ static int diag204_probe(void)
452 rc = PTR_ERR(buf); 454 rc = PTR_ERR(buf);
453 goto fail_alloc; 455 goto fail_alloc;
454 } 456 }
455 if (diag204(SUBC_STIB4 | INFO_SIMPLE, pages, buf) >= 0) { 457 if (diag204((unsigned long)SUBC_STIB4 |
458 (unsigned long)INFO_SIMPLE, pages, buf) >= 0) {
456 diag204_store_sc = SUBC_STIB4; 459 diag204_store_sc = SUBC_STIB4;
457 diag204_info_type = INFO_SIMPLE; 460 diag204_info_type = INFO_SIMPLE;
458 goto out; 461 goto out;
@@ -476,7 +479,8 @@ static void *diag204_store(void)
476 buf = diag204_get_buffer(diag204_info_type, &pages); 479 buf = diag204_get_buffer(diag204_info_type, &pages);
477 if (IS_ERR(buf)) 480 if (IS_ERR(buf))
478 goto out; 481 goto out;
479 if (diag204(diag204_store_sc | diag204_info_type, pages, buf) < 0) 482 if (diag204((unsigned long)diag204_store_sc |
483 (unsigned long)diag204_info_type, pages, buf) < 0)
480 return ERR_PTR(-ENOSYS); 484 return ERR_PTR(-ENOSYS);
481out: 485out:
482 return buf; 486 return buf;
@@ -531,7 +535,7 @@ __init int hypfs_diag_init(void)
531 return rc; 535 return rc;
532} 536}
533 537
534__exit void hypfs_diag_exit(void) 538void hypfs_diag_exit(void)
535{ 539{
536 diag224_delete_name_table(); 540 diag224_delete_name_table();
537 diag204_free_buffer(); 541 diag204_free_buffer();
diff --git a/arch/s390/hypfs/hypfs_diag.h b/arch/s390/hypfs/hypfs_diag.h
index 793dea6b9bb6..256b384aebe1 100644
--- a/arch/s390/hypfs/hypfs_diag.h
+++ b/arch/s390/hypfs/hypfs_diag.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * fs/hypfs/hypfs_diag.h 2 * arch/s390/hypfs_diag.h
3 * Hypervisor filesystem for Linux on s390. 3 * Hypervisor filesystem for Linux on s390.
4 * 4 *
5 * Copyright (C) IBM Corp. 2006 5 * Copyright (C) IBM Corp. 2006
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 18c091925ea5..bdade5f2e325 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * fs/hypfs/inode.c 2 * arch/s390/hypfs/inode.c
3 * Hypervisor filesystem for Linux on s390. 3 * Hypervisor filesystem for Linux on s390.
4 * 4 *
5 * Copyright (C) IBM Corp. 2006 5 * Copyright (C) IBM Corp. 2006
@@ -312,10 +312,12 @@ static void hypfs_kill_super(struct super_block *sb)
312{ 312{
313 struct hypfs_sb_info *sb_info = sb->s_fs_info; 313 struct hypfs_sb_info *sb_info = sb->s_fs_info;
314 314
315 hypfs_delete_tree(sb->s_root); 315 if (sb->s_root) {
316 hypfs_remove(sb_info->update_file); 316 hypfs_delete_tree(sb->s_root);
317 kfree(sb->s_fs_info); 317 hypfs_remove(sb_info->update_file);
318 sb->s_fs_info = NULL; 318 kfree(sb->s_fs_info);
319 sb->s_fs_info = NULL;
320 }
319 kill_litter_super(sb); 321 kill_litter_super(sb);
320} 322}
321 323
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 9a33ed6ca696..aa978978d3d1 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional
6 6
7obj-y := bitmap.o traps.o time.o process.o \ 7obj-y := bitmap.o traps.o time.o process.o \
8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ 8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
9 semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o 9 semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o
10 10
11obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) 11obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
12obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) 12obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
@@ -24,6 +24,7 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \
24 24
25obj-$(CONFIG_VIRT_TIMER) += vtime.o 25obj-$(CONFIG_VIRT_TIMER) += vtime.o
26obj-$(CONFIG_STACKTRACE) += stacktrace.o 26obj-$(CONFIG_STACKTRACE) += stacktrace.o
27obj-$(CONFIG_KPROBES) += kprobes.o
27 28
28# Kexec part 29# Kexec part
29S390_KEXEC_OBJS := machine_kexec.o crash.o 30S390_KEXEC_OBJS := machine_kexec.o crash.o
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 5b5799ac8f83..0c712b78a7e8 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -505,6 +505,8 @@ pgm_no_vtime2:
505 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 505 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
506 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 506 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
507 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 507 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
508 tm SP_PSW+1(%r15),0x01 # kernel per event ?
509 bz BASED(kernel_per)
508 l %r3,__LC_PGM_ILC # load program interruption code 510 l %r3,__LC_PGM_ILC # load program interruption code
509 la %r8,0x7f 511 la %r8,0x7f
510 nr %r8,%r3 # clear per-event-bit and ilc 512 nr %r8,%r3 # clear per-event-bit and ilc
@@ -536,6 +538,16 @@ pgm_no_vtime3:
536 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 538 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
537 b BASED(sysc_do_svc) 539 b BASED(sysc_do_svc)
538 540
541#
542# per was called from kernel, must be kprobes
543#
544kernel_per:
545 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
546 la %r2,SP_PTREGS(%r15) # address of register-save area
547 l %r1,BASED(.Lhandle_per) # load adr. of per handler
548 la %r14,BASED(sysc_leave) # load adr. of system return
549 br %r1 # branch to do_single_step
550
539/* 551/*
540 * IO interrupt handler routine 552 * IO interrupt handler routine
541 */ 553 */
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 56f5f613b868..29bbfbab7332 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -518,6 +518,8 @@ pgm_no_vtime2:
518#endif 518#endif
519 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 519 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
520 lg %r1,__TI_task(%r9) 520 lg %r1,__TI_task(%r9)
521 tm SP_PSW+1(%r15),0x01 # kernel per event ?
522 jz kernel_per
521 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 523 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
522 mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS 524 mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
523 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 525 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
@@ -553,6 +555,16 @@ pgm_no_vtime3:
553 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 555 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
554 j sysc_do_svc 556 j sysc_do_svc
555 557
558#
559# per was called from kernel, must be kprobes
560#
561kernel_per:
562 lhi %r0,__LC_PGM_OLD_PSW
563 sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
564 la %r2,SP_PTREGS(%r15) # address of register-save area
565 larl %r14,sysc_leave # load adr. of system ret, no work
566 jg do_single_step # branch to do_single_step
567
556/* 568/*
557 * IO interrupt handler routine 569 * IO interrupt handler routine
558 */ 570 */
@@ -815,7 +827,7 @@ restart_go:
815 */ 827 */
816stack_overflow: 828stack_overflow:
817 lg %r15,__LC_PANIC_STACK # change to panic stack 829 lg %r15,__LC_PANIC_STACK # change to panic stack
818 aghi %r1,-SP_SIZE 830 aghi %r15,-SP_SIZE
819 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 831 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
820 stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 832 stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
821 la %r1,__LC_SAVE_AREA 833 la %r1,__LC_SAVE_AREA
@@ -823,7 +835,7 @@ stack_overflow:
823 je 0f 835 je 0f
824 chi %r12,__LC_PGM_OLD_PSW 836 chi %r12,__LC_PGM_OLD_PSW
825 je 0f 837 je 0f
826 la %r1,__LC_SAVE_AREA+16 838 la %r1,__LC_SAVE_AREA+32
8270: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack 8390: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack
828 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain 840 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
829 la %r2,SP_PTREGS(%r15) # load pt_regs 841 la %r2,SP_PTREGS(%r15) # load pt_regs
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index adad8863ee2f..0f1db268a8a9 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -272,7 +272,7 @@ iplstart:
272# load parameter file from ipl device 272# load parameter file from ipl device
273# 273#
274.Lagain1: 274.Lagain1:
275 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp 275 l %r2,.Linitrd # ramdisk loc. is temp
276 bas %r14,.Lloader # load parameter file 276 bas %r14,.Lloader # load parameter file
277 ltr %r2,%r2 # got anything ? 277 ltr %r2,%r2 # got anything ?
278 bz .Lnopf 278 bz .Lnopf
@@ -280,7 +280,7 @@ iplstart:
280 bnh .Lnotrunc 280 bnh .Lnotrunc
281 la %r2,895 281 la %r2,895
282.Lnotrunc: 282.Lnotrunc:
283 l %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) 283 l %r4,.Linitrd
284 clc 0(3,%r4),.L_hdr # if it is HDRx 284 clc 0(3,%r4),.L_hdr # if it is HDRx
285 bz .Lagain1 # skip dataset header 285 bz .Lagain1 # skip dataset header
286 clc 0(3,%r4),.L_eof # if it is EOFx 286 clc 0(3,%r4),.L_eof # if it is EOFx
@@ -323,14 +323,15 @@ iplstart:
323# load ramdisk from ipl device 323# load ramdisk from ipl device
324# 324#
325.Lagain2: 325.Lagain2:
326 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk 326 l %r2,.Linitrd # addr of ramdisk
327 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
327 bas %r14,.Lloader # load ramdisk 328 bas %r14,.Lloader # load ramdisk
328 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk 329 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
329 ltr %r2,%r2 330 ltr %r2,%r2
330 bnz .Lrdcont 331 bnz .Lrdcont
331 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found 332 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
332.Lrdcont: 333.Lrdcont:
333 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) 334 l %r2,.Linitrd
334 335
335 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx 336 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
336 bz .Lagain2 337 bz .Lagain2
@@ -379,6 +380,7 @@ iplstart:
379 l %r1,.Lstartup 380 l %r1,.Lstartup
380 br %r1 381 br %r1
381 382
383.Linitrd:.long _end + 0x400000 # default address of initrd
382.Lparm: .long PARMAREA 384.Lparm: .long PARMAREA
383.Lstartup: .long startup 385.Lstartup: .long startup
384.Lcvtab:.long _ebcasc # ebcdic to ascii table 386.Lcvtab:.long _ebcasc # ebcdic to ascii table
@@ -479,65 +481,6 @@ start:
479 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 481 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
480 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff 482 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
481 483
482.macro GET_IPL_DEVICE
483.Lget_ipl_device:
484 l %r1,0xb8 # get sid
485 sll %r1,15 # test if subchannel is enabled
486 srl %r1,31
487 ltr %r1,%r1
488 bz 2f-.LPG1(%r13) # subchannel disabled
489 l %r1,0xb8
490 la %r5,.Lipl_schib-.LPG1(%r13)
491 stsch 0(%r5) # get schib of subchannel
492 bnz 2f-.LPG1(%r13) # schib not available
493 tm 5(%r5),0x01 # devno valid?
494 bno 2f-.LPG1(%r13)
495 la %r6,ipl_parameter_flags-.LPG1(%r13)
496 oi 3(%r6),0x01 # set flag
497 la %r2,ipl_devno-.LPG1(%r13)
498 mvc 0(2,%r2),6(%r5) # store devno
499 tm 4(%r5),0x80 # qdio capable device?
500 bno 2f-.LPG1(%r13)
501 oi 3(%r6),0x02 # set flag
502
503 # copy ipl parameters
504
505 lhi %r0,4096
506 l %r2,20(%r0) # get address of parameter list
507 lhi %r3,IPL_PARMBLOCK_ORIGIN
508 st %r3,20(%r0)
509 lhi %r4,1
510 cr %r2,%r3 # start parameters < destination ?
511 jl 0f
512 lhi %r1,1 # copy direction is upwards
513 j 1f
5140: lhi %r1,-1 # copy direction is downwards
515 ar %r2,%r0
516 ar %r3,%r0
517 ar %r2,%r1
518 ar %r3,%r1
5191: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
520 ar %r3,%r1
521 ar %r2,%r1
522 sr %r0,%r4
523 jne 1b
524 b 2f-.LPG1(%r13)
525
526 .align 4
527.Lipl_schib:
528 .rept 13
529 .long 0
530 .endr
531
532 .globl ipl_parameter_flags
533ipl_parameter_flags:
534 .long 0
535 .globl ipl_devno
536ipl_devno:
537 .word 0
5382:
539.endm
540
541#ifdef CONFIG_64BIT 484#ifdef CONFIG_64BIT
542#include "head64.S" 485#include "head64.S"
543#else 486#else
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index a4dc61f3285e..1fa9fa1ca740 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -26,8 +26,8 @@ startup:basr %r13,0 # get base
26# 26#
27 .org PARMAREA 27 .org PARMAREA
28 .long 0,0 # IPL_DEVICE 28 .long 0,0 # IPL_DEVICE
29 .long 0,RAMDISK_ORIGIN # INITRD_START 29 .long 0,0 # INITRD_START
30 .long 0,RAMDISK_SIZE # INITRD_SIZE 30 .long 0,0 # INITRD_SIZE
31 31
32 .org COMMAND_LINE 32 .org COMMAND_LINE
33 .byte "root=/dev/ram0 ro" 33 .byte "root=/dev/ram0 ro"
@@ -37,12 +37,23 @@ startup:basr %r13,0 # get base
37 37
38startup_continue: 38startup_continue:
39 basr %r13,0 # get base 39 basr %r13,0 # get base
40.LPG1: GET_IPL_DEVICE 40.LPG1: mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
41 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 41 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
42 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area 42 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
43 # move IPL device to lowcore 43 # move IPL device to lowcore
44 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) 44 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
45#
46# Setup stack
47#
48 l %r15,.Linittu-.LPG1(%r13)
49 mvc __LC_CURRENT(4),__TI_task(%r15)
50 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
51 st %r15,__LC_KERNEL_STACK # set end of kernel stack
52 ahi %r15,-96
53 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
45 54
55 l %r14,.Lipl_save_parameters-.LPG1(%r13)
56 basr %r14,%r14
46# 57#
47# clear bss memory 58# clear bss memory
48# 59#
@@ -114,6 +125,10 @@ startup_continue:
114 b .Lfchunk-.LPG1(%r13) 125 b .Lfchunk-.LPG1(%r13)
115 126
116 .align 4 127 .align 4
128.Lipl_save_parameters:
129 .long ipl_save_parameters
130.Linittu:
131 .long init_thread_union
117.Lpmask: 132.Lpmask:
118 .byte 0 133 .byte 0
119.align 8 134.align 8
@@ -273,7 +288,23 @@ startup_continue:
273.Lbss_end: .long _end 288.Lbss_end: .long _end
274.Lparmaddr: .long PARMAREA 289.Lparmaddr: .long PARMAREA
275.Lsccbaddr: .long .Lsccb 290.Lsccbaddr: .long .Lsccb
291
292 .globl ipl_schib
293ipl_schib:
294 .rept 13
295 .long 0
296 .endr
297
298 .globl ipl_flags
299ipl_flags:
300 .long 0
301 .globl ipl_devno
302ipl_devno:
303 .word 0
304
276 .org 0x12000 305 .org 0x12000
306.globl s390_readinfo_sccb
307s390_readinfo_sccb:
277.Lsccb: 308.Lsccb:
278 .hword 0x1000 # length, one page 309 .hword 0x1000 # length, one page
279 .byte 0x00,0x00,0x00 310 .byte 0x00,0x00,0x00
@@ -302,16 +333,6 @@ startup_continue:
302 .globl _stext 333 .globl _stext
303_stext: basr %r13,0 # get base 334_stext: basr %r13,0 # get base
304.LPG3: 335.LPG3:
305#
306# Setup stack
307#
308 l %r15,.Linittu-.LPG3(%r13)
309 mvc __LC_CURRENT(4),__TI_task(%r15)
310 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
311 st %r15,__LC_KERNEL_STACK # set end of kernel stack
312 ahi %r15,-96
313 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
314
315# check control registers 336# check control registers
316 stctl %c0,%c15,0(%r15) 337 stctl %c0,%c15,0(%r15)
317 oi 2(%r15),0x40 # enable sigp emergency signal 338 oi 2(%r15),0x40 # enable sigp emergency signal
@@ -330,6 +351,5 @@ _stext: basr %r13,0 # get base
330# 351#
331 .align 8 352 .align 8
332.Ldw: .long 0x000a0000,0x00000000 353.Ldw: .long 0x000a0000,0x00000000
333.Linittu:.long init_thread_union
334.Lstart:.long start_kernel 354.Lstart:.long start_kernel
335.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 355.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 9d80c5b1ef95..a8bdd96494c7 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -26,8 +26,8 @@ startup:basr %r13,0 # get base
26# 26#
27 .org PARMAREA 27 .org PARMAREA
28 .quad 0 # IPL_DEVICE 28 .quad 0 # IPL_DEVICE
29 .quad RAMDISK_ORIGIN # INITRD_START 29 .quad 0 # INITRD_START
30 .quad RAMDISK_SIZE # INITRD_SIZE 30 .quad 0 # INITRD_SIZE
31 31
32 .org COMMAND_LINE 32 .org COMMAND_LINE
33 .byte "root=/dev/ram0 ro" 33 .byte "root=/dev/ram0 ro"
@@ -39,8 +39,8 @@ startup_continue:
39 basr %r13,0 # get base 39 basr %r13,0 # get base
40.LPG1: sll %r13,1 # remove high order bit 40.LPG1: sll %r13,1 # remove high order bit
41 srl %r13,1 41 srl %r13,1
42 GET_IPL_DEVICE
43 lhi %r1,1 # mode 1 = esame 42 lhi %r1,1 # mode 1 = esame
43 mvi __LC_AR_MODE_ID,1 # set esame flag
44 slr %r0,%r0 # set cpuid to zero 44 slr %r0,%r0 # set cpuid to zero
45 sigp %r1,%r0,0x12 # switch to esame mode 45 sigp %r1,%r0,0x12 # switch to esame mode
46 sam64 # switch to 64 bit mode 46 sam64 # switch to 64 bit mode
@@ -48,7 +48,18 @@ startup_continue:
48 lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area 48 lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area
49 # move IPL device to lowcore 49 # move IPL device to lowcore
50 mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) 50 mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
51#
52# Setup stack
53#
54 larl %r15,init_thread_union
55 lg %r14,__TI_task(%r15) # cache current in lowcore
56 stg %r14,__LC_CURRENT
57 aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
58 stg %r15,__LC_KERNEL_STACK # set end of kernel stack
59 aghi %r15,-160
60 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
51 61
62 brasl %r14,ipl_save_parameters
52# 63#
53# clear bss memory 64# clear bss memory
54# 65#
@@ -239,6 +250,19 @@ startup_continue:
239 oi 7(%r12),0x80 # set IDTE flag 250 oi 7(%r12),0x80 # set IDTE flag
2400: 2510:
241 252
253#
254# find out if we have the MVCOS instruction
255#
256 la %r1,0f-.LPG1(%r13) # set program check address
257 stg %r1,__LC_PGM_NEW_PSW+8
258 .short 0xc800 # mvcos 0(%r0),0(%r0),%r0
259 .short 0x0000
260 .short 0x0000
2610: tm 0x8f,0x13 # special-operation exception?
262 bno 1f-.LPG1(%r13) # if yes, MVCOS is present
263 oi 6(%r12),2 # set MVCOS flag
2641:
265
242 lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, 266 lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space,
243 # virtual and never return ... 267 # virtual and never return ...
244 .align 16 268 .align 16
@@ -268,7 +292,22 @@ startup_continue:
268.Lparmaddr: 292.Lparmaddr:
269 .quad PARMAREA 293 .quad PARMAREA
270 294
295 .globl ipl_schib
296ipl_schib:
297 .rept 13
298 .long 0
299 .endr
300
301 .globl ipl_flags
302ipl_flags:
303 .long 0
304 .globl ipl_devno
305ipl_devno:
306 .word 0
307
271 .org 0x12000 308 .org 0x12000
309.globl s390_readinfo_sccb
310s390_readinfo_sccb:
272.Lsccb: 311.Lsccb:
273 .hword 0x1000 # length, one page 312 .hword 0x1000 # length, one page
274 .byte 0x00,0x00,0x00 313 .byte 0x00,0x00,0x00
@@ -297,24 +336,12 @@ startup_continue:
297 .globl _stext 336 .globl _stext
298_stext: basr %r13,0 # get base 337_stext: basr %r13,0 # get base
299.LPG3: 338.LPG3:
300#
301# Setup stack
302#
303 larl %r15,init_thread_union
304 lg %r14,__TI_task(%r15) # cache current in lowcore
305 stg %r14,__LC_CURRENT
306 aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
307 stg %r15,__LC_KERNEL_STACK # set end of kernel stack
308 aghi %r15,-160
309 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
310
311# check control registers 339# check control registers
312 stctg %c0,%c15,0(%r15) 340 stctg %c0,%c15,0(%r15)
313 oi 6(%r15),0x40 # enable sigp emergency signal 341 oi 6(%r15),0x40 # enable sigp emergency signal
314 oi 4(%r15),0x10 # switch on low address proctection 342 oi 4(%r15),0x10 # switch on low address proctection
315 lctlg %c0,%c15,0(%r15) 343 lctlg %c0,%c15,0(%r15)
316 344
317#
318 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess 345 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
319 brasl %r14,start_kernel # go to C code 346 brasl %r14,start_kernel # go to C code
320# 347#
@@ -322,7 +349,7 @@ _stext: basr %r13,0 # get base
322# 349#
323 basr %r13,0 350 basr %r13,0
324 lpswe .Ldw-.(%r13) # load disabled wait psw 351 lpswe .Ldw-.(%r13) # load disabled wait psw
325# 352
326 .align 8 353 .align 8
327.Ldw: .quad 0x0002000180000000,0x0000000000000000 354.Ldw: .quad 0x0002000180000000,0x0000000000000000
328.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 355.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
new file mode 100644
index 000000000000..6555cc48e28f
--- /dev/null
+++ b/arch/s390/kernel/ipl.c
@@ -0,0 +1,942 @@
1/*
2 * arch/s390/kernel/ipl.c
3 * ipl/reipl/dump support for Linux on s390.
4 *
5 * Copyright (C) IBM Corp. 2005,2006
6 * Author(s): Michael Holzheu <holzheu@de.ibm.com>
7 * Heiko Carstens <heiko.carstens@de.ibm.com>
8 * Volker Sameske <sameske@de.ibm.com>
9 */
10
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/device.h>
14#include <linux/delay.h>
15#include <linux/reboot.h>
16#include <asm/smp.h>
17#include <asm/setup.h>
18#include <asm/cpcmd.h>
19#include <asm/cio.h>
20
21#define IPL_PARM_BLOCK_VERSION 0
22
23enum ipl_type {
24 IPL_TYPE_NONE = 1,
25 IPL_TYPE_UNKNOWN = 2,
26 IPL_TYPE_CCW = 4,
27 IPL_TYPE_FCP = 8,
28};
29
30#define IPL_NONE_STR "none"
31#define IPL_UNKNOWN_STR "unknown"
32#define IPL_CCW_STR "ccw"
33#define IPL_FCP_STR "fcp"
34
35static char *ipl_type_str(enum ipl_type type)
36{
37 switch (type) {
38 case IPL_TYPE_NONE:
39 return IPL_NONE_STR;
40 case IPL_TYPE_CCW:
41 return IPL_CCW_STR;
42 case IPL_TYPE_FCP:
43 return IPL_FCP_STR;
44 case IPL_TYPE_UNKNOWN:
45 default:
46 return IPL_UNKNOWN_STR;
47 }
48}
49
50enum ipl_method {
51 IPL_METHOD_NONE,
52 IPL_METHOD_CCW_CIO,
53 IPL_METHOD_CCW_DIAG,
54 IPL_METHOD_CCW_VM,
55 IPL_METHOD_FCP_RO_DIAG,
56 IPL_METHOD_FCP_RW_DIAG,
57 IPL_METHOD_FCP_RO_VM,
58};
59
60enum shutdown_action {
61 SHUTDOWN_REIPL,
62 SHUTDOWN_DUMP,
63 SHUTDOWN_STOP,
64};
65
66#define SHUTDOWN_REIPL_STR "reipl"
67#define SHUTDOWN_DUMP_STR "dump"
68#define SHUTDOWN_STOP_STR "stop"
69
70static char *shutdown_action_str(enum shutdown_action action)
71{
72 switch (action) {
73 case SHUTDOWN_REIPL:
74 return SHUTDOWN_REIPL_STR;
75 case SHUTDOWN_DUMP:
76 return SHUTDOWN_DUMP_STR;
77 case SHUTDOWN_STOP:
78 return SHUTDOWN_STOP_STR;
79 default:
80 BUG();
81 }
82}
83
84enum diag308_subcode {
85 DIAG308_IPL = 3,
86 DIAG308_DUMP = 4,
87 DIAG308_SET = 5,
88 DIAG308_STORE = 6,
89};
90
91enum diag308_ipl_type {
92 DIAG308_IPL_TYPE_FCP = 0,
93 DIAG308_IPL_TYPE_CCW = 2,
94};
95
96enum diag308_opt {
97 DIAG308_IPL_OPT_IPL = 0x10,
98 DIAG308_IPL_OPT_DUMP = 0x20,
99};
100
101enum diag308_rc {
102 DIAG308_RC_OK = 1,
103};
104
105static int diag308_set_works = 0;
106
107static int reipl_capabilities = IPL_TYPE_UNKNOWN;
108static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
109static enum ipl_method reipl_method = IPL_METHOD_NONE;
110static struct ipl_parameter_block *reipl_block_fcp;
111static struct ipl_parameter_block *reipl_block_ccw;
112
113static int dump_capabilities = IPL_TYPE_NONE;
114static enum ipl_type dump_type = IPL_TYPE_NONE;
115static enum ipl_method dump_method = IPL_METHOD_NONE;
116static struct ipl_parameter_block *dump_block_fcp;
117static struct ipl_parameter_block *dump_block_ccw;
118
119static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
120
121static int diag308(unsigned long subcode, void *addr)
122{
123 register unsigned long _addr asm("0") = (unsigned long)addr;
124 register unsigned long _rc asm("1") = 0;
125
126 asm volatile (
127 " diag %0,%2,0x308\n"
128 "0: \n"
129 ".section __ex_table,\"a\"\n"
130#ifdef CONFIG_64BIT
131 " .align 8\n"
132 " .quad 0b, 0b\n"
133#else
134 " .align 4\n"
135 " .long 0b, 0b\n"
136#endif
137 ".previous\n"
138 : "+d" (_addr), "+d" (_rc)
139 : "d" (subcode) : "cc", "memory" );
140
141 return _rc;
142}
143
144/* SYSFS */
145
146#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \
147static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
148 char *page) \
149{ \
150 return sprintf(page, _format, _value); \
151} \
152static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
153 __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
154
155#define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \
156static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
157 char *page) \
158{ \
159 return sprintf(page, _fmt_out, \
160 (unsigned long long) _value); \
161} \
162static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\
163 const char *buf, size_t len) \
164{ \
165 unsigned long long value; \
166 if (sscanf(buf, _fmt_in, &value) != 1) \
167 return -EINVAL; \
168 _value = value; \
169 return len; \
170} \
171static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
172 __ATTR(_name,(S_IRUGO | S_IWUSR), \
173 sys_##_prefix##_##_name##_show, \
174 sys_##_prefix##_##_name##_store);
175
176static void make_attrs_ro(struct attribute **attrs)
177{
178 while (*attrs) {
179 (*attrs)->mode = S_IRUGO;
180 attrs++;
181 }
182}
183
184/*
185 * ipl section
186 */
187
188static enum ipl_type ipl_get_type(void)
189{
190 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
191
192 if (!(ipl_flags & IPL_DEVNO_VALID))
193 return IPL_TYPE_UNKNOWN;
194 if (!(ipl_flags & IPL_PARMBLOCK_VALID))
195 return IPL_TYPE_CCW;
196 if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION)
197 return IPL_TYPE_UNKNOWN;
198 if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP)
199 return IPL_TYPE_UNKNOWN;
200 return IPL_TYPE_FCP;
201}
202
203static ssize_t ipl_type_show(struct subsystem *subsys, char *page)
204{
205 return sprintf(page, "%s\n", ipl_type_str(ipl_get_type()));
206}
207
208static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
209
210static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page)
211{
212 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
213
214 switch (ipl_get_type()) {
215 case IPL_TYPE_CCW:
216 return sprintf(page, "0.0.%04x\n", ipl_devno);
217 case IPL_TYPE_FCP:
218 return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
219 default:
220 return 0;
221 }
222}
223
224static struct subsys_attribute sys_ipl_device_attr =
225 __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
226
227static ssize_t ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off,
228 size_t count)
229{
230 unsigned int size = IPL_PARMBLOCK_SIZE;
231
232 if (off > size)
233 return 0;
234 if (off + count > size)
235 count = size - off;
236 memcpy(buf, (void *)IPL_PARMBLOCK_START + off, count);
237 return count;
238}
239
240static struct bin_attribute ipl_parameter_attr = {
241 .attr = {
242 .name = "binary_parameter",
243 .mode = S_IRUGO,
244 .owner = THIS_MODULE,
245 },
246 .size = PAGE_SIZE,
247 .read = &ipl_parameter_read,
248};
249
250static ssize_t ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off,
251 size_t count)
252{
253 unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
254 void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
255
256 if (off > size)
257 return 0;
258 if (off + count > size)
259 count = size - off;
260 memcpy(buf, scp_data + off, count);
261 return count;
262}
263
264static struct bin_attribute ipl_scp_data_attr = {
265 .attr = {
266 .name = "scp_data",
267 .mode = S_IRUGO,
268 .owner = THIS_MODULE,
269 },
270 .size = PAGE_SIZE,
271 .read = &ipl_scp_data_read,
272};
273
274/* FCP ipl device attributes */
275
276DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long)
277 IPL_PARMBLOCK_START->ipl_info.fcp.wwpn);
278DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long)
279 IPL_PARMBLOCK_START->ipl_info.fcp.lun);
280DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long)
281 IPL_PARMBLOCK_START->ipl_info.fcp.bootprog);
282DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)
283 IPL_PARMBLOCK_START->ipl_info.fcp.br_lba);
284
285static struct attribute *ipl_fcp_attrs[] = {
286 &sys_ipl_type_attr.attr,
287 &sys_ipl_device_attr.attr,
288 &sys_ipl_fcp_wwpn_attr.attr,
289 &sys_ipl_fcp_lun_attr.attr,
290 &sys_ipl_fcp_bootprog_attr.attr,
291 &sys_ipl_fcp_br_lba_attr.attr,
292 NULL,
293};
294
295static struct attribute_group ipl_fcp_attr_group = {
296 .attrs = ipl_fcp_attrs,
297};
298
299/* CCW ipl device attributes */
300
301static struct attribute *ipl_ccw_attrs[] = {
302 &sys_ipl_type_attr.attr,
303 &sys_ipl_device_attr.attr,
304 NULL,
305};
306
307static struct attribute_group ipl_ccw_attr_group = {
308 .attrs = ipl_ccw_attrs,
309};
310
311/* UNKNOWN ipl device attributes */
312
313static struct attribute *ipl_unknown_attrs[] = {
314 &sys_ipl_type_attr.attr,
315 NULL,
316};
317
318static struct attribute_group ipl_unknown_attr_group = {
319 .attrs = ipl_unknown_attrs,
320};
321
322static decl_subsys(ipl, NULL, NULL);
323
324/*
325 * reipl section
326 */
327
328/* FCP reipl device attributes */
329
330DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n",
331 reipl_block_fcp->ipl_info.fcp.wwpn);
332DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n",
333 reipl_block_fcp->ipl_info.fcp.lun);
334DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
335 reipl_block_fcp->ipl_info.fcp.bootprog);
336DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
337 reipl_block_fcp->ipl_info.fcp.br_lba);
338DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
339 reipl_block_fcp->ipl_info.fcp.devno);
340
341static struct attribute *reipl_fcp_attrs[] = {
342 &sys_reipl_fcp_device_attr.attr,
343 &sys_reipl_fcp_wwpn_attr.attr,
344 &sys_reipl_fcp_lun_attr.attr,
345 &sys_reipl_fcp_bootprog_attr.attr,
346 &sys_reipl_fcp_br_lba_attr.attr,
347 NULL,
348};
349
350static struct attribute_group reipl_fcp_attr_group = {
351 .name = IPL_FCP_STR,
352 .attrs = reipl_fcp_attrs,
353};
354
355/* CCW reipl device attributes */
356
357DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
358 reipl_block_ccw->ipl_info.ccw.devno);
359
360static struct attribute *reipl_ccw_attrs[] = {
361 &sys_reipl_ccw_device_attr.attr,
362 NULL,
363};
364
365static struct attribute_group reipl_ccw_attr_group = {
366 .name = IPL_CCW_STR,
367 .attrs = reipl_ccw_attrs,
368};
369
370/* reipl type */
371
372static int reipl_set_type(enum ipl_type type)
373{
374 if (!(reipl_capabilities & type))
375 return -EINVAL;
376
377 switch(type) {
378 case IPL_TYPE_CCW:
379 if (MACHINE_IS_VM)
380 reipl_method = IPL_METHOD_CCW_VM;
381 else
382 reipl_method = IPL_METHOD_CCW_CIO;
383 break;
384 case IPL_TYPE_FCP:
385 if (diag308_set_works)
386 reipl_method = IPL_METHOD_FCP_RW_DIAG;
387 else if (MACHINE_IS_VM)
388 reipl_method = IPL_METHOD_FCP_RO_VM;
389 else
390 reipl_method = IPL_METHOD_FCP_RO_DIAG;
391 break;
392 default:
393 reipl_method = IPL_METHOD_NONE;
394 }
395 reipl_type = type;
396 return 0;
397}
398
399static ssize_t reipl_type_show(struct subsystem *subsys, char *page)
400{
401 return sprintf(page, "%s\n", ipl_type_str(reipl_type));
402}
403
404static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf,
405 size_t len)
406{
407 int rc = -EINVAL;
408
409 if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
410 rc = reipl_set_type(IPL_TYPE_CCW);
411 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
412 rc = reipl_set_type(IPL_TYPE_FCP);
413 return (rc != 0) ? rc : len;
414}
415
416static struct subsys_attribute reipl_type_attr =
417 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
418
419static decl_subsys(reipl, NULL, NULL);
420
421/*
422 * dump section
423 */
424
425/* FCP dump device attributes */
426
427DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
428 dump_block_fcp->ipl_info.fcp.wwpn);
429DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
430 dump_block_fcp->ipl_info.fcp.lun);
431DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
432 dump_block_fcp->ipl_info.fcp.bootprog);
433DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
434 dump_block_fcp->ipl_info.fcp.br_lba);
435DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
436 dump_block_fcp->ipl_info.fcp.devno);
437
438static struct attribute *dump_fcp_attrs[] = {
439 &sys_dump_fcp_device_attr.attr,
440 &sys_dump_fcp_wwpn_attr.attr,
441 &sys_dump_fcp_lun_attr.attr,
442 &sys_dump_fcp_bootprog_attr.attr,
443 &sys_dump_fcp_br_lba_attr.attr,
444 NULL,
445};
446
447static struct attribute_group dump_fcp_attr_group = {
448 .name = IPL_FCP_STR,
449 .attrs = dump_fcp_attrs,
450};
451
452/* CCW dump device attributes */
453
454DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
455 dump_block_ccw->ipl_info.ccw.devno);
456
457static struct attribute *dump_ccw_attrs[] = {
458 &sys_dump_ccw_device_attr.attr,
459 NULL,
460};
461
462static struct attribute_group dump_ccw_attr_group = {
463 .name = IPL_CCW_STR,
464 .attrs = dump_ccw_attrs,
465};
466
467/* dump type */
468
469static int dump_set_type(enum ipl_type type)
470{
471 if (!(dump_capabilities & type))
472 return -EINVAL;
473 switch(type) {
474 case IPL_TYPE_CCW:
475 if (MACHINE_IS_VM)
476 dump_method = IPL_METHOD_CCW_VM;
477 else
478 dump_method = IPL_METHOD_CCW_CIO;
479 break;
480 case IPL_TYPE_FCP:
481 dump_method = IPL_METHOD_FCP_RW_DIAG;
482 break;
483 default:
484 dump_method = IPL_METHOD_NONE;
485 }
486 dump_type = type;
487 return 0;
488}
489
490static ssize_t dump_type_show(struct subsystem *subsys, char *page)
491{
492 return sprintf(page, "%s\n", ipl_type_str(dump_type));
493}
494
495static ssize_t dump_type_store(struct subsystem *subsys, const char *buf,
496 size_t len)
497{
498 int rc = -EINVAL;
499
500 if (strncmp(buf, IPL_NONE_STR, strlen(IPL_NONE_STR)) == 0)
501 rc = dump_set_type(IPL_TYPE_NONE);
502 else if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
503 rc = dump_set_type(IPL_TYPE_CCW);
504 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
505 rc = dump_set_type(IPL_TYPE_FCP);
506 return (rc != 0) ? rc : len;
507}
508
509static struct subsys_attribute dump_type_attr =
510 __ATTR(dump_type, 0644, dump_type_show, dump_type_store);
511
512static decl_subsys(dump, NULL, NULL);
513
514#ifdef CONFIG_SMP
515static void dump_smp_stop_all(void)
516{
517 int cpu;
518 preempt_disable();
519 for_each_online_cpu(cpu) {
520 if (cpu == smp_processor_id())
521 continue;
522 while (signal_processor(cpu, sigp_stop) == sigp_busy)
523 udelay(10);
524 }
525 preempt_enable();
526}
527#else
528#define dump_smp_stop_all() do { } while (0)
529#endif
530
531/*
532 * Shutdown actions section
533 */
534
535static decl_subsys(shutdown_actions, NULL, NULL);
536
537/* on panic */
538
539static ssize_t on_panic_show(struct subsystem *subsys, char *page)
540{
541 return sprintf(page, "%s\n", shutdown_action_str(on_panic_action));
542}
543
544static ssize_t on_panic_store(struct subsystem *subsys, const char *buf,
545 size_t len)
546{
547 if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0)
548 on_panic_action = SHUTDOWN_REIPL;
549 else if (strncmp(buf, SHUTDOWN_DUMP_STR,
550 strlen(SHUTDOWN_DUMP_STR)) == 0)
551 on_panic_action = SHUTDOWN_DUMP;
552 else if (strncmp(buf, SHUTDOWN_STOP_STR,
553 strlen(SHUTDOWN_STOP_STR)) == 0)
554 on_panic_action = SHUTDOWN_STOP;
555 else
556 return -EINVAL;
557
558 return len;
559}
560
561static struct subsys_attribute on_panic_attr =
562 __ATTR(on_panic, 0644, on_panic_show, on_panic_store);
563
564static void print_fcp_block(struct ipl_parameter_block *fcp_block)
565{
566 printk(KERN_EMERG "wwpn: %016llx\n",
567 (unsigned long long)fcp_block->ipl_info.fcp.wwpn);
568 printk(KERN_EMERG "lun: %016llx\n",
569 (unsigned long long)fcp_block->ipl_info.fcp.lun);
570 printk(KERN_EMERG "bootprog: %lld\n",
571 (unsigned long long)fcp_block->ipl_info.fcp.bootprog);
572 printk(KERN_EMERG "br_lba: %lld\n",
573 (unsigned long long)fcp_block->ipl_info.fcp.br_lba);
574 printk(KERN_EMERG "device: %llx\n",
575 (unsigned long long)fcp_block->ipl_info.fcp.devno);
576 printk(KERN_EMERG "opt: %x\n", fcp_block->ipl_info.fcp.opt);
577}
578
579void do_reipl(void)
580{
581 struct ccw_dev_id devid;
582 static char buf[100];
583
584 switch (reipl_type) {
585 case IPL_TYPE_CCW:
586 printk(KERN_EMERG "reboot on ccw device: 0.0.%04x\n",
587 reipl_block_ccw->ipl_info.ccw.devno);
588 break;
589 case IPL_TYPE_FCP:
590 printk(KERN_EMERG "reboot on fcp device:\n");
591 print_fcp_block(reipl_block_fcp);
592 break;
593 default:
594 break;
595 }
596
597 switch (reipl_method) {
598 case IPL_METHOD_CCW_CIO:
599 devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
600 devid.ssid = 0;
601 reipl_ccw_dev(&devid);
602 break;
603 case IPL_METHOD_CCW_VM:
604 sprintf(buf, "IPL %X", reipl_block_ccw->ipl_info.ccw.devno);
605 cpcmd(buf, NULL, 0, NULL);
606 break;
607 case IPL_METHOD_CCW_DIAG:
608 diag308(DIAG308_SET, reipl_block_ccw);
609 diag308(DIAG308_IPL, NULL);
610 break;
611 case IPL_METHOD_FCP_RW_DIAG:
612 diag308(DIAG308_SET, reipl_block_fcp);
613 diag308(DIAG308_IPL, NULL);
614 break;
615 case IPL_METHOD_FCP_RO_DIAG:
616 diag308(DIAG308_IPL, NULL);
617 break;
618 case IPL_METHOD_FCP_RO_VM:
619 cpcmd("IPL", NULL, 0, NULL);
620 break;
621 case IPL_METHOD_NONE:
622 default:
623 if (MACHINE_IS_VM)
624 cpcmd("IPL", NULL, 0, NULL);
625 diag308(DIAG308_IPL, NULL);
626 break;
627 }
628 panic("reipl failed!\n");
629}
630
631static void do_dump(void)
632{
633 struct ccw_dev_id devid;
634 static char buf[100];
635
636 switch (dump_type) {
637 case IPL_TYPE_CCW:
638 printk(KERN_EMERG "Automatic dump on ccw device: 0.0.%04x\n",
639 dump_block_ccw->ipl_info.ccw.devno);
640 break;
641 case IPL_TYPE_FCP:
642 printk(KERN_EMERG "Automatic dump on fcp device:\n");
643 print_fcp_block(dump_block_fcp);
644 break;
645 default:
646 return;
647 }
648
649 switch (dump_method) {
650 case IPL_METHOD_CCW_CIO:
651 dump_smp_stop_all();
652 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
653 devid.ssid = 0;
654 reipl_ccw_dev(&devid);
655 break;
656 case IPL_METHOD_CCW_VM:
657 dump_smp_stop_all();
658 sprintf(buf, "STORE STATUS");
659 cpcmd(buf, NULL, 0, NULL);
660 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
661 cpcmd(buf, NULL, 0, NULL);
662 break;
663 case IPL_METHOD_CCW_DIAG:
664 diag308(DIAG308_SET, dump_block_ccw);
665 diag308(DIAG308_DUMP, NULL);
666 break;
667 case IPL_METHOD_FCP_RW_DIAG:
668 diag308(DIAG308_SET, dump_block_fcp);
669 diag308(DIAG308_DUMP, NULL);
670 break;
671 case IPL_METHOD_NONE:
672 default:
673 return;
674 }
675 printk(KERN_EMERG "Dump failed!\n");
676}
677
678/* init functions */
679
680static int __init ipl_register_fcp_files(void)
681{
682 int rc;
683
684 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
685 &ipl_fcp_attr_group);
686 if (rc)
687 goto out;
688 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
689 &ipl_parameter_attr);
690 if (rc)
691 goto out_ipl_parm;
692 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
693 &ipl_scp_data_attr);
694 if (!rc)
695 goto out;
696
697 sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
698
699out_ipl_parm:
700 sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
701out:
702 return rc;
703}
704
705static int __init ipl_init(void)
706{
707 int rc;
708
709 rc = firmware_register(&ipl_subsys);
710 if (rc)
711 return rc;
712 switch (ipl_get_type()) {
713 case IPL_TYPE_CCW:
714 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
715 &ipl_ccw_attr_group);
716 break;
717 case IPL_TYPE_FCP:
718 rc = ipl_register_fcp_files();
719 break;
720 default:
721 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
722 &ipl_unknown_attr_group);
723 break;
724 }
725 if (rc)
726 firmware_unregister(&ipl_subsys);
727 return rc;
728}
729
730static void __init reipl_probe(void)
731{
732 void *buffer;
733
734 buffer = (void *) get_zeroed_page(GFP_KERNEL);
735 if (!buffer)
736 return;
737 if (diag308(DIAG308_STORE, buffer) == DIAG308_RC_OK)
738 diag308_set_works = 1;
739 free_page((unsigned long)buffer);
740}
741
742static int __init reipl_ccw_init(void)
743{
744 int rc;
745
746 reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
747 if (!reipl_block_ccw)
748 return -ENOMEM;
749 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_ccw_attr_group);
750 if (rc) {
751 free_page((unsigned long)reipl_block_ccw);
752 return rc;
753 }
754 reipl_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
755 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
756 reipl_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
757 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
758 if (ipl_get_type() == IPL_TYPE_CCW)
759 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
760 reipl_capabilities |= IPL_TYPE_CCW;
761 return 0;
762}
763
764static int __init reipl_fcp_init(void)
765{
766 int rc;
767
768 if ((!diag308_set_works) && (ipl_get_type() != IPL_TYPE_FCP))
769 return 0;
770 if ((!diag308_set_works) && (ipl_get_type() == IPL_TYPE_FCP))
771 make_attrs_ro(reipl_fcp_attrs);
772
773 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
774 if (!reipl_block_fcp)
775 return -ENOMEM;
776 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_fcp_attr_group);
777 if (rc) {
778 free_page((unsigned long)reipl_block_fcp);
779 return rc;
780 }
781 if (ipl_get_type() == IPL_TYPE_FCP) {
782 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
783 } else {
784 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
785 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
786 reipl_block_fcp->hdr.blk0_len =
787 sizeof(reipl_block_fcp->ipl_info.fcp);
788 reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
789 reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL;
790 }
791 reipl_capabilities |= IPL_TYPE_FCP;
792 return 0;
793}
794
795static int __init reipl_init(void)
796{
797 int rc;
798
799 rc = firmware_register(&reipl_subsys);
800 if (rc)
801 return rc;
802 rc = subsys_create_file(&reipl_subsys, &reipl_type_attr);
803 if (rc) {
804 firmware_unregister(&reipl_subsys);
805 return rc;
806 }
807 rc = reipl_ccw_init();
808 if (rc)
809 return rc;
810 rc = reipl_fcp_init();
811 if (rc)
812 return rc;
813 rc = reipl_set_type(ipl_get_type());
814 if (rc)
815 return rc;
816 return 0;
817}
818
819static int __init dump_ccw_init(void)
820{
821 int rc;
822
823 dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
824 if (!dump_block_ccw)
825 return -ENOMEM;
826 rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_ccw_attr_group);
827 if (rc) {
828 free_page((unsigned long)dump_block_ccw);
829 return rc;
830 }
831 dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
832 dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
833 dump_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
834 dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
835 dump_capabilities |= IPL_TYPE_CCW;
836 return 0;
837}
838
839extern char s390_readinfo_sccb[];
840
841static int __init dump_fcp_init(void)
842{
843 int rc;
844
845 if(!(s390_readinfo_sccb[91] & 0x2))
846 return 0; /* LDIPL DUMP is not installed */
847 if (!diag308_set_works)
848 return 0;
849 dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
850 if (!dump_block_fcp)
851 return -ENOMEM;
852 rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_fcp_attr_group);
853 if (rc) {
854 free_page((unsigned long)dump_block_fcp);
855 return rc;
856 }
857 dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
858 dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
859 dump_block_fcp->hdr.blk0_len = sizeof(dump_block_fcp->ipl_info.fcp);
860 dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
861 dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP;
862 dump_capabilities |= IPL_TYPE_FCP;
863 return 0;
864}
865
866#define SHUTDOWN_ON_PANIC_PRIO 0
867
868static int shutdown_on_panic_notify(struct notifier_block *self,
869 unsigned long event, void *data)
870{
871 if (on_panic_action == SHUTDOWN_DUMP)
872 do_dump();
873 else if (on_panic_action == SHUTDOWN_REIPL)
874 do_reipl();
875 return NOTIFY_OK;
876}
877
878static struct notifier_block shutdown_on_panic_nb = {
879 .notifier_call = shutdown_on_panic_notify,
880 .priority = SHUTDOWN_ON_PANIC_PRIO
881};
882
883static int __init dump_init(void)
884{
885 int rc;
886
887 rc = firmware_register(&dump_subsys);
888 if (rc)
889 return rc;
890 rc = subsys_create_file(&dump_subsys, &dump_type_attr);
891 if (rc) {
892 firmware_unregister(&dump_subsys);
893 return rc;
894 }
895 rc = dump_ccw_init();
896 if (rc)
897 return rc;
898 rc = dump_fcp_init();
899 if (rc)
900 return rc;
901 dump_set_type(IPL_TYPE_NONE);
902 return 0;
903}
904
905static int __init shutdown_actions_init(void)
906{
907 int rc;
908
909 rc = firmware_register(&shutdown_actions_subsys);
910 if (rc)
911 return rc;
912 rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr);
913 if (rc) {
914 firmware_unregister(&shutdown_actions_subsys);
915 return rc;
916 }
917 atomic_notifier_chain_register(&panic_notifier_list,
918 &shutdown_on_panic_nb);
919 return 0;
920}
921
922static int __init s390_ipl_init(void)
923{
924 int rc;
925
926 reipl_probe();
927 rc = ipl_init();
928 if (rc)
929 return rc;
930 rc = reipl_init();
931 if (rc)
932 return rc;
933 rc = dump_init();
934 if (rc)
935 return rc;
936 rc = shutdown_actions_init();
937 if (rc)
938 return rc;
939 return 0;
940}
941
942__initcall(s390_ipl_init);
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
new file mode 100644
index 000000000000..ca28fb0b3790
--- /dev/null
+++ b/arch/s390/kernel/kprobes.c
@@ -0,0 +1,657 @@
1/*
2 * Kernel Probes (KProbes)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) IBM Corporation, 2002, 2006
19 *
20 * s390 port, used ppc64 as template. Mike Grundy <grundym@us.ibm.com>
21 */
22
23#include <linux/config.h>
24#include <linux/kprobes.h>
25#include <linux/ptrace.h>
26#include <linux/preempt.h>
27#include <linux/stop_machine.h>
28#include <asm/cacheflush.h>
29#include <asm/kdebug.h>
30#include <asm/sections.h>
31#include <asm/uaccess.h>
32#include <linux/module.h>
33
34DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
35DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
36
37int __kprobes arch_prepare_kprobe(struct kprobe *p)
38{
39 /* Make sure the probe isn't going on a difficult instruction */
40 if (is_prohibited_opcode((kprobe_opcode_t *) p->addr))
41 return -EINVAL;
42
43 if ((unsigned long)p->addr & 0x01) {
44 printk("Attempt to register kprobe at an unaligned address\n");
45 return -EINVAL;
46 }
47
48 /* Use the get_insn_slot() facility for correctness */
49 if (!(p->ainsn.insn = get_insn_slot()))
50 return -ENOMEM;
51
52 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
53
54 get_instruction_type(&p->ainsn);
55 p->opcode = *p->addr;
56 return 0;
57}
58
59int __kprobes is_prohibited_opcode(kprobe_opcode_t *instruction)
60{
61 switch (*(__u8 *) instruction) {
62 case 0x0c: /* bassm */
63 case 0x0b: /* bsm */
64 case 0x83: /* diag */
65 case 0x44: /* ex */
66 return -EINVAL;
67 }
68 switch (*(__u16 *) instruction) {
69 case 0x0101: /* pr */
70 case 0xb25a: /* bsa */
71 case 0xb240: /* bakr */
72 case 0xb258: /* bsg */
73 case 0xb218: /* pc */
74 case 0xb228: /* pt */
75 return -EINVAL;
76 }
77 return 0;
78}
79
80void __kprobes get_instruction_type(struct arch_specific_insn *ainsn)
81{
82 /* default fixup method */
83 ainsn->fixup = FIXUP_PSW_NORMAL;
84
85 /* save r1 operand */
86 ainsn->reg = (*ainsn->insn & 0xf0) >> 4;
87
88 /* save the instruction length (pop 5-5) in bytes */
89 switch (*(__u8 *) (ainsn->insn) >> 4) {
90 case 0:
91 ainsn->ilen = 2;
92 break;
93 case 1:
94 case 2:
95 ainsn->ilen = 4;
96 break;
97 case 3:
98 ainsn->ilen = 6;
99 break;
100 }
101
102 switch (*(__u8 *) ainsn->insn) {
103 case 0x05: /* balr */
104 case 0x0d: /* basr */
105 ainsn->fixup = FIXUP_RETURN_REGISTER;
106 /* if r2 = 0, no branch will be taken */
107 if ((*ainsn->insn & 0x0f) == 0)
108 ainsn->fixup |= FIXUP_BRANCH_NOT_TAKEN;
109 break;
110 case 0x06: /* bctr */
111 case 0x07: /* bcr */
112 ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
113 break;
114 case 0x45: /* bal */
115 case 0x4d: /* bas */
116 ainsn->fixup = FIXUP_RETURN_REGISTER;
117 break;
118 case 0x47: /* bc */
119 case 0x46: /* bct */
120 case 0x86: /* bxh */
121 case 0x87: /* bxle */
122 ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
123 break;
124 case 0x82: /* lpsw */
125 ainsn->fixup = FIXUP_NOT_REQUIRED;
126 break;
127 case 0xb2: /* lpswe */
128 if (*(((__u8 *) ainsn->insn) + 1) == 0xb2) {
129 ainsn->fixup = FIXUP_NOT_REQUIRED;
130 }
131 break;
132 case 0xa7: /* bras */
133 if ((*ainsn->insn & 0x0f) == 0x05) {
134 ainsn->fixup |= FIXUP_RETURN_REGISTER;
135 }
136 break;
137 case 0xc0:
138 if ((*ainsn->insn & 0x0f) == 0x00 /* larl */
139 || (*ainsn->insn & 0x0f) == 0x05) /* brasl */
140 ainsn->fixup |= FIXUP_RETURN_REGISTER;
141 break;
142 case 0xeb:
143 if (*(((__u8 *) ainsn->insn) + 5 ) == 0x44 || /* bxhg */
144 *(((__u8 *) ainsn->insn) + 5) == 0x45) {/* bxleg */
145 ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
146 }
147 break;
148 case 0xe3: /* bctg */
149 if (*(((__u8 *) ainsn->insn) + 5) == 0x46) {
150 ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
151 }
152 break;
153 }
154}
155
156static int __kprobes swap_instruction(void *aref)
157{
158 struct ins_replace_args *args = aref;
159 int err = -EFAULT;
160
161 asm volatile(
162 "0: mvc 0(2,%2),0(%3)\n"
163 "1: la %0,0\n"
164 "2:\n"
165 EX_TABLE(0b,2b)
166 : "+d" (err), "=m" (*args->ptr)
167 : "a" (args->ptr), "a" (&args->new), "m" (args->new));
168 return err;
169}
170
171void __kprobes arch_arm_kprobe(struct kprobe *p)
172{
173 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
174 unsigned long status = kcb->kprobe_status;
175 struct ins_replace_args args;
176
177 args.ptr = p->addr;
178 args.old = p->opcode;
179 args.new = BREAKPOINT_INSTRUCTION;
180
181 kcb->kprobe_status = KPROBE_SWAP_INST;
182 stop_machine_run(swap_instruction, &args, NR_CPUS);
183 kcb->kprobe_status = status;
184}
185
186void __kprobes arch_disarm_kprobe(struct kprobe *p)
187{
188 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
189 unsigned long status = kcb->kprobe_status;
190 struct ins_replace_args args;
191
192 args.ptr = p->addr;
193 args.old = BREAKPOINT_INSTRUCTION;
194 args.new = p->opcode;
195
196 kcb->kprobe_status = KPROBE_SWAP_INST;
197 stop_machine_run(swap_instruction, &args, NR_CPUS);
198 kcb->kprobe_status = status;
199}
200
201void __kprobes arch_remove_kprobe(struct kprobe *p)
202{
203 mutex_lock(&kprobe_mutex);
204 free_insn_slot(p->ainsn.insn);
205 mutex_unlock(&kprobe_mutex);
206}
207
208static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
209{
210 per_cr_bits kprobe_per_regs[1];
211
212 memset(kprobe_per_regs, 0, sizeof(per_cr_bits));
213 regs->psw.addr = (unsigned long)p->ainsn.insn | PSW_ADDR_AMODE;
214
215 /* Set up the per control reg info, will pass to lctl */
216 kprobe_per_regs[0].em_instruction_fetch = 1;
217 kprobe_per_regs[0].starting_addr = (unsigned long)p->ainsn.insn;
218 kprobe_per_regs[0].ending_addr = (unsigned long)p->ainsn.insn + 1;
219
220 /* Set the PER control regs, turns on single step for this address */
221 __ctl_load(kprobe_per_regs, 9, 11);
222 regs->psw.mask |= PSW_MASK_PER;
223 regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
224}
225
226static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
227{
228 kcb->prev_kprobe.kp = kprobe_running();
229 kcb->prev_kprobe.status = kcb->kprobe_status;
230 kcb->prev_kprobe.kprobe_saved_imask = kcb->kprobe_saved_imask;
231 memcpy(kcb->prev_kprobe.kprobe_saved_ctl, kcb->kprobe_saved_ctl,
232 sizeof(kcb->kprobe_saved_ctl));
233}
234
235static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
236{
237 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
238 kcb->kprobe_status = kcb->prev_kprobe.status;
239 kcb->kprobe_saved_imask = kcb->prev_kprobe.kprobe_saved_imask;
240 memcpy(kcb->kprobe_saved_ctl, kcb->prev_kprobe.kprobe_saved_ctl,
241 sizeof(kcb->kprobe_saved_ctl));
242}
243
244static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
245 struct kprobe_ctlblk *kcb)
246{
247 __get_cpu_var(current_kprobe) = p;
248 /* Save the interrupt and per flags */
249 kcb->kprobe_saved_imask = regs->psw.mask &
250 (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
251 /* Save the control regs that govern PER */
252 __ctl_store(kcb->kprobe_saved_ctl, 9, 11);
253}
254
255/* Called with kretprobe_lock held */
256void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
257 struct pt_regs *regs)
258{
259 struct kretprobe_instance *ri;
260
261 if ((ri = get_free_rp_inst(rp)) != NULL) {
262 ri->rp = rp;
263 ri->task = current;
264 ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
265
266 /* Replace the return addr with trampoline addr */
267 regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
268
269 add_rp_inst(ri);
270 } else {
271 rp->nmissed++;
272 }
273}
274
275static int __kprobes kprobe_handler(struct pt_regs *regs)
276{
277 struct kprobe *p;
278 int ret = 0;
279 unsigned long *addr = (unsigned long *)
280 ((regs->psw.addr & PSW_ADDR_INSN) - 2);
281 struct kprobe_ctlblk *kcb;
282
283 /*
284 * We don't want to be preempted for the entire
285 * duration of kprobe processing
286 */
287 preempt_disable();
288 kcb = get_kprobe_ctlblk();
289
290 /* Check we're not actually recursing */
291 if (kprobe_running()) {
292 p = get_kprobe(addr);
293 if (p) {
294 if (kcb->kprobe_status == KPROBE_HIT_SS &&
295 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
296 regs->psw.mask &= ~PSW_MASK_PER;
297 regs->psw.mask |= kcb->kprobe_saved_imask;
298 goto no_kprobe;
299 }
300 /* We have reentered the kprobe_handler(), since
301 * another probe was hit while within the handler.
302 * We here save the original kprobes variables and
303 * just single step on the instruction of the new probe
304 * without calling any user handlers.
305 */
306 save_previous_kprobe(kcb);
307 set_current_kprobe(p, regs, kcb);
308 kprobes_inc_nmissed_count(p);
309 prepare_singlestep(p, regs);
310 kcb->kprobe_status = KPROBE_REENTER;
311 return 1;
312 } else {
313 p = __get_cpu_var(current_kprobe);
314 if (p->break_handler && p->break_handler(p, regs)) {
315 goto ss_probe;
316 }
317 }
318 goto no_kprobe;
319 }
320
321 p = get_kprobe(addr);
322 if (!p) {
323 if (*addr != BREAKPOINT_INSTRUCTION) {
324 /*
325 * The breakpoint instruction was removed right
326 * after we hit it. Another cpu has removed
327 * either a probepoint or a debugger breakpoint
328 * at this address. In either case, no further
329 * handling of this interrupt is appropriate.
330 *
331 */
332 ret = 1;
333 }
334 /* Not one of ours: let kernel handle it */
335 goto no_kprobe;
336 }
337
338 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
339 set_current_kprobe(p, regs, kcb);
340 if (p->pre_handler && p->pre_handler(p, regs))
341 /* handler has already set things up, so skip ss setup */
342 return 1;
343
344ss_probe:
345 prepare_singlestep(p, regs);
346 kcb->kprobe_status = KPROBE_HIT_SS;
347 return 1;
348
349no_kprobe:
350 preempt_enable_no_resched();
351 return ret;
352}
353
354/*
355 * Function return probe trampoline:
356 * - init_kprobes() establishes a probepoint here
357 * - When the probed function returns, this probe
358 * causes the handlers to fire
359 */
360void __kprobes kretprobe_trampoline_holder(void)
361{
362 asm volatile(".global kretprobe_trampoline\n"
363 "kretprobe_trampoline: bcr 0,0\n");
364}
365
366/*
367 * Called when the probe at kretprobe trampoline is hit
368 */
369int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
370{
371 struct kretprobe_instance *ri = NULL;
372 struct hlist_head *head;
373 struct hlist_node *node, *tmp;
374 unsigned long flags, orig_ret_address = 0;
375 unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
376
377 spin_lock_irqsave(&kretprobe_lock, flags);
378 head = kretprobe_inst_table_head(current);
379
380 /*
381 * It is possible to have multiple instances associated with a given
382 * task either because an multiple functions in the call path
383 * have a return probe installed on them, and/or more then one return
384 * return probe was registered for a target function.
385 *
386 * We can handle this because:
387 * - instances are always inserted at the head of the list
388 * - when multiple return probes are registered for the same
389 * function, the first instance's ret_addr will point to the
390 * real return address, and all the rest will point to
391 * kretprobe_trampoline
392 */
393 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
394 if (ri->task != current)
395 /* another task is sharing our hash bucket */
396 continue;
397
398 if (ri->rp && ri->rp->handler)
399 ri->rp->handler(ri, regs);
400
401 orig_ret_address = (unsigned long)ri->ret_addr;
402 recycle_rp_inst(ri);
403
404 if (orig_ret_address != trampoline_address) {
405 /*
406 * This is the real return address. Any other
407 * instances associated with this task are for
408 * other calls deeper on the call stack
409 */
410 break;
411 }
412 }
413 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
414 regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE;
415
416 reset_current_kprobe();
417 spin_unlock_irqrestore(&kretprobe_lock, flags);
418 preempt_enable_no_resched();
419
420 /*
421 * By returning a non-zero value, we are telling
422 * kprobe_handler() that we don't want the post_handler
423 * to run (and have re-enabled preemption)
424 */
425 return 1;
426}
427
428/*
429 * Called after single-stepping. p->addr is the address of the
430 * instruction whose first byte has been replaced by the "breakpoint"
431 * instruction. To avoid the SMP problems that can occur when we
432 * temporarily put back the original opcode to single-step, we
433 * single-stepped a copy of the instruction. The address of this
434 * copy is p->ainsn.insn.
435 */
436static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
437{
438 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
439
440 regs->psw.addr &= PSW_ADDR_INSN;
441
442 if (p->ainsn.fixup & FIXUP_PSW_NORMAL)
443 regs->psw.addr = (unsigned long)p->addr +
444 ((unsigned long)regs->psw.addr -
445 (unsigned long)p->ainsn.insn);
446
447 if (p->ainsn.fixup & FIXUP_BRANCH_NOT_TAKEN)
448 if ((unsigned long)regs->psw.addr -
449 (unsigned long)p->ainsn.insn == p->ainsn.ilen)
450 regs->psw.addr = (unsigned long)p->addr + p->ainsn.ilen;
451
452 if (p->ainsn.fixup & FIXUP_RETURN_REGISTER)
453 regs->gprs[p->ainsn.reg] = ((unsigned long)p->addr +
454 (regs->gprs[p->ainsn.reg] -
455 (unsigned long)p->ainsn.insn))
456 | PSW_ADDR_AMODE;
457
458 regs->psw.addr |= PSW_ADDR_AMODE;
459 /* turn off PER mode */
460 regs->psw.mask &= ~PSW_MASK_PER;
461 /* Restore the original per control regs */
462 __ctl_load(kcb->kprobe_saved_ctl, 9, 11);
463 regs->psw.mask |= kcb->kprobe_saved_imask;
464}
465
466static int __kprobes post_kprobe_handler(struct pt_regs *regs)
467{
468 struct kprobe *cur = kprobe_running();
469 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
470
471 if (!cur)
472 return 0;
473
474 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
475 kcb->kprobe_status = KPROBE_HIT_SSDONE;
476 cur->post_handler(cur, regs, 0);
477 }
478
479 resume_execution(cur, regs);
480
481 /*Restore back the original saved kprobes variables and continue. */
482 if (kcb->kprobe_status == KPROBE_REENTER) {
483 restore_previous_kprobe(kcb);
484 goto out;
485 }
486 reset_current_kprobe();
487out:
488 preempt_enable_no_resched();
489
490 /*
491 * if somebody else is singlestepping across a probe point, psw mask
492 * will have PER set, in which case, continue the remaining processing
493 * of do_single_step, as if this is not a probe hit.
494 */
495 if (regs->psw.mask & PSW_MASK_PER) {
496 return 0;
497 }
498
499 return 1;
500}
501
502static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
503{
504 struct kprobe *cur = kprobe_running();
505 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
506 const struct exception_table_entry *entry;
507
508 switch(kcb->kprobe_status) {
509 case KPROBE_SWAP_INST:
510 /* We are here because the instruction replacement failed */
511 return 0;
512 case KPROBE_HIT_SS:
513 case KPROBE_REENTER:
514 /*
515 * We are here because the instruction being single
516 * stepped caused a page fault. We reset the current
517 * kprobe and the nip points back to the probe address
518 * and allow the page fault handler to continue as a
519 * normal page fault.
520 */
521 regs->psw.addr = (unsigned long)cur->addr | PSW_ADDR_AMODE;
522 regs->psw.mask &= ~PSW_MASK_PER;
523 regs->psw.mask |= kcb->kprobe_saved_imask;
524 if (kcb->kprobe_status == KPROBE_REENTER)
525 restore_previous_kprobe(kcb);
526 else
527 reset_current_kprobe();
528 preempt_enable_no_resched();
529 break;
530 case KPROBE_HIT_ACTIVE:
531 case KPROBE_HIT_SSDONE:
532 /*
533 * We increment the nmissed count for accounting,
534 * we can also use npre/npostfault count for accouting
535 * these specific fault cases.
536 */
537 kprobes_inc_nmissed_count(cur);
538
539 /*
540 * We come here because instructions in the pre/post
541 * handler caused the page_fault, this could happen
542 * if handler tries to access user space by
543 * copy_from_user(), get_user() etc. Let the
544 * user-specified handler try to fix it first.
545 */
546 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
547 return 1;
548
549 /*
550 * In case the user-specified fault handler returned
551 * zero, try to fix up.
552 */
553 entry = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
554 if (entry) {
555 regs->psw.addr = entry->fixup | PSW_ADDR_AMODE;
556 return 1;
557 }
558
559 /*
560 * fixup_exception() could not handle it,
561 * Let do_page_fault() fix it.
562 */
563 break;
564 default:
565 break;
566 }
567 return 0;
568}
569
570/*
571 * Wrapper routine to for handling exceptions.
572 */
573int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
574 unsigned long val, void *data)
575{
576 struct die_args *args = (struct die_args *)data;
577 int ret = NOTIFY_DONE;
578
579 switch (val) {
580 case DIE_BPT:
581 if (kprobe_handler(args->regs))
582 ret = NOTIFY_STOP;
583 break;
584 case DIE_SSTEP:
585 if (post_kprobe_handler(args->regs))
586 ret = NOTIFY_STOP;
587 break;
588 case DIE_TRAP:
589 case DIE_PAGE_FAULT:
590 /* kprobe_running() needs smp_processor_id() */
591 preempt_disable();
592 if (kprobe_running() &&
593 kprobe_fault_handler(args->regs, args->trapnr))
594 ret = NOTIFY_STOP;
595 preempt_enable();
596 break;
597 default:
598 break;
599 }
600 return ret;
601}
602
603int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
604{
605 struct jprobe *jp = container_of(p, struct jprobe, kp);
606 unsigned long addr;
607 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
608
609 memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
610
611 /* setup return addr to the jprobe handler routine */
612 regs->psw.addr = (unsigned long)(jp->entry) | PSW_ADDR_AMODE;
613
614 /* r14 is the function return address */
615 kcb->jprobe_saved_r14 = (unsigned long)regs->gprs[14];
616 /* r15 is the stack pointer */
617 kcb->jprobe_saved_r15 = (unsigned long)regs->gprs[15];
618 addr = (unsigned long)kcb->jprobe_saved_r15;
619
620 memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr,
621 MIN_STACK_SIZE(addr));
622 return 1;
623}
624
625void __kprobes jprobe_return(void)
626{
627 asm volatile(".word 0x0002");
628}
629
630void __kprobes jprobe_return_end(void)
631{
632 asm volatile("bcr 0,0");
633}
634
635int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
636{
637 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
638 unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_r15);
639
640 /* Put the regs back */
641 memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
642 /* put the stack back */
643 memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
644 MIN_STACK_SIZE(stack_addr));
645 preempt_enable_no_resched();
646 return 1;
647}
648
649static struct kprobe trampoline_p = {
650 .addr = (kprobe_opcode_t *) & kretprobe_trampoline,
651 .pre_handler = trampoline_probe_handler
652};
653
654int __init arch_init_kprobes(void)
655{
656 return register_kprobe(&trampoline_p);
657}
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index 658e5ac484f9..4562cdbce8eb 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -8,13 +8,30 @@
8 8
9#include <asm/lowcore.h> 9#include <asm/lowcore.h>
10 10
11 .globl do_reipl 11 .globl do_reipl_asm
12do_reipl: basr %r13,0 12do_reipl_asm: basr %r13,0
13.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13) 13.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13)
14.Lpg1: lctl %c6,%c6,.Lall-.Lpg0(%r13) 14
15 stctl %c0,%c0,.Lctlsave-.Lpg0(%r13) 15 # switch off lowcore protection
16 ni .Lctlsave-.Lpg0(%r13),0xef 16
17 lctl %c0,%c0,.Lctlsave-.Lpg0(%r13) 17.Lpg1: stctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
18 stctl %c0,%c0,.Lctlsave2-.Lpg0(%r13)
19 ni .Lctlsave1-.Lpg0(%r13),0xef
20 lctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
21
22 # do store status of all registers
23
24 stm %r0,%r15,__LC_GPREGS_SAVE_AREA
25 stctl %c0,%c15,__LC_CREGS_SAVE_AREA
26 mvc __LC_CREGS_SAVE_AREA(4),.Lctlsave2-.Lpg0(%r13)
27 stam %a0,%a15,__LC_AREGS_SAVE_AREA
28 stpx __LC_PREFIX_SAVE_AREA
29 stckc .Lclkcmp-.Lpg0(%r13)
30 mvc __LC_CLOCK_COMP_SAVE_AREA(8),.Lclkcmp-.Lpg0(%r13)
31 stpt __LC_CPU_TIMER_SAVE_AREA
32 st %r13, __LC_PSW_SAVE_AREA+4
33
34 lctl %c6,%c6,.Lall-.Lpg0(%r13)
18 lr %r1,%r2 35 lr %r1,%r2
19 mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13) 36 mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13)
20 stsch .Lschib-.Lpg0(%r13) 37 stsch .Lschib-.Lpg0(%r13)
@@ -46,9 +63,11 @@ do_reipl: basr %r13,0
46.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) 63.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13)
47 lpsw .Ldispsw-.Lpg0(%r13) 64 lpsw .Ldispsw-.Lpg0(%r13)
48 .align 8 65 .align 8
66.Lclkcmp: .quad 0x0000000000000000
49.Lall: .long 0xff000000 67.Lall: .long 0xff000000
50.Lnull: .long 0x00000000 68.Lnull: .long 0x00000000
51.Lctlsave: .long 0x00000000 69.Lctlsave1: .long 0x00000000
70.Lctlsave2: .long 0x00000000
52 .align 8 71 .align 8
53.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 72.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1
54.Lpcnew: .long 0x00080000,0x80000000+.Lecs 73.Lpcnew: .long 0x00080000,0x80000000+.Lecs
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index 4d090d60f3ef..95bd1e234f63 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -8,13 +8,30 @@
8 */ 8 */
9 9
10#include <asm/lowcore.h> 10#include <asm/lowcore.h>
11 .globl do_reipl 11 .globl do_reipl_asm
12do_reipl: basr %r13,0 12do_reipl_asm: basr %r13,0
13.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) 13
14 # do store status of all registers
15
16.Lpg0: stg %r1,.Lregsave-.Lpg0(%r13)
17 lghi %r1,0x1000
18 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
19 lg %r0,.Lregsave-.Lpg0(%r13)
20 stg %r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1)
21 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1)
22 stam %a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1)
23 stpx __LC_PREFIX_SAVE_AREA-0x1000(%r1)
24 stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1)
25 stckc .Lclkcmp-.Lpg0(%r13)
26 mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(8,%r1),.Lclkcmp-.Lpg0(%r13)
27 stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
28 stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
29
30 lpswe .Lnewpsw-.Lpg0(%r13)
14.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13) 31.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
15 stctg %c0,%c0,.Lctlsave-.Lpg0(%r13) 32 stctg %c0,%c0,.Lregsave-.Lpg0(%r13)
16 ni .Lctlsave+4-.Lpg0(%r13),0xef 33 ni .Lregsave+4-.Lpg0(%r13),0xef
17 lctlg %c0,%c0,.Lctlsave-.Lpg0(%r13) 34 lctlg %c0,%c0,.Lregsave-.Lpg0(%r13)
18 lgr %r1,%r2 35 lgr %r1,%r2
19 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) 36 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
20 stsch .Lschib-.Lpg0(%r13) 37 stsch .Lschib-.Lpg0(%r13)
@@ -50,8 +67,9 @@ do_reipl: basr %r13,0
50 st %r14,.Ldispsw+12-.Lpg0(%r13) 67 st %r14,.Ldispsw+12-.Lpg0(%r13)
51 lpswe .Ldispsw-.Lpg0(%r13) 68 lpswe .Ldispsw-.Lpg0(%r13)
52 .align 8 69 .align 8
70.Lclkcmp: .quad 0x0000000000000000
53.Lall: .quad 0x00000000ff000000 71.Lall: .quad 0x00000000ff000000
54.Lctlsave: .quad 0x0000000000000000 72.Lregsave: .quad 0x0000000000000000
55.Lnull: .long 0x0000000000000000 73.Lnull: .long 0x0000000000000000
56 .align 16 74 .align 16
57/* 75/*
@@ -92,5 +110,3 @@ do_reipl: basr %r13,0
92 .long 0x00000000,0x00000000 110 .long 0x00000000,0x00000000
93 .long 0x00000000,0x00000000 111 .long 0x00000000,0x00000000
94 112
95
96
diff --git a/arch/s390/kernel/reipl_diag.c b/arch/s390/kernel/reipl_diag.c
deleted file mode 100644
index 1f33951ba439..000000000000
--- a/arch/s390/kernel/reipl_diag.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * This file contains the implementation of the
3 * Linux re-IPL support
4 *
5 * (C) Copyright IBM Corp. 2005
6 *
7 * Author(s): Volker Sameske (sameske@de.ibm.com)
8 *
9 */
10
11#include <linux/kernel.h>
12
13static unsigned int reipl_diag_rc1;
14static unsigned int reipl_diag_rc2;
15
16/*
17 * re-IPL the system using the last used IPL parameters
18 */
19void reipl_diag(void)
20{
21 asm volatile (
22 " la %%r4,0\n"
23 " la %%r5,0\n"
24 " diag %%r4,%2,0x308\n"
25 "0:\n"
26 " st %%r4,%0\n"
27 " st %%r5,%1\n"
28 ".section __ex_table,\"a\"\n"
29#ifdef CONFIG_64BIT
30 " .align 8\n"
31 " .quad 0b, 0b\n"
32#else
33 " .align 4\n"
34 " .long 0b, 0b\n"
35#endif
36 ".previous\n"
37 : "=m" (reipl_diag_rc1), "=m" (reipl_diag_rc2)
38 : "d" (3) : "cc", "4", "5" );
39}
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index c73a45467fa4..9f19e833a562 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -25,12 +25,6 @@ EXPORT_SYMBOL(_oi_bitmap);
25EXPORT_SYMBOL(_ni_bitmap); 25EXPORT_SYMBOL(_ni_bitmap);
26EXPORT_SYMBOL(_zb_findmap); 26EXPORT_SYMBOL(_zb_findmap);
27EXPORT_SYMBOL(_sb_findmap); 27EXPORT_SYMBOL(_sb_findmap);
28EXPORT_SYMBOL(__copy_from_user_asm);
29EXPORT_SYMBOL(__copy_to_user_asm);
30EXPORT_SYMBOL(__copy_in_user_asm);
31EXPORT_SYMBOL(__clear_user_asm);
32EXPORT_SYMBOL(__strncpy_from_user_asm);
33EXPORT_SYMBOL(__strnlen_user_asm);
34EXPORT_SYMBOL(diag10); 28EXPORT_SYMBOL(diag10);
35 29
36/* 30/*
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c902f059c7aa..e3d9325f6022 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -37,6 +37,7 @@
37#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include <linux/notifier.h> 39#include <linux/notifier.h>
40#include <linux/pfn.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/system.h> 43#include <asm/system.h>
@@ -50,6 +51,12 @@
50#include <asm/sections.h> 51#include <asm/sections.h>
51 52
52/* 53/*
54 * User copy operations.
55 */
56struct uaccess_ops uaccess;
57EXPORT_SYMBOL_GPL(uaccess);
58
59/*
53 * Machine setup.. 60 * Machine setup..
54 */ 61 */
55unsigned int console_mode = 0; 62unsigned int console_mode = 0;
@@ -284,16 +291,9 @@ void (*_machine_power_off)(void) = machine_power_off_smp;
284/* 291/*
285 * Reboot, halt and power_off routines for non SMP. 292 * Reboot, halt and power_off routines for non SMP.
286 */ 293 */
287extern void reipl(unsigned long devno);
288extern void reipl_diag(void);
289static void do_machine_restart_nonsmp(char * __unused) 294static void do_machine_restart_nonsmp(char * __unused)
290{ 295{
291 reipl_diag(); 296 do_reipl();
292
293 if (MACHINE_IS_VM)
294 cpcmd ("IPL", NULL, 0, NULL);
295 else
296 reipl (0x10000 | S390_lowcore.ipl_device);
297} 297}
298 298
299static void do_machine_halt_nonsmp(void) 299static void do_machine_halt_nonsmp(void)
@@ -501,13 +501,47 @@ setup_memory(void)
501 * partially used pages are not usable - thus 501 * partially used pages are not usable - thus
502 * we are rounding upwards: 502 * we are rounding upwards:
503 */ 503 */
504 start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT; 504 start_pfn = PFN_UP(__pa(&_end));
505 end_pfn = max_pfn = memory_end >> PAGE_SHIFT; 505 end_pfn = max_pfn = PFN_DOWN(memory_end);
506 506
507 /* Initialize storage key for kernel pages */ 507 /* Initialize storage key for kernel pages */
508 for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++) 508 for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
509 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); 509 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
510 510
511#ifdef CONFIG_BLK_DEV_INITRD
512 /*
513 * Move the initrd in case the bitmap of the bootmem allocater
514 * would overwrite it.
515 */
516
517 if (INITRD_START && INITRD_SIZE) {
518 unsigned long bmap_size;
519 unsigned long start;
520
521 bmap_size = bootmem_bootmap_pages(end_pfn - start_pfn + 1);
522 bmap_size = PFN_PHYS(bmap_size);
523
524 if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {
525 start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;
526
527 if (start + INITRD_SIZE > memory_end) {
528 printk("initrd extends beyond end of memory "
529 "(0x%08lx > 0x%08lx)\n"
530 "disabling initrd\n",
531 start + INITRD_SIZE, memory_end);
532 INITRD_START = INITRD_SIZE = 0;
533 } else {
534 printk("Moving initrd (0x%08lx -> 0x%08lx, "
535 "size: %ld)\n",
536 INITRD_START, start, INITRD_SIZE);
537 memmove((void *) start, (void *) INITRD_START,
538 INITRD_SIZE);
539 INITRD_START = start;
540 }
541 }
542 }
543#endif
544
511 /* 545 /*
512 * Initialize the boot-time allocator (with low memory only): 546 * Initialize the boot-time allocator (with low memory only):
513 */ 547 */
@@ -559,7 +593,7 @@ setup_memory(void)
559 reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size); 593 reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);
560 594
561#ifdef CONFIG_BLK_DEV_INITRD 595#ifdef CONFIG_BLK_DEV_INITRD
562 if (INITRD_START) { 596 if (INITRD_START && INITRD_SIZE) {
563 if (INITRD_START + INITRD_SIZE <= memory_end) { 597 if (INITRD_START + INITRD_SIZE <= memory_end) {
564 reserve_bootmem(INITRD_START, INITRD_SIZE); 598 reserve_bootmem(INITRD_START, INITRD_SIZE);
565 initrd_start = INITRD_START; 599 initrd_start = INITRD_START;
@@ -613,6 +647,11 @@ setup_arch(char **cmdline_p)
613 647
614 memory_end = memory_size; 648 memory_end = memory_size;
615 649
650 if (MACHINE_HAS_MVCOS)
651 memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess));
652 else
653 memcpy(&uaccess, &uaccess_std, sizeof(uaccess));
654
616 parse_early_param(); 655 parse_early_param();
617 656
618#ifndef CONFIG_64BIT 657#ifndef CONFIG_64BIT
@@ -720,214 +759,3 @@ struct seq_operations cpuinfo_op = {
720 .show = show_cpuinfo, 759 .show = show_cpuinfo,
721}; 760};
722 761
723#define DEFINE_IPL_ATTR(_name, _format, _value) \
724static ssize_t ipl_##_name##_show(struct subsystem *subsys, \
725 char *page) \
726{ \
727 return sprintf(page, _format, _value); \
728} \
729static struct subsys_attribute ipl_##_name##_attr = \
730 __ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);
731
732DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long)
733 IPL_PARMBLOCK_START->fcp.wwpn);
734DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long)
735 IPL_PARMBLOCK_START->fcp.lun);
736DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long)
737 IPL_PARMBLOCK_START->fcp.bootprog);
738DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long)
739 IPL_PARMBLOCK_START->fcp.br_lba);
740
741enum ipl_type_type {
742 ipl_type_unknown,
743 ipl_type_ccw,
744 ipl_type_fcp,
745};
746
747static enum ipl_type_type
748get_ipl_type(void)
749{
750 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
751
752 if (!IPL_DEVNO_VALID)
753 return ipl_type_unknown;
754 if (!IPL_PARMBLOCK_VALID)
755 return ipl_type_ccw;
756 if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION)
757 return ipl_type_unknown;
758 if (ipl->fcp.pbt != IPL_TYPE_FCP)
759 return ipl_type_unknown;
760 return ipl_type_fcp;
761}
762
763static ssize_t
764ipl_type_show(struct subsystem *subsys, char *page)
765{
766 switch (get_ipl_type()) {
767 case ipl_type_ccw:
768 return sprintf(page, "ccw\n");
769 case ipl_type_fcp:
770 return sprintf(page, "fcp\n");
771 default:
772 return sprintf(page, "unknown\n");
773 }
774}
775
776static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);
777
778static ssize_t
779ipl_device_show(struct subsystem *subsys, char *page)
780{
781 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
782
783 switch (get_ipl_type()) {
784 case ipl_type_ccw:
785 return sprintf(page, "0.0.%04x\n", ipl_devno);
786 case ipl_type_fcp:
787 return sprintf(page, "0.0.%04x\n", ipl->fcp.devno);
788 default:
789 return 0;
790 }
791}
792
793static struct subsys_attribute ipl_device_attr =
794 __ATTR(device, S_IRUGO, ipl_device_show, NULL);
795
796static struct attribute *ipl_fcp_attrs[] = {
797 &ipl_type_attr.attr,
798 &ipl_device_attr.attr,
799 &ipl_wwpn_attr.attr,
800 &ipl_lun_attr.attr,
801 &ipl_bootprog_attr.attr,
802 &ipl_br_lba_attr.attr,
803 NULL,
804};
805
806static struct attribute_group ipl_fcp_attr_group = {
807 .attrs = ipl_fcp_attrs,
808};
809
810static struct attribute *ipl_ccw_attrs[] = {
811 &ipl_type_attr.attr,
812 &ipl_device_attr.attr,
813 NULL,
814};
815
816static struct attribute_group ipl_ccw_attr_group = {
817 .attrs = ipl_ccw_attrs,
818};
819
820static struct attribute *ipl_unknown_attrs[] = {
821 &ipl_type_attr.attr,
822 NULL,
823};
824
825static struct attribute_group ipl_unknown_attr_group = {
826 .attrs = ipl_unknown_attrs,
827};
828
829static ssize_t
830ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
831{
832 unsigned int size = IPL_PARMBLOCK_SIZE;
833
834 if (off > size)
835 return 0;
836 if (off + count > size)
837 count = size - off;
838
839 memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count);
840 return count;
841}
842
843static struct bin_attribute ipl_parameter_attr = {
844 .attr = {
845 .name = "binary_parameter",
846 .mode = S_IRUGO,
847 .owner = THIS_MODULE,
848 },
849 .size = PAGE_SIZE,
850 .read = &ipl_parameter_read,
851};
852
853static ssize_t
854ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
855{
856 unsigned int size = IPL_PARMBLOCK_START->fcp.scp_data_len;
857 void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data;
858
859 if (off > size)
860 return 0;
861 if (off + count > size)
862 count = size - off;
863
864 memcpy(buf, scp_data + off, count);
865 return count;
866}
867
868static struct bin_attribute ipl_scp_data_attr = {
869 .attr = {
870 .name = "scp_data",
871 .mode = S_IRUGO,
872 .owner = THIS_MODULE,
873 },
874 .size = PAGE_SIZE,
875 .read = &ipl_scp_data_read,
876};
877
878static decl_subsys(ipl, NULL, NULL);
879
880static int ipl_register_fcp_files(void)
881{
882 int rc;
883
884 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
885 &ipl_fcp_attr_group);
886 if (rc)
887 goto out;
888 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
889 &ipl_parameter_attr);
890 if (rc)
891 goto out_ipl_parm;
892 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
893 &ipl_scp_data_attr);
894 if (!rc)
895 goto out;
896
897 sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
898
899out_ipl_parm:
900 sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
901out:
902 return rc;
903}
904
905static int __init
906ipl_device_sysfs_register(void) {
907 int rc;
908
909 rc = firmware_register(&ipl_subsys);
910 if (rc)
911 goto out;
912
913 switch (get_ipl_type()) {
914 case ipl_type_ccw:
915 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
916 &ipl_ccw_attr_group);
917 break;
918 case ipl_type_fcp:
919 rc = ipl_register_fcp_files();
920 break;
921 default:
922 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
923 &ipl_unknown_attr_group);
924 break;
925 }
926
927 if (rc)
928 firmware_unregister(&ipl_subsys);
929out:
930 return rc;
931}
932
933__initcall(ipl_device_sysfs_register);
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index a887b686f279..642095ec7c07 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -114,29 +114,26 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
114static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs) 114static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
115{ 115{
116 unsigned long old_mask = regs->psw.mask; 116 unsigned long old_mask = regs->psw.mask;
117 int err; 117 _sigregs user_sregs;
118 118
119 save_access_regs(current->thread.acrs); 119 save_access_regs(current->thread.acrs);
120 120
121 /* Copy a 'clean' PSW mask to the user to avoid leaking 121 /* Copy a 'clean' PSW mask to the user to avoid leaking
122 information about whether PER is currently on. */ 122 information about whether PER is currently on. */
123 regs->psw.mask = PSW_MASK_MERGE(PSW_USER_BITS, regs->psw.mask); 123 regs->psw.mask = PSW_MASK_MERGE(PSW_USER_BITS, regs->psw.mask);
124 err = __copy_to_user(&sregs->regs.psw, &regs->psw, 124 memcpy(&user_sregs.regs.psw, &regs->psw, sizeof(sregs->regs.psw) +
125 sizeof(sregs->regs.psw)+sizeof(sregs->regs.gprs)); 125 sizeof(sregs->regs.gprs));
126 regs->psw.mask = old_mask; 126 regs->psw.mask = old_mask;
127 if (err != 0) 127 memcpy(&user_sregs.regs.acrs, current->thread.acrs,
128 return err; 128 sizeof(sregs->regs.acrs));
129 err = __copy_to_user(&sregs->regs.acrs, current->thread.acrs,
130 sizeof(sregs->regs.acrs));
131 if (err != 0)
132 return err;
133 /* 129 /*
134 * We have to store the fp registers to current->thread.fp_regs 130 * We have to store the fp registers to current->thread.fp_regs
135 * to merge them with the emulated registers. 131 * to merge them with the emulated registers.
136 */ 132 */
137 save_fp_regs(&current->thread.fp_regs); 133 save_fp_regs(&current->thread.fp_regs);
138 return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs, 134 memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
139 sizeof(s390_fp_regs)); 135 sizeof(s390_fp_regs));
136 return __copy_to_user(sregs, &user_sregs, sizeof(_sigregs));
140} 137}
141 138
142/* Returns positive number on error */ 139/* Returns positive number on error */
@@ -144,27 +141,25 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
144{ 141{
145 unsigned long old_mask = regs->psw.mask; 142 unsigned long old_mask = regs->psw.mask;
146 int err; 143 int err;
144 _sigregs user_sregs;
147 145
148 /* Alwys make any pending restarted system call return -EINTR */ 146 /* Alwys make any pending restarted system call return -EINTR */
149 current_thread_info()->restart_block.fn = do_no_restart_syscall; 147 current_thread_info()->restart_block.fn = do_no_restart_syscall;
150 148
151 err = __copy_from_user(&regs->psw, &sregs->regs.psw, 149 err = __copy_from_user(&user_sregs, sregs, sizeof(_sigregs));
152 sizeof(sregs->regs.psw)+sizeof(sregs->regs.gprs));
153 regs->psw.mask = PSW_MASK_MERGE(old_mask, regs->psw.mask); 150 regs->psw.mask = PSW_MASK_MERGE(old_mask, regs->psw.mask);
154 regs->psw.addr |= PSW_ADDR_AMODE; 151 regs->psw.addr |= PSW_ADDR_AMODE;
155 if (err) 152 if (err)
156 return err; 153 return err;
157 err = __copy_from_user(&current->thread.acrs, &sregs->regs.acrs, 154 memcpy(&regs->psw, &user_sregs.regs.psw, sizeof(sregs->regs.psw) +
158 sizeof(sregs->regs.acrs)); 155 sizeof(sregs->regs.gprs));
159 if (err) 156 memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
160 return err; 157 sizeof(sregs->regs.acrs));
161 restore_access_regs(current->thread.acrs); 158 restore_access_regs(current->thread.acrs);
162 159
163 err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs, 160 memcpy(&current->thread.fp_regs, &user_sregs.fpregs,
164 sizeof(s390_fp_regs)); 161 sizeof(s390_fp_regs));
165 current->thread.fp_regs.fpc &= FPC_VALID_MASK; 162 current->thread.fp_regs.fpc &= FPC_VALID_MASK;
166 if (err)
167 return err;
168 163
169 restore_fp_regs(&current->thread.fp_regs); 164 restore_fp_regs(&current->thread.fp_regs);
170 regs->trap = -1; /* disable syscall checks */ 165 regs->trap = -1; /* disable syscall checks */
@@ -457,6 +452,7 @@ void do_signal(struct pt_regs *regs)
457 case -ERESTART_RESTARTBLOCK: 452 case -ERESTART_RESTARTBLOCK:
458 regs->gprs[2] = -EINTR; 453 regs->gprs[2] = -EINTR;
459 } 454 }
455 regs->trap = -1; /* Don't deal with this again. */
460 } 456 }
461 457
462 /* Get signal to deliver. When running under ptrace, at this point 458 /* Get signal to deliver. When running under ptrace, at this point
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8e03219eea76..b2e6f4c8d382 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -59,9 +59,6 @@ static struct task_struct *current_set[NR_CPUS];
59extern char vmhalt_cmd[]; 59extern char vmhalt_cmd[];
60extern char vmpoff_cmd[]; 60extern char vmpoff_cmd[];
61 61
62extern void reipl(unsigned long devno);
63extern void reipl_diag(void);
64
65static void smp_ext_bitcall(int, ec_bit_sig); 62static void smp_ext_bitcall(int, ec_bit_sig);
66static void smp_ext_bitcall_others(ec_bit_sig); 63static void smp_ext_bitcall_others(ec_bit_sig);
67 64
@@ -279,12 +276,7 @@ static void do_machine_restart(void * __unused)
279 * interrupted by an external interrupt and s390irq 276 * interrupted by an external interrupt and s390irq
280 * locks are always held disabled). 277 * locks are always held disabled).
281 */ 278 */
282 reipl_diag(); 279 do_reipl();
283
284 if (MACHINE_IS_VM)
285 cpcmd ("IPL", NULL, 0, NULL);
286 else
287 reipl (0x10000 | S390_lowcore.ipl_device);
288} 280}
289 281
290void machine_restart_smp(char * __unused) 282void machine_restart_smp(char * __unused)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index bde1d1d59858..c4982c963424 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -29,6 +29,7 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/kallsyms.h> 30#include <linux/kallsyms.h>
31#include <linux/reboot.h> 31#include <linux/reboot.h>
32#include <linux/kprobes.h>
32 33
33#include <asm/system.h> 34#include <asm/system.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -39,6 +40,7 @@
39#include <asm/s390_ext.h> 40#include <asm/s390_ext.h>
40#include <asm/lowcore.h> 41#include <asm/lowcore.h>
41#include <asm/debug.h> 42#include <asm/debug.h>
43#include <asm/kdebug.h>
42 44
43/* Called from entry.S only */ 45/* Called from entry.S only */
44extern void handle_per_exception(struct pt_regs *regs); 46extern void handle_per_exception(struct pt_regs *regs);
@@ -74,6 +76,20 @@ static int kstack_depth_to_print = 12;
74static int kstack_depth_to_print = 20; 76static int kstack_depth_to_print = 20;
75#endif /* CONFIG_64BIT */ 77#endif /* CONFIG_64BIT */
76 78
79ATOMIC_NOTIFIER_HEAD(s390die_chain);
80
81int register_die_notifier(struct notifier_block *nb)
82{
83 return atomic_notifier_chain_register(&s390die_chain, nb);
84}
85EXPORT_SYMBOL(register_die_notifier);
86
87int unregister_die_notifier(struct notifier_block *nb)
88{
89 return atomic_notifier_chain_unregister(&s390die_chain, nb);
90}
91EXPORT_SYMBOL(unregister_die_notifier);
92
77/* 93/*
78 * For show_trace we have tree different stack to consider: 94 * For show_trace we have tree different stack to consider:
79 * - the panic stack which is used if the kernel stack has overflown 95 * - the panic stack which is used if the kernel stack has overflown
@@ -305,8 +321,9 @@ report_user_fault(long interruption_code, struct pt_regs *regs)
305#endif 321#endif
306} 322}
307 323
308static void inline do_trap(long interruption_code, int signr, char *str, 324static void __kprobes inline do_trap(long interruption_code, int signr,
309 struct pt_regs *regs, siginfo_t *info) 325 char *str, struct pt_regs *regs,
326 siginfo_t *info)
310{ 327{
311 /* 328 /*
312 * We got all needed information from the lowcore and can 329 * We got all needed information from the lowcore and can
@@ -315,6 +332,10 @@ static void inline do_trap(long interruption_code, int signr, char *str,
315 if (regs->psw.mask & PSW_MASK_PSTATE) 332 if (regs->psw.mask & PSW_MASK_PSTATE)
316 local_irq_enable(); 333 local_irq_enable();
317 334
335 if (notify_die(DIE_TRAP, str, regs, interruption_code,
336 interruption_code, signr) == NOTIFY_STOP)
337 return;
338
318 if (regs->psw.mask & PSW_MASK_PSTATE) { 339 if (regs->psw.mask & PSW_MASK_PSTATE) {
319 struct task_struct *tsk = current; 340 struct task_struct *tsk = current;
320 341
@@ -336,8 +357,12 @@ static inline void __user *get_check_address(struct pt_regs *regs)
336 return (void __user *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN); 357 return (void __user *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN);
337} 358}
338 359
339void do_single_step(struct pt_regs *regs) 360void __kprobes do_single_step(struct pt_regs *regs)
340{ 361{
362 if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0,
363 SIGTRAP) == NOTIFY_STOP){
364 return;
365 }
341 if ((current->ptrace & PT_PTRACED) != 0) 366 if ((current->ptrace & PT_PTRACED) != 0)
342 force_sig(SIGTRAP, current); 367 force_sig(SIGTRAP, current);
343} 368}
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index ff5f7bb34f75..af9e69a03011 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -24,6 +24,7 @@ SECTIONS
24 *(.text) 24 *(.text)
25 SCHED_TEXT 25 SCHED_TEXT
26 LOCK_TEXT 26 LOCK_TEXT
27 KPROBES_TEXT
27 *(.fixup) 28 *(.fixup)
28 *(.gnu.warning) 29 *(.gnu.warning)
29 } = 0x0700 30 } = 0x0700
@@ -117,7 +118,7 @@ SECTIONS
117 118
118 /* Sections to be discarded */ 119 /* Sections to be discarded */
119 /DISCARD/ : { 120 /DISCARD/ : {
120 *(.exitcall.exit) 121 *(.exit.text) *(.exit.data) *(.exitcall.exit)
121 } 122 }
122 123
123 /* Stabs debugging sections. */ 124 /* Stabs debugging sections. */
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index e05d087a6eae..c42ffedfdb49 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,6 +4,6 @@
4 4
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7lib-y += delay.o string.o 7lib-y += delay.o string.o uaccess_std.o
8lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o) 8lib-$(CONFIG_64BIT) += uaccess_mvcos.o
9lib-$(CONFIG_SMP) += spinlock.o 9lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S
deleted file mode 100644
index 837275284d9f..000000000000
--- a/arch/s390/lib/uaccess.S
+++ /dev/null
@@ -1,211 +0,0 @@
1/*
2 * arch/s390/lib/uaccess.S
3 * __copy_{from|to}_user functions.
4 *
5 * s390
6 * Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
8 *
9 * These functions have standard call interface
10 */
11
12#include <linux/errno.h>
13#include <asm/lowcore.h>
14#include <asm/asm-offsets.h>
15
16 .text
17 .align 4
18 .globl __copy_from_user_asm
19 # %r2 = to, %r3 = n, %r4 = from
20__copy_from_user_asm:
21 slr %r0,%r0
220: mvcp 0(%r3,%r2),0(%r4),%r0
23 jnz 1f
24 slr %r2,%r2
25 br %r14
261: la %r2,256(%r2)
27 la %r4,256(%r4)
28 ahi %r3,-256
292: mvcp 0(%r3,%r2),0(%r4),%r0
30 jnz 1b
313: slr %r2,%r2
32 br %r14
334: lhi %r0,-4096
34 lr %r5,%r4
35 slr %r5,%r0
36 nr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
37 slr %r5,%r4 # %r5 = #bytes to next user page boundary
38 clr %r3,%r5 # copy crosses next page boundary ?
39 jnh 6f # no, the current page faulted
40 # move with the reduced length which is < 256
415: mvcp 0(%r5,%r2),0(%r4),%r0
42 slr %r3,%r5
436: lr %r2,%r3
44 br %r14
45 .section __ex_table,"a"
46 .long 0b,4b
47 .long 2b,4b
48 .long 5b,6b
49 .previous
50
51 .align 4
52 .text
53 .globl __copy_to_user_asm
54 # %r2 = from, %r3 = n, %r4 = to
55__copy_to_user_asm:
56 slr %r0,%r0
570: mvcs 0(%r3,%r4),0(%r2),%r0
58 jnz 1f
59 slr %r2,%r2
60 br %r14
611: la %r2,256(%r2)
62 la %r4,256(%r4)
63 ahi %r3,-256
642: mvcs 0(%r3,%r4),0(%r2),%r0
65 jnz 1b
663: slr %r2,%r2
67 br %r14
684: lhi %r0,-4096
69 lr %r5,%r4
70 slr %r5,%r0
71 nr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
72 slr %r5,%r4 # %r5 = #bytes to next user page boundary
73 clr %r3,%r5 # copy crosses next page boundary ?
74 jnh 6f # no, the current page faulted
75 # move with the reduced length which is < 256
765: mvcs 0(%r5,%r4),0(%r2),%r0
77 slr %r3,%r5
786: lr %r2,%r3
79 br %r14
80 .section __ex_table,"a"
81 .long 0b,4b
82 .long 2b,4b
83 .long 5b,6b
84 .previous
85
86 .align 4
87 .text
88 .globl __copy_in_user_asm
89 # %r2 = from, %r3 = n, %r4 = to
90__copy_in_user_asm:
91 ahi %r3,-1
92 jo 6f
93 sacf 256
94 bras %r1,4f
950: ahi %r3,257
961: mvc 0(1,%r4),0(%r2)
97 la %r2,1(%r2)
98 la %r4,1(%r4)
99 ahi %r3,-1
100 jnz 1b
1012: lr %r2,%r3
102 br %r14
1033: mvc 0(256,%r4),0(%r2)
104 la %r2,256(%r2)
105 la %r4,256(%r4)
1064: ahi %r3,-256
107 jnm 3b
1085: ex %r3,4(%r1)
109 sacf 0
1106: slr %r2,%r2
111 br %r14
112 .section __ex_table,"a"
113 .long 1b,2b
114 .long 3b,0b
115 .long 5b,0b
116 .previous
117
118 .align 4
119 .text
120 .globl __clear_user_asm
121 # %r2 = to, %r3 = n
122__clear_user_asm:
123 bras %r5,0f
124 .long empty_zero_page
1250: l %r5,0(%r5)
126 slr %r0,%r0
1271: mvcs 0(%r3,%r2),0(%r5),%r0
128 jnz 2f
129 slr %r2,%r2
130 br %r14
1312: la %r2,256(%r2)
132 ahi %r3,-256
1333: mvcs 0(%r3,%r2),0(%r5),%r0
134 jnz 2b
1354: slr %r2,%r2
136 br %r14
1375: lhi %r0,-4096
138 lr %r4,%r2
139 slr %r4,%r0
140 nr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
141 slr %r4,%r2 # %r4 = #bytes to next user page boundary
142 clr %r3,%r4 # clear crosses next page boundary ?
143 jnh 7f # no, the current page faulted
144 # clear with the reduced length which is < 256
1456: mvcs 0(%r4,%r2),0(%r5),%r0
146 slr %r3,%r4
1477: lr %r2,%r3
148 br %r14
149 .section __ex_table,"a"
150 .long 1b,5b
151 .long 3b,5b
152 .long 6b,7b
153 .previous
154
155 .align 4
156 .text
157 .globl __strncpy_from_user_asm
158 # %r2 = count, %r3 = dst, %r4 = src
159__strncpy_from_user_asm:
160 lhi %r0,0
161 lr %r1,%r4
162 la %r4,0(%r4) # clear high order bit from %r4
163 la %r2,0(%r2,%r4) # %r2 points to first byte after string
164 sacf 256
1650: srst %r2,%r1
166 jo 0b
167 sacf 0
168 lr %r1,%r2
169 jh 1f # \0 found in string ?
170 ahi %r1,1 # include \0 in copy
1711: slr %r1,%r4 # %r1 = copy length (without \0)
172 slr %r2,%r4 # %r2 = return length (including \0)
1732: mvcp 0(%r1,%r3),0(%r4),%r0
174 jnz 3f
175 br %r14
1763: la %r3,256(%r3)
177 la %r4,256(%r4)
178 ahi %r1,-256
179 mvcp 0(%r1,%r3),0(%r4),%r0
180 jnz 3b
181 br %r14
1824: sacf 0
183 lhi %r2,-EFAULT
184 br %r14
185 .section __ex_table,"a"
186 .long 0b,4b
187 .previous
188
189 .align 4
190 .text
191 .globl __strnlen_user_asm
192 # %r2 = count, %r3 = src
193__strnlen_user_asm:
194 lhi %r0,0
195 lr %r1,%r3
196 la %r3,0(%r3) # clear high order bit from %r4
197 la %r2,0(%r2,%r3) # %r2 points to first byte after string
198 sacf 256
1990: srst %r2,%r1
200 jo 0b
201 sacf 0
202 ahi %r2,1 # strnlen_user result includes the \0
203 # or return count+1 if \0 not found
204 slr %r2,%r3
205 br %r14
2062: sacf 0
207 slr %r2,%r2 # return 0 on exception
208 br %r14
209 .section __ex_table,"a"
210 .long 0b,2b
211 .previous
diff --git a/arch/s390/lib/uaccess64.S b/arch/s390/lib/uaccess64.S
deleted file mode 100644
index 1f755be22f92..000000000000
--- a/arch/s390/lib/uaccess64.S
+++ /dev/null
@@ -1,207 +0,0 @@
1/*
2 * arch/s390x/lib/uaccess.S
3 * __copy_{from|to}_user functions.
4 *
5 * s390
6 * Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
8 *
9 * These functions have standard call interface
10 */
11
12#include <linux/errno.h>
13#include <asm/lowcore.h>
14#include <asm/asm-offsets.h>
15
16 .text
17 .align 4
18 .globl __copy_from_user_asm
19 # %r2 = to, %r3 = n, %r4 = from
20__copy_from_user_asm:
21 slgr %r0,%r0
220: mvcp 0(%r3,%r2),0(%r4),%r0
23 jnz 1f
24 slgr %r2,%r2
25 br %r14
261: la %r2,256(%r2)
27 la %r4,256(%r4)
28 aghi %r3,-256
292: mvcp 0(%r3,%r2),0(%r4),%r0
30 jnz 1b
313: slgr %r2,%r2
32 br %r14
334: lghi %r0,-4096
34 lgr %r5,%r4
35 slgr %r5,%r0
36 ngr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
37 slgr %r5,%r4 # %r5 = #bytes to next user page boundary
38 clgr %r3,%r5 # copy crosses next page boundary ?
39 jnh 6f # no, the current page faulted
40 # move with the reduced length which is < 256
415: mvcp 0(%r5,%r2),0(%r4),%r0
42 slgr %r3,%r5
436: lgr %r2,%r3
44 br %r14
45 .section __ex_table,"a"
46 .quad 0b,4b
47 .quad 2b,4b
48 .quad 5b,6b
49 .previous
50
51 .align 4
52 .text
53 .globl __copy_to_user_asm
54 # %r2 = from, %r3 = n, %r4 = to
55__copy_to_user_asm:
56 slgr %r0,%r0
570: mvcs 0(%r3,%r4),0(%r2),%r0
58 jnz 1f
59 slgr %r2,%r2
60 br %r14
611: la %r2,256(%r2)
62 la %r4,256(%r4)
63 aghi %r3,-256
642: mvcs 0(%r3,%r4),0(%r2),%r0
65 jnz 1b
663: slgr %r2,%r2
67 br %r14
684: lghi %r0,-4096
69 lgr %r5,%r4
70 slgr %r5,%r0
71 ngr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
72 slgr %r5,%r4 # %r5 = #bytes to next user page boundary
73 clgr %r3,%r5 # copy crosses next page boundary ?
74 jnh 6f # no, the current page faulted
75 # move with the reduced length which is < 256
765: mvcs 0(%r5,%r4),0(%r2),%r0
77 slgr %r3,%r5
786: lgr %r2,%r3
79 br %r14
80 .section __ex_table,"a"
81 .quad 0b,4b
82 .quad 2b,4b
83 .quad 5b,6b
84 .previous
85
86 .align 4
87 .text
88 .globl __copy_in_user_asm
89 # %r2 = from, %r3 = n, %r4 = to
90__copy_in_user_asm:
91 aghi %r3,-1
92 jo 6f
93 sacf 256
94 bras %r1,4f
950: aghi %r3,257
961: mvc 0(1,%r4),0(%r2)
97 la %r2,1(%r2)
98 la %r4,1(%r4)
99 aghi %r3,-1
100 jnz 1b
1012: lgr %r2,%r3
102 br %r14
1033: mvc 0(256,%r4),0(%r2)
104 la %r2,256(%r2)
105 la %r4,256(%r4)
1064: aghi %r3,-256
107 jnm 3b
1085: ex %r3,4(%r1)
109 sacf 0
1106: slgr %r2,%r2
111 br 14
112 .section __ex_table,"a"
113 .quad 1b,2b
114 .quad 3b,0b
115 .quad 5b,0b
116 .previous
117
118 .align 4
119 .text
120 .globl __clear_user_asm
121 # %r2 = to, %r3 = n
122__clear_user_asm:
123 slgr %r0,%r0
124 larl %r5,empty_zero_page
1251: mvcs 0(%r3,%r2),0(%r5),%r0
126 jnz 2f
127 slgr %r2,%r2
128 br %r14
1292: la %r2,256(%r2)
130 aghi %r3,-256
1313: mvcs 0(%r3,%r2),0(%r5),%r0
132 jnz 2b
1334: slgr %r2,%r2
134 br %r14
1355: lghi %r0,-4096
136 lgr %r4,%r2
137 slgr %r4,%r0
138 ngr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
139 slgr %r4,%r2 # %r4 = #bytes to next user page boundary
140 clgr %r3,%r4 # clear crosses next page boundary ?
141 jnh 7f # no, the current page faulted
142 # clear with the reduced length which is < 256
1436: mvcs 0(%r4,%r2),0(%r5),%r0
144 slgr %r3,%r4
1457: lgr %r2,%r3
146 br %r14
147 .section __ex_table,"a"
148 .quad 1b,5b
149 .quad 3b,5b
150 .quad 6b,7b
151 .previous
152
153 .align 4
154 .text
155 .globl __strncpy_from_user_asm
156 # %r2 = count, %r3 = dst, %r4 = src
157__strncpy_from_user_asm:
158 lghi %r0,0
159 lgr %r1,%r4
160 la %r2,0(%r2,%r4) # %r2 points to first byte after string
161 sacf 256
1620: srst %r2,%r1
163 jo 0b
164 sacf 0
165 lgr %r1,%r2
166 jh 1f # \0 found in string ?
167 aghi %r1,1 # include \0 in copy
1681: slgr %r1,%r4 # %r1 = copy length (without \0)
169 slgr %r2,%r4 # %r2 = return length (including \0)
1702: mvcp 0(%r1,%r3),0(%r4),%r0
171 jnz 3f
172 br %r14
1733: la %r3,256(%r3)
174 la %r4,256(%r4)
175 aghi %r1,-256
176 mvcp 0(%r1,%r3),0(%r4),%r0
177 jnz 3b
178 br %r14
1794: sacf 0
180 lghi %r2,-EFAULT
181 br %r14
182 .section __ex_table,"a"
183 .quad 0b,4b
184 .previous
185
186 .align 4
187 .text
188 .globl __strnlen_user_asm
189 # %r2 = count, %r3 = src
190__strnlen_user_asm:
191 lghi %r0,0
192 lgr %r1,%r3
193 la %r2,0(%r2,%r3) # %r2 points to first byte after string
194 sacf 256
1950: srst %r2,%r1
196 jo 0b
197 sacf 0
198 aghi %r2,1 # strnlen_user result includes the \0
199 # or return count+1 if \0 not found
200 slgr %r2,%r3
201 br %r14
2022: sacf 0
203 slgr %r2,%r2 # return 0 on exception
204 br %r14
205 .section __ex_table,"a"
206 .quad 0b,2b
207 .previous
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c
new file mode 100644
index 000000000000..86c96d6c191a
--- /dev/null
+++ b/arch/s390/lib/uaccess_mvcos.c
@@ -0,0 +1,156 @@
1/*
2 * arch/s390/lib/uaccess_mvcos.c
3 *
4 * Optimized user space space access functions based on mvcos.
5 *
6 * Copyright (C) IBM Corp. 2006
7 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
8 * Gerald Schaefer (gerald.schaefer@de.ibm.com)
9 */
10
11#include <linux/errno.h>
12#include <linux/mm.h>
13#include <asm/uaccess.h>
14#include <asm/futex.h>
15
16#ifndef __s390x__
17#define AHI "ahi"
18#define ALR "alr"
19#define CLR "clr"
20#define LHI "lhi"
21#define SLR "slr"
22#else
23#define AHI "aghi"
24#define ALR "algr"
25#define CLR "clgr"
26#define LHI "lghi"
27#define SLR "slgr"
28#endif
29
30size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
31{
32 register unsigned long reg0 asm("0") = 0x81UL;
33 unsigned long tmp1, tmp2;
34
35 tmp1 = -4096UL;
36 asm volatile(
37 "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
38 " jz 4f\n"
39 "1:"ALR" %0,%3\n"
40 " "SLR" %1,%3\n"
41 " "SLR" %2,%3\n"
42 " j 0b\n"
43 "2: la %4,4095(%1)\n"/* %4 = ptr + 4095 */
44 " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */
45 " "SLR" %4,%1\n"
46 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
47 " jnh 5f\n"
48 "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n"
49 " "SLR" %0,%4\n"
50 " j 5f\n"
51 "4:"SLR" %0,%0\n"
52 "5: \n"
53 EX_TABLE(0b,2b) EX_TABLE(3b,5b)
54 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
55 : "d" (reg0) : "cc", "memory");
56 return size;
57}
58
59size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
60{
61 register unsigned long reg0 asm("0") = 0x810000UL;
62 unsigned long tmp1, tmp2;
63
64 tmp1 = -4096UL;
65 asm volatile(
66 "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
67 " jz 4f\n"
68 "1:"ALR" %0,%3\n"
69 " "SLR" %1,%3\n"
70 " "SLR" %2,%3\n"
71 " j 0b\n"
72 "2: la %4,4095(%1)\n"/* %4 = ptr + 4095 */
73 " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */
74 " "SLR" %4,%1\n"
75 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
76 " jnh 5f\n"
77 "3: .insn ss,0xc80000000000,0(%4,%1),0(%2),0\n"
78 " "SLR" %0,%4\n"
79 " j 5f\n"
80 "4:"SLR" %0,%0\n"
81 "5: \n"
82 EX_TABLE(0b,2b) EX_TABLE(3b,5b)
83 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
84 : "d" (reg0) : "cc", "memory");
85 return size;
86}
87
88size_t copy_in_user_mvcos(size_t size, void __user *to, const void __user *from)
89{
90 register unsigned long reg0 asm("0") = 0x810081UL;
91 unsigned long tmp1, tmp2;
92
93 tmp1 = -4096UL;
94 /* FIXME: copy with reduced length. */
95 asm volatile(
96 "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
97 " jz 2f\n"
98 "1:"ALR" %0,%3\n"
99 " "SLR" %1,%3\n"
100 " "SLR" %2,%3\n"
101 " j 0b\n"
102 "2:"SLR" %0,%0\n"
103 "3: \n"
104 EX_TABLE(0b,3b)
105 : "+a" (size), "+a" (to), "+a" (from), "+a" (tmp1), "=a" (tmp2)
106 : "d" (reg0) : "cc", "memory");
107 return size;
108}
109
110size_t clear_user_mvcos(size_t size, void __user *to)
111{
112 register unsigned long reg0 asm("0") = 0x810000UL;
113 unsigned long tmp1, tmp2;
114
115 tmp1 = -4096UL;
116 asm volatile(
117 "0: .insn ss,0xc80000000000,0(%0,%1),0(%4),0\n"
118 " jz 4f\n"
119 "1:"ALR" %0,%2\n"
120 " "SLR" %1,%2\n"
121 " j 0b\n"
122 "2: la %3,4095(%1)\n"/* %4 = to + 4095 */
123 " nr %3,%2\n" /* %4 = (to + 4095) & -4096 */
124 " "SLR" %3,%1\n"
125 " "CLR" %0,%3\n" /* copy crosses next page boundary? */
126 " jnh 5f\n"
127 "3: .insn ss,0xc80000000000,0(%3,%1),0(%4),0\n"
128 " "SLR" %0,%3\n"
129 " j 5f\n"
130 "4:"SLR" %0,%0\n"
131 "5: \n"
132 EX_TABLE(0b,2b) EX_TABLE(3b,5b)
133 : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
134 : "a" (empty_zero_page), "d" (reg0) : "cc", "memory");
135 return size;
136}
137
138extern size_t copy_from_user_std_small(size_t, const void __user *, void *);
139extern size_t copy_to_user_std_small(size_t, void __user *, const void *);
140extern size_t strnlen_user_std(size_t, const char __user *);
141extern size_t strncpy_from_user_std(size_t, const char __user *, char *);
142extern int futex_atomic_op(int, int __user *, int, int *);
143extern int futex_atomic_cmpxchg(int __user *, int, int);
144
145struct uaccess_ops uaccess_mvcos = {
146 .copy_from_user = copy_from_user_mvcos,
147 .copy_from_user_small = copy_from_user_std_small,
148 .copy_to_user = copy_to_user_mvcos,
149 .copy_to_user_small = copy_to_user_std_small,
150 .copy_in_user = copy_in_user_mvcos,
151 .clear_user = clear_user_mvcos,
152 .strnlen_user = strnlen_user_std,
153 .strncpy_from_user = strncpy_from_user_std,
154 .futex_atomic_op = futex_atomic_op,
155 .futex_atomic_cmpxchg = futex_atomic_cmpxchg,
156};
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c
new file mode 100644
index 000000000000..9a4d4a29ea79
--- /dev/null
+++ b/arch/s390/lib/uaccess_std.c
@@ -0,0 +1,340 @@
1/*
2 * arch/s390/lib/uaccess_std.c
3 *
4 * Standard user space access functions based on mvcp/mvcs and doing
5 * interesting things in the secondary space mode.
6 *
7 * Copyright (C) IBM Corp. 2006
8 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
9 * Gerald Schaefer (gerald.schaefer@de.ibm.com)
10 */
11
12#include <linux/errno.h>
13#include <linux/mm.h>
14#include <asm/uaccess.h>
15#include <asm/futex.h>
16
17#ifndef __s390x__
18#define AHI "ahi"
19#define ALR "alr"
20#define CLR "clr"
21#define LHI "lhi"
22#define SLR "slr"
23#else
24#define AHI "aghi"
25#define ALR "algr"
26#define CLR "clgr"
27#define LHI "lghi"
28#define SLR "slgr"
29#endif
30
31size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
32{
33 unsigned long tmp1, tmp2;
34
35 tmp1 = -256UL;
36 asm volatile(
37 "0: mvcp 0(%0,%2),0(%1),%3\n"
38 " jz 5f\n"
39 "1:"ALR" %0,%3\n"
40 " la %1,256(%1)\n"
41 " la %2,256(%2)\n"
42 "2: mvcp 0(%0,%2),0(%1),%3\n"
43 " jnz 1b\n"
44 " j 5f\n"
45 "3: la %4,255(%1)\n" /* %4 = ptr + 255 */
46 " "LHI" %3,-4096\n"
47 " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
48 " "SLR" %4,%1\n"
49 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
50 " jnh 6f\n"
51 "4: mvcp 0(%4,%2),0(%1),%3\n"
52 " "SLR" %0,%4\n"
53 " j 6f\n"
54 "5:"SLR" %0,%0\n"
55 "6: \n"
56 EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
57 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
58 : : "cc", "memory");
59 return size;
60}
61
62size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x)
63{
64 unsigned long tmp1, tmp2;
65
66 tmp1 = 0UL;
67 asm volatile(
68 "0: mvcp 0(%0,%2),0(%1),%3\n"
69 " "SLR" %0,%0\n"
70 " j 3f\n"
71 "1: la %4,255(%1)\n" /* %4 = ptr + 255 */
72 " "LHI" %3,-4096\n"
73 " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
74 " "SLR" %4,%1\n"
75 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
76 " jnh 3f\n"
77 "2: mvcp 0(%4,%2),0(%1),%3\n"
78 " "SLR" %0,%4\n"
79 "3:\n"
80 EX_TABLE(0b,1b) EX_TABLE(2b,3b)
81 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
82 : : "cc", "memory");
83 return size;
84}
85
86size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
87{
88 unsigned long tmp1, tmp2;
89
90 tmp1 = -256UL;
91 asm volatile(
92 "0: mvcs 0(%0,%1),0(%2),%3\n"
93 " jz 5f\n"
94 "1:"ALR" %0,%3\n"
95 " la %1,256(%1)\n"
96 " la %2,256(%2)\n"
97 "2: mvcs 0(%0,%1),0(%2),%3\n"
98 " jnz 1b\n"
99 " j 5f\n"
100 "3: la %4,255(%1)\n" /* %4 = ptr + 255 */
101 " "LHI" %3,-4096\n"
102 " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
103 " "SLR" %4,%1\n"
104 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
105 " jnh 6f\n"
106 "4: mvcs 0(%4,%1),0(%2),%3\n"
107 " "SLR" %0,%4\n"
108 " j 6f\n"
109 "5:"SLR" %0,%0\n"
110 "6: \n"
111 EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
112 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
113 : : "cc", "memory");
114 return size;
115}
116
117size_t copy_to_user_std_small(size_t size, void __user *ptr, const void *x)
118{
119 unsigned long tmp1, tmp2;
120
121 tmp1 = 0UL;
122 asm volatile(
123 "0: mvcs 0(%0,%1),0(%2),%3\n"
124 " "SLR" %0,%0\n"
125 " j 3f\n"
126 "1: la %4,255(%1)\n" /* ptr + 255 */
127 " "LHI" %3,-4096\n"
128 " nr %4,%3\n" /* (ptr + 255) & -4096UL */
129 " "SLR" %4,%1\n"
130 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
131 " jnh 3f\n"
132 "2: mvcs 0(%4,%1),0(%2),%3\n"
133 " "SLR" %0,%4\n"
134 "3:\n"
135 EX_TABLE(0b,1b) EX_TABLE(2b,3b)
136 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
137 : : "cc", "memory");
138 return size;
139}
140
141size_t copy_in_user_std(size_t size, void __user *to, const void __user *from)
142{
143 unsigned long tmp1;
144
145 asm volatile(
146 " "AHI" %0,-1\n"
147 " jo 5f\n"
148 " sacf 256\n"
149 " bras %3,3f\n"
150 "0:"AHI" %0,257\n"
151 "1: mvc 0(1,%1),0(%2)\n"
152 " la %1,1(%1)\n"
153 " la %2,1(%2)\n"
154 " "AHI" %0,-1\n"
155 " jnz 1b\n"
156 " j 5f\n"
157 "2: mvc 0(256,%1),0(%2)\n"
158 " la %1,256(%1)\n"
159 " la %2,256(%2)\n"
160 "3:"AHI" %0,-256\n"
161 " jnm 2b\n"
162 "4: ex %0,1b-0b(%3)\n"
163 " sacf 0\n"
164 "5: "SLR" %0,%0\n"
165 "6:\n"
166 EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
167 : "+a" (size), "+a" (to), "+a" (from), "=a" (tmp1)
168 : : "cc", "memory");
169 return size;
170}
171
172size_t clear_user_std(size_t size, void __user *to)
173{
174 unsigned long tmp1, tmp2;
175
176 asm volatile(
177 " "AHI" %0,-1\n"
178 " jo 5f\n"
179 " sacf 256\n"
180 " bras %3,3f\n"
181 " xc 0(1,%1),0(%1)\n"
182 "0:"AHI" %0,257\n"
183 " la %2,255(%1)\n" /* %2 = ptr + 255 */
184 " srl %2,12\n"
185 " sll %2,12\n" /* %2 = (ptr + 255) & -4096 */
186 " "SLR" %2,%1\n"
187 " "CLR" %0,%2\n" /* clear crosses next page boundary? */
188 " jnh 5f\n"
189 " "AHI" %2,-1\n"
190 "1: ex %2,0(%3)\n"
191 " "AHI" %2,1\n"
192 " "SLR" %0,%2\n"
193 " j 5f\n"
194 "2: xc 0(256,%1),0(%1)\n"
195 " la %1,256(%1)\n"
196 "3:"AHI" %0,-256\n"
197 " jnm 2b\n"
198 "4: ex %0,0(%3)\n"
199 " sacf 0\n"
200 "5: "SLR" %0,%0\n"
201 "6:\n"
202 EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
203 : "+a" (size), "+a" (to), "=a" (tmp1), "=a" (tmp2)
204 : : "cc", "memory");
205 return size;
206}
207
208size_t strnlen_user_std(size_t size, const char __user *src)
209{
210 register unsigned long reg0 asm("0") = 0UL;
211 unsigned long tmp1, tmp2;
212
213 asm volatile(
214 " la %2,0(%1)\n"
215 " la %3,0(%0,%1)\n"
216 " "SLR" %0,%0\n"
217 " sacf 256\n"
218 "0: srst %3,%2\n"
219 " jo 0b\n"
220 " la %0,1(%3)\n" /* strnlen_user results includes \0 */
221 " "SLR" %0,%1\n"
222 "1: sacf 0\n"
223 EX_TABLE(0b,1b)
224 : "+a" (size), "+a" (src), "=a" (tmp1), "=a" (tmp2)
225 : "d" (reg0) : "cc", "memory");
226 return size;
227}
228
229size_t strncpy_from_user_std(size_t size, const char __user *src, char *dst)
230{
231 register unsigned long reg0 asm("0") = 0UL;
232 unsigned long tmp1, tmp2;
233
234 asm volatile(
235 " la %3,0(%1)\n"
236 " la %4,0(%0,%1)\n"
237 " sacf 256\n"
238 "0: srst %4,%3\n"
239 " jo 0b\n"
240 " sacf 0\n"
241 " la %0,0(%4)\n"
242 " jh 1f\n" /* found \0 in string ? */
243 " "AHI" %4,1\n" /* include \0 in copy */
244 "1:"SLR" %0,%1\n" /* %0 = return length (without \0) */
245 " "SLR" %4,%1\n" /* %4 = copy length (including \0) */
246 "2: mvcp 0(%4,%2),0(%1),%5\n"
247 " jz 9f\n"
248 "3:"AHI" %4,-256\n"
249 " la %1,256(%1)\n"
250 " la %2,256(%2)\n"
251 "4: mvcp 0(%4,%2),0(%1),%5\n"
252 " jnz 3b\n"
253 " j 9f\n"
254 "7: sacf 0\n"
255 "8:"LHI" %0,%6\n"
256 "9:\n"
257 EX_TABLE(0b,7b) EX_TABLE(2b,8b) EX_TABLE(4b,8b)
258 : "+a" (size), "+a" (src), "+d" (dst), "=a" (tmp1), "=a" (tmp2)
259 : "d" (reg0), "K" (-EFAULT) : "cc", "memory");
260 return size;
261}
262
263#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \
264 asm volatile( \
265 " sacf 256\n" \
266 "0: l %1,0(%6)\n" \
267 "1:"insn \
268 "2: cs %1,%2,0(%6)\n" \
269 "3: jl 1b\n" \
270 " lhi %0,0\n" \
271 "4: sacf 0\n" \
272 EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
273 : "=d" (ret), "=&d" (oldval), "=&d" (newval), \
274 "=m" (*uaddr) \
275 : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
276 "m" (*uaddr) : "cc");
277
278int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old)
279{
280 int oldval = 0, newval, ret;
281
282 inc_preempt_count();
283
284 switch (op) {
285 case FUTEX_OP_SET:
286 __futex_atomic_op("lr %2,%5\n",
287 ret, oldval, newval, uaddr, oparg);
288 break;
289 case FUTEX_OP_ADD:
290 __futex_atomic_op("lr %2,%1\nar %2,%5\n",
291 ret, oldval, newval, uaddr, oparg);
292 break;
293 case FUTEX_OP_OR:
294 __futex_atomic_op("lr %2,%1\nor %2,%5\n",
295 ret, oldval, newval, uaddr, oparg);
296 break;
297 case FUTEX_OP_ANDN:
298 __futex_atomic_op("lr %2,%1\nnr %2,%5\n",
299 ret, oldval, newval, uaddr, oparg);
300 break;
301 case FUTEX_OP_XOR:
302 __futex_atomic_op("lr %2,%1\nxr %2,%5\n",
303 ret, oldval, newval, uaddr, oparg);
304 break;
305 default:
306 ret = -ENOSYS;
307 }
308 dec_preempt_count();
309 *old = oldval;
310 return ret;
311}
312
313int futex_atomic_cmpxchg(int __user *uaddr, int oldval, int newval)
314{
315 int ret;
316
317 asm volatile(
318 " sacf 256\n"
319 " cs %1,%4,0(%5)\n"
320 "0: lr %0,%1\n"
321 "1: sacf 0\n"
322 EX_TABLE(0b,1b)
323 : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
324 : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
325 : "cc", "memory" );
326 return ret;
327}
328
329struct uaccess_ops uaccess_std = {
330 .copy_from_user = copy_from_user_std,
331 .copy_from_user_small = copy_from_user_std_small,
332 .copy_to_user = copy_to_user_std,
333 .copy_to_user_small = copy_to_user_std_small,
334 .copy_in_user = copy_in_user_std,
335 .clear_user = clear_user_std,
336 .strnlen_user = strnlen_user_std,
337 .strncpy_from_user = strncpy_from_user_std,
338 .futex_atomic_op = futex_atomic_op,
339 .futex_atomic_cmpxchg = futex_atomic_cmpxchg,
340};
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index ceea51cff03b..786a44dba5bf 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -53,22 +53,6 @@ static void cmm_timer_fn(unsigned long);
53static void cmm_set_timer(void); 53static void cmm_set_timer(void);
54 54
55static long 55static long
56cmm_strtoul(const char *cp, char **endp)
57{
58 unsigned int base = 10;
59
60 if (*cp == '0') {
61 base = 8;
62 cp++;
63 if ((*cp == 'x' || *cp == 'X') && isxdigit(cp[1])) {
64 base = 16;
65 cp++;
66 }
67 }
68 return simple_strtoul(cp, endp, base);
69}
70
71static long
72cmm_alloc_pages(long pages, long *counter, struct cmm_page_array **list) 56cmm_alloc_pages(long pages, long *counter, struct cmm_page_array **list)
73{ 57{
74 struct cmm_page_array *pa; 58 struct cmm_page_array *pa;
@@ -276,7 +260,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
276 return -EFAULT; 260 return -EFAULT;
277 buf[sizeof(buf) - 1] = '\0'; 261 buf[sizeof(buf) - 1] = '\0';
278 cmm_skip_blanks(buf, &p); 262 cmm_skip_blanks(buf, &p);
279 pages = cmm_strtoul(p, &p); 263 pages = simple_strtoul(p, &p, 0);
280 if (ctl == &cmm_table[0]) 264 if (ctl == &cmm_table[0])
281 cmm_set_pages(pages); 265 cmm_set_pages(pages);
282 else 266 else
@@ -317,9 +301,9 @@ cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
317 return -EFAULT; 301 return -EFAULT;
318 buf[sizeof(buf) - 1] = '\0'; 302 buf[sizeof(buf) - 1] = '\0';
319 cmm_skip_blanks(buf, &p); 303 cmm_skip_blanks(buf, &p);
320 pages = cmm_strtoul(p, &p); 304 pages = simple_strtoul(p, &p, 0);
321 cmm_skip_blanks(p, &p); 305 cmm_skip_blanks(p, &p);
322 seconds = cmm_strtoul(p, &p); 306 seconds = simple_strtoul(p, &p, 0);
323 cmm_set_timeout(pages, seconds); 307 cmm_set_timeout(pages, seconds);
324 } else { 308 } else {
325 len = sprintf(buf, "%ld %ld\n", 309 len = sprintf(buf, "%ld %ld\n",
@@ -382,24 +366,24 @@ cmm_smsg_target(char *from, char *msg)
382 if (strncmp(msg, "SHRINK", 6) == 0) { 366 if (strncmp(msg, "SHRINK", 6) == 0) {
383 if (!cmm_skip_blanks(msg + 6, &msg)) 367 if (!cmm_skip_blanks(msg + 6, &msg))
384 return; 368 return;
385 pages = cmm_strtoul(msg, &msg); 369 pages = simple_strtoul(msg, &msg, 0);
386 cmm_skip_blanks(msg, &msg); 370 cmm_skip_blanks(msg, &msg);
387 if (*msg == '\0') 371 if (*msg == '\0')
388 cmm_set_pages(pages); 372 cmm_set_pages(pages);
389 } else if (strncmp(msg, "RELEASE", 7) == 0) { 373 } else if (strncmp(msg, "RELEASE", 7) == 0) {
390 if (!cmm_skip_blanks(msg + 7, &msg)) 374 if (!cmm_skip_blanks(msg + 7, &msg))
391 return; 375 return;
392 pages = cmm_strtoul(msg, &msg); 376 pages = simple_strtoul(msg, &msg, 0);
393 cmm_skip_blanks(msg, &msg); 377 cmm_skip_blanks(msg, &msg);
394 if (*msg == '\0') 378 if (*msg == '\0')
395 cmm_add_timed_pages(pages); 379 cmm_add_timed_pages(pages);
396 } else if (strncmp(msg, "REUSE", 5) == 0) { 380 } else if (strncmp(msg, "REUSE", 5) == 0) {
397 if (!cmm_skip_blanks(msg + 5, &msg)) 381 if (!cmm_skip_blanks(msg + 5, &msg))
398 return; 382 return;
399 pages = cmm_strtoul(msg, &msg); 383 pages = simple_strtoul(msg, &msg, 0);
400 if (!cmm_skip_blanks(msg, &msg)) 384 if (!cmm_skip_blanks(msg, &msg))
401 return; 385 return;
402 seconds = cmm_strtoul(msg, &msg); 386 seconds = simple_strtoul(msg, &msg, 0);
403 cmm_skip_blanks(msg, &msg); 387 cmm_skip_blanks(msg, &msg);
404 if (*msg == '\0') 388 if (*msg == '\0')
405 cmm_set_timeout(pages, seconds); 389 cmm_set_timeout(pages, seconds);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 7cd82575813d..44f0cda7e72e 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -25,10 +25,12 @@
25#include <linux/console.h> 25#include <linux/console.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/hardirq.h> 27#include <linux/hardirq.h>
28#include <linux/kprobes.h>
28 29
29#include <asm/system.h> 30#include <asm/system.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/pgtable.h> 32#include <asm/pgtable.h>
33#include <asm/kdebug.h>
32 34
33#ifndef CONFIG_64BIT 35#ifndef CONFIG_64BIT
34#define __FAIL_ADDR_MASK 0x7ffff000 36#define __FAIL_ADDR_MASK 0x7ffff000
@@ -48,6 +50,38 @@ extern int sysctl_userprocess_debug;
48 50
49extern void die(const char *,struct pt_regs *,long); 51extern void die(const char *,struct pt_regs *,long);
50 52
53#ifdef CONFIG_KPROBES
54ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
55int register_page_fault_notifier(struct notifier_block *nb)
56{
57 return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
58}
59
60int unregister_page_fault_notifier(struct notifier_block *nb)
61{
62 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
63}
64
65static inline int notify_page_fault(enum die_val val, const char *str,
66 struct pt_regs *regs, long err, int trap, int sig)
67{
68 struct die_args args = {
69 .regs = regs,
70 .str = str,
71 .err = err,
72 .trapnr = trap,
73 .signr = sig
74 };
75 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
76}
77#else
78static inline int notify_page_fault(enum die_val val, const char *str,
79 struct pt_regs *regs, long err, int trap, int sig)
80{
81 return NOTIFY_DONE;
82}
83#endif
84
51extern spinlock_t timerlist_lock; 85extern spinlock_t timerlist_lock;
52 86
53/* 87/*
@@ -159,7 +193,7 @@ static void do_sigsegv(struct pt_regs *regs, unsigned long error_code,
159 * 11 Page translation -> Not present (nullification) 193 * 11 Page translation -> Not present (nullification)
160 * 3b Region third trans. -> Not present (nullification) 194 * 3b Region third trans. -> Not present (nullification)
161 */ 195 */
162static inline void 196static inline void __kprobes
163do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) 197do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
164{ 198{
165 struct task_struct *tsk; 199 struct task_struct *tsk;
@@ -173,6 +207,10 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
173 tsk = current; 207 tsk = current;
174 mm = tsk->mm; 208 mm = tsk->mm;
175 209
210 if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
211 SIGSEGV) == NOTIFY_STOP)
212 return;
213
176 /* 214 /*
177 * Check for low-address protection. This needs to be treated 215 * Check for low-address protection. This needs to be treated
178 * as a special case because the translation exception code 216 * as a special case because the translation exception code
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 6e6b6de77770..cfd9b8f7a523 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -108,16 +108,23 @@ void __init paging_init(void)
108 unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; 108 unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE;
109 static const int ssm_mask = 0x04000000L; 109 static const int ssm_mask = 0x04000000L;
110 unsigned long ro_start_pfn, ro_end_pfn; 110 unsigned long ro_start_pfn, ro_end_pfn;
111 unsigned long zones_size[MAX_NR_ZONES];
111 112
112 ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); 113 ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata);
113 ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); 114 ro_end_pfn = PFN_UP((unsigned long)&__end_rodata);
114 115
116 memset(zones_size, 0, sizeof(zones_size));
117 zones_size[ZONE_DMA] = max_low_pfn;
118 free_area_init_node(0, &contig_page_data, zones_size,
119 __pa(PAGE_OFFSET) >> PAGE_SHIFT,
120 zholes_size);
121
115 /* unmap whole virtual address space */ 122 /* unmap whole virtual address space */
116 123
117 pg_dir = swapper_pg_dir; 124 pg_dir = swapper_pg_dir;
118 125
119 for (i=0;i<KERNEL_PGD_PTRS;i++) 126 for (i = 0; i < PTRS_PER_PGD; i++)
120 pmd_clear((pmd_t*)pg_dir++); 127 pmd_clear((pmd_t *) pg_dir++);
121 128
122 /* 129 /*
123 * map whole physical memory to virtual memory (identity mapping) 130 * map whole physical memory to virtual memory (identity mapping)
@@ -131,10 +138,7 @@ void __init paging_init(void)
131 */ 138 */
132 pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); 139 pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
133 140
134 pg_dir->pgd0 = (_PAGE_TABLE | __pa(pg_table)); 141 pmd_populate_kernel(&init_mm, (pmd_t *) pg_dir, pg_table);
135 pg_dir->pgd1 = (_PAGE_TABLE | (__pa(pg_table)+1024));
136 pg_dir->pgd2 = (_PAGE_TABLE | (__pa(pg_table)+2048));
137 pg_dir->pgd3 = (_PAGE_TABLE | (__pa(pg_table)+3072));
138 pg_dir++; 142 pg_dir++;
139 143
140 for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { 144 for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
@@ -143,8 +147,8 @@ void __init paging_init(void)
143 else 147 else
144 pte = pfn_pte(pfn, PAGE_KERNEL); 148 pte = pfn_pte(pfn, PAGE_KERNEL);
145 if (pfn >= max_low_pfn) 149 if (pfn >= max_low_pfn)
146 pte_clear(&init_mm, 0, &pte); 150 pte_val(pte) = _PAGE_TYPE_EMPTY;
147 set_pte(pg_table, pte); 151 set_pte(pg_table, pte);
148 pfn++; 152 pfn++;
149 } 153 }
150 } 154 }
@@ -159,16 +163,6 @@ void __init paging_init(void)
159 : : "m" (pgdir_k), "m" (ssm_mask)); 163 : : "m" (pgdir_k), "m" (ssm_mask));
160 164
161 local_flush_tlb(); 165 local_flush_tlb();
162
163 {
164 unsigned long zones_size[MAX_NR_ZONES];
165
166 memset(zones_size, 0, sizeof(zones_size));
167 zones_size[ZONE_DMA] = max_low_pfn;
168 free_area_init_node(0, &contig_page_data, zones_size,
169 __pa(PAGE_OFFSET) >> PAGE_SHIFT,
170 zholes_size);
171 }
172 return; 166 return;
173} 167}
174 168
@@ -236,10 +230,8 @@ void __init paging_init(void)
236 pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); 230 pte = pfn_pte(pfn, __pgprot(_PAGE_RO));
237 else 231 else
238 pte = pfn_pte(pfn, PAGE_KERNEL); 232 pte = pfn_pte(pfn, PAGE_KERNEL);
239 if (pfn >= max_low_pfn) { 233 if (pfn >= max_low_pfn)
240 pte_clear(&init_mm, 0, &pte); 234 pte_val(pte) = _PAGE_TYPE_EMPTY;
241 continue;
242 }
243 set_pte(pt_dir, pte); 235 set_pte(pt_dir, pte);
244 pfn++; 236 pfn++;
245 } 237 }
diff --git a/arch/x86_64/crypto/Makefile b/arch/x86_64/crypto/Makefile
index 426d20f4b72e..15b538a8b7f7 100644
--- a/arch/x86_64/crypto/Makefile
+++ b/arch/x86_64/crypto/Makefile
@@ -5,5 +5,8 @@
5# 5#
6 6
7obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o 7obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
8obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
8 9
9aes-x86_64-y := aes-x86_64-asm.o aes.o 10aes-x86_64-y := aes-x86_64-asm.o aes.o
11twofish-x86_64-y := twofish-x86_64-asm.o twofish.o
12
diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c
index 68866fab37aa..5cdb13ea5cc2 100644
--- a/arch/x86_64/crypto/aes.c
+++ b/arch/x86_64/crypto/aes.c
@@ -228,13 +228,14 @@ static void __init gen_tabs(void)
228} 228}
229 229
230static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 230static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
231 unsigned int key_len, u32 *flags) 231 unsigned int key_len)
232{ 232{
233 struct aes_ctx *ctx = crypto_tfm_ctx(tfm); 233 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
234 const __le32 *key = (const __le32 *)in_key; 234 const __le32 *key = (const __le32 *)in_key;
235 u32 *flags = &tfm->crt_flags;
235 u32 i, j, t, u, v, w; 236 u32 i, j, t, u, v, w;
236 237
237 if (key_len != 16 && key_len != 24 && key_len != 32) { 238 if (key_len % 8) {
238 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 239 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
239 return -EINVAL; 240 return -EINVAL;
240 } 241 }
diff --git a/arch/x86_64/crypto/twofish-x86_64-asm.S b/arch/x86_64/crypto/twofish-x86_64-asm.S
new file mode 100644
index 000000000000..35974a586615
--- /dev/null
+++ b/arch/x86_64/crypto/twofish-x86_64-asm.S
@@ -0,0 +1,324 @@
1/***************************************************************************
2* Copyright (C) 2006 by Joachim Fritschi, <jfritschi@freenet.de> *
3* *
4* This program is free software; you can redistribute it and/or modify *
5* it under the terms of the GNU General Public License as published by *
6* the Free Software Foundation; either version 2 of the License, or *
7* (at your option) any later version. *
8* *
9* This program is distributed in the hope that it will be useful, *
10* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12* GNU General Public License for more details. *
13* *
14* You should have received a copy of the GNU General Public License *
15* along with this program; if not, write to the *
16* Free Software Foundation, Inc., *
17* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18***************************************************************************/
19
20.file "twofish-x86_64-asm.S"
21.text
22
23#include <asm/asm-offsets.h>
24
25#define a_offset 0
26#define b_offset 4
27#define c_offset 8
28#define d_offset 12
29
30/* Structure of the crypto context struct*/
31
32#define s0 0 /* S0 Array 256 Words each */
33#define s1 1024 /* S1 Array */
34#define s2 2048 /* S2 Array */
35#define s3 3072 /* S3 Array */
36#define w 4096 /* 8 whitening keys (word) */
37#define k 4128 /* key 1-32 ( word ) */
38
39/* define a few register aliases to allow macro substitution */
40
41#define R0 %rax
42#define R0D %eax
43#define R0B %al
44#define R0H %ah
45
46#define R1 %rbx
47#define R1D %ebx
48#define R1B %bl
49#define R1H %bh
50
51#define R2 %rcx
52#define R2D %ecx
53#define R2B %cl
54#define R2H %ch
55
56#define R3 %rdx
57#define R3D %edx
58#define R3B %dl
59#define R3H %dh
60
61
62/* performs input whitening */
63#define input_whitening(src,context,offset)\
64 xor w+offset(context), src;
65
66/* performs input whitening */
67#define output_whitening(src,context,offset)\
68 xor w+16+offset(context), src;
69
70
71/*
72 * a input register containing a (rotated 16)
73 * b input register containing b
74 * c input register containing c
75 * d input register containing d (already rol $1)
76 * operations on a and b are interleaved to increase performance
77 */
78#define encrypt_round(a,b,c,d,round)\
79 movzx b ## B, %edi;\
80 mov s1(%r11,%rdi,4),%r8d;\
81 movzx a ## B, %edi;\
82 mov s2(%r11,%rdi,4),%r9d;\
83 movzx b ## H, %edi;\
84 ror $16, b ## D;\
85 xor s2(%r11,%rdi,4),%r8d;\
86 movzx a ## H, %edi;\
87 ror $16, a ## D;\
88 xor s3(%r11,%rdi,4),%r9d;\
89 movzx b ## B, %edi;\
90 xor s3(%r11,%rdi,4),%r8d;\
91 movzx a ## B, %edi;\
92 xor (%r11,%rdi,4), %r9d;\
93 movzx b ## H, %edi;\
94 ror $15, b ## D;\
95 xor (%r11,%rdi,4), %r8d;\
96 movzx a ## H, %edi;\
97 xor s1(%r11,%rdi,4),%r9d;\
98 add %r8d, %r9d;\
99 add %r9d, %r8d;\
100 add k+round(%r11), %r9d;\
101 xor %r9d, c ## D;\
102 rol $15, c ## D;\
103 add k+4+round(%r11),%r8d;\
104 xor %r8d, d ## D;
105
106/*
107 * a input register containing a(rotated 16)
108 * b input register containing b
109 * c input register containing c
110 * d input register containing d (already rol $1)
111 * operations on a and b are interleaved to increase performance
112 * during the round a and b are prepared for the output whitening
113 */
114#define encrypt_last_round(a,b,c,d,round)\
115 mov b ## D, %r10d;\
116 shl $32, %r10;\
117 movzx b ## B, %edi;\
118 mov s1(%r11,%rdi,4),%r8d;\
119 movzx a ## B, %edi;\
120 mov s2(%r11,%rdi,4),%r9d;\
121 movzx b ## H, %edi;\
122 ror $16, b ## D;\
123 xor s2(%r11,%rdi,4),%r8d;\
124 movzx a ## H, %edi;\
125 ror $16, a ## D;\
126 xor s3(%r11,%rdi,4),%r9d;\
127 movzx b ## B, %edi;\
128 xor s3(%r11,%rdi,4),%r8d;\
129 movzx a ## B, %edi;\
130 xor (%r11,%rdi,4), %r9d;\
131 xor a, %r10;\
132 movzx b ## H, %edi;\
133 xor (%r11,%rdi,4), %r8d;\
134 movzx a ## H, %edi;\
135 xor s1(%r11,%rdi,4),%r9d;\
136 add %r8d, %r9d;\
137 add %r9d, %r8d;\
138 add k+round(%r11), %r9d;\
139 xor %r9d, c ## D;\
140 ror $1, c ## D;\
141 add k+4+round(%r11),%r8d;\
142 xor %r8d, d ## D
143
144/*
145 * a input register containing a
146 * b input register containing b (rotated 16)
147 * c input register containing c (already rol $1)
148 * d input register containing d
149 * operations on a and b are interleaved to increase performance
150 */
151#define decrypt_round(a,b,c,d,round)\
152 movzx a ## B, %edi;\
153 mov (%r11,%rdi,4), %r9d;\
154 movzx b ## B, %edi;\
155 mov s3(%r11,%rdi,4),%r8d;\
156 movzx a ## H, %edi;\
157 ror $16, a ## D;\
158 xor s1(%r11,%rdi,4),%r9d;\
159 movzx b ## H, %edi;\
160 ror $16, b ## D;\
161 xor (%r11,%rdi,4), %r8d;\
162 movzx a ## B, %edi;\
163 xor s2(%r11,%rdi,4),%r9d;\
164 movzx b ## B, %edi;\
165 xor s1(%r11,%rdi,4),%r8d;\
166 movzx a ## H, %edi;\
167 ror $15, a ## D;\
168 xor s3(%r11,%rdi,4),%r9d;\
169 movzx b ## H, %edi;\
170 xor s2(%r11,%rdi,4),%r8d;\
171 add %r8d, %r9d;\
172 add %r9d, %r8d;\
173 add k+round(%r11), %r9d;\
174 xor %r9d, c ## D;\
175 add k+4+round(%r11),%r8d;\
176 xor %r8d, d ## D;\
177 rol $15, d ## D;
178
179/*
180 * a input register containing a
181 * b input register containing b
182 * c input register containing c (already rol $1)
183 * d input register containing d
184 * operations on a and b are interleaved to increase performance
185 * during the round a and b are prepared for the output whitening
186 */
187#define decrypt_last_round(a,b,c,d,round)\
188 movzx a ## B, %edi;\
189 mov (%r11,%rdi,4), %r9d;\
190 movzx b ## B, %edi;\
191 mov s3(%r11,%rdi,4),%r8d;\
192 movzx b ## H, %edi;\
193 ror $16, b ## D;\
194 xor (%r11,%rdi,4), %r8d;\
195 movzx a ## H, %edi;\
196 mov b ## D, %r10d;\
197 shl $32, %r10;\
198 xor a, %r10;\
199 ror $16, a ## D;\
200 xor s1(%r11,%rdi,4),%r9d;\
201 movzx b ## B, %edi;\
202 xor s1(%r11,%rdi,4),%r8d;\
203 movzx a ## B, %edi;\
204 xor s2(%r11,%rdi,4),%r9d;\
205 movzx b ## H, %edi;\
206 xor s2(%r11,%rdi,4),%r8d;\
207 movzx a ## H, %edi;\
208 xor s3(%r11,%rdi,4),%r9d;\
209 add %r8d, %r9d;\
210 add %r9d, %r8d;\
211 add k+round(%r11), %r9d;\
212 xor %r9d, c ## D;\
213 add k+4+round(%r11),%r8d;\
214 xor %r8d, d ## D;\
215 ror $1, d ## D;
216
217.align 8
218.global twofish_enc_blk
219.global twofish_dec_blk
220
221twofish_enc_blk:
222 pushq R1
223
224 /* %rdi contains the crypto tfm adress */
225 /* %rsi contains the output adress */
226 /* %rdx contains the input adress */
227 add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */
228 /* ctx adress is moved to free one non-rex register
229 as target for the 8bit high operations */
230 mov %rdi, %r11
231
232 movq (R3), R1
233 movq 8(R3), R3
234 input_whitening(R1,%r11,a_offset)
235 input_whitening(R3,%r11,c_offset)
236 mov R1D, R0D
237 rol $16, R0D
238 shr $32, R1
239 mov R3D, R2D
240 shr $32, R3
241 rol $1, R3D
242
243 encrypt_round(R0,R1,R2,R3,0);
244 encrypt_round(R2,R3,R0,R1,8);
245 encrypt_round(R0,R1,R2,R3,2*8);
246 encrypt_round(R2,R3,R0,R1,3*8);
247 encrypt_round(R0,R1,R2,R3,4*8);
248 encrypt_round(R2,R3,R0,R1,5*8);
249 encrypt_round(R0,R1,R2,R3,6*8);
250 encrypt_round(R2,R3,R0,R1,7*8);
251 encrypt_round(R0,R1,R2,R3,8*8);
252 encrypt_round(R2,R3,R0,R1,9*8);
253 encrypt_round(R0,R1,R2,R3,10*8);
254 encrypt_round(R2,R3,R0,R1,11*8);
255 encrypt_round(R0,R1,R2,R3,12*8);
256 encrypt_round(R2,R3,R0,R1,13*8);
257 encrypt_round(R0,R1,R2,R3,14*8);
258 encrypt_last_round(R2,R3,R0,R1,15*8);
259
260
261 output_whitening(%r10,%r11,a_offset)
262 movq %r10, (%rsi)
263
264 shl $32, R1
265 xor R0, R1
266
267 output_whitening(R1,%r11,c_offset)
268 movq R1, 8(%rsi)
269
270 popq R1
271 movq $1,%rax
272 ret
273
274twofish_dec_blk:
275 pushq R1
276
277 /* %rdi contains the crypto tfm adress */
278 /* %rsi contains the output adress */
279 /* %rdx contains the input adress */
280 add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */
281 /* ctx adress is moved to free one non-rex register
282 as target for the 8bit high operations */
283 mov %rdi, %r11
284
285 movq (R3), R1
286 movq 8(R3), R3
287 output_whitening(R1,%r11,a_offset)
288 output_whitening(R3,%r11,c_offset)
289 mov R1D, R0D
290 shr $32, R1
291 rol $16, R1D
292 mov R3D, R2D
293 shr $32, R3
294 rol $1, R2D
295
296 decrypt_round(R0,R1,R2,R3,15*8);
297 decrypt_round(R2,R3,R0,R1,14*8);
298 decrypt_round(R0,R1,R2,R3,13*8);
299 decrypt_round(R2,R3,R0,R1,12*8);
300 decrypt_round(R0,R1,R2,R3,11*8);
301 decrypt_round(R2,R3,R0,R1,10*8);
302 decrypt_round(R0,R1,R2,R3,9*8);
303 decrypt_round(R2,R3,R0,R1,8*8);
304 decrypt_round(R0,R1,R2,R3,7*8);
305 decrypt_round(R2,R3,R0,R1,6*8);
306 decrypt_round(R0,R1,R2,R3,5*8);
307 decrypt_round(R2,R3,R0,R1,4*8);
308 decrypt_round(R0,R1,R2,R3,3*8);
309 decrypt_round(R2,R3,R0,R1,2*8);
310 decrypt_round(R0,R1,R2,R3,1*8);
311 decrypt_last_round(R2,R3,R0,R1,0);
312
313 input_whitening(%r10,%r11,a_offset)
314 movq %r10, (%rsi)
315
316 shl $32, R1
317 xor R0, R1
318
319 input_whitening(R1,%r11,c_offset)
320 movq R1, 8(%rsi)
321
322 popq R1
323 movq $1,%rax
324 ret
diff --git a/arch/x86_64/crypto/twofish.c b/arch/x86_64/crypto/twofish.c
new file mode 100644
index 000000000000..182d91d5cfb9
--- /dev/null
+++ b/arch/x86_64/crypto/twofish.c
@@ -0,0 +1,97 @@
1/*
2 * Glue Code for optimized x86_64 assembler version of TWOFISH
3 *
4 * Originally Twofish for GPG
5 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
6 * 256-bit key length added March 20, 1999
7 * Some modifications to reduce the text size by Werner Koch, April, 1998
8 * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
9 * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
10 *
11 * The original author has disclaimed all copyright interest in this
12 * code and thus put it in the public domain. The subsequent authors
13 * have put this under the GNU General Public License.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 * USA
29 *
30 * This code is a "clean room" implementation, written from the paper
31 * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
32 * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
33 * through http://www.counterpane.com/twofish.html
34 *
35 * For background information on multiplication in finite fields, used for
36 * the matrix operations in the key schedule, see the book _Contemporary
37 * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
38 * Third Edition.
39 */
40
41#include <crypto/twofish.h>
42#include <linux/crypto.h>
43#include <linux/init.h>
44#include <linux/kernel.h>
45#include <linux/module.h>
46#include <linux/types.h>
47
48asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
49asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
50
51static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
52{
53 twofish_enc_blk(tfm, dst, src);
54}
55
56static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
57{
58 twofish_dec_blk(tfm, dst, src);
59}
60
61static struct crypto_alg alg = {
62 .cra_name = "twofish",
63 .cra_driver_name = "twofish-x86_64",
64 .cra_priority = 200,
65 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
66 .cra_blocksize = TF_BLOCK_SIZE,
67 .cra_ctxsize = sizeof(struct twofish_ctx),
68 .cra_alignmask = 3,
69 .cra_module = THIS_MODULE,
70 .cra_list = LIST_HEAD_INIT(alg.cra_list),
71 .cra_u = {
72 .cipher = {
73 .cia_min_keysize = TF_MIN_KEY_SIZE,
74 .cia_max_keysize = TF_MAX_KEY_SIZE,
75 .cia_setkey = twofish_setkey,
76 .cia_encrypt = twofish_encrypt,
77 .cia_decrypt = twofish_decrypt
78 }
79 }
80};
81
82static int __init init(void)
83{
84 return crypto_register_alg(&alg);
85}
86
87static void __exit fini(void)
88{
89 crypto_unregister_alg(&alg);
90}
91
92module_init(init);
93module_exit(fini);
94
95MODULE_LICENSE("GPL");
96MODULE_DESCRIPTION ("Twofish Cipher Algorithm, x86_64 asm optimized");
97MODULE_ALIAS("twofish");
diff --git a/crypto/Kconfig b/crypto/Kconfig
index ba133d557045..1e2f39c21180 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -9,47 +9,71 @@ config CRYPTO
9 help 9 help
10 This option provides the core Cryptographic API. 10 This option provides the core Cryptographic API.
11 11
12if CRYPTO
13
14config CRYPTO_ALGAPI
15 tristate
16 help
17 This option provides the API for cryptographic algorithms.
18
19config CRYPTO_BLKCIPHER
20 tristate
21 select CRYPTO_ALGAPI
22
23config CRYPTO_HASH
24 tristate
25 select CRYPTO_ALGAPI
26
27config CRYPTO_MANAGER
28 tristate "Cryptographic algorithm manager"
29 select CRYPTO_ALGAPI
30 default m
31 help
32 Create default cryptographic template instantiations such as
33 cbc(aes).
34
12config CRYPTO_HMAC 35config CRYPTO_HMAC
13 bool "HMAC support" 36 tristate "HMAC support"
14 depends on CRYPTO 37 select CRYPTO_HASH
15 help 38 help
16 HMAC: Keyed-Hashing for Message Authentication (RFC2104). 39 HMAC: Keyed-Hashing for Message Authentication (RFC2104).
17 This is required for IPSec. 40 This is required for IPSec.
18 41
19config CRYPTO_NULL 42config CRYPTO_NULL
20 tristate "Null algorithms" 43 tristate "Null algorithms"
21 depends on CRYPTO 44 select CRYPTO_ALGAPI
22 help 45 help
23 These are 'Null' algorithms, used by IPsec, which do nothing. 46 These are 'Null' algorithms, used by IPsec, which do nothing.
24 47
25config CRYPTO_MD4 48config CRYPTO_MD4
26 tristate "MD4 digest algorithm" 49 tristate "MD4 digest algorithm"
27 depends on CRYPTO 50 select CRYPTO_ALGAPI
28 help 51 help
29 MD4 message digest algorithm (RFC1320). 52 MD4 message digest algorithm (RFC1320).
30 53
31config CRYPTO_MD5 54config CRYPTO_MD5
32 tristate "MD5 digest algorithm" 55 tristate "MD5 digest algorithm"
33 depends on CRYPTO 56 select CRYPTO_ALGAPI
34 help 57 help
35 MD5 message digest algorithm (RFC1321). 58 MD5 message digest algorithm (RFC1321).
36 59
37config CRYPTO_SHA1 60config CRYPTO_SHA1
38 tristate "SHA1 digest algorithm" 61 tristate "SHA1 digest algorithm"
39 depends on CRYPTO 62 select CRYPTO_ALGAPI
40 help 63 help
41 SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). 64 SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
42 65
43config CRYPTO_SHA1_S390 66config CRYPTO_SHA1_S390
44 tristate "SHA1 digest algorithm (s390)" 67 tristate "SHA1 digest algorithm (s390)"
45 depends on CRYPTO && S390 68 depends on S390
69 select CRYPTO_ALGAPI
46 help 70 help
47 This is the s390 hardware accelerated implementation of the 71 This is the s390 hardware accelerated implementation of the
48 SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). 72 SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
49 73
50config CRYPTO_SHA256 74config CRYPTO_SHA256
51 tristate "SHA256 digest algorithm" 75 tristate "SHA256 digest algorithm"
52 depends on CRYPTO 76 select CRYPTO_ALGAPI
53 help 77 help
54 SHA256 secure hash standard (DFIPS 180-2). 78 SHA256 secure hash standard (DFIPS 180-2).
55 79
@@ -58,7 +82,8 @@ config CRYPTO_SHA256
58 82
59config CRYPTO_SHA256_S390 83config CRYPTO_SHA256_S390
60 tristate "SHA256 digest algorithm (s390)" 84 tristate "SHA256 digest algorithm (s390)"
61 depends on CRYPTO && S390 85 depends on S390
86 select CRYPTO_ALGAPI
62 help 87 help
63 This is the s390 hardware accelerated implementation of the 88 This is the s390 hardware accelerated implementation of the
64 SHA256 secure hash standard (DFIPS 180-2). 89 SHA256 secure hash standard (DFIPS 180-2).
@@ -68,7 +93,7 @@ config CRYPTO_SHA256_S390
68 93
69config CRYPTO_SHA512 94config CRYPTO_SHA512
70 tristate "SHA384 and SHA512 digest algorithms" 95 tristate "SHA384 and SHA512 digest algorithms"
71 depends on CRYPTO 96 select CRYPTO_ALGAPI
72 help 97 help
73 SHA512 secure hash standard (DFIPS 180-2). 98 SHA512 secure hash standard (DFIPS 180-2).
74 99
@@ -80,7 +105,7 @@ config CRYPTO_SHA512
80 105
81config CRYPTO_WP512 106config CRYPTO_WP512
82 tristate "Whirlpool digest algorithms" 107 tristate "Whirlpool digest algorithms"
83 depends on CRYPTO 108 select CRYPTO_ALGAPI
84 help 109 help
85 Whirlpool hash algorithm 512, 384 and 256-bit hashes 110 Whirlpool hash algorithm 512, 384 and 256-bit hashes
86 111
@@ -92,7 +117,7 @@ config CRYPTO_WP512
92 117
93config CRYPTO_TGR192 118config CRYPTO_TGR192
94 tristate "Tiger digest algorithms" 119 tristate "Tiger digest algorithms"
95 depends on CRYPTO 120 select CRYPTO_ALGAPI
96 help 121 help
97 Tiger hash algorithm 192, 160 and 128-bit hashes 122 Tiger hash algorithm 192, 160 and 128-bit hashes
98 123
@@ -103,21 +128,40 @@ config CRYPTO_TGR192
103 See also: 128 See also:
104 <http://www.cs.technion.ac.il/~biham/Reports/Tiger/>. 129 <http://www.cs.technion.ac.il/~biham/Reports/Tiger/>.
105 130
131config CRYPTO_ECB
132 tristate "ECB support"
133 select CRYPTO_BLKCIPHER
134 default m
135 help
136 ECB: Electronic CodeBook mode
137 This is the simplest block cipher algorithm. It simply encrypts
138 the input block by block.
139
140config CRYPTO_CBC
141 tristate "CBC support"
142 select CRYPTO_BLKCIPHER
143 default m
144 help
145 CBC: Cipher Block Chaining mode
146 This block cipher algorithm is required for IPSec.
147
106config CRYPTO_DES 148config CRYPTO_DES
107 tristate "DES and Triple DES EDE cipher algorithms" 149 tristate "DES and Triple DES EDE cipher algorithms"
108 depends on CRYPTO 150 select CRYPTO_ALGAPI
109 help 151 help
110 DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). 152 DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
111 153
112config CRYPTO_DES_S390 154config CRYPTO_DES_S390
113 tristate "DES and Triple DES cipher algorithms (s390)" 155 tristate "DES and Triple DES cipher algorithms (s390)"
114 depends on CRYPTO && S390 156 depends on S390
157 select CRYPTO_ALGAPI
158 select CRYPTO_BLKCIPHER
115 help 159 help
116 DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). 160 DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
117 161
118config CRYPTO_BLOWFISH 162config CRYPTO_BLOWFISH
119 tristate "Blowfish cipher algorithm" 163 tristate "Blowfish cipher algorithm"
120 depends on CRYPTO 164 select CRYPTO_ALGAPI
121 help 165 help
122 Blowfish cipher algorithm, by Bruce Schneier. 166 Blowfish cipher algorithm, by Bruce Schneier.
123 167
@@ -130,7 +174,8 @@ config CRYPTO_BLOWFISH
130 174
131config CRYPTO_TWOFISH 175config CRYPTO_TWOFISH
132 tristate "Twofish cipher algorithm" 176 tristate "Twofish cipher algorithm"
133 depends on CRYPTO 177 select CRYPTO_ALGAPI
178 select CRYPTO_TWOFISH_COMMON
134 help 179 help
135 Twofish cipher algorithm. 180 Twofish cipher algorithm.
136 181
@@ -142,9 +187,47 @@ config CRYPTO_TWOFISH
142 See also: 187 See also:
143 <http://www.schneier.com/twofish.html> 188 <http://www.schneier.com/twofish.html>
144 189
190config CRYPTO_TWOFISH_COMMON
191 tristate
192 help
193 Common parts of the Twofish cipher algorithm shared by the
194 generic c and the assembler implementations.
195
196config CRYPTO_TWOFISH_586
197 tristate "Twofish cipher algorithms (i586)"
198 depends on (X86 || UML_X86) && !64BIT
199 select CRYPTO_ALGAPI
200 select CRYPTO_TWOFISH_COMMON
201 help
202 Twofish cipher algorithm.
203
204 Twofish was submitted as an AES (Advanced Encryption Standard)
205 candidate cipher by researchers at CounterPane Systems. It is a
206 16 round block cipher supporting key sizes of 128, 192, and 256
207 bits.
208
209 See also:
210 <http://www.schneier.com/twofish.html>
211
212config CRYPTO_TWOFISH_X86_64
213 tristate "Twofish cipher algorithm (x86_64)"
214 depends on (X86 || UML_X86) && 64BIT
215 select CRYPTO_ALGAPI
216 select CRYPTO_TWOFISH_COMMON
217 help
218 Twofish cipher algorithm (x86_64).
219
220 Twofish was submitted as an AES (Advanced Encryption Standard)
221 candidate cipher by researchers at CounterPane Systems. It is a
222 16 round block cipher supporting key sizes of 128, 192, and 256
223 bits.
224
225 See also:
226 <http://www.schneier.com/twofish.html>
227
145config CRYPTO_SERPENT 228config CRYPTO_SERPENT
146 tristate "Serpent cipher algorithm" 229 tristate "Serpent cipher algorithm"
147 depends on CRYPTO 230 select CRYPTO_ALGAPI
148 help 231 help
149 Serpent cipher algorithm, by Anderson, Biham & Knudsen. 232 Serpent cipher algorithm, by Anderson, Biham & Knudsen.
150 233
@@ -157,7 +240,7 @@ config CRYPTO_SERPENT
157 240
158config CRYPTO_AES 241config CRYPTO_AES
159 tristate "AES cipher algorithms" 242 tristate "AES cipher algorithms"
160 depends on CRYPTO 243 select CRYPTO_ALGAPI
161 help 244 help
162 AES cipher algorithms (FIPS-197). AES uses the Rijndael 245 AES cipher algorithms (FIPS-197). AES uses the Rijndael
163 algorithm. 246 algorithm.
@@ -177,7 +260,8 @@ config CRYPTO_AES
177 260
178config CRYPTO_AES_586 261config CRYPTO_AES_586
179 tristate "AES cipher algorithms (i586)" 262 tristate "AES cipher algorithms (i586)"
180 depends on CRYPTO && ((X86 || UML_X86) && !64BIT) 263 depends on (X86 || UML_X86) && !64BIT
264 select CRYPTO_ALGAPI
181 help 265 help
182 AES cipher algorithms (FIPS-197). AES uses the Rijndael 266 AES cipher algorithms (FIPS-197). AES uses the Rijndael
183 algorithm. 267 algorithm.
@@ -197,7 +281,8 @@ config CRYPTO_AES_586
197 281
198config CRYPTO_AES_X86_64 282config CRYPTO_AES_X86_64
199 tristate "AES cipher algorithms (x86_64)" 283 tristate "AES cipher algorithms (x86_64)"
200 depends on CRYPTO && ((X86 || UML_X86) && 64BIT) 284 depends on (X86 || UML_X86) && 64BIT
285 select CRYPTO_ALGAPI
201 help 286 help
202 AES cipher algorithms (FIPS-197). AES uses the Rijndael 287 AES cipher algorithms (FIPS-197). AES uses the Rijndael
203 algorithm. 288 algorithm.
@@ -217,7 +302,9 @@ config CRYPTO_AES_X86_64
217 302
218config CRYPTO_AES_S390 303config CRYPTO_AES_S390
219 tristate "AES cipher algorithms (s390)" 304 tristate "AES cipher algorithms (s390)"
220 depends on CRYPTO && S390 305 depends on S390
306 select CRYPTO_ALGAPI
307 select CRYPTO_BLKCIPHER
221 help 308 help
222 This is the s390 hardware accelerated implementation of the 309 This is the s390 hardware accelerated implementation of the
223 AES cipher algorithms (FIPS-197). AES uses the Rijndael 310 AES cipher algorithms (FIPS-197). AES uses the Rijndael
@@ -237,21 +324,21 @@ config CRYPTO_AES_S390
237 324
238config CRYPTO_CAST5 325config CRYPTO_CAST5
239 tristate "CAST5 (CAST-128) cipher algorithm" 326 tristate "CAST5 (CAST-128) cipher algorithm"
240 depends on CRYPTO 327 select CRYPTO_ALGAPI
241 help 328 help
242 The CAST5 encryption algorithm (synonymous with CAST-128) is 329 The CAST5 encryption algorithm (synonymous with CAST-128) is
243 described in RFC2144. 330 described in RFC2144.
244 331
245config CRYPTO_CAST6 332config CRYPTO_CAST6
246 tristate "CAST6 (CAST-256) cipher algorithm" 333 tristate "CAST6 (CAST-256) cipher algorithm"
247 depends on CRYPTO 334 select CRYPTO_ALGAPI
248 help 335 help
249 The CAST6 encryption algorithm (synonymous with CAST-256) is 336 The CAST6 encryption algorithm (synonymous with CAST-256) is
250 described in RFC2612. 337 described in RFC2612.
251 338
252config CRYPTO_TEA 339config CRYPTO_TEA
253 tristate "TEA, XTEA and XETA cipher algorithms" 340 tristate "TEA, XTEA and XETA cipher algorithms"
254 depends on CRYPTO 341 select CRYPTO_ALGAPI
255 help 342 help
256 TEA cipher algorithm. 343 TEA cipher algorithm.
257 344
@@ -268,7 +355,7 @@ config CRYPTO_TEA
268 355
269config CRYPTO_ARC4 356config CRYPTO_ARC4
270 tristate "ARC4 cipher algorithm" 357 tristate "ARC4 cipher algorithm"
271 depends on CRYPTO 358 select CRYPTO_ALGAPI
272 help 359 help
273 ARC4 cipher algorithm. 360 ARC4 cipher algorithm.
274 361
@@ -279,7 +366,7 @@ config CRYPTO_ARC4
279 366
280config CRYPTO_KHAZAD 367config CRYPTO_KHAZAD
281 tristate "Khazad cipher algorithm" 368 tristate "Khazad cipher algorithm"
282 depends on CRYPTO 369 select CRYPTO_ALGAPI
283 help 370 help
284 Khazad cipher algorithm. 371 Khazad cipher algorithm.
285 372
@@ -292,7 +379,7 @@ config CRYPTO_KHAZAD
292 379
293config CRYPTO_ANUBIS 380config CRYPTO_ANUBIS
294 tristate "Anubis cipher algorithm" 381 tristate "Anubis cipher algorithm"
295 depends on CRYPTO 382 select CRYPTO_ALGAPI
296 help 383 help
297 Anubis cipher algorithm. 384 Anubis cipher algorithm.
298 385
@@ -307,7 +394,7 @@ config CRYPTO_ANUBIS
307 394
308config CRYPTO_DEFLATE 395config CRYPTO_DEFLATE
309 tristate "Deflate compression algorithm" 396 tristate "Deflate compression algorithm"
310 depends on CRYPTO 397 select CRYPTO_ALGAPI
311 select ZLIB_INFLATE 398 select ZLIB_INFLATE
312 select ZLIB_DEFLATE 399 select ZLIB_DEFLATE
313 help 400 help
@@ -318,7 +405,7 @@ config CRYPTO_DEFLATE
318 405
319config CRYPTO_MICHAEL_MIC 406config CRYPTO_MICHAEL_MIC
320 tristate "Michael MIC keyed digest algorithm" 407 tristate "Michael MIC keyed digest algorithm"
321 depends on CRYPTO 408 select CRYPTO_ALGAPI
322 help 409 help
323 Michael MIC is used for message integrity protection in TKIP 410 Michael MIC is used for message integrity protection in TKIP
324 (IEEE 802.11i). This algorithm is required for TKIP, but it 411 (IEEE 802.11i). This algorithm is required for TKIP, but it
@@ -327,7 +414,7 @@ config CRYPTO_MICHAEL_MIC
327 414
328config CRYPTO_CRC32C 415config CRYPTO_CRC32C
329 tristate "CRC32c CRC algorithm" 416 tristate "CRC32c CRC algorithm"
330 depends on CRYPTO 417 select CRYPTO_ALGAPI
331 select LIBCRC32C 418 select LIBCRC32C
332 help 419 help
333 Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used 420 Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
@@ -337,10 +424,13 @@ config CRYPTO_CRC32C
337 424
338config CRYPTO_TEST 425config CRYPTO_TEST
339 tristate "Testing module" 426 tristate "Testing module"
340 depends on CRYPTO && m 427 depends on m
428 select CRYPTO_ALGAPI
341 help 429 help
342 Quick & dirty crypto test module. 430 Quick & dirty crypto test module.
343 431
344source "drivers/crypto/Kconfig" 432source "drivers/crypto/Kconfig"
345endmenu
346 433
434endif # if CRYPTO
435
436endmenu
diff --git a/crypto/Makefile b/crypto/Makefile
index d287b9e60c47..72366208e291 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -2,11 +2,18 @@
2# Cryptographic API 2# Cryptographic API
3# 3#
4 4
5proc-crypto-$(CONFIG_PROC_FS) = proc.o 5obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o
6 6
7obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o \ 7crypto_algapi-$(CONFIG_PROC_FS) += proc.o
8 $(proc-crypto-y) 8crypto_algapi-objs := algapi.o $(crypto_algapi-y)
9obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o
9 10
11obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o
12
13crypto_hash-objs := hash.o
14obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o
15
16obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o
10obj-$(CONFIG_CRYPTO_HMAC) += hmac.o 17obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
11obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o 18obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
12obj-$(CONFIG_CRYPTO_MD4) += md4.o 19obj-$(CONFIG_CRYPTO_MD4) += md4.o
@@ -16,9 +23,12 @@ obj-$(CONFIG_CRYPTO_SHA256) += sha256.o
16obj-$(CONFIG_CRYPTO_SHA512) += sha512.o 23obj-$(CONFIG_CRYPTO_SHA512) += sha512.o
17obj-$(CONFIG_CRYPTO_WP512) += wp512.o 24obj-$(CONFIG_CRYPTO_WP512) += wp512.o
18obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o 25obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
26obj-$(CONFIG_CRYPTO_ECB) += ecb.o
27obj-$(CONFIG_CRYPTO_CBC) += cbc.o
19obj-$(CONFIG_CRYPTO_DES) += des.o 28obj-$(CONFIG_CRYPTO_DES) += des.o
20obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o 29obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
21obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o 30obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
31obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
22obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o 32obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
23obj-$(CONFIG_CRYPTO_AES) += aes.o 33obj-$(CONFIG_CRYPTO_AES) += aes.o
24obj-$(CONFIG_CRYPTO_CAST5) += cast5.o 34obj-$(CONFIG_CRYPTO_CAST5) += cast5.o
diff --git a/crypto/aes.c b/crypto/aes.c
index a038711831e7..e2440773878c 100644
--- a/crypto/aes.c
+++ b/crypto/aes.c
@@ -249,13 +249,14 @@ gen_tabs (void)
249} 249}
250 250
251static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 251static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
252 unsigned int key_len, u32 *flags) 252 unsigned int key_len)
253{ 253{
254 struct aes_ctx *ctx = crypto_tfm_ctx(tfm); 254 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
255 const __le32 *key = (const __le32 *)in_key; 255 const __le32 *key = (const __le32 *)in_key;
256 u32 *flags = &tfm->crt_flags;
256 u32 i, t, u, v, w; 257 u32 i, t, u, v, w;
257 258
258 if (key_len != 16 && key_len != 24 && key_len != 32) { 259 if (key_len % 8) {
259 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 260 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
260 return -EINVAL; 261 return -EINVAL;
261 } 262 }
diff --git a/crypto/algapi.c b/crypto/algapi.c
new file mode 100644
index 000000000000..c91530021e9c
--- /dev/null
+++ b/crypto/algapi.c
@@ -0,0 +1,486 @@
1/*
2 * Cryptographic API for algorithms (i.e., low-level API).
3 *
4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 */
12
13#include <linux/err.h>
14#include <linux/errno.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/list.h>
18#include <linux/module.h>
19#include <linux/rtnetlink.h>
20#include <linux/string.h>
21
22#include "internal.h"
23
24static LIST_HEAD(crypto_template_list);
25
26void crypto_larval_error(const char *name, u32 type, u32 mask)
27{
28 struct crypto_alg *alg;
29
30 down_read(&crypto_alg_sem);
31 alg = __crypto_alg_lookup(name, type, mask);
32 up_read(&crypto_alg_sem);
33
34 if (alg) {
35 if (crypto_is_larval(alg)) {
36 struct crypto_larval *larval = (void *)alg;
37 complete(&larval->completion);
38 }
39 crypto_mod_put(alg);
40 }
41}
42EXPORT_SYMBOL_GPL(crypto_larval_error);
43
44static inline int crypto_set_driver_name(struct crypto_alg *alg)
45{
46 static const char suffix[] = "-generic";
47 char *driver_name = alg->cra_driver_name;
48 int len;
49
50 if (*driver_name)
51 return 0;
52
53 len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
54 if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME)
55 return -ENAMETOOLONG;
56
57 memcpy(driver_name + len, suffix, sizeof(suffix));
58 return 0;
59}
60
61static int crypto_check_alg(struct crypto_alg *alg)
62{
63 if (alg->cra_alignmask & (alg->cra_alignmask + 1))
64 return -EINVAL;
65
66 if (alg->cra_alignmask & alg->cra_blocksize)
67 return -EINVAL;
68
69 if (alg->cra_blocksize > PAGE_SIZE / 8)
70 return -EINVAL;
71
72 if (alg->cra_priority < 0)
73 return -EINVAL;
74
75 return crypto_set_driver_name(alg);
76}
77
78static void crypto_destroy_instance(struct crypto_alg *alg)
79{
80 struct crypto_instance *inst = (void *)alg;
81 struct crypto_template *tmpl = inst->tmpl;
82
83 tmpl->free(inst);
84 crypto_tmpl_put(tmpl);
85}
86
87static void crypto_remove_spawns(struct list_head *spawns,
88 struct list_head *list)
89{
90 struct crypto_spawn *spawn, *n;
91
92 list_for_each_entry_safe(spawn, n, spawns, list) {
93 struct crypto_instance *inst = spawn->inst;
94 struct crypto_template *tmpl = inst->tmpl;
95
96 list_del_init(&spawn->list);
97 spawn->alg = NULL;
98
99 if (crypto_is_dead(&inst->alg))
100 continue;
101
102 inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
103 if (!tmpl || !crypto_tmpl_get(tmpl))
104 continue;
105
106 crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg);
107 list_move(&inst->alg.cra_list, list);
108 hlist_del(&inst->list);
109 inst->alg.cra_destroy = crypto_destroy_instance;
110
111 if (!list_empty(&inst->alg.cra_users)) {
112 if (&n->list == spawns)
113 n = list_entry(inst->alg.cra_users.next,
114 typeof(*n), list);
115 __list_splice(&inst->alg.cra_users, spawns->prev);
116 }
117 }
118}
119
120static int __crypto_register_alg(struct crypto_alg *alg,
121 struct list_head *list)
122{
123 struct crypto_alg *q;
124 int ret = -EAGAIN;
125
126 if (crypto_is_dead(alg))
127 goto out;
128
129 INIT_LIST_HEAD(&alg->cra_users);
130
131 ret = -EEXIST;
132
133 atomic_set(&alg->cra_refcnt, 1);
134 list_for_each_entry(q, &crypto_alg_list, cra_list) {
135 if (q == alg)
136 goto out;
137
138 if (crypto_is_moribund(q))
139 continue;
140
141 if (crypto_is_larval(q)) {
142 struct crypto_larval *larval = (void *)q;
143
144 if (strcmp(alg->cra_name, q->cra_name) &&
145 strcmp(alg->cra_driver_name, q->cra_name))
146 continue;
147
148 if (larval->adult)
149 continue;
150 if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
151 continue;
152 if (!crypto_mod_get(alg))
153 continue;
154
155 larval->adult = alg;
156 complete(&larval->completion);
157 continue;
158 }
159
160 if (strcmp(alg->cra_name, q->cra_name))
161 continue;
162
163 if (strcmp(alg->cra_driver_name, q->cra_driver_name) &&
164 q->cra_priority > alg->cra_priority)
165 continue;
166
167 crypto_remove_spawns(&q->cra_users, list);
168 }
169
170 list_add(&alg->cra_list, &crypto_alg_list);
171
172 crypto_notify(CRYPTO_MSG_ALG_REGISTER, alg);
173 ret = 0;
174
175out:
176 return ret;
177}
178
179static void crypto_remove_final(struct list_head *list)
180{
181 struct crypto_alg *alg;
182 struct crypto_alg *n;
183
184 list_for_each_entry_safe(alg, n, list, cra_list) {
185 list_del_init(&alg->cra_list);
186 crypto_alg_put(alg);
187 }
188}
189
190int crypto_register_alg(struct crypto_alg *alg)
191{
192 LIST_HEAD(list);
193 int err;
194
195 err = crypto_check_alg(alg);
196 if (err)
197 return err;
198
199 down_write(&crypto_alg_sem);
200 err = __crypto_register_alg(alg, &list);
201 up_write(&crypto_alg_sem);
202
203 crypto_remove_final(&list);
204 return err;
205}
206EXPORT_SYMBOL_GPL(crypto_register_alg);
207
208static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list)
209{
210 if (unlikely(list_empty(&alg->cra_list)))
211 return -ENOENT;
212
213 alg->cra_flags |= CRYPTO_ALG_DEAD;
214
215 crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg);
216 list_del_init(&alg->cra_list);
217 crypto_remove_spawns(&alg->cra_users, list);
218
219 return 0;
220}
221
222int crypto_unregister_alg(struct crypto_alg *alg)
223{
224 int ret;
225 LIST_HEAD(list);
226
227 down_write(&crypto_alg_sem);
228 ret = crypto_remove_alg(alg, &list);
229 up_write(&crypto_alg_sem);
230
231 if (ret)
232 return ret;
233
234 BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
235 if (alg->cra_destroy)
236 alg->cra_destroy(alg);
237
238 crypto_remove_final(&list);
239 return 0;
240}
241EXPORT_SYMBOL_GPL(crypto_unregister_alg);
242
243int crypto_register_template(struct crypto_template *tmpl)
244{
245 struct crypto_template *q;
246 int err = -EEXIST;
247
248 down_write(&crypto_alg_sem);
249
250 list_for_each_entry(q, &crypto_template_list, list) {
251 if (q == tmpl)
252 goto out;
253 }
254
255 list_add(&tmpl->list, &crypto_template_list);
256 crypto_notify(CRYPTO_MSG_TMPL_REGISTER, tmpl);
257 err = 0;
258out:
259 up_write(&crypto_alg_sem);
260 return err;
261}
262EXPORT_SYMBOL_GPL(crypto_register_template);
263
264void crypto_unregister_template(struct crypto_template *tmpl)
265{
266 struct crypto_instance *inst;
267 struct hlist_node *p, *n;
268 struct hlist_head *list;
269 LIST_HEAD(users);
270
271 down_write(&crypto_alg_sem);
272
273 BUG_ON(list_empty(&tmpl->list));
274 list_del_init(&tmpl->list);
275
276 list = &tmpl->instances;
277 hlist_for_each_entry(inst, p, list, list) {
278 int err = crypto_remove_alg(&inst->alg, &users);
279 BUG_ON(err);
280 }
281
282 crypto_notify(CRYPTO_MSG_TMPL_UNREGISTER, tmpl);
283
284 up_write(&crypto_alg_sem);
285
286 hlist_for_each_entry_safe(inst, p, n, list, list) {
287 BUG_ON(atomic_read(&inst->alg.cra_refcnt) != 1);
288 tmpl->free(inst);
289 }
290 crypto_remove_final(&users);
291}
292EXPORT_SYMBOL_GPL(crypto_unregister_template);
293
294static struct crypto_template *__crypto_lookup_template(const char *name)
295{
296 struct crypto_template *q, *tmpl = NULL;
297
298 down_read(&crypto_alg_sem);
299 list_for_each_entry(q, &crypto_template_list, list) {
300 if (strcmp(q->name, name))
301 continue;
302 if (unlikely(!crypto_tmpl_get(q)))
303 continue;
304
305 tmpl = q;
306 break;
307 }
308 up_read(&crypto_alg_sem);
309
310 return tmpl;
311}
312
313struct crypto_template *crypto_lookup_template(const char *name)
314{
315 return try_then_request_module(__crypto_lookup_template(name), name);
316}
317EXPORT_SYMBOL_GPL(crypto_lookup_template);
318
319int crypto_register_instance(struct crypto_template *tmpl,
320 struct crypto_instance *inst)
321{
322 LIST_HEAD(list);
323 int err = -EINVAL;
324
325 if (inst->alg.cra_destroy)
326 goto err;
327
328 err = crypto_check_alg(&inst->alg);
329 if (err)
330 goto err;
331
332 inst->alg.cra_module = tmpl->module;
333
334 down_write(&crypto_alg_sem);
335
336 err = __crypto_register_alg(&inst->alg, &list);
337 if (err)
338 goto unlock;
339
340 hlist_add_head(&inst->list, &tmpl->instances);
341 inst->tmpl = tmpl;
342
343unlock:
344 up_write(&crypto_alg_sem);
345
346 crypto_remove_final(&list);
347
348err:
349 return err;
350}
351EXPORT_SYMBOL_GPL(crypto_register_instance);
352
353int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
354 struct crypto_instance *inst)
355{
356 int err = -EAGAIN;
357
358 spawn->inst = inst;
359
360 down_write(&crypto_alg_sem);
361 if (!crypto_is_moribund(alg)) {
362 list_add(&spawn->list, &alg->cra_users);
363 spawn->alg = alg;
364 err = 0;
365 }
366 up_write(&crypto_alg_sem);
367
368 return err;
369}
370EXPORT_SYMBOL_GPL(crypto_init_spawn);
371
372void crypto_drop_spawn(struct crypto_spawn *spawn)
373{
374 down_write(&crypto_alg_sem);
375 list_del(&spawn->list);
376 up_write(&crypto_alg_sem);
377}
378EXPORT_SYMBOL_GPL(crypto_drop_spawn);
379
380struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn)
381{
382 struct crypto_alg *alg;
383 struct crypto_alg *alg2;
384 struct crypto_tfm *tfm;
385
386 down_read(&crypto_alg_sem);
387 alg = spawn->alg;
388 alg2 = alg;
389 if (alg2)
390 alg2 = crypto_mod_get(alg2);
391 up_read(&crypto_alg_sem);
392
393 if (!alg2) {
394 if (alg)
395 crypto_shoot_alg(alg);
396 return ERR_PTR(-EAGAIN);
397 }
398
399 tfm = __crypto_alloc_tfm(alg, 0);
400 if (IS_ERR(tfm))
401 crypto_mod_put(alg);
402
403 return tfm;
404}
405EXPORT_SYMBOL_GPL(crypto_spawn_tfm);
406
407int crypto_register_notifier(struct notifier_block *nb)
408{
409 return blocking_notifier_chain_register(&crypto_chain, nb);
410}
411EXPORT_SYMBOL_GPL(crypto_register_notifier);
412
413int crypto_unregister_notifier(struct notifier_block *nb)
414{
415 return blocking_notifier_chain_unregister(&crypto_chain, nb);
416}
417EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
418
419struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len,
420 u32 type, u32 mask)
421{
422 struct rtattr *rta = param;
423 struct crypto_attr_alg *alga;
424
425 if (!RTA_OK(rta, len))
426 return ERR_PTR(-EBADR);
427 if (rta->rta_type != CRYPTOA_ALG || RTA_PAYLOAD(rta) < sizeof(*alga))
428 return ERR_PTR(-EINVAL);
429
430 alga = RTA_DATA(rta);
431 alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
432
433 return crypto_alg_mod_lookup(alga->name, type, mask);
434}
435EXPORT_SYMBOL_GPL(crypto_get_attr_alg);
436
437struct crypto_instance *crypto_alloc_instance(const char *name,
438 struct crypto_alg *alg)
439{
440 struct crypto_instance *inst;
441 struct crypto_spawn *spawn;
442 int err;
443
444 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
445 if (!inst)
446 return ERR_PTR(-ENOMEM);
447
448 err = -ENAMETOOLONG;
449 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name,
450 alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
451 goto err_free_inst;
452
453 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
454 name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
455 goto err_free_inst;
456
457 spawn = crypto_instance_ctx(inst);
458 err = crypto_init_spawn(spawn, alg, inst);
459
460 if (err)
461 goto err_free_inst;
462
463 return inst;
464
465err_free_inst:
466 kfree(inst);
467 return ERR_PTR(err);
468}
469EXPORT_SYMBOL_GPL(crypto_alloc_instance);
470
471static int __init crypto_algapi_init(void)
472{
473 crypto_init_proc();
474 return 0;
475}
476
477static void __exit crypto_algapi_exit(void)
478{
479 crypto_exit_proc();
480}
481
482module_init(crypto_algapi_init);
483module_exit(crypto_algapi_exit);
484
485MODULE_LICENSE("GPL");
486MODULE_DESCRIPTION("Cryptographic algorithms API");
diff --git a/crypto/anubis.c b/crypto/anubis.c
index 7e2e1a29800e..1c771f7f4dc5 100644
--- a/crypto/anubis.c
+++ b/crypto/anubis.c
@@ -461,10 +461,11 @@ static const u32 rc[] = {
461}; 461};
462 462
463static int anubis_setkey(struct crypto_tfm *tfm, const u8 *in_key, 463static int anubis_setkey(struct crypto_tfm *tfm, const u8 *in_key,
464 unsigned int key_len, u32 *flags) 464 unsigned int key_len)
465{ 465{
466 struct anubis_ctx *ctx = crypto_tfm_ctx(tfm); 466 struct anubis_ctx *ctx = crypto_tfm_ctx(tfm);
467 const __be32 *key = (const __be32 *)in_key; 467 const __be32 *key = (const __be32 *)in_key;
468 u32 *flags = &tfm->crt_flags;
468 int N, R, i, r; 469 int N, R, i, r;
469 u32 kappa[ANUBIS_MAX_N]; 470 u32 kappa[ANUBIS_MAX_N];
470 u32 inter[ANUBIS_MAX_N]; 471 u32 inter[ANUBIS_MAX_N];
diff --git a/crypto/api.c b/crypto/api.c
index c11ec1fd4f18..2e84d4b54790 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -15,70 +15,202 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/compiler.h> 18#include <linux/err.h>
19#include <linux/init.h>
20#include <linux/crypto.h>
21#include <linux/errno.h> 19#include <linux/errno.h>
22#include <linux/kernel.h> 20#include <linux/kernel.h>
23#include <linux/kmod.h> 21#include <linux/kmod.h>
24#include <linux/rwsem.h> 22#include <linux/module.h>
23#include <linux/param.h>
24#include <linux/sched.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include "internal.h" 27#include "internal.h"
28 28
29LIST_HEAD(crypto_alg_list); 29LIST_HEAD(crypto_alg_list);
30EXPORT_SYMBOL_GPL(crypto_alg_list);
30DECLARE_RWSEM(crypto_alg_sem); 31DECLARE_RWSEM(crypto_alg_sem);
32EXPORT_SYMBOL_GPL(crypto_alg_sem);
31 33
32static inline int crypto_alg_get(struct crypto_alg *alg) 34BLOCKING_NOTIFIER_HEAD(crypto_chain);
35EXPORT_SYMBOL_GPL(crypto_chain);
36
37static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
38{
39 atomic_inc(&alg->cra_refcnt);
40 return alg;
41}
42
43struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
33{ 44{
34 return try_module_get(alg->cra_module); 45 return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL;
35} 46}
47EXPORT_SYMBOL_GPL(crypto_mod_get);
36 48
37static inline void crypto_alg_put(struct crypto_alg *alg) 49void crypto_mod_put(struct crypto_alg *alg)
38{ 50{
51 crypto_alg_put(alg);
39 module_put(alg->cra_module); 52 module_put(alg->cra_module);
40} 53}
54EXPORT_SYMBOL_GPL(crypto_mod_put);
41 55
42static struct crypto_alg *crypto_alg_lookup(const char *name) 56struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask)
43{ 57{
44 struct crypto_alg *q, *alg = NULL; 58 struct crypto_alg *q, *alg = NULL;
45 int best = -1; 59 int best = -2;
46 60
47 if (!name)
48 return NULL;
49
50 down_read(&crypto_alg_sem);
51
52 list_for_each_entry(q, &crypto_alg_list, cra_list) { 61 list_for_each_entry(q, &crypto_alg_list, cra_list) {
53 int exact, fuzzy; 62 int exact, fuzzy;
54 63
64 if (crypto_is_moribund(q))
65 continue;
66
67 if ((q->cra_flags ^ type) & mask)
68 continue;
69
70 if (crypto_is_larval(q) &&
71 ((struct crypto_larval *)q)->mask != mask)
72 continue;
73
55 exact = !strcmp(q->cra_driver_name, name); 74 exact = !strcmp(q->cra_driver_name, name);
56 fuzzy = !strcmp(q->cra_name, name); 75 fuzzy = !strcmp(q->cra_name, name);
57 if (!exact && !(fuzzy && q->cra_priority > best)) 76 if (!exact && !(fuzzy && q->cra_priority > best))
58 continue; 77 continue;
59 78
60 if (unlikely(!crypto_alg_get(q))) 79 if (unlikely(!crypto_mod_get(q)))
61 continue; 80 continue;
62 81
63 best = q->cra_priority; 82 best = q->cra_priority;
64 if (alg) 83 if (alg)
65 crypto_alg_put(alg); 84 crypto_mod_put(alg);
66 alg = q; 85 alg = q;
67 86
68 if (exact) 87 if (exact)
69 break; 88 break;
70 } 89 }
71 90
91 return alg;
92}
93EXPORT_SYMBOL_GPL(__crypto_alg_lookup);
94
95static void crypto_larval_destroy(struct crypto_alg *alg)
96{
97 struct crypto_larval *larval = (void *)alg;
98
99 BUG_ON(!crypto_is_larval(alg));
100 if (larval->adult)
101 crypto_mod_put(larval->adult);
102 kfree(larval);
103}
104
105static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
106 u32 mask)
107{
108 struct crypto_alg *alg;
109 struct crypto_larval *larval;
110
111 larval = kzalloc(sizeof(*larval), GFP_KERNEL);
112 if (!larval)
113 return ERR_PTR(-ENOMEM);
114
115 larval->mask = mask;
116 larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type;
117 larval->alg.cra_priority = -1;
118 larval->alg.cra_destroy = crypto_larval_destroy;
119
120 atomic_set(&larval->alg.cra_refcnt, 2);
121 strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
122 init_completion(&larval->completion);
123
124 down_write(&crypto_alg_sem);
125 alg = __crypto_alg_lookup(name, type, mask);
126 if (!alg) {
127 alg = &larval->alg;
128 list_add(&alg->cra_list, &crypto_alg_list);
129 }
130 up_write(&crypto_alg_sem);
131
132 if (alg != &larval->alg)
133 kfree(larval);
134
135 return alg;
136}
137
138static void crypto_larval_kill(struct crypto_alg *alg)
139{
140 struct crypto_larval *larval = (void *)alg;
141
142 down_write(&crypto_alg_sem);
143 list_del(&alg->cra_list);
144 up_write(&crypto_alg_sem);
145 complete(&larval->completion);
146 crypto_alg_put(alg);
147}
148
149static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
150{
151 struct crypto_larval *larval = (void *)alg;
152
153 wait_for_completion_interruptible_timeout(&larval->completion, 60 * HZ);
154 alg = larval->adult;
155 if (alg) {
156 if (!crypto_mod_get(alg))
157 alg = ERR_PTR(-EAGAIN);
158 } else
159 alg = ERR_PTR(-ENOENT);
160 crypto_mod_put(&larval->alg);
161
162 return alg;
163}
164
165static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
166 u32 mask)
167{
168 struct crypto_alg *alg;
169
170 down_read(&crypto_alg_sem);
171 alg = __crypto_alg_lookup(name, type, mask);
72 up_read(&crypto_alg_sem); 172 up_read(&crypto_alg_sem);
173
73 return alg; 174 return alg;
74} 175}
75 176
76/* A far more intelligent version of this is planned. For now, just 177struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
77 * try an exact match on the name of the algorithm. */
78static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
79{ 178{
80 return try_then_request_module(crypto_alg_lookup(name), name); 179 struct crypto_alg *alg;
180 struct crypto_alg *larval;
181 int ok;
182
183 if (!name)
184 return ERR_PTR(-ENOENT);
185
186 mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
187 type &= mask;
188
189 alg = try_then_request_module(crypto_alg_lookup(name, type, mask),
190 name);
191 if (alg)
192 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
193
194 larval = crypto_larval_alloc(name, type, mask);
195 if (IS_ERR(larval) || !crypto_is_larval(larval))
196 return larval;
197
198 ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
199 if (ok == NOTIFY_DONE) {
200 request_module("cryptomgr");
201 ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
202 }
203
204 if (ok == NOTIFY_STOP)
205 alg = crypto_larval_wait(larval);
206 else {
207 crypto_mod_put(larval);
208 alg = ERR_PTR(-ENOENT);
209 }
210 crypto_larval_kill(larval);
211 return alg;
81} 212}
213EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup);
82 214
83static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) 215static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
84{ 216{
@@ -94,17 +226,18 @@ static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
94 226
95 case CRYPTO_ALG_TYPE_COMPRESS: 227 case CRYPTO_ALG_TYPE_COMPRESS:
96 return crypto_init_compress_flags(tfm, flags); 228 return crypto_init_compress_flags(tfm, flags);
97
98 default:
99 break;
100 } 229 }
101 230
102 BUG(); 231 return 0;
103 return -EINVAL;
104} 232}
105 233
106static int crypto_init_ops(struct crypto_tfm *tfm) 234static int crypto_init_ops(struct crypto_tfm *tfm)
107{ 235{
236 const struct crypto_type *type = tfm->__crt_alg->cra_type;
237
238 if (type)
239 return type->init(tfm);
240
108 switch (crypto_tfm_alg_type(tfm)) { 241 switch (crypto_tfm_alg_type(tfm)) {
109 case CRYPTO_ALG_TYPE_CIPHER: 242 case CRYPTO_ALG_TYPE_CIPHER:
110 return crypto_init_cipher_ops(tfm); 243 return crypto_init_cipher_ops(tfm);
@@ -125,6 +258,14 @@ static int crypto_init_ops(struct crypto_tfm *tfm)
125 258
126static void crypto_exit_ops(struct crypto_tfm *tfm) 259static void crypto_exit_ops(struct crypto_tfm *tfm)
127{ 260{
261 const struct crypto_type *type = tfm->__crt_alg->cra_type;
262
263 if (type) {
264 if (type->exit)
265 type->exit(tfm);
266 return;
267 }
268
128 switch (crypto_tfm_alg_type(tfm)) { 269 switch (crypto_tfm_alg_type(tfm)) {
129 case CRYPTO_ALG_TYPE_CIPHER: 270 case CRYPTO_ALG_TYPE_CIPHER:
130 crypto_exit_cipher_ops(tfm); 271 crypto_exit_cipher_ops(tfm);
@@ -146,53 +287,67 @@ static void crypto_exit_ops(struct crypto_tfm *tfm)
146 287
147static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags) 288static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags)
148{ 289{
290 const struct crypto_type *type = alg->cra_type;
149 unsigned int len; 291 unsigned int len;
150 292
293 len = alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1);
294 if (type)
295 return len + type->ctxsize(alg);
296
151 switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { 297 switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
152 default: 298 default:
153 BUG(); 299 BUG();
154 300
155 case CRYPTO_ALG_TYPE_CIPHER: 301 case CRYPTO_ALG_TYPE_CIPHER:
156 len = crypto_cipher_ctxsize(alg, flags); 302 len += crypto_cipher_ctxsize(alg, flags);
157 break; 303 break;
158 304
159 case CRYPTO_ALG_TYPE_DIGEST: 305 case CRYPTO_ALG_TYPE_DIGEST:
160 len = crypto_digest_ctxsize(alg, flags); 306 len += crypto_digest_ctxsize(alg, flags);
161 break; 307 break;
162 308
163 case CRYPTO_ALG_TYPE_COMPRESS: 309 case CRYPTO_ALG_TYPE_COMPRESS:
164 len = crypto_compress_ctxsize(alg, flags); 310 len += crypto_compress_ctxsize(alg, flags);
165 break; 311 break;
166 } 312 }
167 313
168 return len + (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1)); 314 return len;
169} 315}
170 316
171struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) 317void crypto_shoot_alg(struct crypto_alg *alg)
318{
319 down_write(&crypto_alg_sem);
320 alg->cra_flags |= CRYPTO_ALG_DYING;
321 up_write(&crypto_alg_sem);
322}
323EXPORT_SYMBOL_GPL(crypto_shoot_alg);
324
325struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags)
172{ 326{
173 struct crypto_tfm *tfm = NULL; 327 struct crypto_tfm *tfm = NULL;
174 struct crypto_alg *alg;
175 unsigned int tfm_size; 328 unsigned int tfm_size;
176 329 int err = -ENOMEM;
177 alg = crypto_alg_mod_lookup(name);
178 if (alg == NULL)
179 goto out;
180 330
181 tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags); 331 tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags);
182 tfm = kzalloc(tfm_size, GFP_KERNEL); 332 tfm = kzalloc(tfm_size, GFP_KERNEL);
183 if (tfm == NULL) 333 if (tfm == NULL)
184 goto out_put; 334 goto out;
185 335
186 tfm->__crt_alg = alg; 336 tfm->__crt_alg = alg;
187 337
188 if (crypto_init_flags(tfm, flags)) 338 err = crypto_init_flags(tfm, flags);
339 if (err)
189 goto out_free_tfm; 340 goto out_free_tfm;
190 341
191 if (crypto_init_ops(tfm)) 342 err = crypto_init_ops(tfm);
343 if (err)
192 goto out_free_tfm; 344 goto out_free_tfm;
193 345
194 if (alg->cra_init && alg->cra_init(tfm)) 346 if (alg->cra_init && (err = alg->cra_init(tfm))) {
347 if (err == -EAGAIN)
348 crypto_shoot_alg(alg);
195 goto cra_init_failed; 349 goto cra_init_failed;
350 }
196 351
197 goto out; 352 goto out;
198 353
@@ -200,13 +355,97 @@ cra_init_failed:
200 crypto_exit_ops(tfm); 355 crypto_exit_ops(tfm);
201out_free_tfm: 356out_free_tfm:
202 kfree(tfm); 357 kfree(tfm);
203 tfm = NULL; 358 tfm = ERR_PTR(err);
204out_put:
205 crypto_alg_put(alg);
206out: 359out:
207 return tfm; 360 return tfm;
208} 361}
362EXPORT_SYMBOL_GPL(__crypto_alloc_tfm);
363
364struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
365{
366 struct crypto_tfm *tfm = NULL;
367 int err;
368
369 do {
370 struct crypto_alg *alg;
371
372 alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC);
373 err = PTR_ERR(alg);
374 if (IS_ERR(alg))
375 continue;
376
377 tfm = __crypto_alloc_tfm(alg, flags);
378 err = 0;
379 if (IS_ERR(tfm)) {
380 crypto_mod_put(alg);
381 err = PTR_ERR(tfm);
382 tfm = NULL;
383 }
384 } while (err == -EAGAIN && !signal_pending(current));
385
386 return tfm;
387}
388
389/*
390 * crypto_alloc_base - Locate algorithm and allocate transform
391 * @alg_name: Name of algorithm
392 * @type: Type of algorithm
393 * @mask: Mask for type comparison
394 *
395 * crypto_alloc_base() will first attempt to locate an already loaded
396 * algorithm. If that fails and the kernel supports dynamically loadable
397 * modules, it will then attempt to load a module of the same name or
398 * alias. If that fails it will send a query to any loaded crypto manager
399 * to construct an algorithm on the fly. A refcount is grabbed on the
400 * algorithm which is then associated with the new transform.
401 *
402 * The returned transform is of a non-determinate type. Most people
403 * should use one of the more specific allocation functions such as
404 * crypto_alloc_blkcipher.
405 *
406 * In case of error the return value is an error pointer.
407 */
408struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
409{
410 struct crypto_tfm *tfm;
411 int err;
412
413 for (;;) {
414 struct crypto_alg *alg;
415
416 alg = crypto_alg_mod_lookup(alg_name, type, mask);
417 err = PTR_ERR(alg);
418 tfm = ERR_PTR(err);
419 if (IS_ERR(alg))
420 goto err;
421
422 tfm = __crypto_alloc_tfm(alg, 0);
423 if (!IS_ERR(tfm))
424 break;
425
426 crypto_mod_put(alg);
427 err = PTR_ERR(tfm);
209 428
429err:
430 if (err != -EAGAIN)
431 break;
432 if (signal_pending(current)) {
433 err = -EINTR;
434 break;
435 }
436 };
437
438 return tfm;
439}
440EXPORT_SYMBOL_GPL(crypto_alloc_base);
441
442/*
443 * crypto_free_tfm - Free crypto transform
444 * @tfm: Transform to free
445 *
446 * crypto_free_tfm() frees up the transform and any associated resources,
447 * then drops the refcount on the associated algorithm.
448 */
210void crypto_free_tfm(struct crypto_tfm *tfm) 449void crypto_free_tfm(struct crypto_tfm *tfm)
211{ 450{
212 struct crypto_alg *alg; 451 struct crypto_alg *alg;
@@ -221,108 +460,39 @@ void crypto_free_tfm(struct crypto_tfm *tfm)
221 if (alg->cra_exit) 460 if (alg->cra_exit)
222 alg->cra_exit(tfm); 461 alg->cra_exit(tfm);
223 crypto_exit_ops(tfm); 462 crypto_exit_ops(tfm);
224 crypto_alg_put(alg); 463 crypto_mod_put(alg);
225 memset(tfm, 0, size); 464 memset(tfm, 0, size);
226 kfree(tfm); 465 kfree(tfm);
227} 466}
228 467
229static inline int crypto_set_driver_name(struct crypto_alg *alg) 468int crypto_alg_available(const char *name, u32 flags)
230{
231 static const char suffix[] = "-generic";
232 char *driver_name = alg->cra_driver_name;
233 int len;
234
235 if (*driver_name)
236 return 0;
237
238 len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
239 if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME)
240 return -ENAMETOOLONG;
241
242 memcpy(driver_name + len, suffix, sizeof(suffix));
243 return 0;
244}
245
246int crypto_register_alg(struct crypto_alg *alg)
247{ 469{
248 int ret; 470 int ret = 0;
249 struct crypto_alg *q; 471 struct crypto_alg *alg = crypto_alg_mod_lookup(name, 0,
250 472 CRYPTO_ALG_ASYNC);
251 if (alg->cra_alignmask & (alg->cra_alignmask + 1))
252 return -EINVAL;
253
254 if (alg->cra_alignmask & alg->cra_blocksize)
255 return -EINVAL;
256
257 if (alg->cra_blocksize > PAGE_SIZE / 8)
258 return -EINVAL;
259
260 if (alg->cra_priority < 0)
261 return -EINVAL;
262
263 ret = crypto_set_driver_name(alg);
264 if (unlikely(ret))
265 return ret;
266
267 down_write(&crypto_alg_sem);
268 473
269 list_for_each_entry(q, &crypto_alg_list, cra_list) { 474 if (!IS_ERR(alg)) {
270 if (q == alg) { 475 crypto_mod_put(alg);
271 ret = -EEXIST; 476 ret = 1;
272 goto out;
273 }
274 } 477 }
275 478
276 list_add(&alg->cra_list, &crypto_alg_list);
277out:
278 up_write(&crypto_alg_sem);
279 return ret; 479 return ret;
280} 480}
281 481
282int crypto_unregister_alg(struct crypto_alg *alg) 482EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
283{ 483EXPORT_SYMBOL_GPL(crypto_free_tfm);
284 int ret = -ENOENT; 484EXPORT_SYMBOL_GPL(crypto_alg_available);
285 struct crypto_alg *q;
286
287 BUG_ON(!alg->cra_module);
288
289 down_write(&crypto_alg_sem);
290 list_for_each_entry(q, &crypto_alg_list, cra_list) {
291 if (alg == q) {
292 list_del(&alg->cra_list);
293 ret = 0;
294 goto out;
295 }
296 }
297out:
298 up_write(&crypto_alg_sem);
299 return ret;
300}
301 485
302int crypto_alg_available(const char *name, u32 flags) 486int crypto_has_alg(const char *name, u32 type, u32 mask)
303{ 487{
304 int ret = 0; 488 int ret = 0;
305 struct crypto_alg *alg = crypto_alg_mod_lookup(name); 489 struct crypto_alg *alg = crypto_alg_mod_lookup(name, type, mask);
306 490
307 if (alg) { 491 if (!IS_ERR(alg)) {
308 crypto_alg_put(alg); 492 crypto_mod_put(alg);
309 ret = 1; 493 ret = 1;
310 } 494 }
311 495
312 return ret; 496 return ret;
313} 497}
314 498EXPORT_SYMBOL_GPL(crypto_has_alg);
315static int __init init_crypto(void)
316{
317 printk(KERN_INFO "Initializing Cryptographic API\n");
318 crypto_init_proc();
319 return 0;
320}
321
322__initcall(init_crypto);
323
324EXPORT_SYMBOL_GPL(crypto_register_alg);
325EXPORT_SYMBOL_GPL(crypto_unregister_alg);
326EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
327EXPORT_SYMBOL_GPL(crypto_free_tfm);
328EXPORT_SYMBOL_GPL(crypto_alg_available);
diff --git a/crypto/arc4.c b/crypto/arc4.c
index 5edc6a65b987..8be47e13a9e3 100644
--- a/crypto/arc4.c
+++ b/crypto/arc4.c
@@ -25,7 +25,7 @@ struct arc4_ctx {
25}; 25};
26 26
27static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, 27static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key,
28 unsigned int key_len, u32 *flags) 28 unsigned int key_len)
29{ 29{
30 struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); 30 struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
31 int i, j = 0, k = 0; 31 int i, j = 0, k = 0;
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
new file mode 100644
index 000000000000..034c939bf91a
--- /dev/null
+++ b/crypto/blkcipher.c
@@ -0,0 +1,405 @@
1/*
2 * Block chaining cipher operations.
3 *
4 * Generic encrypt/decrypt wrapper for ciphers, handles operations across
5 * multiple page boundaries by using temporary blocks. In user context,
6 * the kernel is given a chance to schedule us once per page.
7 *
8 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 */
16
17#include <linux/crypto.h>
18#include <linux/errno.h>
19#include <linux/kernel.h>
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/scatterlist.h>
23#include <linux/seq_file.h>
24#include <linux/slab.h>
25#include <linux/string.h>
26
27#include "internal.h"
28#include "scatterwalk.h"
29
30enum {
31 BLKCIPHER_WALK_PHYS = 1 << 0,
32 BLKCIPHER_WALK_SLOW = 1 << 1,
33 BLKCIPHER_WALK_COPY = 1 << 2,
34 BLKCIPHER_WALK_DIFF = 1 << 3,
35};
36
37static int blkcipher_walk_next(struct blkcipher_desc *desc,
38 struct blkcipher_walk *walk);
39static int blkcipher_walk_first(struct blkcipher_desc *desc,
40 struct blkcipher_walk *walk);
41
42static inline void blkcipher_map_src(struct blkcipher_walk *walk)
43{
44 walk->src.virt.addr = scatterwalk_map(&walk->in, 0);
45}
46
47static inline void blkcipher_map_dst(struct blkcipher_walk *walk)
48{
49 walk->dst.virt.addr = scatterwalk_map(&walk->out, 1);
50}
51
52static inline void blkcipher_unmap_src(struct blkcipher_walk *walk)
53{
54 scatterwalk_unmap(walk->src.virt.addr, 0);
55}
56
57static inline void blkcipher_unmap_dst(struct blkcipher_walk *walk)
58{
59 scatterwalk_unmap(walk->dst.virt.addr, 1);
60}
61
62static inline u8 *blkcipher_get_spot(u8 *start, unsigned int len)
63{
64 if (offset_in_page(start + len) < len)
65 return (u8 *)((unsigned long)(start + len) & PAGE_MASK);
66 return start;
67}
68
69static inline unsigned int blkcipher_done_slow(struct crypto_blkcipher *tfm,
70 struct blkcipher_walk *walk,
71 unsigned int bsize)
72{
73 u8 *addr;
74 unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
75
76 addr = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1);
77 addr = blkcipher_get_spot(addr, bsize);
78 scatterwalk_copychunks(addr, &walk->out, bsize, 1);
79 return bsize;
80}
81
82static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk,
83 unsigned int n)
84{
85 n = walk->nbytes - n;
86
87 if (walk->flags & BLKCIPHER_WALK_COPY) {
88 blkcipher_map_dst(walk);
89 memcpy(walk->dst.virt.addr, walk->page, n);
90 blkcipher_unmap_dst(walk);
91 } else if (!(walk->flags & BLKCIPHER_WALK_PHYS)) {
92 blkcipher_unmap_src(walk);
93 if (walk->flags & BLKCIPHER_WALK_DIFF)
94 blkcipher_unmap_dst(walk);
95 }
96
97 scatterwalk_advance(&walk->in, n);
98 scatterwalk_advance(&walk->out, n);
99
100 return n;
101}
102
103int blkcipher_walk_done(struct blkcipher_desc *desc,
104 struct blkcipher_walk *walk, int err)
105{
106 struct crypto_blkcipher *tfm = desc->tfm;
107 unsigned int nbytes = 0;
108
109 if (likely(err >= 0)) {
110 unsigned int bsize = crypto_blkcipher_blocksize(tfm);
111 unsigned int n;
112
113 if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW)))
114 n = blkcipher_done_fast(walk, err);
115 else
116 n = blkcipher_done_slow(tfm, walk, bsize);
117
118 nbytes = walk->total - n;
119 err = 0;
120 }
121
122 scatterwalk_done(&walk->in, 0, nbytes);
123 scatterwalk_done(&walk->out, 1, nbytes);
124
125 walk->total = nbytes;
126 walk->nbytes = nbytes;
127
128 if (nbytes) {
129 crypto_yield(desc->flags);
130 return blkcipher_walk_next(desc, walk);
131 }
132
133 if (walk->iv != desc->info)
134 memcpy(desc->info, walk->iv, crypto_blkcipher_ivsize(tfm));
135 if (walk->buffer != walk->page)
136 kfree(walk->buffer);
137 if (walk->page)
138 free_page((unsigned long)walk->page);
139
140 return err;
141}
142EXPORT_SYMBOL_GPL(blkcipher_walk_done);
143
144static inline int blkcipher_next_slow(struct blkcipher_desc *desc,
145 struct blkcipher_walk *walk,
146 unsigned int bsize,
147 unsigned int alignmask)
148{
149 unsigned int n;
150
151 if (walk->buffer)
152 goto ok;
153
154 walk->buffer = walk->page;
155 if (walk->buffer)
156 goto ok;
157
158 n = bsize * 2 + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
159 walk->buffer = kmalloc(n, GFP_ATOMIC);
160 if (!walk->buffer)
161 return blkcipher_walk_done(desc, walk, -ENOMEM);
162
163ok:
164 walk->dst.virt.addr = (u8 *)ALIGN((unsigned long)walk->buffer,
165 alignmask + 1);
166 walk->dst.virt.addr = blkcipher_get_spot(walk->dst.virt.addr, bsize);
167 walk->src.virt.addr = blkcipher_get_spot(walk->dst.virt.addr + bsize,
168 bsize);
169
170 scatterwalk_copychunks(walk->src.virt.addr, &walk->in, bsize, 0);
171
172 walk->nbytes = bsize;
173 walk->flags |= BLKCIPHER_WALK_SLOW;
174
175 return 0;
176}
177
178static inline int blkcipher_next_copy(struct blkcipher_walk *walk)
179{
180 u8 *tmp = walk->page;
181
182 blkcipher_map_src(walk);
183 memcpy(tmp, walk->src.virt.addr, walk->nbytes);
184 blkcipher_unmap_src(walk);
185
186 walk->src.virt.addr = tmp;
187 walk->dst.virt.addr = tmp;
188
189 return 0;
190}
191
192static inline int blkcipher_next_fast(struct blkcipher_desc *desc,
193 struct blkcipher_walk *walk)
194{
195 unsigned long diff;
196
197 walk->src.phys.page = scatterwalk_page(&walk->in);
198 walk->src.phys.offset = offset_in_page(walk->in.offset);
199 walk->dst.phys.page = scatterwalk_page(&walk->out);
200 walk->dst.phys.offset = offset_in_page(walk->out.offset);
201
202 if (walk->flags & BLKCIPHER_WALK_PHYS)
203 return 0;
204
205 diff = walk->src.phys.offset - walk->dst.phys.offset;
206 diff |= walk->src.virt.page - walk->dst.virt.page;
207
208 blkcipher_map_src(walk);
209 walk->dst.virt.addr = walk->src.virt.addr;
210
211 if (diff) {
212 walk->flags |= BLKCIPHER_WALK_DIFF;
213 blkcipher_map_dst(walk);
214 }
215
216 return 0;
217}
218
219static int blkcipher_walk_next(struct blkcipher_desc *desc,
220 struct blkcipher_walk *walk)
221{
222 struct crypto_blkcipher *tfm = desc->tfm;
223 unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
224 unsigned int bsize = crypto_blkcipher_blocksize(tfm);
225 unsigned int n;
226 int err;
227
228 n = walk->total;
229 if (unlikely(n < bsize)) {
230 desc->flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
231 return blkcipher_walk_done(desc, walk, -EINVAL);
232 }
233
234 walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
235 BLKCIPHER_WALK_DIFF);
236 if (!scatterwalk_aligned(&walk->in, alignmask) ||
237 !scatterwalk_aligned(&walk->out, alignmask)) {
238 walk->flags |= BLKCIPHER_WALK_COPY;
239 if (!walk->page) {
240 walk->page = (void *)__get_free_page(GFP_ATOMIC);
241 if (!walk->page)
242 n = 0;
243 }
244 }
245
246 n = scatterwalk_clamp(&walk->in, n);
247 n = scatterwalk_clamp(&walk->out, n);
248
249 if (unlikely(n < bsize)) {
250 err = blkcipher_next_slow(desc, walk, bsize, alignmask);
251 goto set_phys_lowmem;
252 }
253
254 walk->nbytes = n;
255 if (walk->flags & BLKCIPHER_WALK_COPY) {
256 err = blkcipher_next_copy(walk);
257 goto set_phys_lowmem;
258 }
259
260 return blkcipher_next_fast(desc, walk);
261
262set_phys_lowmem:
263 if (walk->flags & BLKCIPHER_WALK_PHYS) {
264 walk->src.phys.page = virt_to_page(walk->src.virt.addr);
265 walk->dst.phys.page = virt_to_page(walk->dst.virt.addr);
266 walk->src.phys.offset &= PAGE_SIZE - 1;
267 walk->dst.phys.offset &= PAGE_SIZE - 1;
268 }
269 return err;
270}
271
272static inline int blkcipher_copy_iv(struct blkcipher_walk *walk,
273 struct crypto_blkcipher *tfm,
274 unsigned int alignmask)
275{
276 unsigned bs = crypto_blkcipher_blocksize(tfm);
277 unsigned int ivsize = crypto_blkcipher_ivsize(tfm);
278 unsigned int size = bs * 2 + ivsize + max(bs, ivsize) - (alignmask + 1);
279 u8 *iv;
280
281 size += alignmask & ~(crypto_tfm_ctx_alignment() - 1);
282 walk->buffer = kmalloc(size, GFP_ATOMIC);
283 if (!walk->buffer)
284 return -ENOMEM;
285
286 iv = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1);
287 iv = blkcipher_get_spot(iv, bs) + bs;
288 iv = blkcipher_get_spot(iv, bs) + bs;
289 iv = blkcipher_get_spot(iv, ivsize);
290
291 walk->iv = memcpy(iv, walk->iv, ivsize);
292 return 0;
293}
294
295int blkcipher_walk_virt(struct blkcipher_desc *desc,
296 struct blkcipher_walk *walk)
297{
298 walk->flags &= ~BLKCIPHER_WALK_PHYS;
299 return blkcipher_walk_first(desc, walk);
300}
301EXPORT_SYMBOL_GPL(blkcipher_walk_virt);
302
303int blkcipher_walk_phys(struct blkcipher_desc *desc,
304 struct blkcipher_walk *walk)
305{
306 walk->flags |= BLKCIPHER_WALK_PHYS;
307 return blkcipher_walk_first(desc, walk);
308}
309EXPORT_SYMBOL_GPL(blkcipher_walk_phys);
310
311static int blkcipher_walk_first(struct blkcipher_desc *desc,
312 struct blkcipher_walk *walk)
313{
314 struct crypto_blkcipher *tfm = desc->tfm;
315 unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
316
317 walk->nbytes = walk->total;
318 if (unlikely(!walk->total))
319 return 0;
320
321 walk->buffer = NULL;
322 walk->iv = desc->info;
323 if (unlikely(((unsigned long)walk->iv & alignmask))) {
324 int err = blkcipher_copy_iv(walk, tfm, alignmask);
325 if (err)
326 return err;
327 }
328
329 scatterwalk_start(&walk->in, walk->in.sg);
330 scatterwalk_start(&walk->out, walk->out.sg);
331 walk->page = NULL;
332
333 return blkcipher_walk_next(desc, walk);
334}
335
336static int setkey(struct crypto_tfm *tfm, const u8 *key,
337 unsigned int keylen)
338{
339 struct blkcipher_alg *cipher = &tfm->__crt_alg->cra_blkcipher;
340
341 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
342 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
343 return -EINVAL;
344 }
345
346 return cipher->setkey(tfm, key, keylen);
347}
348
349static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg)
350{
351 struct blkcipher_alg *cipher = &alg->cra_blkcipher;
352 unsigned int len = alg->cra_ctxsize;
353
354 if (cipher->ivsize) {
355 len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1);
356 len += cipher->ivsize;
357 }
358
359 return len;
360}
361
362static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm)
363{
364 struct blkcipher_tfm *crt = &tfm->crt_blkcipher;
365 struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
366 unsigned long align = crypto_tfm_alg_alignmask(tfm) + 1;
367 unsigned long addr;
368
369 if (alg->ivsize > PAGE_SIZE / 8)
370 return -EINVAL;
371
372 crt->setkey = setkey;
373 crt->encrypt = alg->encrypt;
374 crt->decrypt = alg->decrypt;
375
376 addr = (unsigned long)crypto_tfm_ctx(tfm);
377 addr = ALIGN(addr, align);
378 addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align);
379 crt->iv = (void *)addr;
380
381 return 0;
382}
383
384static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
385 __attribute_used__;
386static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
387{
388 seq_printf(m, "type : blkcipher\n");
389 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
390 seq_printf(m, "min keysize : %u\n", alg->cra_blkcipher.min_keysize);
391 seq_printf(m, "max keysize : %u\n", alg->cra_blkcipher.max_keysize);
392 seq_printf(m, "ivsize : %u\n", alg->cra_blkcipher.ivsize);
393}
394
395const struct crypto_type crypto_blkcipher_type = {
396 .ctxsize = crypto_blkcipher_ctxsize,
397 .init = crypto_init_blkcipher_ops,
398#ifdef CONFIG_PROC_FS
399 .show = crypto_blkcipher_show,
400#endif
401};
402EXPORT_SYMBOL_GPL(crypto_blkcipher_type);
403
404MODULE_LICENSE("GPL");
405MODULE_DESCRIPTION("Generic block chaining cipher type");
diff --git a/crypto/blowfish.c b/crypto/blowfish.c
index 490265f42b3b..55238c4e37f0 100644
--- a/crypto/blowfish.c
+++ b/crypto/blowfish.c
@@ -399,8 +399,7 @@ static void bf_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
399/* 399/*
400 * Calculates the blowfish S and P boxes for encryption and decryption. 400 * Calculates the blowfish S and P boxes for encryption and decryption.
401 */ 401 */
402static int bf_setkey(struct crypto_tfm *tfm, const u8 *key, 402static int bf_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
403 unsigned int keylen, u32 *flags)
404{ 403{
405 struct bf_ctx *ctx = crypto_tfm_ctx(tfm); 404 struct bf_ctx *ctx = crypto_tfm_ctx(tfm);
406 u32 *P = ctx->p; 405 u32 *P = ctx->p;
diff --git a/crypto/cast5.c b/crypto/cast5.c
index 08eef58c1d3d..13ea60abc19a 100644
--- a/crypto/cast5.c
+++ b/crypto/cast5.c
@@ -769,8 +769,7 @@ static void key_schedule(u32 * x, u32 * z, u32 * k)
769} 769}
770 770
771 771
772static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, 772static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned key_len)
773 unsigned key_len, u32 *flags)
774{ 773{
775 struct cast5_ctx *c = crypto_tfm_ctx(tfm); 774 struct cast5_ctx *c = crypto_tfm_ctx(tfm);
776 int i; 775 int i;
@@ -778,11 +777,6 @@ static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key,
778 u32 z[4]; 777 u32 z[4];
779 u32 k[16]; 778 u32 k[16];
780 __be32 p_key[4]; 779 __be32 p_key[4];
781
782 if (key_len < 5 || key_len > 16) {
783 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
784 return -EINVAL;
785 }
786 780
787 c->rr = key_len <= 10 ? 1 : 0; 781 c->rr = key_len <= 10 ? 1 : 0;
788 782
diff --git a/crypto/cast6.c b/crypto/cast6.c
index 08e33bfc3ad1..136ab6dfe8c5 100644
--- a/crypto/cast6.c
+++ b/crypto/cast6.c
@@ -382,14 +382,15 @@ static inline void W(u32 *key, unsigned int i) {
382} 382}
383 383
384static int cast6_setkey(struct crypto_tfm *tfm, const u8 *in_key, 384static int cast6_setkey(struct crypto_tfm *tfm, const u8 *in_key,
385 unsigned key_len, u32 *flags) 385 unsigned key_len)
386{ 386{
387 int i; 387 int i;
388 u32 key[8]; 388 u32 key[8];
389 __be32 p_key[8]; /* padded key */ 389 __be32 p_key[8]; /* padded key */
390 struct cast6_ctx *c = crypto_tfm_ctx(tfm); 390 struct cast6_ctx *c = crypto_tfm_ctx(tfm);
391 u32 *flags = &tfm->crt_flags;
391 392
392 if (key_len < 16 || key_len > 32 || key_len % 4 != 0) { 393 if (key_len % 4 != 0) {
393 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 394 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
394 return -EINVAL; 395 return -EINVAL;
395 } 396 }
diff --git a/crypto/cbc.c b/crypto/cbc.c
new file mode 100644
index 000000000000..f5542b4db387
--- /dev/null
+++ b/crypto/cbc.c
@@ -0,0 +1,344 @@
1/*
2 * CBC: Cipher Block Chaining mode
3 *
4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 */
12
13#include <crypto/algapi.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/scatterlist.h>
19#include <linux/slab.h>
20
21struct crypto_cbc_ctx {
22 struct crypto_cipher *child;
23 void (*xor)(u8 *dst, const u8 *src, unsigned int bs);
24};
25
26static int crypto_cbc_setkey(struct crypto_tfm *parent, const u8 *key,
27 unsigned int keylen)
28{
29 struct crypto_cbc_ctx *ctx = crypto_tfm_ctx(parent);
30 struct crypto_cipher *child = ctx->child;
31 int err;
32
33 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
34 crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
35 CRYPTO_TFM_REQ_MASK);
36 err = crypto_cipher_setkey(child, key, keylen);
37 crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
38 CRYPTO_TFM_RES_MASK);
39 return err;
40}
41
42static int crypto_cbc_encrypt_segment(struct blkcipher_desc *desc,
43 struct blkcipher_walk *walk,
44 struct crypto_cipher *tfm,
45 void (*xor)(u8 *, const u8 *,
46 unsigned int))
47{
48 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
49 crypto_cipher_alg(tfm)->cia_encrypt;
50 int bsize = crypto_cipher_blocksize(tfm);
51 unsigned int nbytes = walk->nbytes;
52 u8 *src = walk->src.virt.addr;
53 u8 *dst = walk->dst.virt.addr;
54 u8 *iv = walk->iv;
55
56 do {
57 xor(iv, src, bsize);
58 fn(crypto_cipher_tfm(tfm), dst, iv);
59 memcpy(iv, dst, bsize);
60
61 src += bsize;
62 dst += bsize;
63 } while ((nbytes -= bsize) >= bsize);
64
65 return nbytes;
66}
67
68static int crypto_cbc_encrypt_inplace(struct blkcipher_desc *desc,
69 struct blkcipher_walk *walk,
70 struct crypto_cipher *tfm,
71 void (*xor)(u8 *, const u8 *,
72 unsigned int))
73{
74 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
75 crypto_cipher_alg(tfm)->cia_encrypt;
76 int bsize = crypto_cipher_blocksize(tfm);
77 unsigned int nbytes = walk->nbytes;
78 u8 *src = walk->src.virt.addr;
79 u8 *iv = walk->iv;
80
81 do {
82 xor(src, iv, bsize);
83 fn(crypto_cipher_tfm(tfm), src, src);
84 iv = src;
85
86 src += bsize;
87 } while ((nbytes -= bsize) >= bsize);
88
89 memcpy(walk->iv, iv, bsize);
90
91 return nbytes;
92}
93
94static int crypto_cbc_encrypt(struct blkcipher_desc *desc,
95 struct scatterlist *dst, struct scatterlist *src,
96 unsigned int nbytes)
97{
98 struct blkcipher_walk walk;
99 struct crypto_blkcipher *tfm = desc->tfm;
100 struct crypto_cbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
101 struct crypto_cipher *child = ctx->child;
102 void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
103 int err;
104
105 blkcipher_walk_init(&walk, dst, src, nbytes);
106 err = blkcipher_walk_virt(desc, &walk);
107
108 while ((nbytes = walk.nbytes)) {
109 if (walk.src.virt.addr == walk.dst.virt.addr)
110 nbytes = crypto_cbc_encrypt_inplace(desc, &walk, child,
111 xor);
112 else
113 nbytes = crypto_cbc_encrypt_segment(desc, &walk, child,
114 xor);
115 err = blkcipher_walk_done(desc, &walk, nbytes);
116 }
117
118 return err;
119}
120
121static int crypto_cbc_decrypt_segment(struct blkcipher_desc *desc,
122 struct blkcipher_walk *walk,
123 struct crypto_cipher *tfm,
124 void (*xor)(u8 *, const u8 *,
125 unsigned int))
126{
127 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
128 crypto_cipher_alg(tfm)->cia_decrypt;
129 int bsize = crypto_cipher_blocksize(tfm);
130 unsigned int nbytes = walk->nbytes;
131 u8 *src = walk->src.virt.addr;
132 u8 *dst = walk->dst.virt.addr;
133 u8 *iv = walk->iv;
134
135 do {
136 fn(crypto_cipher_tfm(tfm), dst, src);
137 xor(dst, iv, bsize);
138 iv = src;
139
140 src += bsize;
141 dst += bsize;
142 } while ((nbytes -= bsize) >= bsize);
143
144 memcpy(walk->iv, iv, bsize);
145
146 return nbytes;
147}
148
149static int crypto_cbc_decrypt_inplace(struct blkcipher_desc *desc,
150 struct blkcipher_walk *walk,
151 struct crypto_cipher *tfm,
152 void (*xor)(u8 *, const u8 *,
153 unsigned int))
154{
155 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
156 crypto_cipher_alg(tfm)->cia_decrypt;
157 int bsize = crypto_cipher_blocksize(tfm);
158 unsigned long alignmask = crypto_cipher_alignmask(tfm);
159 unsigned int nbytes = walk->nbytes;
160 u8 *src = walk->src.virt.addr;
161 u8 stack[bsize + alignmask];
162 u8 *first_iv = (u8 *)ALIGN((unsigned long)stack, alignmask + 1);
163
164 memcpy(first_iv, walk->iv, bsize);
165
166 /* Start of the last block. */
167 src += nbytes - nbytes % bsize - bsize;
168 memcpy(walk->iv, src, bsize);
169
170 for (;;) {
171 fn(crypto_cipher_tfm(tfm), src, src);
172 if ((nbytes -= bsize) < bsize)
173 break;
174 xor(src, src - bsize, bsize);
175 src -= bsize;
176 }
177
178 xor(src, first_iv, bsize);
179
180 return nbytes;
181}
182
183static int crypto_cbc_decrypt(struct blkcipher_desc *desc,
184 struct scatterlist *dst, struct scatterlist *src,
185 unsigned int nbytes)
186{
187 struct blkcipher_walk walk;
188 struct crypto_blkcipher *tfm = desc->tfm;
189 struct crypto_cbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
190 struct crypto_cipher *child = ctx->child;
191 void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
192 int err;
193
194 blkcipher_walk_init(&walk, dst, src, nbytes);
195 err = blkcipher_walk_virt(desc, &walk);
196
197 while ((nbytes = walk.nbytes)) {
198 if (walk.src.virt.addr == walk.dst.virt.addr)
199 nbytes = crypto_cbc_decrypt_inplace(desc, &walk, child,
200 xor);
201 else
202 nbytes = crypto_cbc_decrypt_segment(desc, &walk, child,
203 xor);
204 err = blkcipher_walk_done(desc, &walk, nbytes);
205 }
206
207 return err;
208}
209
210static void xor_byte(u8 *a, const u8 *b, unsigned int bs)
211{
212 do {
213 *a++ ^= *b++;
214 } while (--bs);
215}
216
217static void xor_quad(u8 *dst, const u8 *src, unsigned int bs)
218{
219 u32 *a = (u32 *)dst;
220 u32 *b = (u32 *)src;
221
222 do {
223 *a++ ^= *b++;
224 } while ((bs -= 4));
225}
226
227static void xor_64(u8 *a, const u8 *b, unsigned int bs)
228{
229 ((u32 *)a)[0] ^= ((u32 *)b)[0];
230 ((u32 *)a)[1] ^= ((u32 *)b)[1];
231}
232
233static void xor_128(u8 *a, const u8 *b, unsigned int bs)
234{
235 ((u32 *)a)[0] ^= ((u32 *)b)[0];
236 ((u32 *)a)[1] ^= ((u32 *)b)[1];
237 ((u32 *)a)[2] ^= ((u32 *)b)[2];
238 ((u32 *)a)[3] ^= ((u32 *)b)[3];
239}
240
241static int crypto_cbc_init_tfm(struct crypto_tfm *tfm)
242{
243 struct crypto_instance *inst = (void *)tfm->__crt_alg;
244 struct crypto_spawn *spawn = crypto_instance_ctx(inst);
245 struct crypto_cbc_ctx *ctx = crypto_tfm_ctx(tfm);
246
247 switch (crypto_tfm_alg_blocksize(tfm)) {
248 case 8:
249 ctx->xor = xor_64;
250 break;
251
252 case 16:
253 ctx->xor = xor_128;
254 break;
255
256 default:
257 if (crypto_tfm_alg_blocksize(tfm) % 4)
258 ctx->xor = xor_byte;
259 else
260 ctx->xor = xor_quad;
261 }
262
263 tfm = crypto_spawn_tfm(spawn);
264 if (IS_ERR(tfm))
265 return PTR_ERR(tfm);
266
267 ctx->child = crypto_cipher_cast(tfm);
268 return 0;
269}
270
271static void crypto_cbc_exit_tfm(struct crypto_tfm *tfm)
272{
273 struct crypto_cbc_ctx *ctx = crypto_tfm_ctx(tfm);
274 crypto_free_cipher(ctx->child);
275}
276
277static struct crypto_instance *crypto_cbc_alloc(void *param, unsigned int len)
278{
279 struct crypto_instance *inst;
280 struct crypto_alg *alg;
281
282 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
283 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
284 if (IS_ERR(alg))
285 return ERR_PTR(PTR_ERR(alg));
286
287 inst = crypto_alloc_instance("cbc", alg);
288 if (IS_ERR(inst))
289 goto out_put_alg;
290
291 inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
292 inst->alg.cra_priority = alg->cra_priority;
293 inst->alg.cra_blocksize = alg->cra_blocksize;
294 inst->alg.cra_alignmask = alg->cra_alignmask;
295 inst->alg.cra_type = &crypto_blkcipher_type;
296
297 if (!(alg->cra_blocksize % 4))
298 inst->alg.cra_alignmask |= 3;
299 inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
300 inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
301 inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
302
303 inst->alg.cra_ctxsize = sizeof(struct crypto_cbc_ctx);
304
305 inst->alg.cra_init = crypto_cbc_init_tfm;
306 inst->alg.cra_exit = crypto_cbc_exit_tfm;
307
308 inst->alg.cra_blkcipher.setkey = crypto_cbc_setkey;
309 inst->alg.cra_blkcipher.encrypt = crypto_cbc_encrypt;
310 inst->alg.cra_blkcipher.decrypt = crypto_cbc_decrypt;
311
312out_put_alg:
313 crypto_mod_put(alg);
314 return inst;
315}
316
317static void crypto_cbc_free(struct crypto_instance *inst)
318{
319 crypto_drop_spawn(crypto_instance_ctx(inst));
320 kfree(inst);
321}
322
323static struct crypto_template crypto_cbc_tmpl = {
324 .name = "cbc",
325 .alloc = crypto_cbc_alloc,
326 .free = crypto_cbc_free,
327 .module = THIS_MODULE,
328};
329
330static int __init crypto_cbc_module_init(void)
331{
332 return crypto_register_template(&crypto_cbc_tmpl);
333}
334
335static void __exit crypto_cbc_module_exit(void)
336{
337 crypto_unregister_template(&crypto_cbc_tmpl);
338}
339
340module_init(crypto_cbc_module_init);
341module_exit(crypto_cbc_module_exit);
342
343MODULE_LICENSE("GPL");
344MODULE_DESCRIPTION("CBC block cipher algorithm");
diff --git a/crypto/cipher.c b/crypto/cipher.c
index b899eb97abd7..9e03701cfdcc 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -23,6 +23,28 @@
23#include "internal.h" 23#include "internal.h"
24#include "scatterwalk.h" 24#include "scatterwalk.h"
25 25
26struct cipher_alg_compat {
27 unsigned int cia_min_keysize;
28 unsigned int cia_max_keysize;
29 int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key,
30 unsigned int keylen);
31 void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
32 void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
33
34 unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc,
35 u8 *dst, const u8 *src,
36 unsigned int nbytes);
37 unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc,
38 u8 *dst, const u8 *src,
39 unsigned int nbytes);
40 unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc,
41 u8 *dst, const u8 *src,
42 unsigned int nbytes);
43 unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc,
44 u8 *dst, const u8 *src,
45 unsigned int nbytes);
46};
47
26static inline void xor_64(u8 *a, const u8 *b) 48static inline void xor_64(u8 *a, const u8 *b)
27{ 49{
28 ((u32 *)a)[0] ^= ((u32 *)b)[0]; 50 ((u32 *)a)[0] ^= ((u32 *)b)[0];
@@ -45,15 +67,10 @@ static unsigned int crypt_slow(const struct cipher_desc *desc,
45 u8 buffer[bsize * 2 + alignmask]; 67 u8 buffer[bsize * 2 + alignmask];
46 u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); 68 u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
47 u8 *dst = src + bsize; 69 u8 *dst = src + bsize;
48 unsigned int n;
49
50 n = scatterwalk_copychunks(src, in, bsize, 0);
51 scatterwalk_advance(in, n);
52 70
71 scatterwalk_copychunks(src, in, bsize, 0);
53 desc->prfn(desc, dst, src, bsize); 72 desc->prfn(desc, dst, src, bsize);
54 73 scatterwalk_copychunks(dst, out, bsize, 1);
55 n = scatterwalk_copychunks(dst, out, bsize, 1);
56 scatterwalk_advance(out, n);
57 74
58 return bsize; 75 return bsize;
59} 76}
@@ -64,12 +81,16 @@ static inline unsigned int crypt_fast(const struct cipher_desc *desc,
64 unsigned int nbytes, u8 *tmp) 81 unsigned int nbytes, u8 *tmp)
65{ 82{
66 u8 *src, *dst; 83 u8 *src, *dst;
84 u8 *real_src, *real_dst;
85
86 real_src = scatterwalk_map(in, 0);
87 real_dst = scatterwalk_map(out, 1);
67 88
68 src = in->data; 89 src = real_src;
69 dst = scatterwalk_samebuf(in, out) ? src : out->data; 90 dst = scatterwalk_samebuf(in, out) ? src : real_dst;
70 91
71 if (tmp) { 92 if (tmp) {
72 memcpy(tmp, in->data, nbytes); 93 memcpy(tmp, src, nbytes);
73 src = tmp; 94 src = tmp;
74 dst = tmp; 95 dst = tmp;
75 } 96 }
@@ -77,7 +98,10 @@ static inline unsigned int crypt_fast(const struct cipher_desc *desc,
77 nbytes = desc->prfn(desc, dst, src, nbytes); 98 nbytes = desc->prfn(desc, dst, src, nbytes);
78 99
79 if (tmp) 100 if (tmp)
80 memcpy(out->data, tmp, nbytes); 101 memcpy(real_dst, tmp, nbytes);
102
103 scatterwalk_unmap(real_src, 0);
104 scatterwalk_unmap(real_dst, 1);
81 105
82 scatterwalk_advance(in, nbytes); 106 scatterwalk_advance(in, nbytes);
83 scatterwalk_advance(out, nbytes); 107 scatterwalk_advance(out, nbytes);
@@ -126,9 +150,6 @@ static int crypt(const struct cipher_desc *desc,
126 tmp = (u8 *)buffer; 150 tmp = (u8 *)buffer;
127 } 151 }
128 152
129 scatterwalk_map(&walk_in, 0);
130 scatterwalk_map(&walk_out, 1);
131
132 n = scatterwalk_clamp(&walk_in, n); 153 n = scatterwalk_clamp(&walk_in, n);
133 n = scatterwalk_clamp(&walk_out, n); 154 n = scatterwalk_clamp(&walk_out, n);
134 155
@@ -145,7 +166,7 @@ static int crypt(const struct cipher_desc *desc,
145 if (!nbytes) 166 if (!nbytes)
146 break; 167 break;
147 168
148 crypto_yield(tfm); 169 crypto_yield(tfm->crt_flags);
149 } 170 }
150 171
151 if (buffer) 172 if (buffer)
@@ -264,12 +285,12 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
264{ 285{
265 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; 286 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
266 287
288 tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
267 if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { 289 if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
268 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 290 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
269 return -EINVAL; 291 return -EINVAL;
270 } else 292 } else
271 return cia->cia_setkey(tfm, key, keylen, 293 return cia->cia_setkey(tfm, key, keylen);
272 &tfm->crt_flags);
273} 294}
274 295
275static int ecb_encrypt(struct crypto_tfm *tfm, 296static int ecb_encrypt(struct crypto_tfm *tfm,
@@ -277,7 +298,7 @@ static int ecb_encrypt(struct crypto_tfm *tfm,
277 struct scatterlist *src, unsigned int nbytes) 298 struct scatterlist *src, unsigned int nbytes)
278{ 299{
279 struct cipher_desc desc; 300 struct cipher_desc desc;
280 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; 301 struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
281 302
282 desc.tfm = tfm; 303 desc.tfm = tfm;
283 desc.crfn = cipher->cia_encrypt; 304 desc.crfn = cipher->cia_encrypt;
@@ -292,7 +313,7 @@ static int ecb_decrypt(struct crypto_tfm *tfm,
292 unsigned int nbytes) 313 unsigned int nbytes)
293{ 314{
294 struct cipher_desc desc; 315 struct cipher_desc desc;
295 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; 316 struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
296 317
297 desc.tfm = tfm; 318 desc.tfm = tfm;
298 desc.crfn = cipher->cia_decrypt; 319 desc.crfn = cipher->cia_decrypt;
@@ -307,7 +328,7 @@ static int cbc_encrypt(struct crypto_tfm *tfm,
307 unsigned int nbytes) 328 unsigned int nbytes)
308{ 329{
309 struct cipher_desc desc; 330 struct cipher_desc desc;
310 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; 331 struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
311 332
312 desc.tfm = tfm; 333 desc.tfm = tfm;
313 desc.crfn = cipher->cia_encrypt; 334 desc.crfn = cipher->cia_encrypt;
@@ -323,7 +344,7 @@ static int cbc_encrypt_iv(struct crypto_tfm *tfm,
323 unsigned int nbytes, u8 *iv) 344 unsigned int nbytes, u8 *iv)
324{ 345{
325 struct cipher_desc desc; 346 struct cipher_desc desc;
326 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; 347 struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
327 348
328 desc.tfm = tfm; 349 desc.tfm = tfm;
329 desc.crfn = cipher->cia_encrypt; 350 desc.crfn = cipher->cia_encrypt;
@@ -339,7 +360,7 @@ static int cbc_decrypt(struct crypto_tfm *tfm,
339 unsigned int nbytes) 360 unsigned int nbytes)
340{ 361{
341 struct cipher_desc desc; 362 struct cipher_desc desc;
342 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; 363 struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
343 364
344 desc.tfm = tfm; 365 desc.tfm = tfm;
345 desc.crfn = cipher->cia_decrypt; 366 desc.crfn = cipher->cia_decrypt;
@@ -355,7 +376,7 @@ static int cbc_decrypt_iv(struct crypto_tfm *tfm,
355 unsigned int nbytes, u8 *iv) 376 unsigned int nbytes, u8 *iv)
356{ 377{
357 struct cipher_desc desc; 378 struct cipher_desc desc;
358 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; 379 struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
359 380
360 desc.tfm = tfm; 381 desc.tfm = tfm;
361 desc.crfn = cipher->cia_decrypt; 382 desc.crfn = cipher->cia_decrypt;
@@ -388,17 +409,67 @@ int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
388 return 0; 409 return 0;
389} 410}
390 411
412static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *,
413 const u8 *),
414 struct crypto_tfm *tfm,
415 u8 *dst, const u8 *src)
416{
417 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
418 unsigned int size = crypto_tfm_alg_blocksize(tfm);
419 u8 buffer[size + alignmask];
420 u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
421
422 memcpy(tmp, src, size);
423 fn(tfm, tmp, tmp);
424 memcpy(dst, tmp, size);
425}
426
427static void cipher_encrypt_unaligned(struct crypto_tfm *tfm,
428 u8 *dst, const u8 *src)
429{
430 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
431 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
432
433 if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) {
434 cipher_crypt_unaligned(cipher->cia_encrypt, tfm, dst, src);
435 return;
436 }
437
438 cipher->cia_encrypt(tfm, dst, src);
439}
440
441static void cipher_decrypt_unaligned(struct crypto_tfm *tfm,
442 u8 *dst, const u8 *src)
443{
444 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
445 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
446
447 if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) {
448 cipher_crypt_unaligned(cipher->cia_decrypt, tfm, dst, src);
449 return;
450 }
451
452 cipher->cia_decrypt(tfm, dst, src);
453}
454
391int crypto_init_cipher_ops(struct crypto_tfm *tfm) 455int crypto_init_cipher_ops(struct crypto_tfm *tfm)
392{ 456{
393 int ret = 0; 457 int ret = 0;
394 struct cipher_tfm *ops = &tfm->crt_cipher; 458 struct cipher_tfm *ops = &tfm->crt_cipher;
459 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
395 460
396 ops->cit_setkey = setkey; 461 ops->cit_setkey = setkey;
462 ops->cit_encrypt_one = crypto_tfm_alg_alignmask(tfm) ?
463 cipher_encrypt_unaligned : cipher->cia_encrypt;
464 ops->cit_decrypt_one = crypto_tfm_alg_alignmask(tfm) ?
465 cipher_decrypt_unaligned : cipher->cia_decrypt;
397 466
398 switch (tfm->crt_cipher.cit_mode) { 467 switch (tfm->crt_cipher.cit_mode) {
399 case CRYPTO_TFM_MODE_ECB: 468 case CRYPTO_TFM_MODE_ECB:
400 ops->cit_encrypt = ecb_encrypt; 469 ops->cit_encrypt = ecb_encrypt;
401 ops->cit_decrypt = ecb_decrypt; 470 ops->cit_decrypt = ecb_decrypt;
471 ops->cit_encrypt_iv = nocrypt_iv;
472 ops->cit_decrypt_iv = nocrypt_iv;
402 break; 473 break;
403 474
404 case CRYPTO_TFM_MODE_CBC: 475 case CRYPTO_TFM_MODE_CBC:
diff --git a/crypto/crc32c.c b/crypto/crc32c.c
index f2660123aeb4..0fa744392a4c 100644
--- a/crypto/crc32c.c
+++ b/crypto/crc32c.c
@@ -16,14 +16,14 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/crypto.h> 17#include <linux/crypto.h>
18#include <linux/crc32c.h> 18#include <linux/crc32c.h>
19#include <linux/types.h> 19#include <linux/kernel.h>
20#include <asm/byteorder.h>
21 20
22#define CHKSUM_BLOCK_SIZE 32 21#define CHKSUM_BLOCK_SIZE 32
23#define CHKSUM_DIGEST_SIZE 4 22#define CHKSUM_DIGEST_SIZE 4
24 23
25struct chksum_ctx { 24struct chksum_ctx {
26 u32 crc; 25 u32 crc;
26 u32 key;
27}; 27};
28 28
29/* 29/*
@@ -35,7 +35,7 @@ static void chksum_init(struct crypto_tfm *tfm)
35{ 35{
36 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); 36 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
37 37
38 mctx->crc = ~(u32)0; /* common usage */ 38 mctx->crc = mctx->key;
39} 39}
40 40
41/* 41/*
@@ -44,16 +44,15 @@ static void chksum_init(struct crypto_tfm *tfm)
44 * the seed. 44 * the seed.
45 */ 45 */
46static int chksum_setkey(struct crypto_tfm *tfm, const u8 *key, 46static int chksum_setkey(struct crypto_tfm *tfm, const u8 *key,
47 unsigned int keylen, u32 *flags) 47 unsigned int keylen)
48{ 48{
49 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); 49 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
50 50
51 if (keylen != sizeof(mctx->crc)) { 51 if (keylen != sizeof(mctx->crc)) {
52 if (flags) 52 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
53 *flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
54 return -EINVAL; 53 return -EINVAL;
55 } 54 }
56 mctx->crc = __cpu_to_le32(*(u32 *)key); 55 mctx->key = le32_to_cpu(*(__le32 *)key);
57 return 0; 56 return 0;
58} 57}
59 58
@@ -61,19 +60,23 @@ static void chksum_update(struct crypto_tfm *tfm, const u8 *data,
61 unsigned int length) 60 unsigned int length)
62{ 61{
63 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); 62 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
64 u32 mcrc;
65 63
66 mcrc = crc32c(mctx->crc, data, (size_t)length); 64 mctx->crc = crc32c(mctx->crc, data, length);
67
68 mctx->crc = mcrc;
69} 65}
70 66
71static void chksum_final(struct crypto_tfm *tfm, u8 *out) 67static void chksum_final(struct crypto_tfm *tfm, u8 *out)
72{ 68{
73 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); 69 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
74 u32 mcrc = (mctx->crc ^ ~(u32)0);
75 70
76 *(u32 *)out = __le32_to_cpu(mcrc); 71 *(__le32 *)out = ~cpu_to_le32(mctx->crc);
72}
73
74static int crc32c_cra_init(struct crypto_tfm *tfm)
75{
76 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
77
78 mctx->key = ~0;
79 return 0;
77} 80}
78 81
79static struct crypto_alg alg = { 82static struct crypto_alg alg = {
@@ -83,6 +86,7 @@ static struct crypto_alg alg = {
83 .cra_ctxsize = sizeof(struct chksum_ctx), 86 .cra_ctxsize = sizeof(struct chksum_ctx),
84 .cra_module = THIS_MODULE, 87 .cra_module = THIS_MODULE,
85 .cra_list = LIST_HEAD_INIT(alg.cra_list), 88 .cra_list = LIST_HEAD_INIT(alg.cra_list),
89 .cra_init = crc32c_cra_init,
86 .cra_u = { 90 .cra_u = {
87 .digest = { 91 .digest = {
88 .dia_digestsize= CHKSUM_DIGEST_SIZE, 92 .dia_digestsize= CHKSUM_DIGEST_SIZE,
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c
index a0d956b52949..24dbb5d8617e 100644
--- a/crypto/crypto_null.c
+++ b/crypto/crypto_null.c
@@ -48,7 +48,7 @@ static void null_final(struct crypto_tfm *tfm, u8 *out)
48{ } 48{ }
49 49
50static int null_setkey(struct crypto_tfm *tfm, const u8 *key, 50static int null_setkey(struct crypto_tfm *tfm, const u8 *key,
51 unsigned int keylen, u32 *flags) 51 unsigned int keylen)
52{ return 0; } 52{ return 0; }
53 53
54static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 54static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c
new file mode 100644
index 000000000000..9b5b15601068
--- /dev/null
+++ b/crypto/cryptomgr.c
@@ -0,0 +1,156 @@
1/*
2 * Create default crypto algorithm instances.
3 *
4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 */
12
13#include <linux/crypto.h>
14#include <linux/ctype.h>
15#include <linux/err.h>
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/notifier.h>
19#include <linux/rtnetlink.h>
20#include <linux/sched.h>
21#include <linux/string.h>
22#include <linux/workqueue.h>
23
24#include "internal.h"
25
26struct cryptomgr_param {
27 struct work_struct work;
28
29 struct {
30 struct rtattr attr;
31 struct crypto_attr_alg data;
32 } alg;
33
34 struct {
35 u32 type;
36 u32 mask;
37 char name[CRYPTO_MAX_ALG_NAME];
38 } larval;
39
40 char template[CRYPTO_MAX_ALG_NAME];
41};
42
43static void cryptomgr_probe(void *data)
44{
45 struct cryptomgr_param *param = data;
46 struct crypto_template *tmpl;
47 struct crypto_instance *inst;
48 int err;
49
50 tmpl = crypto_lookup_template(param->template);
51 if (!tmpl)
52 goto err;
53
54 do {
55 inst = tmpl->alloc(&param->alg, sizeof(param->alg));
56 if (IS_ERR(inst))
57 err = PTR_ERR(inst);
58 else if ((err = crypto_register_instance(tmpl, inst)))
59 tmpl->free(inst);
60 } while (err == -EAGAIN && !signal_pending(current));
61
62 crypto_tmpl_put(tmpl);
63
64 if (err)
65 goto err;
66
67out:
68 kfree(param);
69 return;
70
71err:
72 crypto_larval_error(param->larval.name, param->larval.type,
73 param->larval.mask);
74 goto out;
75}
76
77static int cryptomgr_schedule_probe(struct crypto_larval *larval)
78{
79 struct cryptomgr_param *param;
80 const char *name = larval->alg.cra_name;
81 const char *p;
82 unsigned int len;
83
84 param = kmalloc(sizeof(*param), GFP_KERNEL);
85 if (!param)
86 goto err;
87
88 for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++)
89 ;
90
91 len = p - name;
92 if (!len || *p != '(')
93 goto err_free_param;
94
95 memcpy(param->template, name, len);
96 param->template[len] = 0;
97
98 name = p + 1;
99 for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++)
100 ;
101
102 len = p - name;
103 if (!len || *p != ')' || p[1])
104 goto err_free_param;
105
106 param->alg.attr.rta_len = sizeof(param->alg);
107 param->alg.attr.rta_type = CRYPTOA_ALG;
108 memcpy(param->alg.data.name, name, len);
109 param->alg.data.name[len] = 0;
110
111 memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
112 param->larval.type = larval->alg.cra_flags;
113 param->larval.mask = larval->mask;
114
115 INIT_WORK(&param->work, cryptomgr_probe, param);
116 schedule_work(&param->work);
117
118 return NOTIFY_STOP;
119
120err_free_param:
121 kfree(param);
122err:
123 return NOTIFY_OK;
124}
125
126static int cryptomgr_notify(struct notifier_block *this, unsigned long msg,
127 void *data)
128{
129 switch (msg) {
130 case CRYPTO_MSG_ALG_REQUEST:
131 return cryptomgr_schedule_probe(data);
132 }
133
134 return NOTIFY_DONE;
135}
136
137static struct notifier_block cryptomgr_notifier = {
138 .notifier_call = cryptomgr_notify,
139};
140
141static int __init cryptomgr_init(void)
142{
143 return crypto_register_notifier(&cryptomgr_notifier);
144}
145
146static void __exit cryptomgr_exit(void)
147{
148 int err = crypto_unregister_notifier(&cryptomgr_notifier);
149 BUG_ON(err);
150}
151
152module_init(cryptomgr_init);
153module_exit(cryptomgr_exit);
154
155MODULE_LICENSE("GPL");
156MODULE_DESCRIPTION("Crypto Algorithm Manager");
diff --git a/crypto/des.c b/crypto/des.c
index a9d3c235a6af..1df3a714fa47 100644
--- a/crypto/des.c
+++ b/crypto/des.c
@@ -784,9 +784,10 @@ static void dkey(u32 *pe, const u8 *k)
784} 784}
785 785
786static int des_setkey(struct crypto_tfm *tfm, const u8 *key, 786static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
787 unsigned int keylen, u32 *flags) 787 unsigned int keylen)
788{ 788{
789 struct des_ctx *dctx = crypto_tfm_ctx(tfm); 789 struct des_ctx *dctx = crypto_tfm_ctx(tfm);
790 u32 *flags = &tfm->crt_flags;
790 u32 tmp[DES_EXPKEY_WORDS]; 791 u32 tmp[DES_EXPKEY_WORDS];
791 int ret; 792 int ret;
792 793
@@ -864,11 +865,12 @@ static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
864 * 865 *
865 */ 866 */
866static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, 867static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
867 unsigned int keylen, u32 *flags) 868 unsigned int keylen)
868{ 869{
869 const u32 *K = (const u32 *)key; 870 const u32 *K = (const u32 *)key;
870 struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); 871 struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
871 u32 *expkey = dctx->expkey; 872 u32 *expkey = dctx->expkey;
873 u32 *flags = &tfm->crt_flags;
872 874
873 if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || 875 if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
874 !((K[2] ^ K[4]) | (K[3] ^ K[5])))) 876 !((K[2] ^ K[4]) | (K[3] ^ K[5]))))
diff --git a/crypto/digest.c b/crypto/digest.c
index 603006a7bef2..0155a94e4b15 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -11,29 +11,89 @@
11 * any later version. 11 * any later version.
12 * 12 *
13 */ 13 */
14#include <linux/crypto.h> 14
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/highmem.h> 17#include <linux/highmem.h>
18#include <asm/scatterlist.h> 18#include <linux/module.h>
19#include <linux/scatterlist.h>
20
19#include "internal.h" 21#include "internal.h"
22#include "scatterwalk.h"
20 23
21static void init(struct crypto_tfm *tfm) 24void crypto_digest_init(struct crypto_tfm *tfm)
22{ 25{
23 tfm->__crt_alg->cra_digest.dia_init(tfm); 26 struct crypto_hash *hash = crypto_hash_cast(tfm);
27 struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
28
29 crypto_hash_init(&desc);
30}
31EXPORT_SYMBOL_GPL(crypto_digest_init);
32
33void crypto_digest_update(struct crypto_tfm *tfm,
34 struct scatterlist *sg, unsigned int nsg)
35{
36 struct crypto_hash *hash = crypto_hash_cast(tfm);
37 struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
38 unsigned int nbytes = 0;
39 unsigned int i;
40
41 for (i = 0; i < nsg; i++)
42 nbytes += sg[i].length;
43
44 crypto_hash_update(&desc, sg, nbytes);
45}
46EXPORT_SYMBOL_GPL(crypto_digest_update);
47
48void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
49{
50 struct crypto_hash *hash = crypto_hash_cast(tfm);
51 struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
52
53 crypto_hash_final(&desc, out);
24} 54}
55EXPORT_SYMBOL_GPL(crypto_digest_final);
25 56
26static void update(struct crypto_tfm *tfm, 57void crypto_digest_digest(struct crypto_tfm *tfm,
27 struct scatterlist *sg, unsigned int nsg) 58 struct scatterlist *sg, unsigned int nsg, u8 *out)
28{ 59{
60 struct crypto_hash *hash = crypto_hash_cast(tfm);
61 struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
62 unsigned int nbytes = 0;
29 unsigned int i; 63 unsigned int i;
64
65 for (i = 0; i < nsg; i++)
66 nbytes += sg[i].length;
67
68 crypto_hash_digest(&desc, sg, nbytes, out);
69}
70EXPORT_SYMBOL_GPL(crypto_digest_digest);
71
72static int init(struct hash_desc *desc)
73{
74 struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
75
76 tfm->__crt_alg->cra_digest.dia_init(tfm);
77 return 0;
78}
79
80static int update(struct hash_desc *desc,
81 struct scatterlist *sg, unsigned int nbytes)
82{
83 struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
30 unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); 84 unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
31 85
32 for (i = 0; i < nsg; i++) { 86 if (!nbytes)
87 return 0;
88
89 for (;;) {
90 struct page *pg = sg->page;
91 unsigned int offset = sg->offset;
92 unsigned int l = sg->length;
33 93
34 struct page *pg = sg[i].page; 94 if (unlikely(l > nbytes))
35 unsigned int offset = sg[i].offset; 95 l = nbytes;
36 unsigned int l = sg[i].length; 96 nbytes -= l;
37 97
38 do { 98 do {
39 unsigned int bytes_from_page = min(l, ((unsigned int) 99 unsigned int bytes_from_page = min(l, ((unsigned int)
@@ -55,41 +115,60 @@ static void update(struct crypto_tfm *tfm,
55 tfm->__crt_alg->cra_digest.dia_update(tfm, p, 115 tfm->__crt_alg->cra_digest.dia_update(tfm, p,
56 bytes_from_page); 116 bytes_from_page);
57 crypto_kunmap(src, 0); 117 crypto_kunmap(src, 0);
58 crypto_yield(tfm); 118 crypto_yield(desc->flags);
59 offset = 0; 119 offset = 0;
60 pg++; 120 pg++;
61 l -= bytes_from_page; 121 l -= bytes_from_page;
62 } while (l > 0); 122 } while (l > 0);
123
124 if (!nbytes)
125 break;
126 sg = sg_next(sg);
63 } 127 }
128
129 return 0;
64} 130}
65 131
66static void final(struct crypto_tfm *tfm, u8 *out) 132static int final(struct hash_desc *desc, u8 *out)
67{ 133{
134 struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
68 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); 135 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
136 struct digest_alg *digest = &tfm->__crt_alg->cra_digest;
137
69 if (unlikely((unsigned long)out & alignmask)) { 138 if (unlikely((unsigned long)out & alignmask)) {
70 unsigned int size = crypto_tfm_alg_digestsize(tfm); 139 unsigned long align = alignmask + 1;
71 u8 buffer[size + alignmask]; 140 unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm);
72 u8 *dst = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); 141 u8 *dst = (u8 *)ALIGN(addr, align) +
73 tfm->__crt_alg->cra_digest.dia_final(tfm, dst); 142 ALIGN(tfm->__crt_alg->cra_ctxsize, align);
74 memcpy(out, dst, size); 143
144 digest->dia_final(tfm, dst);
145 memcpy(out, dst, digest->dia_digestsize);
75 } else 146 } else
76 tfm->__crt_alg->cra_digest.dia_final(tfm, out); 147 digest->dia_final(tfm, out);
148
149 return 0;
150}
151
152static int nosetkey(struct crypto_hash *tfm, const u8 *key, unsigned int keylen)
153{
154 crypto_hash_clear_flags(tfm, CRYPTO_TFM_RES_MASK);
155 return -ENOSYS;
77} 156}
78 157
79static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) 158static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen)
80{ 159{
81 u32 flags; 160 struct crypto_tfm *tfm = crypto_hash_tfm(hash);
82 if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) 161
83 return -ENOSYS; 162 crypto_hash_clear_flags(hash, CRYPTO_TFM_RES_MASK);
84 return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen, &flags); 163 return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen);
85} 164}
86 165
87static void digest(struct crypto_tfm *tfm, 166static int digest(struct hash_desc *desc,
88 struct scatterlist *sg, unsigned int nsg, u8 *out) 167 struct scatterlist *sg, unsigned int nbytes, u8 *out)
89{ 168{
90 init(tfm); 169 init(desc);
91 update(tfm, sg, nsg); 170 update(desc, sg, nbytes);
92 final(tfm, out); 171 return final(desc, out);
93} 172}
94 173
95int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) 174int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
@@ -99,18 +178,22 @@ int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
99 178
100int crypto_init_digest_ops(struct crypto_tfm *tfm) 179int crypto_init_digest_ops(struct crypto_tfm *tfm)
101{ 180{
102 struct digest_tfm *ops = &tfm->crt_digest; 181 struct hash_tfm *ops = &tfm->crt_hash;
182 struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
183
184 if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm))
185 return -EINVAL;
103 186
104 ops->dit_init = init; 187 ops->init = init;
105 ops->dit_update = update; 188 ops->update = update;
106 ops->dit_final = final; 189 ops->final = final;
107 ops->dit_digest = digest; 190 ops->digest = digest;
108 ops->dit_setkey = setkey; 191 ops->setkey = dalg->dia_setkey ? setkey : nosetkey;
192 ops->digestsize = dalg->dia_digestsize;
109 193
110 return crypto_alloc_hmac_block(tfm); 194 return 0;
111} 195}
112 196
113void crypto_exit_digest_ops(struct crypto_tfm *tfm) 197void crypto_exit_digest_ops(struct crypto_tfm *tfm)
114{ 198{
115 crypto_free_hmac_block(tfm);
116} 199}
diff --git a/crypto/ecb.c b/crypto/ecb.c
new file mode 100644
index 000000000000..f239aa9c4017
--- /dev/null
+++ b/crypto/ecb.c
@@ -0,0 +1,181 @@
1/*
2 * ECB: Electronic CodeBook mode
3 *
4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 */
12
13#include <crypto/algapi.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/scatterlist.h>
19#include <linux/slab.h>
20
21struct crypto_ecb_ctx {
22 struct crypto_cipher *child;
23};
24
25static int crypto_ecb_setkey(struct crypto_tfm *parent, const u8 *key,
26 unsigned int keylen)
27{
28 struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(parent);
29 struct crypto_cipher *child = ctx->child;
30 int err;
31
32 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
33 crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
34 CRYPTO_TFM_REQ_MASK);
35 err = crypto_cipher_setkey(child, key, keylen);
36 crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
37 CRYPTO_TFM_RES_MASK);
38 return err;
39}
40
41static int crypto_ecb_crypt(struct blkcipher_desc *desc,
42 struct blkcipher_walk *walk,
43 struct crypto_cipher *tfm,
44 void (*fn)(struct crypto_tfm *, u8 *, const u8 *))
45{
46 int bsize = crypto_cipher_blocksize(tfm);
47 unsigned int nbytes;
48 int err;
49
50 err = blkcipher_walk_virt(desc, walk);
51
52 while ((nbytes = walk->nbytes)) {
53 u8 *wsrc = walk->src.virt.addr;
54 u8 *wdst = walk->dst.virt.addr;
55
56 do {
57 fn(crypto_cipher_tfm(tfm), wdst, wsrc);
58
59 wsrc += bsize;
60 wdst += bsize;
61 } while ((nbytes -= bsize) >= bsize);
62
63 err = blkcipher_walk_done(desc, walk, nbytes);
64 }
65
66 return err;
67}
68
69static int crypto_ecb_encrypt(struct blkcipher_desc *desc,
70 struct scatterlist *dst, struct scatterlist *src,
71 unsigned int nbytes)
72{
73 struct blkcipher_walk walk;
74 struct crypto_blkcipher *tfm = desc->tfm;
75 struct crypto_ecb_ctx *ctx = crypto_blkcipher_ctx(tfm);
76 struct crypto_cipher *child = ctx->child;
77
78 blkcipher_walk_init(&walk, dst, src, nbytes);
79 return crypto_ecb_crypt(desc, &walk, child,
80 crypto_cipher_alg(child)->cia_encrypt);
81}
82
83static int crypto_ecb_decrypt(struct blkcipher_desc *desc,
84 struct scatterlist *dst, struct scatterlist *src,
85 unsigned int nbytes)
86{
87 struct blkcipher_walk walk;
88 struct crypto_blkcipher *tfm = desc->tfm;
89 struct crypto_ecb_ctx *ctx = crypto_blkcipher_ctx(tfm);
90 struct crypto_cipher *child = ctx->child;
91
92 blkcipher_walk_init(&walk, dst, src, nbytes);
93 return crypto_ecb_crypt(desc, &walk, child,
94 crypto_cipher_alg(child)->cia_decrypt);
95}
96
97static int crypto_ecb_init_tfm(struct crypto_tfm *tfm)
98{
99 struct crypto_instance *inst = (void *)tfm->__crt_alg;
100 struct crypto_spawn *spawn = crypto_instance_ctx(inst);
101 struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(tfm);
102
103 tfm = crypto_spawn_tfm(spawn);
104 if (IS_ERR(tfm))
105 return PTR_ERR(tfm);
106
107 ctx->child = crypto_cipher_cast(tfm);
108 return 0;
109}
110
111static void crypto_ecb_exit_tfm(struct crypto_tfm *tfm)
112{
113 struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(tfm);
114 crypto_free_cipher(ctx->child);
115}
116
117static struct crypto_instance *crypto_ecb_alloc(void *param, unsigned int len)
118{
119 struct crypto_instance *inst;
120 struct crypto_alg *alg;
121
122 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
123 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
124 if (IS_ERR(alg))
125 return ERR_PTR(PTR_ERR(alg));
126
127 inst = crypto_alloc_instance("ecb", alg);
128 if (IS_ERR(inst))
129 goto out_put_alg;
130
131 inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
132 inst->alg.cra_priority = alg->cra_priority;
133 inst->alg.cra_blocksize = alg->cra_blocksize;
134 inst->alg.cra_alignmask = alg->cra_alignmask;
135 inst->alg.cra_type = &crypto_blkcipher_type;
136
137 inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
138 inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
139
140 inst->alg.cra_ctxsize = sizeof(struct crypto_ecb_ctx);
141
142 inst->alg.cra_init = crypto_ecb_init_tfm;
143 inst->alg.cra_exit = crypto_ecb_exit_tfm;
144
145 inst->alg.cra_blkcipher.setkey = crypto_ecb_setkey;
146 inst->alg.cra_blkcipher.encrypt = crypto_ecb_encrypt;
147 inst->alg.cra_blkcipher.decrypt = crypto_ecb_decrypt;
148
149out_put_alg:
150 crypto_mod_put(alg);
151 return inst;
152}
153
154static void crypto_ecb_free(struct crypto_instance *inst)
155{
156 crypto_drop_spawn(crypto_instance_ctx(inst));
157 kfree(inst);
158}
159
160static struct crypto_template crypto_ecb_tmpl = {
161 .name = "ecb",
162 .alloc = crypto_ecb_alloc,
163 .free = crypto_ecb_free,
164 .module = THIS_MODULE,
165};
166
167static int __init crypto_ecb_module_init(void)
168{
169 return crypto_register_template(&crypto_ecb_tmpl);
170}
171
172static void __exit crypto_ecb_module_exit(void)
173{
174 crypto_unregister_template(&crypto_ecb_tmpl);
175}
176
177module_init(crypto_ecb_module_init);
178module_exit(crypto_ecb_module_exit);
179
180MODULE_LICENSE("GPL");
181MODULE_DESCRIPTION("ECB block cipher algorithm");
diff --git a/crypto/hash.c b/crypto/hash.c
new file mode 100644
index 000000000000..cdec23d885fe
--- /dev/null
+++ b/crypto/hash.c
@@ -0,0 +1,61 @@
1/*
2 * Cryptographic Hash operations.
3 *
4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 */
11
12#include <linux/errno.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/seq_file.h>
16
17#include "internal.h"
18
19static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg)
20{
21 return alg->cra_ctxsize;
22}
23
24static int crypto_init_hash_ops(struct crypto_tfm *tfm)
25{
26 struct hash_tfm *crt = &tfm->crt_hash;
27 struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
28
29 if (alg->digestsize > crypto_tfm_alg_blocksize(tfm))
30 return -EINVAL;
31
32 crt->init = alg->init;
33 crt->update = alg->update;
34 crt->final = alg->final;
35 crt->digest = alg->digest;
36 crt->setkey = alg->setkey;
37 crt->digestsize = alg->digestsize;
38
39 return 0;
40}
41
42static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
43 __attribute_used__;
44static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
45{
46 seq_printf(m, "type : hash\n");
47 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
48 seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize);
49}
50
51const struct crypto_type crypto_hash_type = {
52 .ctxsize = crypto_hash_ctxsize,
53 .init = crypto_init_hash_ops,
54#ifdef CONFIG_PROC_FS
55 .show = crypto_hash_show,
56#endif
57};
58EXPORT_SYMBOL_GPL(crypto_hash_type);
59
60MODULE_LICENSE("GPL");
61MODULE_DESCRIPTION("Generic cryptographic hash type");
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 46120dee5ada..f403b6946047 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -4,121 +4,249 @@
4 * HMAC: Keyed-Hashing for Message Authentication (RFC2104). 4 * HMAC: Keyed-Hashing for Message Authentication (RFC2104).
5 * 5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
7 * 8 *
8 * The HMAC implementation is derived from USAGI. 9 * The HMAC implementation is derived from USAGI.
9 * Copyright (c) 2002 Kazunori Miyazawa <miyazawa@linux-ipv6.org> / USAGI 10 * Copyright (c) 2002 Kazunori Miyazawa <miyazawa@linux-ipv6.org> / USAGI
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify it 12 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free 13 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option) 14 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version. 15 * any later version.
15 * 16 *
16 */ 17 */
17#include <linux/crypto.h> 18
18#include <linux/mm.h> 19#include <crypto/algapi.h>
19#include <linux/highmem.h> 20#include <linux/err.h>
20#include <linux/slab.h> 21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
21#include <linux/scatterlist.h> 24#include <linux/scatterlist.h>
22#include "internal.h" 25#include <linux/slab.h>
26#include <linux/string.h>
23 27
24static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen) 28struct hmac_ctx {
29 struct crypto_hash *child;
30};
31
32static inline void *align_ptr(void *p, unsigned int align)
25{ 33{
26 struct scatterlist tmp; 34 return (void *)ALIGN((unsigned long)p, align);
27
28 sg_set_buf(&tmp, key, keylen);
29 crypto_digest_digest(tfm, &tmp, 1, key);
30} 35}
31 36
32int crypto_alloc_hmac_block(struct crypto_tfm *tfm) 37static inline struct hmac_ctx *hmac_ctx(struct crypto_hash *tfm)
33{ 38{
34 int ret = 0; 39 return align_ptr(crypto_hash_ctx_aligned(tfm) +
40 crypto_hash_blocksize(tfm) * 2 +
41 crypto_hash_digestsize(tfm), sizeof(void *));
42}
43
44static int hmac_setkey(struct crypto_hash *parent,
45 const u8 *inkey, unsigned int keylen)
46{
47 int bs = crypto_hash_blocksize(parent);
48 int ds = crypto_hash_digestsize(parent);
49 char *ipad = crypto_hash_ctx_aligned(parent);
50 char *opad = ipad + bs;
51 char *digest = opad + bs;
52 struct hmac_ctx *ctx = align_ptr(digest + ds, sizeof(void *));
53 struct crypto_hash *tfm = ctx->child;
54 unsigned int i;
55
56 if (keylen > bs) {
57 struct hash_desc desc;
58 struct scatterlist tmp;
59 int err;
60
61 desc.tfm = tfm;
62 desc.flags = crypto_hash_get_flags(parent);
63 desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP;
64 sg_set_buf(&tmp, inkey, keylen);
35 65
36 BUG_ON(!crypto_tfm_alg_blocksize(tfm)); 66 err = crypto_hash_digest(&desc, &tmp, keylen, digest);
37 67 if (err)
38 tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm), 68 return err;
39 GFP_KERNEL);
40 if (tfm->crt_digest.dit_hmac_block == NULL)
41 ret = -ENOMEM;
42 69
43 return ret; 70 inkey = digest;
44 71 keylen = ds;
72 }
73
74 memcpy(ipad, inkey, keylen);
75 memset(ipad + keylen, 0, bs - keylen);
76 memcpy(opad, ipad, bs);
77
78 for (i = 0; i < bs; i++) {
79 ipad[i] ^= 0x36;
80 opad[i] ^= 0x5c;
81 }
82
83 return 0;
45} 84}
46 85
47void crypto_free_hmac_block(struct crypto_tfm *tfm) 86static int hmac_init(struct hash_desc *pdesc)
48{ 87{
49 kfree(tfm->crt_digest.dit_hmac_block); 88 struct crypto_hash *parent = pdesc->tfm;
89 int bs = crypto_hash_blocksize(parent);
90 int ds = crypto_hash_digestsize(parent);
91 char *ipad = crypto_hash_ctx_aligned(parent);
92 struct hmac_ctx *ctx = align_ptr(ipad + bs * 2 + ds, sizeof(void *));
93 struct hash_desc desc;
94 struct scatterlist tmp;
95
96 desc.tfm = ctx->child;
97 desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
98 sg_set_buf(&tmp, ipad, bs);
99
100 return unlikely(crypto_hash_init(&desc)) ?:
101 crypto_hash_update(&desc, &tmp, 1);
50} 102}
51 103
52void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen) 104static int hmac_update(struct hash_desc *pdesc,
105 struct scatterlist *sg, unsigned int nbytes)
53{ 106{
54 unsigned int i; 107 struct hmac_ctx *ctx = hmac_ctx(pdesc->tfm);
108 struct hash_desc desc;
109
110 desc.tfm = ctx->child;
111 desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
112
113 return crypto_hash_update(&desc, sg, nbytes);
114}
115
116static int hmac_final(struct hash_desc *pdesc, u8 *out)
117{
118 struct crypto_hash *parent = pdesc->tfm;
119 int bs = crypto_hash_blocksize(parent);
120 int ds = crypto_hash_digestsize(parent);
121 char *opad = crypto_hash_ctx_aligned(parent) + bs;
122 char *digest = opad + bs;
123 struct hmac_ctx *ctx = align_ptr(digest + ds, sizeof(void *));
124 struct hash_desc desc;
55 struct scatterlist tmp; 125 struct scatterlist tmp;
56 char *ipad = tfm->crt_digest.dit_hmac_block;
57
58 if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
59 hash_key(tfm, key, *keylen);
60 *keylen = crypto_tfm_alg_digestsize(tfm);
61 }
62 126
63 memset(ipad, 0, crypto_tfm_alg_blocksize(tfm)); 127 desc.tfm = ctx->child;
64 memcpy(ipad, key, *keylen); 128 desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
129 sg_set_buf(&tmp, opad, bs + ds);
65 130
66 for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++) 131 return unlikely(crypto_hash_final(&desc, digest)) ?:
67 ipad[i] ^= 0x36; 132 crypto_hash_digest(&desc, &tmp, bs + ds, out);
133}
68 134
69 sg_set_buf(&tmp, ipad, crypto_tfm_alg_blocksize(tfm)); 135static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
70 136 unsigned int nbytes, u8 *out)
71 crypto_digest_init(tfm); 137{
72 crypto_digest_update(tfm, &tmp, 1); 138 struct crypto_hash *parent = pdesc->tfm;
139 int bs = crypto_hash_blocksize(parent);
140 int ds = crypto_hash_digestsize(parent);
141 char *ipad = crypto_hash_ctx_aligned(parent);
142 char *opad = ipad + bs;
143 char *digest = opad + bs;
144 struct hmac_ctx *ctx = align_ptr(digest + ds, sizeof(void *));
145 struct hash_desc desc;
146 struct scatterlist sg1[2];
147 struct scatterlist sg2[1];
148
149 desc.tfm = ctx->child;
150 desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
151
152 sg_set_buf(sg1, ipad, bs);
153 sg1[1].page = (void *)sg;
154 sg1[1].length = 0;
155 sg_set_buf(sg2, opad, bs + ds);
156
157 return unlikely(crypto_hash_digest(&desc, sg1, nbytes + bs, digest)) ?:
158 crypto_hash_digest(&desc, sg2, bs + ds, out);
73} 159}
74 160
75void crypto_hmac_update(struct crypto_tfm *tfm, 161static int hmac_init_tfm(struct crypto_tfm *tfm)
76 struct scatterlist *sg, unsigned int nsg)
77{ 162{
78 crypto_digest_update(tfm, sg, nsg); 163 struct crypto_instance *inst = (void *)tfm->__crt_alg;
164 struct crypto_spawn *spawn = crypto_instance_ctx(inst);
165 struct hmac_ctx *ctx = hmac_ctx(__crypto_hash_cast(tfm));
166
167 tfm = crypto_spawn_tfm(spawn);
168 if (IS_ERR(tfm))
169 return PTR_ERR(tfm);
170
171 ctx->child = crypto_hash_cast(tfm);
172 return 0;
79} 173}
80 174
81void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, 175static void hmac_exit_tfm(struct crypto_tfm *tfm)
82 unsigned int *keylen, u8 *out)
83{ 176{
84 unsigned int i; 177 struct hmac_ctx *ctx = hmac_ctx(__crypto_hash_cast(tfm));
85 struct scatterlist tmp; 178 crypto_free_hash(ctx->child);
86 char *opad = tfm->crt_digest.dit_hmac_block; 179}
87
88 if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
89 hash_key(tfm, key, *keylen);
90 *keylen = crypto_tfm_alg_digestsize(tfm);
91 }
92 180
93 crypto_digest_final(tfm, out); 181static void hmac_free(struct crypto_instance *inst)
182{
183 crypto_drop_spawn(crypto_instance_ctx(inst));
184 kfree(inst);
185}
94 186
95 memset(opad, 0, crypto_tfm_alg_blocksize(tfm)); 187static struct crypto_instance *hmac_alloc(void *param, unsigned int len)
96 memcpy(opad, key, *keylen); 188{
97 189 struct crypto_instance *inst;
98 for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++) 190 struct crypto_alg *alg;
99 opad[i] ^= 0x5c; 191
192 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_HASH,
193 CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC);
194 if (IS_ERR(alg))
195 return ERR_PTR(PTR_ERR(alg));
196
197 inst = crypto_alloc_instance("hmac", alg);
198 if (IS_ERR(inst))
199 goto out_put_alg;
200
201 inst->alg.cra_flags = CRYPTO_ALG_TYPE_HASH;
202 inst->alg.cra_priority = alg->cra_priority;
203 inst->alg.cra_blocksize = alg->cra_blocksize;
204 inst->alg.cra_alignmask = alg->cra_alignmask;
205 inst->alg.cra_type = &crypto_hash_type;
206
207 inst->alg.cra_hash.digestsize =
208 (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
209 CRYPTO_ALG_TYPE_HASH ? alg->cra_hash.digestsize :
210 alg->cra_digest.dia_digestsize;
211
212 inst->alg.cra_ctxsize = sizeof(struct hmac_ctx) +
213 ALIGN(inst->alg.cra_blocksize * 2 +
214 inst->alg.cra_hash.digestsize,
215 sizeof(void *));
216
217 inst->alg.cra_init = hmac_init_tfm;
218 inst->alg.cra_exit = hmac_exit_tfm;
219
220 inst->alg.cra_hash.init = hmac_init;
221 inst->alg.cra_hash.update = hmac_update;
222 inst->alg.cra_hash.final = hmac_final;
223 inst->alg.cra_hash.digest = hmac_digest;
224 inst->alg.cra_hash.setkey = hmac_setkey;
225
226out_put_alg:
227 crypto_mod_put(alg);
228 return inst;
229}
100 230
101 sg_set_buf(&tmp, opad, crypto_tfm_alg_blocksize(tfm)); 231static struct crypto_template hmac_tmpl = {
232 .name = "hmac",
233 .alloc = hmac_alloc,
234 .free = hmac_free,
235 .module = THIS_MODULE,
236};
102 237
103 crypto_digest_init(tfm); 238static int __init hmac_module_init(void)
104 crypto_digest_update(tfm, &tmp, 1); 239{
105 240 return crypto_register_template(&hmac_tmpl);
106 sg_set_buf(&tmp, out, crypto_tfm_alg_digestsize(tfm));
107
108 crypto_digest_update(tfm, &tmp, 1);
109 crypto_digest_final(tfm, out);
110} 241}
111 242
112void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, 243static void __exit hmac_module_exit(void)
113 struct scatterlist *sg, unsigned int nsg, u8 *out)
114{ 244{
115 crypto_hmac_init(tfm, key, keylen); 245 crypto_unregister_template(&hmac_tmpl);
116 crypto_hmac_update(tfm, sg, nsg);
117 crypto_hmac_final(tfm, key, keylen, out);
118} 246}
119 247
120EXPORT_SYMBOL_GPL(crypto_hmac_init); 248module_init(hmac_module_init);
121EXPORT_SYMBOL_GPL(crypto_hmac_update); 249module_exit(hmac_module_exit);
122EXPORT_SYMBOL_GPL(crypto_hmac_final);
123EXPORT_SYMBOL_GPL(crypto_hmac);
124 250
251MODULE_LICENSE("GPL");
252MODULE_DESCRIPTION("HMAC hash algorithm");
diff --git a/crypto/internal.h b/crypto/internal.h
index 959e602909a6..2da6ad4f3593 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -12,19 +12,43 @@
12 */ 12 */
13#ifndef _CRYPTO_INTERNAL_H 13#ifndef _CRYPTO_INTERNAL_H
14#define _CRYPTO_INTERNAL_H 14#define _CRYPTO_INTERNAL_H
15#include <linux/crypto.h> 15
16#include <crypto/algapi.h>
17#include <linux/completion.h>
16#include <linux/mm.h> 18#include <linux/mm.h>
17#include <linux/highmem.h> 19#include <linux/highmem.h>
18#include <linux/interrupt.h> 20#include <linux/interrupt.h>
19#include <linux/init.h> 21#include <linux/init.h>
20#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/module.h>
21#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/notifier.h>
22#include <linux/rwsem.h> 26#include <linux/rwsem.h>
23#include <linux/slab.h> 27#include <linux/slab.h>
24#include <asm/kmap_types.h> 28#include <asm/kmap_types.h>
25 29
30/* Crypto notification events. */
31enum {
32 CRYPTO_MSG_ALG_REQUEST,
33 CRYPTO_MSG_ALG_REGISTER,
34 CRYPTO_MSG_ALG_UNREGISTER,
35 CRYPTO_MSG_TMPL_REGISTER,
36 CRYPTO_MSG_TMPL_UNREGISTER,
37};
38
39struct crypto_instance;
40struct crypto_template;
41
42struct crypto_larval {
43 struct crypto_alg alg;
44 struct crypto_alg *adult;
45 struct completion completion;
46 u32 mask;
47};
48
26extern struct list_head crypto_alg_list; 49extern struct list_head crypto_alg_list;
27extern struct rw_semaphore crypto_alg_sem; 50extern struct rw_semaphore crypto_alg_sem;
51extern struct blocking_notifier_head crypto_chain;
28 52
29extern enum km_type crypto_km_types[]; 53extern enum km_type crypto_km_types[];
30 54
@@ -43,36 +67,33 @@ static inline void crypto_kunmap(void *vaddr, int out)
43 kunmap_atomic(vaddr, crypto_kmap_type(out)); 67 kunmap_atomic(vaddr, crypto_kmap_type(out));
44} 68}
45 69
46static inline void crypto_yield(struct crypto_tfm *tfm) 70static inline void crypto_yield(u32 flags)
47{ 71{
48 if (tfm->crt_flags & CRYPTO_TFM_REQ_MAY_SLEEP) 72 if (flags & CRYPTO_TFM_REQ_MAY_SLEEP)
49 cond_resched(); 73 cond_resched();
50} 74}
51 75
52#ifdef CONFIG_CRYPTO_HMAC
53int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
54void crypto_free_hmac_block(struct crypto_tfm *tfm);
55#else
56static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
57{
58 return 0;
59}
60
61static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
62{ }
63#endif
64
65#ifdef CONFIG_PROC_FS 76#ifdef CONFIG_PROC_FS
66void __init crypto_init_proc(void); 77void __init crypto_init_proc(void);
78void __exit crypto_exit_proc(void);
67#else 79#else
68static inline void crypto_init_proc(void) 80static inline void crypto_init_proc(void)
69{ } 81{ }
82static inline void crypto_exit_proc(void)
83{ }
70#endif 84#endif
71 85
72static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg, 86static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg,
73 int flags) 87 int flags)
74{ 88{
75 return alg->cra_ctxsize; 89 unsigned int len = alg->cra_ctxsize;
90
91 if (alg->cra_alignmask) {
92 len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1);
93 len += alg->cra_digest.dia_digestsize;
94 }
95
96 return len;
76} 97}
77 98
78static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg, 99static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg,
@@ -96,6 +117,10 @@ static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg,
96 return alg->cra_ctxsize; 117 return alg->cra_ctxsize;
97} 118}
98 119
120struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
121struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask);
122struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
123
99int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); 124int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
100int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); 125int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
101int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags); 126int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
@@ -108,5 +133,52 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm);
108void crypto_exit_cipher_ops(struct crypto_tfm *tfm); 133void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
109void crypto_exit_compress_ops(struct crypto_tfm *tfm); 134void crypto_exit_compress_ops(struct crypto_tfm *tfm);
110 135
136void crypto_larval_error(const char *name, u32 type, u32 mask);
137
138void crypto_shoot_alg(struct crypto_alg *alg);
139struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags);
140
141int crypto_register_instance(struct crypto_template *tmpl,
142 struct crypto_instance *inst);
143
144int crypto_register_notifier(struct notifier_block *nb);
145int crypto_unregister_notifier(struct notifier_block *nb);
146
147static inline void crypto_alg_put(struct crypto_alg *alg)
148{
149 if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
150 alg->cra_destroy(alg);
151}
152
153static inline int crypto_tmpl_get(struct crypto_template *tmpl)
154{
155 return try_module_get(tmpl->module);
156}
157
158static inline void crypto_tmpl_put(struct crypto_template *tmpl)
159{
160 module_put(tmpl->module);
161}
162
163static inline int crypto_is_larval(struct crypto_alg *alg)
164{
165 return alg->cra_flags & CRYPTO_ALG_LARVAL;
166}
167
168static inline int crypto_is_dead(struct crypto_alg *alg)
169{
170 return alg->cra_flags & CRYPTO_ALG_DEAD;
171}
172
173static inline int crypto_is_moribund(struct crypto_alg *alg)
174{
175 return alg->cra_flags & (CRYPTO_ALG_DEAD | CRYPTO_ALG_DYING);
176}
177
178static inline int crypto_notify(unsigned long val, void *v)
179{
180 return blocking_notifier_call_chain(&crypto_chain, val, v);
181}
182
111#endif /* _CRYPTO_INTERNAL_H */ 183#endif /* _CRYPTO_INTERNAL_H */
112 184
diff --git a/crypto/khazad.c b/crypto/khazad.c
index d4c9d3657b36..9fa24a2dd6ff 100644
--- a/crypto/khazad.c
+++ b/crypto/khazad.c
@@ -755,19 +755,13 @@ static const u64 c[KHAZAD_ROUNDS + 1] = {
755}; 755};
756 756
757static int khazad_setkey(struct crypto_tfm *tfm, const u8 *in_key, 757static int khazad_setkey(struct crypto_tfm *tfm, const u8 *in_key,
758 unsigned int key_len, u32 *flags) 758 unsigned int key_len)
759{ 759{
760 struct khazad_ctx *ctx = crypto_tfm_ctx(tfm); 760 struct khazad_ctx *ctx = crypto_tfm_ctx(tfm);
761 const __be32 *key = (const __be32 *)in_key; 761 const __be32 *key = (const __be32 *)in_key;
762 int r; 762 int r;
763 const u64 *S = T7; 763 const u64 *S = T7;
764 u64 K2, K1; 764 u64 K2, K1;
765
766 if (key_len != 16)
767 {
768 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
769 return -EINVAL;
770 }
771 765
772 /* key is supposed to be 32-bit aligned */ 766 /* key is supposed to be 32-bit aligned */
773 K2 = ((u64)be32_to_cpu(key[0]) << 32) | be32_to_cpu(key[1]); 767 K2 = ((u64)be32_to_cpu(key[0]) << 32) | be32_to_cpu(key[1]);
diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c
index d061da21cfda..094397b48849 100644
--- a/crypto/michael_mic.c
+++ b/crypto/michael_mic.c
@@ -123,14 +123,13 @@ static void michael_final(struct crypto_tfm *tfm, u8 *out)
123 123
124 124
125static int michael_setkey(struct crypto_tfm *tfm, const u8 *key, 125static int michael_setkey(struct crypto_tfm *tfm, const u8 *key,
126 unsigned int keylen, u32 *flags) 126 unsigned int keylen)
127{ 127{
128 struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); 128 struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm);
129 const __le32 *data = (const __le32 *)key; 129 const __le32 *data = (const __le32 *)key;
130 130
131 if (keylen != 8) { 131 if (keylen != 8) {
132 if (flags) 132 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
133 *flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
134 return -EINVAL; 133 return -EINVAL;
135 } 134 }
136 135
diff --git a/crypto/proc.c b/crypto/proc.c
index c0a5dd7ce2cc..dabce0676f63 100644
--- a/crypto/proc.c
+++ b/crypto/proc.c
@@ -12,6 +12,8 @@
12 * any later version. 12 * any later version.
13 * 13 *
14 */ 14 */
15
16#include <asm/atomic.h>
15#include <linux/init.h> 17#include <linux/init.h>
16#include <linux/crypto.h> 18#include <linux/crypto.h>
17#include <linux/rwsem.h> 19#include <linux/rwsem.h>
@@ -54,6 +56,7 @@ static int c_show(struct seq_file *m, void *p)
54 seq_printf(m, "driver : %s\n", alg->cra_driver_name); 56 seq_printf(m, "driver : %s\n", alg->cra_driver_name);
55 seq_printf(m, "module : %s\n", module_name(alg->cra_module)); 57 seq_printf(m, "module : %s\n", module_name(alg->cra_module));
56 seq_printf(m, "priority : %d\n", alg->cra_priority); 58 seq_printf(m, "priority : %d\n", alg->cra_priority);
59 seq_printf(m, "refcnt : %d\n", atomic_read(&alg->cra_refcnt));
57 60
58 switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { 61 switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
59 case CRYPTO_ALG_TYPE_CIPHER: 62 case CRYPTO_ALG_TYPE_CIPHER:
@@ -75,7 +78,10 @@ static int c_show(struct seq_file *m, void *p)
75 seq_printf(m, "type : compression\n"); 78 seq_printf(m, "type : compression\n");
76 break; 79 break;
77 default: 80 default:
78 seq_printf(m, "type : unknown\n"); 81 if (alg->cra_type && alg->cra_type->show)
82 alg->cra_type->show(m, alg);
83 else
84 seq_printf(m, "type : unknown\n");
79 break; 85 break;
80 } 86 }
81 87
@@ -110,3 +116,8 @@ void __init crypto_init_proc(void)
110 if (proc) 116 if (proc)
111 proc->proc_fops = &proc_crypto_ops; 117 proc->proc_fops = &proc_crypto_ops;
112} 118}
119
120void __exit crypto_exit_proc(void)
121{
122 remove_proc_entry("crypto", NULL);
123}
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index 2953e2cc56f0..35172d3f043b 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -15,9 +15,11 @@
15 */ 15 */
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/module.h>
18#include <linux/pagemap.h> 19#include <linux/pagemap.h>
19#include <linux/highmem.h> 20#include <linux/highmem.h>
20#include <asm/scatterlist.h> 21#include <linux/scatterlist.h>
22
21#include "internal.h" 23#include "internal.h"
22#include "scatterwalk.h" 24#include "scatterwalk.h"
23 25
@@ -27,88 +29,77 @@ enum km_type crypto_km_types[] = {
27 KM_SOFTIRQ0, 29 KM_SOFTIRQ0,
28 KM_SOFTIRQ1, 30 KM_SOFTIRQ1,
29}; 31};
32EXPORT_SYMBOL_GPL(crypto_km_types);
30 33
31static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out) 34static inline void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
32{ 35{
33 if (out) 36 void *src = out ? buf : sgdata;
34 memcpy(sgdata, buf, nbytes); 37 void *dst = out ? sgdata : buf;
35 else 38
36 memcpy(buf, sgdata, nbytes); 39 memcpy(dst, src, nbytes);
37} 40}
38 41
39void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg) 42void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
40{ 43{
41 unsigned int rest_of_page;
42
43 walk->sg = sg; 44 walk->sg = sg;
44 45
45 walk->page = sg->page;
46 walk->len_this_segment = sg->length;
47
48 BUG_ON(!sg->length); 46 BUG_ON(!sg->length);
49 47
50 rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
51 walk->len_this_page = min(sg->length, rest_of_page);
52 walk->offset = sg->offset; 48 walk->offset = sg->offset;
53} 49}
50EXPORT_SYMBOL_GPL(scatterwalk_start);
54 51
55void scatterwalk_map(struct scatter_walk *walk, int out) 52void *scatterwalk_map(struct scatter_walk *walk, int out)
56{
57 walk->data = crypto_kmap(walk->page, out) + walk->offset;
58}
59
60static inline void scatterwalk_unmap(struct scatter_walk *walk, int out)
61{ 53{
62 /* walk->data may be pointing the first byte of the next page; 54 return crypto_kmap(scatterwalk_page(walk), out) +
63 however, we know we transfered at least one byte. So, 55 offset_in_page(walk->offset);
64 walk->data - 1 will be a virtual address in the mapped page. */
65 crypto_kunmap(walk->data - 1, out);
66} 56}
57EXPORT_SYMBOL_GPL(scatterwalk_map);
67 58
68static void scatterwalk_pagedone(struct scatter_walk *walk, int out, 59static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
69 unsigned int more) 60 unsigned int more)
70{ 61{
71 if (out) 62 if (out)
72 flush_dcache_page(walk->page); 63 flush_dcache_page(scatterwalk_page(walk));
73 64
74 if (more) { 65 if (more) {
75 walk->len_this_segment -= walk->len_this_page; 66 walk->offset += PAGE_SIZE - 1;
76 67 walk->offset &= PAGE_MASK;
77 if (walk->len_this_segment) { 68 if (walk->offset >= walk->sg->offset + walk->sg->length)
78 walk->page++;
79 walk->len_this_page = min(walk->len_this_segment,
80 (unsigned)PAGE_CACHE_SIZE);
81 walk->offset = 0;
82 }
83 else
84 scatterwalk_start(walk, sg_next(walk->sg)); 69 scatterwalk_start(walk, sg_next(walk->sg));
85 } 70 }
86} 71}
87 72
88void scatterwalk_done(struct scatter_walk *walk, int out, int more) 73void scatterwalk_done(struct scatter_walk *walk, int out, int more)
89{ 74{
90 scatterwalk_unmap(walk, out); 75 if (!offset_in_page(walk->offset) || !more)
91 if (walk->len_this_page == 0 || !more)
92 scatterwalk_pagedone(walk, out, more); 76 scatterwalk_pagedone(walk, out, more);
93} 77}
78EXPORT_SYMBOL_GPL(scatterwalk_done);
94 79
95/* 80void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
96 * Do not call this unless the total length of all of the fragments 81 size_t nbytes, int out)
97 * has been verified as multiple of the block size.
98 */
99int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
100 size_t nbytes, int out)
101{ 82{
102 while (nbytes > walk->len_this_page) { 83 for (;;) {
103 memcpy_dir(buf, walk->data, walk->len_this_page, out); 84 unsigned int len_this_page = scatterwalk_pagelen(walk);
104 buf += walk->len_this_page; 85 u8 *vaddr;
105 nbytes -= walk->len_this_page; 86
87 if (len_this_page > nbytes)
88 len_this_page = nbytes;
89
90 vaddr = scatterwalk_map(walk, out);
91 memcpy_dir(buf, vaddr, len_this_page, out);
92 scatterwalk_unmap(vaddr, out);
93
94 if (nbytes == len_this_page)
95 break;
96
97 buf += len_this_page;
98 nbytes -= len_this_page;
106 99
107 scatterwalk_unmap(walk, out);
108 scatterwalk_pagedone(walk, out, 1); 100 scatterwalk_pagedone(walk, out, 1);
109 scatterwalk_map(walk, out);
110 } 101 }
111 102
112 memcpy_dir(buf, walk->data, nbytes, out); 103 scatterwalk_advance(walk, nbytes);
113 return nbytes;
114} 104}
105EXPORT_SYMBOL_GPL(scatterwalk_copychunks);
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index e79925c474a3..f1592cc2d0f4 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -14,45 +14,42 @@
14 14
15#ifndef _CRYPTO_SCATTERWALK_H 15#ifndef _CRYPTO_SCATTERWALK_H
16#define _CRYPTO_SCATTERWALK_H 16#define _CRYPTO_SCATTERWALK_H
17
17#include <linux/mm.h> 18#include <linux/mm.h>
18#include <asm/scatterlist.h> 19#include <linux/scatterlist.h>
19 20
20struct scatter_walk { 21#include "internal.h"
21 struct scatterlist *sg;
22 struct page *page;
23 void *data;
24 unsigned int len_this_page;
25 unsigned int len_this_segment;
26 unsigned int offset;
27};
28 22
29/* Define sg_next is an inline routine now in case we want to change
30 scatterlist to a linked list later. */
31static inline struct scatterlist *sg_next(struct scatterlist *sg) 23static inline struct scatterlist *sg_next(struct scatterlist *sg)
32{ 24{
33 return sg + 1; 25 return (++sg)->length ? sg : (void *)sg->page;
34} 26}
35 27
36static inline int scatterwalk_samebuf(struct scatter_walk *walk_in, 28static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
37 struct scatter_walk *walk_out) 29 struct scatter_walk *walk_out)
38{ 30{
39 return walk_in->page == walk_out->page && 31 return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
40 walk_in->offset == walk_out->offset; 32 (int)(walk_in->offset - walk_out->offset));
33}
34
35static inline unsigned int scatterwalk_pagelen(struct scatter_walk *walk)
36{
37 unsigned int len = walk->sg->offset + walk->sg->length - walk->offset;
38 unsigned int len_this_page = offset_in_page(~walk->offset) + 1;
39 return len_this_page > len ? len : len_this_page;
41} 40}
42 41
43static inline unsigned int scatterwalk_clamp(struct scatter_walk *walk, 42static inline unsigned int scatterwalk_clamp(struct scatter_walk *walk,
44 unsigned int nbytes) 43 unsigned int nbytes)
45{ 44{
46 return nbytes > walk->len_this_page ? walk->len_this_page : nbytes; 45 unsigned int len_this_page = scatterwalk_pagelen(walk);
46 return nbytes > len_this_page ? len_this_page : nbytes;
47} 47}
48 48
49static inline void scatterwalk_advance(struct scatter_walk *walk, 49static inline void scatterwalk_advance(struct scatter_walk *walk,
50 unsigned int nbytes) 50 unsigned int nbytes)
51{ 51{
52 walk->data += nbytes;
53 walk->offset += nbytes; 52 walk->offset += nbytes;
54 walk->len_this_page -= nbytes;
55 walk->len_this_segment -= nbytes;
56} 53}
57 54
58static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk, 55static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
@@ -61,9 +58,20 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
61 return !(walk->offset & alignmask); 58 return !(walk->offset & alignmask);
62} 59}
63 60
61static inline struct page *scatterwalk_page(struct scatter_walk *walk)
62{
63 return walk->sg->page + (walk->offset >> PAGE_SHIFT);
64}
65
66static inline void scatterwalk_unmap(void *vaddr, int out)
67{
68 crypto_kunmap(vaddr, out);
69}
70
64void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg); 71void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
65int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out); 72void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
66void scatterwalk_map(struct scatter_walk *walk, int out); 73 size_t nbytes, int out);
74void *scatterwalk_map(struct scatter_walk *walk, int out);
67void scatterwalk_done(struct scatter_walk *walk, int out, int more); 75void scatterwalk_done(struct scatter_walk *walk, int out, int more);
68 76
69#endif /* _CRYPTO_SCATTERWALK_H */ 77#endif /* _CRYPTO_SCATTERWALK_H */
diff --git a/crypto/serpent.c b/crypto/serpent.c
index de60cdddbf4a..465d091cd3ec 100644
--- a/crypto/serpent.c
+++ b/crypto/serpent.c
@@ -216,7 +216,7 @@ struct serpent_ctx {
216 216
217 217
218static int serpent_setkey(struct crypto_tfm *tfm, const u8 *key, 218static int serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
219 unsigned int keylen, u32 *flags) 219 unsigned int keylen)
220{ 220{
221 struct serpent_ctx *ctx = crypto_tfm_ctx(tfm); 221 struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
222 u32 *k = ctx->expkey; 222 u32 *k = ctx->expkey;
@@ -224,13 +224,6 @@ static int serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
224 u32 r0,r1,r2,r3,r4; 224 u32 r0,r1,r2,r3,r4;
225 int i; 225 int i;
226 226
227 if ((keylen < SERPENT_MIN_KEY_SIZE)
228 || (keylen > SERPENT_MAX_KEY_SIZE))
229 {
230 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
231 return -EINVAL;
232 }
233
234 /* Copy key, add padding */ 227 /* Copy key, add padding */
235 228
236 for (i = 0; i < keylen; ++i) 229 for (i = 0; i < keylen; ++i)
@@ -497,21 +490,15 @@ static struct crypto_alg serpent_alg = {
497}; 490};
498 491
499static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key, 492static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key,
500 unsigned int keylen, u32 *flags) 493 unsigned int keylen)
501{ 494{
502 u8 rev_key[SERPENT_MAX_KEY_SIZE]; 495 u8 rev_key[SERPENT_MAX_KEY_SIZE];
503 int i; 496 int i;
504 497
505 if ((keylen < SERPENT_MIN_KEY_SIZE)
506 || (keylen > SERPENT_MAX_KEY_SIZE)) {
507 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
508 return -EINVAL;
509 }
510
511 for (i = 0; i < keylen; ++i) 498 for (i = 0; i < keylen; ++i)
512 rev_key[keylen - i - 1] = key[i]; 499 rev_key[keylen - i - 1] = key[i];
513 500
514 return serpent_setkey(tfm, rev_key, keylen, flags); 501 return serpent_setkey(tfm, rev_key, keylen);
515} 502}
516 503
517static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 504static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
diff --git a/crypto/sha1.c b/crypto/sha1.c
index 6c77b689f87e..1bba551e5b45 100644
--- a/crypto/sha1.c
+++ b/crypto/sha1.c
@@ -109,6 +109,7 @@ static void sha1_final(struct crypto_tfm *tfm, u8 *out)
109 109
110static struct crypto_alg alg = { 110static struct crypto_alg alg = {
111 .cra_name = "sha1", 111 .cra_name = "sha1",
112 .cra_driver_name= "sha1-generic",
112 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 113 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
113 .cra_blocksize = SHA1_HMAC_BLOCK_SIZE, 114 .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
114 .cra_ctxsize = sizeof(struct sha1_ctx), 115 .cra_ctxsize = sizeof(struct sha1_ctx),
@@ -137,3 +138,5 @@ module_exit(fini);
137 138
138MODULE_LICENSE("GPL"); 139MODULE_LICENSE("GPL");
139MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm"); 140MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
141
142MODULE_ALIAS("sha1-generic");
diff --git a/crypto/sha256.c b/crypto/sha256.c
index bc71d85a7d02..716195bb54f2 100644
--- a/crypto/sha256.c
+++ b/crypto/sha256.c
@@ -309,6 +309,7 @@ static void sha256_final(struct crypto_tfm *tfm, u8 *out)
309 309
310static struct crypto_alg alg = { 310static struct crypto_alg alg = {
311 .cra_name = "sha256", 311 .cra_name = "sha256",
312 .cra_driver_name= "sha256-generic",
312 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 313 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
313 .cra_blocksize = SHA256_HMAC_BLOCK_SIZE, 314 .cra_blocksize = SHA256_HMAC_BLOCK_SIZE,
314 .cra_ctxsize = sizeof(struct sha256_ctx), 315 .cra_ctxsize = sizeof(struct sha256_ctx),
@@ -337,3 +338,5 @@ module_exit(fini);
337 338
338MODULE_LICENSE("GPL"); 339MODULE_LICENSE("GPL");
339MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm"); 340MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm");
341
342MODULE_ALIAS("sha256-generic");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index e52f56c5bd5e..83307420d31c 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -17,6 +17,7 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/err.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
@@ -54,8 +55,6 @@
54*/ 55*/
55#define ENCRYPT 1 56#define ENCRYPT 1
56#define DECRYPT 0 57#define DECRYPT 0
57#define MODE_ECB 1
58#define MODE_CBC 0
59 58
60static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; 59static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
61 60
@@ -89,9 +88,11 @@ static void test_hash(char *algo, struct hash_testvec *template,
89 unsigned int i, j, k, temp; 88 unsigned int i, j, k, temp;
90 struct scatterlist sg[8]; 89 struct scatterlist sg[8];
91 char result[64]; 90 char result[64];
92 struct crypto_tfm *tfm; 91 struct crypto_hash *tfm;
92 struct hash_desc desc;
93 struct hash_testvec *hash_tv; 93 struct hash_testvec *hash_tv;
94 unsigned int tsize; 94 unsigned int tsize;
95 int ret;
95 96
96 printk("\ntesting %s\n", algo); 97 printk("\ntesting %s\n", algo);
97 98
@@ -105,30 +106,42 @@ static void test_hash(char *algo, struct hash_testvec *template,
105 106
106 memcpy(tvmem, template, tsize); 107 memcpy(tvmem, template, tsize);
107 hash_tv = (void *)tvmem; 108 hash_tv = (void *)tvmem;
108 tfm = crypto_alloc_tfm(algo, 0); 109
109 if (tfm == NULL) { 110 tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC);
110 printk("failed to load transform for %s\n", algo); 111 if (IS_ERR(tfm)) {
112 printk("failed to load transform for %s: %ld\n", algo,
113 PTR_ERR(tfm));
111 return; 114 return;
112 } 115 }
113 116
117 desc.tfm = tfm;
118 desc.flags = 0;
119
114 for (i = 0; i < tcount; i++) { 120 for (i = 0; i < tcount; i++) {
115 printk("test %u:\n", i + 1); 121 printk("test %u:\n", i + 1);
116 memset(result, 0, 64); 122 memset(result, 0, 64);
117 123
118 sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize); 124 sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
119 125
120 crypto_digest_init(tfm); 126 if (hash_tv[i].ksize) {
121 if (tfm->crt_u.digest.dit_setkey) { 127 ret = crypto_hash_setkey(tfm, hash_tv[i].key,
122 crypto_digest_setkey(tfm, hash_tv[i].key, 128 hash_tv[i].ksize);
123 hash_tv[i].ksize); 129 if (ret) {
130 printk("setkey() failed ret=%d\n", ret);
131 goto out;
132 }
133 }
134
135 ret = crypto_hash_digest(&desc, sg, hash_tv[i].psize, result);
136 if (ret) {
137 printk("digest () failed ret=%d\n", ret);
138 goto out;
124 } 139 }
125 crypto_digest_update(tfm, sg, 1);
126 crypto_digest_final(tfm, result);
127 140
128 hexdump(result, crypto_tfm_alg_digestsize(tfm)); 141 hexdump(result, crypto_hash_digestsize(tfm));
129 printk("%s\n", 142 printk("%s\n",
130 memcmp(result, hash_tv[i].digest, 143 memcmp(result, hash_tv[i].digest,
131 crypto_tfm_alg_digestsize(tfm)) ? 144 crypto_hash_digestsize(tfm)) ?
132 "fail" : "pass"); 145 "fail" : "pass");
133 } 146 }
134 147
@@ -154,127 +167,56 @@ static void test_hash(char *algo, struct hash_testvec *template,
154 hash_tv[i].tap[k]); 167 hash_tv[i].tap[k]);
155 } 168 }
156 169
157 crypto_digest_digest(tfm, sg, hash_tv[i].np, result); 170 if (hash_tv[i].ksize) {
158 171 ret = crypto_hash_setkey(tfm, hash_tv[i].key,
159 hexdump(result, crypto_tfm_alg_digestsize(tfm)); 172 hash_tv[i].ksize);
160 printk("%s\n",
161 memcmp(result, hash_tv[i].digest,
162 crypto_tfm_alg_digestsize(tfm)) ?
163 "fail" : "pass");
164 }
165 }
166
167 crypto_free_tfm(tfm);
168}
169
170
171#ifdef CONFIG_CRYPTO_HMAC
172
173static void test_hmac(char *algo, struct hmac_testvec *template,
174 unsigned int tcount)
175{
176 unsigned int i, j, k, temp;
177 struct scatterlist sg[8];
178 char result[64];
179 struct crypto_tfm *tfm;
180 struct hmac_testvec *hmac_tv;
181 unsigned int tsize, klen;
182
183 tfm = crypto_alloc_tfm(algo, 0);
184 if (tfm == NULL) {
185 printk("failed to load transform for %s\n", algo);
186 return;
187 }
188
189 printk("\ntesting hmac_%s\n", algo);
190
191 tsize = sizeof(struct hmac_testvec);
192 tsize *= tcount;
193 if (tsize > TVMEMSIZE) {
194 printk("template (%u) too big for tvmem (%u)\n", tsize,
195 TVMEMSIZE);
196 goto out;
197 }
198
199 memcpy(tvmem, template, tsize);
200 hmac_tv = (void *)tvmem;
201
202 for (i = 0; i < tcount; i++) {
203 printk("test %u:\n", i + 1);
204 memset(result, 0, sizeof (result));
205
206 klen = hmac_tv[i].ksize;
207 sg_set_buf(&sg[0], hmac_tv[i].plaintext, hmac_tv[i].psize);
208
209 crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result);
210 173
211 hexdump(result, crypto_tfm_alg_digestsize(tfm)); 174 if (ret) {
212 printk("%s\n", 175 printk("setkey() failed ret=%d\n", ret);
213 memcmp(result, hmac_tv[i].digest, 176 goto out;
214 crypto_tfm_alg_digestsize(tfm)) ? "fail" : 177 }
215 "pass");
216 }
217
218 printk("\ntesting hmac_%s across pages\n", algo);
219
220 memset(xbuf, 0, XBUFSIZE);
221
222 j = 0;
223 for (i = 0; i < tcount; i++) {
224 if (hmac_tv[i].np) {
225 j++;
226 printk("test %u:\n",j);
227 memset(result, 0, 64);
228
229 temp = 0;
230 klen = hmac_tv[i].ksize;
231 for (k = 0; k < hmac_tv[i].np; k++) {
232 memcpy(&xbuf[IDX[k]],
233 hmac_tv[i].plaintext + temp,
234 hmac_tv[i].tap[k]);
235 temp += hmac_tv[i].tap[k];
236 sg_set_buf(&sg[k], &xbuf[IDX[k]],
237 hmac_tv[i].tap[k]);
238 } 178 }
239 179
240 crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 180 ret = crypto_hash_digest(&desc, sg, hash_tv[i].psize,
241 hmac_tv[i].np, result); 181 result);
242 hexdump(result, crypto_tfm_alg_digestsize(tfm)); 182 if (ret) {
183 printk("digest () failed ret=%d\n", ret);
184 goto out;
185 }
243 186
187 hexdump(result, crypto_hash_digestsize(tfm));
244 printk("%s\n", 188 printk("%s\n",
245 memcmp(result, hmac_tv[i].digest, 189 memcmp(result, hash_tv[i].digest,
246 crypto_tfm_alg_digestsize(tfm)) ? 190 crypto_hash_digestsize(tfm)) ?
247 "fail" : "pass"); 191 "fail" : "pass");
248 } 192 }
249 } 193 }
194
250out: 195out:
251 crypto_free_tfm(tfm); 196 crypto_free_hash(tfm);
252} 197}
253 198
254#endif /* CONFIG_CRYPTO_HMAC */ 199static void test_cipher(char *algo, int enc,
255
256static void test_cipher(char *algo, int mode, int enc,
257 struct cipher_testvec *template, unsigned int tcount) 200 struct cipher_testvec *template, unsigned int tcount)
258{ 201{
259 unsigned int ret, i, j, k, temp; 202 unsigned int ret, i, j, k, temp;
260 unsigned int tsize; 203 unsigned int tsize;
204 unsigned int iv_len;
205 unsigned int len;
261 char *q; 206 char *q;
262 struct crypto_tfm *tfm; 207 struct crypto_blkcipher *tfm;
263 char *key; 208 char *key;
264 struct cipher_testvec *cipher_tv; 209 struct cipher_testvec *cipher_tv;
210 struct blkcipher_desc desc;
265 struct scatterlist sg[8]; 211 struct scatterlist sg[8];
266 const char *e, *m; 212 const char *e;
267 213
268 if (enc == ENCRYPT) 214 if (enc == ENCRYPT)
269 e = "encryption"; 215 e = "encryption";
270 else 216 else
271 e = "decryption"; 217 e = "decryption";
272 if (mode == MODE_ECB)
273 m = "ECB";
274 else
275 m = "CBC";
276 218
277 printk("\ntesting %s %s %s\n", algo, m, e); 219 printk("\ntesting %s %s\n", algo, e);
278 220
279 tsize = sizeof (struct cipher_testvec); 221 tsize = sizeof (struct cipher_testvec);
280 tsize *= tcount; 222 tsize *= tcount;
@@ -288,15 +230,15 @@ static void test_cipher(char *algo, int mode, int enc,
288 memcpy(tvmem, template, tsize); 230 memcpy(tvmem, template, tsize);
289 cipher_tv = (void *)tvmem; 231 cipher_tv = (void *)tvmem;
290 232
291 if (mode) 233 tfm = crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
292 tfm = crypto_alloc_tfm(algo, 0);
293 else
294 tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC);
295 234
296 if (tfm == NULL) { 235 if (IS_ERR(tfm)) {
297 printk("failed to load transform for %s %s\n", algo, m); 236 printk("failed to load transform for %s: %ld\n", algo,
237 PTR_ERR(tfm));
298 return; 238 return;
299 } 239 }
240 desc.tfm = tfm;
241 desc.flags = 0;
300 242
301 j = 0; 243 j = 0;
302 for (i = 0; i < tcount; i++) { 244 for (i = 0; i < tcount; i++) {
@@ -305,14 +247,17 @@ static void test_cipher(char *algo, int mode, int enc,
305 printk("test %u (%d bit key):\n", 247 printk("test %u (%d bit key):\n",
306 j, cipher_tv[i].klen * 8); 248 j, cipher_tv[i].klen * 8);
307 249
308 tfm->crt_flags = 0; 250 crypto_blkcipher_clear_flags(tfm, ~0);
309 if (cipher_tv[i].wk) 251 if (cipher_tv[i].wk)
310 tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; 252 crypto_blkcipher_set_flags(
253 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
311 key = cipher_tv[i].key; 254 key = cipher_tv[i].key;
312 255
313 ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen); 256 ret = crypto_blkcipher_setkey(tfm, key,
257 cipher_tv[i].klen);
314 if (ret) { 258 if (ret) {
315 printk("setkey() failed flags=%x\n", tfm->crt_flags); 259 printk("setkey() failed flags=%x\n",
260 crypto_blkcipher_get_flags(tfm));
316 261
317 if (!cipher_tv[i].fail) 262 if (!cipher_tv[i].fail)
318 goto out; 263 goto out;
@@ -321,19 +266,19 @@ static void test_cipher(char *algo, int mode, int enc,
321 sg_set_buf(&sg[0], cipher_tv[i].input, 266 sg_set_buf(&sg[0], cipher_tv[i].input,
322 cipher_tv[i].ilen); 267 cipher_tv[i].ilen);
323 268
324 if (!mode) { 269 iv_len = crypto_blkcipher_ivsize(tfm);
325 crypto_cipher_set_iv(tfm, cipher_tv[i].iv, 270 if (iv_len)
326 crypto_tfm_alg_ivsize(tfm)); 271 crypto_blkcipher_set_iv(tfm, cipher_tv[i].iv,
327 } 272 iv_len);
328
329 if (enc)
330 ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
331 else
332 ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
333 273
274 len = cipher_tv[i].ilen;
275 ret = enc ?
276 crypto_blkcipher_encrypt(&desc, sg, sg, len) :
277 crypto_blkcipher_decrypt(&desc, sg, sg, len);
334 278
335 if (ret) { 279 if (ret) {
336 printk("%s () failed flags=%x\n", e, tfm->crt_flags); 280 printk("%s () failed flags=%x\n", e,
281 desc.flags);
337 goto out; 282 goto out;
338 } 283 }
339 284
@@ -346,7 +291,7 @@ static void test_cipher(char *algo, int mode, int enc,
346 } 291 }
347 } 292 }
348 293
349 printk("\ntesting %s %s %s across pages (chunking)\n", algo, m, e); 294 printk("\ntesting %s %s across pages (chunking)\n", algo, e);
350 memset(xbuf, 0, XBUFSIZE); 295 memset(xbuf, 0, XBUFSIZE);
351 296
352 j = 0; 297 j = 0;
@@ -356,14 +301,17 @@ static void test_cipher(char *algo, int mode, int enc,
356 printk("test %u (%d bit key):\n", 301 printk("test %u (%d bit key):\n",
357 j, cipher_tv[i].klen * 8); 302 j, cipher_tv[i].klen * 8);
358 303
359 tfm->crt_flags = 0; 304 crypto_blkcipher_clear_flags(tfm, ~0);
360 if (cipher_tv[i].wk) 305 if (cipher_tv[i].wk)
361 tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; 306 crypto_blkcipher_set_flags(
307 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
362 key = cipher_tv[i].key; 308 key = cipher_tv[i].key;
363 309
364 ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen); 310 ret = crypto_blkcipher_setkey(tfm, key,
311 cipher_tv[i].klen);
365 if (ret) { 312 if (ret) {
366 printk("setkey() failed flags=%x\n", tfm->crt_flags); 313 printk("setkey() failed flags=%x\n",
314 crypto_blkcipher_get_flags(tfm));
367 315
368 if (!cipher_tv[i].fail) 316 if (!cipher_tv[i].fail)
369 goto out; 317 goto out;
@@ -379,18 +327,19 @@ static void test_cipher(char *algo, int mode, int enc,
379 cipher_tv[i].tap[k]); 327 cipher_tv[i].tap[k]);
380 } 328 }
381 329
382 if (!mode) { 330 iv_len = crypto_blkcipher_ivsize(tfm);
383 crypto_cipher_set_iv(tfm, cipher_tv[i].iv, 331 if (iv_len)
384 crypto_tfm_alg_ivsize(tfm)); 332 crypto_blkcipher_set_iv(tfm, cipher_tv[i].iv,
385 } 333 iv_len);
386 334
387 if (enc) 335 len = cipher_tv[i].ilen;
388 ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen); 336 ret = enc ?
389 else 337 crypto_blkcipher_encrypt(&desc, sg, sg, len) :
390 ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen); 338 crypto_blkcipher_decrypt(&desc, sg, sg, len);
391 339
392 if (ret) { 340 if (ret) {
393 printk("%s () failed flags=%x\n", e, tfm->crt_flags); 341 printk("%s () failed flags=%x\n", e,
342 desc.flags);
394 goto out; 343 goto out;
395 } 344 }
396 345
@@ -409,10 +358,10 @@ static void test_cipher(char *algo, int mode, int enc,
409 } 358 }
410 359
411out: 360out:
412 crypto_free_tfm(tfm); 361 crypto_free_blkcipher(tfm);
413} 362}
414 363
415static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p, 364static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p,
416 int blen, int sec) 365 int blen, int sec)
417{ 366{
418 struct scatterlist sg[1]; 367 struct scatterlist sg[1];
@@ -425,9 +374,9 @@ static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
425 for (start = jiffies, end = start + sec * HZ, bcount = 0; 374 for (start = jiffies, end = start + sec * HZ, bcount = 0;
426 time_before(jiffies, end); bcount++) { 375 time_before(jiffies, end); bcount++) {
427 if (enc) 376 if (enc)
428 ret = crypto_cipher_encrypt(tfm, sg, sg, blen); 377 ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
429 else 378 else
430 ret = crypto_cipher_decrypt(tfm, sg, sg, blen); 379 ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
431 380
432 if (ret) 381 if (ret)
433 return ret; 382 return ret;
@@ -438,7 +387,7 @@ static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
438 return 0; 387 return 0;
439} 388}
440 389
441static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p, 390static int test_cipher_cycles(struct blkcipher_desc *desc, int enc, char *p,
442 int blen) 391 int blen)
443{ 392{
444 struct scatterlist sg[1]; 393 struct scatterlist sg[1];
@@ -454,9 +403,9 @@ static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p,
454 /* Warm-up run. */ 403 /* Warm-up run. */
455 for (i = 0; i < 4; i++) { 404 for (i = 0; i < 4; i++) {
456 if (enc) 405 if (enc)
457 ret = crypto_cipher_encrypt(tfm, sg, sg, blen); 406 ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
458 else 407 else
459 ret = crypto_cipher_decrypt(tfm, sg, sg, blen); 408 ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
460 409
461 if (ret) 410 if (ret)
462 goto out; 411 goto out;
@@ -468,9 +417,9 @@ static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p,
468 417
469 start = get_cycles(); 418 start = get_cycles();
470 if (enc) 419 if (enc)
471 ret = crypto_cipher_encrypt(tfm, sg, sg, blen); 420 ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
472 else 421 else
473 ret = crypto_cipher_decrypt(tfm, sg, sg, blen); 422 ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
474 end = get_cycles(); 423 end = get_cycles();
475 424
476 if (ret) 425 if (ret)
@@ -490,35 +439,32 @@ out:
490 return ret; 439 return ret;
491} 440}
492 441
493static void test_cipher_speed(char *algo, int mode, int enc, unsigned int sec, 442static void test_cipher_speed(char *algo, int enc, unsigned int sec,
494 struct cipher_testvec *template, 443 struct cipher_testvec *template,
495 unsigned int tcount, struct cipher_speed *speed) 444 unsigned int tcount, struct cipher_speed *speed)
496{ 445{
497 unsigned int ret, i, j, iv_len; 446 unsigned int ret, i, j, iv_len;
498 unsigned char *key, *p, iv[128]; 447 unsigned char *key, *p, iv[128];
499 struct crypto_tfm *tfm; 448 struct crypto_blkcipher *tfm;
500 const char *e, *m; 449 struct blkcipher_desc desc;
450 const char *e;
501 451
502 if (enc == ENCRYPT) 452 if (enc == ENCRYPT)
503 e = "encryption"; 453 e = "encryption";
504 else 454 else
505 e = "decryption"; 455 e = "decryption";
506 if (mode == MODE_ECB)
507 m = "ECB";
508 else
509 m = "CBC";
510 456
511 printk("\ntesting speed of %s %s %s\n", algo, m, e); 457 printk("\ntesting speed of %s %s\n", algo, e);
512 458
513 if (mode) 459 tfm = crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
514 tfm = crypto_alloc_tfm(algo, 0);
515 else
516 tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC);
517 460
518 if (tfm == NULL) { 461 if (IS_ERR(tfm)) {
519 printk("failed to load transform for %s %s\n", algo, m); 462 printk("failed to load transform for %s: %ld\n", algo,
463 PTR_ERR(tfm));
520 return; 464 return;
521 } 465 }
466 desc.tfm = tfm;
467 desc.flags = 0;
522 468
523 for (i = 0; speed[i].klen != 0; i++) { 469 for (i = 0; speed[i].klen != 0; i++) {
524 if ((speed[i].blen + speed[i].klen) > TVMEMSIZE) { 470 if ((speed[i].blen + speed[i].klen) > TVMEMSIZE) {
@@ -542,125 +488,231 @@ static void test_cipher_speed(char *algo, int mode, int enc, unsigned int sec,
542 } 488 }
543 p = (unsigned char *)tvmem + speed[i].klen; 489 p = (unsigned char *)tvmem + speed[i].klen;
544 490
545 ret = crypto_cipher_setkey(tfm, key, speed[i].klen); 491 ret = crypto_blkcipher_setkey(tfm, key, speed[i].klen);
546 if (ret) { 492 if (ret) {
547 printk("setkey() failed flags=%x\n", tfm->crt_flags); 493 printk("setkey() failed flags=%x\n",
494 crypto_blkcipher_get_flags(tfm));
548 goto out; 495 goto out;
549 } 496 }
550 497
551 if (!mode) { 498 iv_len = crypto_blkcipher_ivsize(tfm);
552 iv_len = crypto_tfm_alg_ivsize(tfm); 499 if (iv_len) {
553 memset(&iv, 0xff, iv_len); 500 memset(&iv, 0xff, iv_len);
554 crypto_cipher_set_iv(tfm, iv, iv_len); 501 crypto_blkcipher_set_iv(tfm, iv, iv_len);
555 } 502 }
556 503
557 if (sec) 504 if (sec)
558 ret = test_cipher_jiffies(tfm, enc, p, speed[i].blen, 505 ret = test_cipher_jiffies(&desc, enc, p, speed[i].blen,
559 sec); 506 sec);
560 else 507 else
561 ret = test_cipher_cycles(tfm, enc, p, speed[i].blen); 508 ret = test_cipher_cycles(&desc, enc, p, speed[i].blen);
562 509
563 if (ret) { 510 if (ret) {
564 printk("%s() failed flags=%x\n", e, tfm->crt_flags); 511 printk("%s() failed flags=%x\n", e, desc.flags);
565 break; 512 break;
566 } 513 }
567 } 514 }
568 515
569out: 516out:
570 crypto_free_tfm(tfm); 517 crypto_free_blkcipher(tfm);
571} 518}
572 519
573static void test_digest_jiffies(struct crypto_tfm *tfm, char *p, int blen, 520static int test_hash_jiffies_digest(struct hash_desc *desc, char *p, int blen,
574 int plen, char *out, int sec) 521 char *out, int sec)
522{
523 struct scatterlist sg[1];
524 unsigned long start, end;
525 int bcount;
526 int ret;
527
528 for (start = jiffies, end = start + sec * HZ, bcount = 0;
529 time_before(jiffies, end); bcount++) {
530 sg_set_buf(sg, p, blen);
531 ret = crypto_hash_digest(desc, sg, blen, out);
532 if (ret)
533 return ret;
534 }
535
536 printk("%6u opers/sec, %9lu bytes/sec\n",
537 bcount / sec, ((long)bcount * blen) / sec);
538
539 return 0;
540}
541
542static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen,
543 int plen, char *out, int sec)
575{ 544{
576 struct scatterlist sg[1]; 545 struct scatterlist sg[1];
577 unsigned long start, end; 546 unsigned long start, end;
578 int bcount, pcount; 547 int bcount, pcount;
548 int ret;
549
550 if (plen == blen)
551 return test_hash_jiffies_digest(desc, p, blen, out, sec);
579 552
580 for (start = jiffies, end = start + sec * HZ, bcount = 0; 553 for (start = jiffies, end = start + sec * HZ, bcount = 0;
581 time_before(jiffies, end); bcount++) { 554 time_before(jiffies, end); bcount++) {
582 crypto_digest_init(tfm); 555 ret = crypto_hash_init(desc);
556 if (ret)
557 return ret;
583 for (pcount = 0; pcount < blen; pcount += plen) { 558 for (pcount = 0; pcount < blen; pcount += plen) {
584 sg_set_buf(sg, p + pcount, plen); 559 sg_set_buf(sg, p + pcount, plen);
585 crypto_digest_update(tfm, sg, 1); 560 ret = crypto_hash_update(desc, sg, plen);
561 if (ret)
562 return ret;
586 } 563 }
587 /* we assume there is enough space in 'out' for the result */ 564 /* we assume there is enough space in 'out' for the result */
588 crypto_digest_final(tfm, out); 565 ret = crypto_hash_final(desc, out);
566 if (ret)
567 return ret;
589 } 568 }
590 569
591 printk("%6u opers/sec, %9lu bytes/sec\n", 570 printk("%6u opers/sec, %9lu bytes/sec\n",
592 bcount / sec, ((long)bcount * blen) / sec); 571 bcount / sec, ((long)bcount * blen) / sec);
593 572
594 return; 573 return 0;
574}
575
576static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen,
577 char *out)
578{
579 struct scatterlist sg[1];
580 unsigned long cycles = 0;
581 int i;
582 int ret;
583
584 local_bh_disable();
585 local_irq_disable();
586
587 /* Warm-up run. */
588 for (i = 0; i < 4; i++) {
589 sg_set_buf(sg, p, blen);
590 ret = crypto_hash_digest(desc, sg, blen, out);
591 if (ret)
592 goto out;
593 }
594
595 /* The real thing. */
596 for (i = 0; i < 8; i++) {
597 cycles_t start, end;
598
599 start = get_cycles();
600
601 sg_set_buf(sg, p, blen);
602 ret = crypto_hash_digest(desc, sg, blen, out);
603 if (ret)
604 goto out;
605
606 end = get_cycles();
607
608 cycles += end - start;
609 }
610
611out:
612 local_irq_enable();
613 local_bh_enable();
614
615 if (ret)
616 return ret;
617
618 printk("%6lu cycles/operation, %4lu cycles/byte\n",
619 cycles / 8, cycles / (8 * blen));
620
621 return 0;
595} 622}
596 623
597static void test_digest_cycles(struct crypto_tfm *tfm, char *p, int blen, 624static int test_hash_cycles(struct hash_desc *desc, char *p, int blen,
598 int plen, char *out) 625 int plen, char *out)
599{ 626{
600 struct scatterlist sg[1]; 627 struct scatterlist sg[1];
601 unsigned long cycles = 0; 628 unsigned long cycles = 0;
602 int i, pcount; 629 int i, pcount;
630 int ret;
631
632 if (plen == blen)
633 return test_hash_cycles_digest(desc, p, blen, out);
603 634
604 local_bh_disable(); 635 local_bh_disable();
605 local_irq_disable(); 636 local_irq_disable();
606 637
607 /* Warm-up run. */ 638 /* Warm-up run. */
608 for (i = 0; i < 4; i++) { 639 for (i = 0; i < 4; i++) {
609 crypto_digest_init(tfm); 640 ret = crypto_hash_init(desc);
641 if (ret)
642 goto out;
610 for (pcount = 0; pcount < blen; pcount += plen) { 643 for (pcount = 0; pcount < blen; pcount += plen) {
611 sg_set_buf(sg, p + pcount, plen); 644 sg_set_buf(sg, p + pcount, plen);
612 crypto_digest_update(tfm, sg, 1); 645 ret = crypto_hash_update(desc, sg, plen);
646 if (ret)
647 goto out;
613 } 648 }
614 crypto_digest_final(tfm, out); 649 crypto_hash_final(desc, out);
650 if (ret)
651 goto out;
615 } 652 }
616 653
617 /* The real thing. */ 654 /* The real thing. */
618 for (i = 0; i < 8; i++) { 655 for (i = 0; i < 8; i++) {
619 cycles_t start, end; 656 cycles_t start, end;
620 657
621 crypto_digest_init(tfm);
622
623 start = get_cycles(); 658 start = get_cycles();
624 659
660 ret = crypto_hash_init(desc);
661 if (ret)
662 goto out;
625 for (pcount = 0; pcount < blen; pcount += plen) { 663 for (pcount = 0; pcount < blen; pcount += plen) {
626 sg_set_buf(sg, p + pcount, plen); 664 sg_set_buf(sg, p + pcount, plen);
627 crypto_digest_update(tfm, sg, 1); 665 ret = crypto_hash_update(desc, sg, plen);
666 if (ret)
667 goto out;
628 } 668 }
629 crypto_digest_final(tfm, out); 669 ret = crypto_hash_final(desc, out);
670 if (ret)
671 goto out;
630 672
631 end = get_cycles(); 673 end = get_cycles();
632 674
633 cycles += end - start; 675 cycles += end - start;
634 } 676 }
635 677
678out:
636 local_irq_enable(); 679 local_irq_enable();
637 local_bh_enable(); 680 local_bh_enable();
638 681
682 if (ret)
683 return ret;
684
639 printk("%6lu cycles/operation, %4lu cycles/byte\n", 685 printk("%6lu cycles/operation, %4lu cycles/byte\n",
640 cycles / 8, cycles / (8 * blen)); 686 cycles / 8, cycles / (8 * blen));
641 687
642 return; 688 return 0;
643} 689}
644 690
645static void test_digest_speed(char *algo, unsigned int sec, 691static void test_hash_speed(char *algo, unsigned int sec,
646 struct digest_speed *speed) 692 struct hash_speed *speed)
647{ 693{
648 struct crypto_tfm *tfm; 694 struct crypto_hash *tfm;
695 struct hash_desc desc;
649 char output[1024]; 696 char output[1024];
650 int i; 697 int i;
698 int ret;
651 699
652 printk("\ntesting speed of %s\n", algo); 700 printk("\ntesting speed of %s\n", algo);
653 701
654 tfm = crypto_alloc_tfm(algo, 0); 702 tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC);
655 703
656 if (tfm == NULL) { 704 if (IS_ERR(tfm)) {
657 printk("failed to load transform for %s\n", algo); 705 printk("failed to load transform for %s: %ld\n", algo,
706 PTR_ERR(tfm));
658 return; 707 return;
659 } 708 }
660 709
661 if (crypto_tfm_alg_digestsize(tfm) > sizeof(output)) { 710 desc.tfm = tfm;
711 desc.flags = 0;
712
713 if (crypto_hash_digestsize(tfm) > sizeof(output)) {
662 printk("digestsize(%u) > outputbuffer(%zu)\n", 714 printk("digestsize(%u) > outputbuffer(%zu)\n",
663 crypto_tfm_alg_digestsize(tfm), sizeof(output)); 715 crypto_hash_digestsize(tfm), sizeof(output));
664 goto out; 716 goto out;
665 } 717 }
666 718
@@ -677,20 +729,27 @@ static void test_digest_speed(char *algo, unsigned int sec,
677 memset(tvmem, 0xff, speed[i].blen); 729 memset(tvmem, 0xff, speed[i].blen);
678 730
679 if (sec) 731 if (sec)
680 test_digest_jiffies(tfm, tvmem, speed[i].blen, speed[i].plen, output, sec); 732 ret = test_hash_jiffies(&desc, tvmem, speed[i].blen,
733 speed[i].plen, output, sec);
681 else 734 else
682 test_digest_cycles(tfm, tvmem, speed[i].blen, speed[i].plen, output); 735 ret = test_hash_cycles(&desc, tvmem, speed[i].blen,
736 speed[i].plen, output);
737
738 if (ret) {
739 printk("hashing failed ret=%d\n", ret);
740 break;
741 }
683 } 742 }
684 743
685out: 744out:
686 crypto_free_tfm(tfm); 745 crypto_free_hash(tfm);
687} 746}
688 747
689static void test_deflate(void) 748static void test_deflate(void)
690{ 749{
691 unsigned int i; 750 unsigned int i;
692 char result[COMP_BUF_SIZE]; 751 char result[COMP_BUF_SIZE];
693 struct crypto_tfm *tfm; 752 struct crypto_comp *tfm;
694 struct comp_testvec *tv; 753 struct comp_testvec *tv;
695 unsigned int tsize; 754 unsigned int tsize;
696 755
@@ -762,105 +821,7 @@ static void test_deflate(void)
762 ilen, dlen); 821 ilen, dlen);
763 } 822 }
764out: 823out:
765 crypto_free_tfm(tfm); 824 crypto_free_comp(tfm);
766}
767
768static void test_crc32c(void)
769{
770#define NUMVEC 6
771#define VECSIZE 40
772
773 int i, j, pass;
774 u32 crc;
775 u8 b, test_vec[NUMVEC][VECSIZE];
776 static u32 vec_results[NUMVEC] = {
777 0x0e2c157f, 0xe980ebf6, 0xde74bded,
778 0xd579c862, 0xba979ad0, 0x2b29d913
779 };
780 static u32 tot_vec_results = 0x24c5d375;
781
782 struct scatterlist sg[NUMVEC];
783 struct crypto_tfm *tfm;
784 char *fmtdata = "testing crc32c initialized to %08x: %s\n";
785#define SEEDTESTVAL 0xedcba987
786 u32 seed;
787
788 printk("\ntesting crc32c\n");
789
790 tfm = crypto_alloc_tfm("crc32c", 0);
791 if (tfm == NULL) {
792 printk("failed to load transform for crc32c\n");
793 return;
794 }
795
796 crypto_digest_init(tfm);
797 crypto_digest_final(tfm, (u8*)&crc);
798 printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR");
799
800 /*
801 * stuff test_vec with known values, simple incrementing
802 * byte values.
803 */
804 b = 0;
805 for (i = 0; i < NUMVEC; i++) {
806 for (j = 0; j < VECSIZE; j++)
807 test_vec[i][j] = ++b;
808 sg_set_buf(&sg[i], test_vec[i], VECSIZE);
809 }
810
811 seed = SEEDTESTVAL;
812 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
813 crypto_digest_final(tfm, (u8*)&crc);
814 printk("testing crc32c setkey returns %08x : %s\n", crc, (crc == (SEEDTESTVAL ^ ~(u32)0)) ?
815 "pass" : "ERROR");
816
817 printk("testing crc32c using update/final:\n");
818
819 pass = 1; /* assume all is well */
820
821 for (i = 0; i < NUMVEC; i++) {
822 seed = ~(u32)0;
823 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
824 crypto_digest_update(tfm, &sg[i], 1);
825 crypto_digest_final(tfm, (u8*)&crc);
826 if (crc == vec_results[i]) {
827 printk(" %08x:OK", crc);
828 } else {
829 printk(" %08x:BAD, wanted %08x\n", crc, vec_results[i]);
830 pass = 0;
831 }
832 }
833
834 printk("\ntesting crc32c using incremental accumulator:\n");
835 crc = 0;
836 for (i = 0; i < NUMVEC; i++) {
837 seed = (crc ^ ~(u32)0);
838 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
839 crypto_digest_update(tfm, &sg[i], 1);
840 crypto_digest_final(tfm, (u8*)&crc);
841 }
842 if (crc == tot_vec_results) {
843 printk(" %08x:OK", crc);
844 } else {
845 printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
846 pass = 0;
847 }
848
849 printk("\ntesting crc32c using digest:\n");
850 seed = ~(u32)0;
851 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
852 crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&crc);
853 if (crc == tot_vec_results) {
854 printk(" %08x:OK", crc);
855 } else {
856 printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
857 pass = 0;
858 }
859
860 printk("\n%s\n", pass ? "pass" : "ERROR");
861
862 crypto_free_tfm(tfm);
863 printk("crc32c test complete\n");
864} 825}
865 826
866static void test_available(void) 827static void test_available(void)
@@ -869,8 +830,8 @@ static void test_available(void)
869 830
870 while (*name) { 831 while (*name) {
871 printk("alg %s ", *name); 832 printk("alg %s ", *name);
872 printk((crypto_alg_available(*name, 0)) ? 833 printk(crypto_has_alg(*name, 0, CRYPTO_ALG_ASYNC) ?
873 "found\n" : "not found\n"); 834 "found\n" : "not found\n");
874 name++; 835 name++;
875 } 836 }
876} 837}
@@ -885,79 +846,119 @@ static void do_test(void)
885 test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS); 846 test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
886 847
887 //DES 848 //DES
888 test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS); 849 test_cipher("ecb(des)", ENCRYPT, des_enc_tv_template,
889 test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS); 850 DES_ENC_TEST_VECTORS);
890 test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS); 851 test_cipher("ecb(des)", DECRYPT, des_dec_tv_template,
891 test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS); 852 DES_DEC_TEST_VECTORS);
853 test_cipher("cbc(des)", ENCRYPT, des_cbc_enc_tv_template,
854 DES_CBC_ENC_TEST_VECTORS);
855 test_cipher("cbc(des)", DECRYPT, des_cbc_dec_tv_template,
856 DES_CBC_DEC_TEST_VECTORS);
892 857
893 //DES3_EDE 858 //DES3_EDE
894 test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS); 859 test_cipher("ecb(des3_ede)", ENCRYPT, des3_ede_enc_tv_template,
895 test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS); 860 DES3_EDE_ENC_TEST_VECTORS);
861 test_cipher("ecb(des3_ede)", DECRYPT, des3_ede_dec_tv_template,
862 DES3_EDE_DEC_TEST_VECTORS);
896 863
897 test_hash("md4", md4_tv_template, MD4_TEST_VECTORS); 864 test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
898 865
899 test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS); 866 test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
900 867
901 //BLOWFISH 868 //BLOWFISH
902 test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS); 869 test_cipher("ecb(blowfish)", ENCRYPT, bf_enc_tv_template,
903 test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS); 870 BF_ENC_TEST_VECTORS);
904 test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS); 871 test_cipher("ecb(blowfish)", DECRYPT, bf_dec_tv_template,
905 test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS); 872 BF_DEC_TEST_VECTORS);
873 test_cipher("cbc(blowfish)", ENCRYPT, bf_cbc_enc_tv_template,
874 BF_CBC_ENC_TEST_VECTORS);
875 test_cipher("cbc(blowfish)", DECRYPT, bf_cbc_dec_tv_template,
876 BF_CBC_DEC_TEST_VECTORS);
906 877
907 //TWOFISH 878 //TWOFISH
908 test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS); 879 test_cipher("ecb(twofish)", ENCRYPT, tf_enc_tv_template,
909 test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS); 880 TF_ENC_TEST_VECTORS);
910 test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS); 881 test_cipher("ecb(twofish)", DECRYPT, tf_dec_tv_template,
911 test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS); 882 TF_DEC_TEST_VECTORS);
883 test_cipher("cbc(twofish)", ENCRYPT, tf_cbc_enc_tv_template,
884 TF_CBC_ENC_TEST_VECTORS);
885 test_cipher("cbc(twofish)", DECRYPT, tf_cbc_dec_tv_template,
886 TF_CBC_DEC_TEST_VECTORS);
912 887
913 //SERPENT 888 //SERPENT
914 test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS); 889 test_cipher("ecb(serpent)", ENCRYPT, serpent_enc_tv_template,
915 test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS); 890 SERPENT_ENC_TEST_VECTORS);
891 test_cipher("ecb(serpent)", DECRYPT, serpent_dec_tv_template,
892 SERPENT_DEC_TEST_VECTORS);
916 893
917 //TNEPRES 894 //TNEPRES
918 test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS); 895 test_cipher("ecb(tnepres)", ENCRYPT, tnepres_enc_tv_template,
919 test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS); 896 TNEPRES_ENC_TEST_VECTORS);
897 test_cipher("ecb(tnepres)", DECRYPT, tnepres_dec_tv_template,
898 TNEPRES_DEC_TEST_VECTORS);
920 899
921 //AES 900 //AES
922 test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS); 901 test_cipher("ecb(aes)", ENCRYPT, aes_enc_tv_template,
923 test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS); 902 AES_ENC_TEST_VECTORS);
924 test_cipher ("aes", MODE_CBC, ENCRYPT, aes_cbc_enc_tv_template, AES_CBC_ENC_TEST_VECTORS); 903 test_cipher("ecb(aes)", DECRYPT, aes_dec_tv_template,
925 test_cipher ("aes", MODE_CBC, DECRYPT, aes_cbc_dec_tv_template, AES_CBC_DEC_TEST_VECTORS); 904 AES_DEC_TEST_VECTORS);
905 test_cipher("cbc(aes)", ENCRYPT, aes_cbc_enc_tv_template,
906 AES_CBC_ENC_TEST_VECTORS);
907 test_cipher("cbc(aes)", DECRYPT, aes_cbc_dec_tv_template,
908 AES_CBC_DEC_TEST_VECTORS);
926 909
927 //CAST5 910 //CAST5
928 test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS); 911 test_cipher("ecb(cast5)", ENCRYPT, cast5_enc_tv_template,
929 test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS); 912 CAST5_ENC_TEST_VECTORS);
913 test_cipher("ecb(cast5)", DECRYPT, cast5_dec_tv_template,
914 CAST5_DEC_TEST_VECTORS);
930 915
931 //CAST6 916 //CAST6
932 test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS); 917 test_cipher("ecb(cast6)", ENCRYPT, cast6_enc_tv_template,
933 test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); 918 CAST6_ENC_TEST_VECTORS);
919 test_cipher("ecb(cast6)", DECRYPT, cast6_dec_tv_template,
920 CAST6_DEC_TEST_VECTORS);
934 921
935 //ARC4 922 //ARC4
936 test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); 923 test_cipher("ecb(arc4)", ENCRYPT, arc4_enc_tv_template,
937 test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); 924 ARC4_ENC_TEST_VECTORS);
925 test_cipher("ecb(arc4)", DECRYPT, arc4_dec_tv_template,
926 ARC4_DEC_TEST_VECTORS);
938 927
939 //TEA 928 //TEA
940 test_cipher ("tea", MODE_ECB, ENCRYPT, tea_enc_tv_template, TEA_ENC_TEST_VECTORS); 929 test_cipher("ecb(tea)", ENCRYPT, tea_enc_tv_template,
941 test_cipher ("tea", MODE_ECB, DECRYPT, tea_dec_tv_template, TEA_DEC_TEST_VECTORS); 930 TEA_ENC_TEST_VECTORS);
931 test_cipher("ecb(tea)", DECRYPT, tea_dec_tv_template,
932 TEA_DEC_TEST_VECTORS);
942 933
943 934
944 //XTEA 935 //XTEA
945 test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS); 936 test_cipher("ecb(xtea)", ENCRYPT, xtea_enc_tv_template,
946 test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS); 937 XTEA_ENC_TEST_VECTORS);
938 test_cipher("ecb(xtea)", DECRYPT, xtea_dec_tv_template,
939 XTEA_DEC_TEST_VECTORS);
947 940
948 //KHAZAD 941 //KHAZAD
949 test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS); 942 test_cipher("ecb(khazad)", ENCRYPT, khazad_enc_tv_template,
950 test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS); 943 KHAZAD_ENC_TEST_VECTORS);
944 test_cipher("ecb(khazad)", DECRYPT, khazad_dec_tv_template,
945 KHAZAD_DEC_TEST_VECTORS);
951 946
952 //ANUBIS 947 //ANUBIS
953 test_cipher ("anubis", MODE_ECB, ENCRYPT, anubis_enc_tv_template, ANUBIS_ENC_TEST_VECTORS); 948 test_cipher("ecb(anubis)", ENCRYPT, anubis_enc_tv_template,
954 test_cipher ("anubis", MODE_ECB, DECRYPT, anubis_dec_tv_template, ANUBIS_DEC_TEST_VECTORS); 949 ANUBIS_ENC_TEST_VECTORS);
955 test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); 950 test_cipher("ecb(anubis)", DECRYPT, anubis_dec_tv_template,
956 test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); 951 ANUBIS_DEC_TEST_VECTORS);
952 test_cipher("cbc(anubis)", ENCRYPT, anubis_cbc_enc_tv_template,
953 ANUBIS_CBC_ENC_TEST_VECTORS);
954 test_cipher("cbc(anubis)", DECRYPT, anubis_cbc_dec_tv_template,
955 ANUBIS_CBC_ENC_TEST_VECTORS);
957 956
958 //XETA 957 //XETA
959 test_cipher ("xeta", MODE_ECB, ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS); 958 test_cipher("ecb(xeta)", ENCRYPT, xeta_enc_tv_template,
960 test_cipher ("xeta", MODE_ECB, DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS); 959 XETA_ENC_TEST_VECTORS);
960 test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template,
961 XETA_DEC_TEST_VECTORS);
961 962
962 test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); 963 test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
963 test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); 964 test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
@@ -968,12 +969,13 @@ static void do_test(void)
968 test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS); 969 test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS);
969 test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS); 970 test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
970 test_deflate(); 971 test_deflate();
971 test_crc32c(); 972 test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS);
972#ifdef CONFIG_CRYPTO_HMAC 973 test_hash("hmac(md5)", hmac_md5_tv_template,
973 test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); 974 HMAC_MD5_TEST_VECTORS);
974 test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); 975 test_hash("hmac(sha1)", hmac_sha1_tv_template,
975 test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); 976 HMAC_SHA1_TEST_VECTORS);
976#endif 977 test_hash("hmac(sha256)", hmac_sha256_tv_template,
978 HMAC_SHA256_TEST_VECTORS);
977 979
978 test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); 980 test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
979 break; 981 break;
@@ -987,15 +989,21 @@ static void do_test(void)
987 break; 989 break;
988 990
989 case 3: 991 case 3:
990 test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS); 992 test_cipher("ecb(des)", ENCRYPT, des_enc_tv_template,
991 test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS); 993 DES_ENC_TEST_VECTORS);
992 test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS); 994 test_cipher("ecb(des)", DECRYPT, des_dec_tv_template,
993 test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS); 995 DES_DEC_TEST_VECTORS);
996 test_cipher("cbc(des)", ENCRYPT, des_cbc_enc_tv_template,
997 DES_CBC_ENC_TEST_VECTORS);
998 test_cipher("cbc(des)", DECRYPT, des_cbc_dec_tv_template,
999 DES_CBC_DEC_TEST_VECTORS);
994 break; 1000 break;
995 1001
996 case 4: 1002 case 4:
997 test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS); 1003 test_cipher("ecb(des3_ede)", ENCRYPT, des3_ede_enc_tv_template,
998 test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS); 1004 DES3_EDE_ENC_TEST_VECTORS);
1005 test_cipher("ecb(des3_ede)", DECRYPT, des3_ede_dec_tv_template,
1006 DES3_EDE_DEC_TEST_VECTORS);
999 break; 1007 break;
1000 1008
1001 case 5: 1009 case 5:
@@ -1007,29 +1015,43 @@ static void do_test(void)
1007 break; 1015 break;
1008 1016
1009 case 7: 1017 case 7:
1010 test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS); 1018 test_cipher("ecb(blowfish)", ENCRYPT, bf_enc_tv_template,
1011 test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS); 1019 BF_ENC_TEST_VECTORS);
1012 test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS); 1020 test_cipher("ecb(blowfish)", DECRYPT, bf_dec_tv_template,
1013 test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS); 1021 BF_DEC_TEST_VECTORS);
1022 test_cipher("cbc(blowfish)", ENCRYPT, bf_cbc_enc_tv_template,
1023 BF_CBC_ENC_TEST_VECTORS);
1024 test_cipher("cbc(blowfish)", DECRYPT, bf_cbc_dec_tv_template,
1025 BF_CBC_DEC_TEST_VECTORS);
1014 break; 1026 break;
1015 1027
1016 case 8: 1028 case 8:
1017 test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS); 1029 test_cipher("ecb(twofish)", ENCRYPT, tf_enc_tv_template,
1018 test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS); 1030 TF_ENC_TEST_VECTORS);
1019 test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS); 1031 test_cipher("ecb(twofish)", DECRYPT, tf_dec_tv_template,
1020 test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS); 1032 TF_DEC_TEST_VECTORS);
1033 test_cipher("cbc(twofish)", ENCRYPT, tf_cbc_enc_tv_template,
1034 TF_CBC_ENC_TEST_VECTORS);
1035 test_cipher("cbc(twofish)", DECRYPT, tf_cbc_dec_tv_template,
1036 TF_CBC_DEC_TEST_VECTORS);
1021 break; 1037 break;
1022 1038
1023 case 9: 1039 case 9:
1024 test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS); 1040 test_cipher("ecb(serpent)", ENCRYPT, serpent_enc_tv_template,
1025 test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS); 1041 SERPENT_ENC_TEST_VECTORS);
1042 test_cipher("ecb(serpent)", DECRYPT, serpent_dec_tv_template,
1043 SERPENT_DEC_TEST_VECTORS);
1026 break; 1044 break;
1027 1045
1028 case 10: 1046 case 10:
1029 test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS); 1047 test_cipher("ecb(aes)", ENCRYPT, aes_enc_tv_template,
1030 test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS); 1048 AES_ENC_TEST_VECTORS);
1031 test_cipher ("aes", MODE_CBC, ENCRYPT, aes_cbc_enc_tv_template, AES_CBC_ENC_TEST_VECTORS); 1049 test_cipher("ecb(aes)", DECRYPT, aes_dec_tv_template,
1032 test_cipher ("aes", MODE_CBC, DECRYPT, aes_cbc_dec_tv_template, AES_CBC_DEC_TEST_VECTORS); 1050 AES_DEC_TEST_VECTORS);
1051 test_cipher("cbc(aes)", ENCRYPT, aes_cbc_enc_tv_template,
1052 AES_CBC_ENC_TEST_VECTORS);
1053 test_cipher("cbc(aes)", DECRYPT, aes_cbc_dec_tv_template,
1054 AES_CBC_DEC_TEST_VECTORS);
1033 break; 1055 break;
1034 1056
1035 case 11: 1057 case 11:
@@ -1045,18 +1067,24 @@ static void do_test(void)
1045 break; 1067 break;
1046 1068
1047 case 14: 1069 case 14:
1048 test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS); 1070 test_cipher("ecb(cast5)", ENCRYPT, cast5_enc_tv_template,
1049 test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS); 1071 CAST5_ENC_TEST_VECTORS);
1072 test_cipher("ecb(cast5)", DECRYPT, cast5_dec_tv_template,
1073 CAST5_DEC_TEST_VECTORS);
1050 break; 1074 break;
1051 1075
1052 case 15: 1076 case 15:
1053 test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS); 1077 test_cipher("ecb(cast6)", ENCRYPT, cast6_enc_tv_template,
1054 test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); 1078 CAST6_ENC_TEST_VECTORS);
1079 test_cipher("ecb(cast6)", DECRYPT, cast6_dec_tv_template,
1080 CAST6_DEC_TEST_VECTORS);
1055 break; 1081 break;
1056 1082
1057 case 16: 1083 case 16:
1058 test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); 1084 test_cipher("ecb(arc4)", ENCRYPT, arc4_enc_tv_template,
1059 test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); 1085 ARC4_ENC_TEST_VECTORS);
1086 test_cipher("ecb(arc4)", DECRYPT, arc4_dec_tv_template,
1087 ARC4_DEC_TEST_VECTORS);
1060 break; 1088 break;
1061 1089
1062 case 17: 1090 case 17:
@@ -1064,22 +1092,28 @@ static void do_test(void)
1064 break; 1092 break;
1065 1093
1066 case 18: 1094 case 18:
1067 test_crc32c(); 1095 test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS);
1068 break; 1096 break;
1069 1097
1070 case 19: 1098 case 19:
1071 test_cipher ("tea", MODE_ECB, ENCRYPT, tea_enc_tv_template, TEA_ENC_TEST_VECTORS); 1099 test_cipher("ecb(tea)", ENCRYPT, tea_enc_tv_template,
1072 test_cipher ("tea", MODE_ECB, DECRYPT, tea_dec_tv_template, TEA_DEC_TEST_VECTORS); 1100 TEA_ENC_TEST_VECTORS);
1101 test_cipher("ecb(tea)", DECRYPT, tea_dec_tv_template,
1102 TEA_DEC_TEST_VECTORS);
1073 break; 1103 break;
1074 1104
1075 case 20: 1105 case 20:
1076 test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS); 1106 test_cipher("ecb(xtea)", ENCRYPT, xtea_enc_tv_template,
1077 test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS); 1107 XTEA_ENC_TEST_VECTORS);
1108 test_cipher("ecb(xtea)", DECRYPT, xtea_dec_tv_template,
1109 XTEA_DEC_TEST_VECTORS);
1078 break; 1110 break;
1079 1111
1080 case 21: 1112 case 21:
1081 test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS); 1113 test_cipher("ecb(khazad)", ENCRYPT, khazad_enc_tv_template,
1082 test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS); 1114 KHAZAD_ENC_TEST_VECTORS);
1115 test_cipher("ecb(khazad)", DECRYPT, khazad_dec_tv_template,
1116 KHAZAD_DEC_TEST_VECTORS);
1083 break; 1117 break;
1084 1118
1085 case 22: 1119 case 22:
@@ -1095,15 +1129,21 @@ static void do_test(void)
1095 break; 1129 break;
1096 1130
1097 case 25: 1131 case 25:
1098 test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS); 1132 test_cipher("ecb(tnepres)", ENCRYPT, tnepres_enc_tv_template,
1099 test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS); 1133 TNEPRES_ENC_TEST_VECTORS);
1134 test_cipher("ecb(tnepres)", DECRYPT, tnepres_dec_tv_template,
1135 TNEPRES_DEC_TEST_VECTORS);
1100 break; 1136 break;
1101 1137
1102 case 26: 1138 case 26:
1103 test_cipher ("anubis", MODE_ECB, ENCRYPT, anubis_enc_tv_template, ANUBIS_ENC_TEST_VECTORS); 1139 test_cipher("ecb(anubis)", ENCRYPT, anubis_enc_tv_template,
1104 test_cipher ("anubis", MODE_ECB, DECRYPT, anubis_dec_tv_template, ANUBIS_DEC_TEST_VECTORS); 1140 ANUBIS_ENC_TEST_VECTORS);
1105 test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); 1141 test_cipher("ecb(anubis)", DECRYPT, anubis_dec_tv_template,
1106 test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); 1142 ANUBIS_DEC_TEST_VECTORS);
1143 test_cipher("cbc(anubis)", ENCRYPT, anubis_cbc_enc_tv_template,
1144 ANUBIS_CBC_ENC_TEST_VECTORS);
1145 test_cipher("cbc(anubis)", DECRYPT, anubis_cbc_dec_tv_template,
1146 ANUBIS_CBC_ENC_TEST_VECTORS);
1107 break; 1147 break;
1108 1148
1109 case 27: 1149 case 27:
@@ -1120,85 +1160,88 @@ static void do_test(void)
1120 break; 1160 break;
1121 1161
1122 case 30: 1162 case 30:
1123 test_cipher ("xeta", MODE_ECB, ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS); 1163 test_cipher("ecb(xeta)", ENCRYPT, xeta_enc_tv_template,
1124 test_cipher ("xeta", MODE_ECB, DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS); 1164 XETA_ENC_TEST_VECTORS);
1165 test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template,
1166 XETA_DEC_TEST_VECTORS);
1125 break; 1167 break;
1126 1168
1127#ifdef CONFIG_CRYPTO_HMAC
1128 case 100: 1169 case 100:
1129 test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); 1170 test_hash("hmac(md5)", hmac_md5_tv_template,
1171 HMAC_MD5_TEST_VECTORS);
1130 break; 1172 break;
1131 1173
1132 case 101: 1174 case 101:
1133 test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); 1175 test_hash("hmac(sha1)", hmac_sha1_tv_template,
1176 HMAC_SHA1_TEST_VECTORS);
1134 break; 1177 break;
1135 1178
1136 case 102: 1179 case 102:
1137 test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); 1180 test_hash("hmac(sha256)", hmac_sha256_tv_template,
1181 HMAC_SHA256_TEST_VECTORS);
1138 break; 1182 break;
1139 1183
1140#endif
1141 1184
1142 case 200: 1185 case 200:
1143 test_cipher_speed("aes", MODE_ECB, ENCRYPT, sec, NULL, 0, 1186 test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
1144 aes_speed_template); 1187 aes_speed_template);
1145 test_cipher_speed("aes", MODE_ECB, DECRYPT, sec, NULL, 0, 1188 test_cipher_speed("ecb(aes)", DECRYPT, sec, NULL, 0,
1146 aes_speed_template); 1189 aes_speed_template);
1147 test_cipher_speed("aes", MODE_CBC, ENCRYPT, sec, NULL, 0, 1190 test_cipher_speed("cbc(aes)", ENCRYPT, sec, NULL, 0,
1148 aes_speed_template); 1191 aes_speed_template);
1149 test_cipher_speed("aes", MODE_CBC, DECRYPT, sec, NULL, 0, 1192 test_cipher_speed("cbc(aes)", DECRYPT, sec, NULL, 0,
1150 aes_speed_template); 1193 aes_speed_template);
1151 break; 1194 break;
1152 1195
1153 case 201: 1196 case 201:
1154 test_cipher_speed("des3_ede", MODE_ECB, ENCRYPT, sec, 1197 test_cipher_speed("ecb(des3_ede)", ENCRYPT, sec,
1155 des3_ede_enc_tv_template, 1198 des3_ede_enc_tv_template,
1156 DES3_EDE_ENC_TEST_VECTORS, 1199 DES3_EDE_ENC_TEST_VECTORS,
1157 des3_ede_speed_template); 1200 des3_ede_speed_template);
1158 test_cipher_speed("des3_ede", MODE_ECB, DECRYPT, sec, 1201 test_cipher_speed("ecb(des3_ede)", DECRYPT, sec,
1159 des3_ede_dec_tv_template, 1202 des3_ede_dec_tv_template,
1160 DES3_EDE_DEC_TEST_VECTORS, 1203 DES3_EDE_DEC_TEST_VECTORS,
1161 des3_ede_speed_template); 1204 des3_ede_speed_template);
1162 test_cipher_speed("des3_ede", MODE_CBC, ENCRYPT, sec, 1205 test_cipher_speed("cbc(des3_ede)", ENCRYPT, sec,
1163 des3_ede_enc_tv_template, 1206 des3_ede_enc_tv_template,
1164 DES3_EDE_ENC_TEST_VECTORS, 1207 DES3_EDE_ENC_TEST_VECTORS,
1165 des3_ede_speed_template); 1208 des3_ede_speed_template);
1166 test_cipher_speed("des3_ede", MODE_CBC, DECRYPT, sec, 1209 test_cipher_speed("cbc(des3_ede)", DECRYPT, sec,
1167 des3_ede_dec_tv_template, 1210 des3_ede_dec_tv_template,
1168 DES3_EDE_DEC_TEST_VECTORS, 1211 DES3_EDE_DEC_TEST_VECTORS,
1169 des3_ede_speed_template); 1212 des3_ede_speed_template);
1170 break; 1213 break;
1171 1214
1172 case 202: 1215 case 202:
1173 test_cipher_speed("twofish", MODE_ECB, ENCRYPT, sec, NULL, 0, 1216 test_cipher_speed("ecb(twofish)", ENCRYPT, sec, NULL, 0,
1174 twofish_speed_template); 1217 twofish_speed_template);
1175 test_cipher_speed("twofish", MODE_ECB, DECRYPT, sec, NULL, 0, 1218 test_cipher_speed("ecb(twofish)", DECRYPT, sec, NULL, 0,
1176 twofish_speed_template); 1219 twofish_speed_template);
1177 test_cipher_speed("twofish", MODE_CBC, ENCRYPT, sec, NULL, 0, 1220 test_cipher_speed("cbc(twofish)", ENCRYPT, sec, NULL, 0,
1178 twofish_speed_template); 1221 twofish_speed_template);
1179 test_cipher_speed("twofish", MODE_CBC, DECRYPT, sec, NULL, 0, 1222 test_cipher_speed("cbc(twofish)", DECRYPT, sec, NULL, 0,
1180 twofish_speed_template); 1223 twofish_speed_template);
1181 break; 1224 break;
1182 1225
1183 case 203: 1226 case 203:
1184 test_cipher_speed("blowfish", MODE_ECB, ENCRYPT, sec, NULL, 0, 1227 test_cipher_speed("ecb(blowfish)", ENCRYPT, sec, NULL, 0,
1185 blowfish_speed_template); 1228 blowfish_speed_template);
1186 test_cipher_speed("blowfish", MODE_ECB, DECRYPT, sec, NULL, 0, 1229 test_cipher_speed("ecb(blowfish)", DECRYPT, sec, NULL, 0,
1187 blowfish_speed_template); 1230 blowfish_speed_template);
1188 test_cipher_speed("blowfish", MODE_CBC, ENCRYPT, sec, NULL, 0, 1231 test_cipher_speed("cbc(blowfish)", ENCRYPT, sec, NULL, 0,
1189 blowfish_speed_template); 1232 blowfish_speed_template);
1190 test_cipher_speed("blowfish", MODE_CBC, DECRYPT, sec, NULL, 0, 1233 test_cipher_speed("cbc(blowfish)", DECRYPT, sec, NULL, 0,
1191 blowfish_speed_template); 1234 blowfish_speed_template);
1192 break; 1235 break;
1193 1236
1194 case 204: 1237 case 204:
1195 test_cipher_speed("des", MODE_ECB, ENCRYPT, sec, NULL, 0, 1238 test_cipher_speed("ecb(des)", ENCRYPT, sec, NULL, 0,
1196 des_speed_template); 1239 des_speed_template);
1197 test_cipher_speed("des", MODE_ECB, DECRYPT, sec, NULL, 0, 1240 test_cipher_speed("ecb(des)", DECRYPT, sec, NULL, 0,
1198 des_speed_template); 1241 des_speed_template);
1199 test_cipher_speed("des", MODE_CBC, ENCRYPT, sec, NULL, 0, 1242 test_cipher_speed("cbc(des)", ENCRYPT, sec, NULL, 0,
1200 des_speed_template); 1243 des_speed_template);
1201 test_cipher_speed("des", MODE_CBC, DECRYPT, sec, NULL, 0, 1244 test_cipher_speed("cbc(des)", DECRYPT, sec, NULL, 0,
1202 des_speed_template); 1245 des_speed_template);
1203 break; 1246 break;
1204 1247
@@ -1206,51 +1249,51 @@ static void do_test(void)
1206 /* fall through */ 1249 /* fall through */
1207 1250
1208 case 301: 1251 case 301:
1209 test_digest_speed("md4", sec, generic_digest_speed_template); 1252 test_hash_speed("md4", sec, generic_hash_speed_template);
1210 if (mode > 300 && mode < 400) break; 1253 if (mode > 300 && mode < 400) break;
1211 1254
1212 case 302: 1255 case 302:
1213 test_digest_speed("md5", sec, generic_digest_speed_template); 1256 test_hash_speed("md5", sec, generic_hash_speed_template);
1214 if (mode > 300 && mode < 400) break; 1257 if (mode > 300 && mode < 400) break;
1215 1258
1216 case 303: 1259 case 303:
1217 test_digest_speed("sha1", sec, generic_digest_speed_template); 1260 test_hash_speed("sha1", sec, generic_hash_speed_template);
1218 if (mode > 300 && mode < 400) break; 1261 if (mode > 300 && mode < 400) break;
1219 1262
1220 case 304: 1263 case 304:
1221 test_digest_speed("sha256", sec, generic_digest_speed_template); 1264 test_hash_speed("sha256", sec, generic_hash_speed_template);
1222 if (mode > 300 && mode < 400) break; 1265 if (mode > 300 && mode < 400) break;
1223 1266
1224 case 305: 1267 case 305:
1225 test_digest_speed("sha384", sec, generic_digest_speed_template); 1268 test_hash_speed("sha384", sec, generic_hash_speed_template);
1226 if (mode > 300 && mode < 400) break; 1269 if (mode > 300 && mode < 400) break;
1227 1270
1228 case 306: 1271 case 306:
1229 test_digest_speed("sha512", sec, generic_digest_speed_template); 1272 test_hash_speed("sha512", sec, generic_hash_speed_template);
1230 if (mode > 300 && mode < 400) break; 1273 if (mode > 300 && mode < 400) break;
1231 1274
1232 case 307: 1275 case 307:
1233 test_digest_speed("wp256", sec, generic_digest_speed_template); 1276 test_hash_speed("wp256", sec, generic_hash_speed_template);
1234 if (mode > 300 && mode < 400) break; 1277 if (mode > 300 && mode < 400) break;
1235 1278
1236 case 308: 1279 case 308:
1237 test_digest_speed("wp384", sec, generic_digest_speed_template); 1280 test_hash_speed("wp384", sec, generic_hash_speed_template);
1238 if (mode > 300 && mode < 400) break; 1281 if (mode > 300 && mode < 400) break;
1239 1282
1240 case 309: 1283 case 309:
1241 test_digest_speed("wp512", sec, generic_digest_speed_template); 1284 test_hash_speed("wp512", sec, generic_hash_speed_template);
1242 if (mode > 300 && mode < 400) break; 1285 if (mode > 300 && mode < 400) break;
1243 1286
1244 case 310: 1287 case 310:
1245 test_digest_speed("tgr128", sec, generic_digest_speed_template); 1288 test_hash_speed("tgr128", sec, generic_hash_speed_template);
1246 if (mode > 300 && mode < 400) break; 1289 if (mode > 300 && mode < 400) break;
1247 1290
1248 case 311: 1291 case 311:
1249 test_digest_speed("tgr160", sec, generic_digest_speed_template); 1292 test_hash_speed("tgr160", sec, generic_hash_speed_template);
1250 if (mode > 300 && mode < 400) break; 1293 if (mode > 300 && mode < 400) break;
1251 1294
1252 case 312: 1295 case 312:
1253 test_digest_speed("tgr192", sec, generic_digest_speed_template); 1296 test_hash_speed("tgr192", sec, generic_hash_speed_template);
1254 if (mode > 300 && mode < 400) break; 1297 if (mode > 300 && mode < 400) break;
1255 1298
1256 case 399: 1299 case 399:
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 1fac5602f633..a40c4411729e 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -28,7 +28,7 @@
28struct hash_testvec { 28struct hash_testvec {
29 /* only used with keyed hash algorithms */ 29 /* only used with keyed hash algorithms */
30 char key[128] __attribute__ ((__aligned__(4))); 30 char key[128] __attribute__ ((__aligned__(4)));
31 char plaintext[128]; 31 char plaintext[240];
32 char digest[MAX_DIGEST_SIZE]; 32 char digest[MAX_DIGEST_SIZE];
33 unsigned char tap[MAX_TAP]; 33 unsigned char tap[MAX_TAP];
34 unsigned char psize; 34 unsigned char psize;
@@ -36,16 +36,6 @@ struct hash_testvec {
36 unsigned char ksize; 36 unsigned char ksize;
37}; 37};
38 38
39struct hmac_testvec {
40 char key[128];
41 char plaintext[128];
42 char digest[MAX_DIGEST_SIZE];
43 unsigned char tap[MAX_TAP];
44 unsigned char ksize;
45 unsigned char psize;
46 unsigned char np;
47};
48
49struct cipher_testvec { 39struct cipher_testvec {
50 char key[MAX_KEYLEN] __attribute__ ((__aligned__(4))); 40 char key[MAX_KEYLEN] __attribute__ ((__aligned__(4)));
51 char iv[MAX_IVLEN]; 41 char iv[MAX_IVLEN];
@@ -65,7 +55,7 @@ struct cipher_speed {
65 unsigned int blen; 55 unsigned int blen;
66}; 56};
67 57
68struct digest_speed { 58struct hash_speed {
69 unsigned int blen; /* buffer length */ 59 unsigned int blen; /* buffer length */
70 unsigned int plen; /* per-update length */ 60 unsigned int plen; /* per-update length */
71}; 61};
@@ -697,14 +687,13 @@ static struct hash_testvec tgr128_tv_template[] = {
697 }, 687 },
698}; 688};
699 689
700#ifdef CONFIG_CRYPTO_HMAC
701/* 690/*
702 * HMAC-MD5 test vectors from RFC2202 691 * HMAC-MD5 test vectors from RFC2202
703 * (These need to be fixed to not use strlen). 692 * (These need to be fixed to not use strlen).
704 */ 693 */
705#define HMAC_MD5_TEST_VECTORS 7 694#define HMAC_MD5_TEST_VECTORS 7
706 695
707static struct hmac_testvec hmac_md5_tv_template[] = 696static struct hash_testvec hmac_md5_tv_template[] =
708{ 697{
709 { 698 {
710 .key = { [0 ... 15] = 0x0b }, 699 .key = { [0 ... 15] = 0x0b },
@@ -768,7 +757,7 @@ static struct hmac_testvec hmac_md5_tv_template[] =
768 */ 757 */
769#define HMAC_SHA1_TEST_VECTORS 7 758#define HMAC_SHA1_TEST_VECTORS 7
770 759
771static struct hmac_testvec hmac_sha1_tv_template[] = { 760static struct hash_testvec hmac_sha1_tv_template[] = {
772 { 761 {
773 .key = { [0 ... 19] = 0x0b }, 762 .key = { [0 ... 19] = 0x0b },
774 .ksize = 20, 763 .ksize = 20,
@@ -833,7 +822,7 @@ static struct hmac_testvec hmac_sha1_tv_template[] = {
833 */ 822 */
834#define HMAC_SHA256_TEST_VECTORS 10 823#define HMAC_SHA256_TEST_VECTORS 10
835 824
836static struct hmac_testvec hmac_sha256_tv_template[] = { 825static struct hash_testvec hmac_sha256_tv_template[] = {
837 { 826 {
838 .key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 827 .key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
839 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 828 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
@@ -944,8 +933,6 @@ static struct hmac_testvec hmac_sha256_tv_template[] = {
944 }, 933 },
945}; 934};
946 935
947#endif /* CONFIG_CRYPTO_HMAC */
948
949/* 936/*
950 * DES test vectors. 937 * DES test vectors.
951 */ 938 */
@@ -2897,6 +2884,183 @@ static struct hash_testvec michael_mic_tv_template[] = {
2897}; 2884};
2898 2885
2899/* 2886/*
2887 * CRC32C test vectors
2888 */
2889#define CRC32C_TEST_VECTORS 14
2890
2891static struct hash_testvec crc32c_tv_template[] = {
2892 {
2893 .psize = 0,
2894 .digest = { 0x00, 0x00, 0x00, 0x00 }
2895 },
2896 {
2897 .key = { 0x87, 0xa9, 0xcb, 0xed },
2898 .ksize = 4,
2899 .psize = 0,
2900 .digest = { 0x78, 0x56, 0x34, 0x12 },
2901 },
2902 {
2903 .key = { 0xff, 0xff, 0xff, 0xff },
2904 .ksize = 4,
2905 .plaintext = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
2906 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
2907 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
2908 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
2909 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28 },
2910 .psize = 40,
2911 .digest = { 0x7f, 0x15, 0x2c, 0x0e }
2912 },
2913 {
2914 .key = { 0xff, 0xff, 0xff, 0xff },
2915 .ksize = 4,
2916 .plaintext = { 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
2917 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2918 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
2919 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
2920 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50 },
2921 .psize = 40,
2922 .digest = { 0xf6, 0xeb, 0x80, 0xe9 }
2923 },
2924 {
2925 .key = { 0xff, 0xff, 0xff, 0xff },
2926 .ksize = 4,
2927 .plaintext = { 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
2928 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
2929 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
2930 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
2931 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78 },
2932 .psize = 40,
2933 .digest = { 0xed, 0xbd, 0x74, 0xde }
2934 },
2935 {
2936 .key = { 0xff, 0xff, 0xff, 0xff },
2937 .ksize = 4,
2938 .plaintext = { 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
2939 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
2940 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
2941 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
2942 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0 },
2943 .psize = 40,
2944 .digest = { 0x62, 0xc8, 0x79, 0xd5 }
2945 },
2946 {
2947 .key = { 0xff, 0xff, 0xff, 0xff },
2948 .ksize = 4,
2949 .plaintext = { 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
2950 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
2951 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
2952 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
2953 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8 },
2954 .psize = 40,
2955 .digest = { 0xd0, 0x9a, 0x97, 0xba }
2956 },
2957 {
2958 .key = { 0xff, 0xff, 0xff, 0xff },
2959 .ksize = 4,
2960 .plaintext = { 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
2961 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
2962 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
2963 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
2964 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0 },
2965 .psize = 40,
2966 .digest = { 0x13, 0xd9, 0x29, 0x2b }
2967 },
2968 {
2969 .key = { 0x80, 0xea, 0xd3, 0xf1 },
2970 .ksize = 4,
2971 .plaintext = { 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
2972 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2973 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
2974 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
2975 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50 },
2976 .psize = 40,
2977 .digest = { 0x0c, 0xb5, 0xe2, 0xa2 }
2978 },
2979 {
2980 .key = { 0xf3, 0x4a, 0x1d, 0x5d },
2981 .ksize = 4,
2982 .plaintext = { 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
2983 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
2984 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
2985 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
2986 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78 },
2987 .psize = 40,
2988 .digest = { 0xd1, 0x7f, 0xfb, 0xa6 }
2989 },
2990 {
2991 .key = { 0x2e, 0x80, 0x04, 0x59 },
2992 .ksize = 4,
2993 .plaintext = { 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
2994 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
2995 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
2996 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
2997 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0 },
2998 .psize = 40,
2999 .digest = { 0x59, 0x33, 0xe6, 0x7a }
3000 },
3001 {
3002 .key = { 0xa6, 0xcc, 0x19, 0x85 },
3003 .ksize = 4,
3004 .plaintext = { 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
3005 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
3006 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
3007 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
3008 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8 },
3009 .psize = 40,
3010 .digest = { 0xbe, 0x03, 0x01, 0xd2 }
3011 },
3012 {
3013 .key = { 0x41, 0xfc, 0xfe, 0x2d },
3014 .ksize = 4,
3015 .plaintext = { 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
3016 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
3017 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
3018 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
3019 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0 },
3020 .psize = 40,
3021 .digest = { 0x75, 0xd3, 0xc5, 0x24 }
3022 },
3023 {
3024 .key = { 0xff, 0xff, 0xff, 0xff },
3025 .ksize = 4,
3026 .plaintext = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
3027 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
3028 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
3029 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
3030 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
3031 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
3032 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
3033 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
3034 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
3035 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
3036 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
3037 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
3038 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
3039 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
3040 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
3041 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
3042 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
3043 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
3044 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
3045 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
3046 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
3047 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
3048 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
3049 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
3050 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
3051 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
3052 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
3053 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
3054 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
3055 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0 },
3056 .psize = 240,
3057 .digest = { 0x75, 0xd3, 0xc5, 0x24 },
3058 .np = 2,
3059 .tap = { 31, 209 }
3060 },
3061};
3062
3063/*
2900 * Cipher speed tests 3064 * Cipher speed tests
2901 */ 3065 */
2902static struct cipher_speed aes_speed_template[] = { 3066static struct cipher_speed aes_speed_template[] = {
@@ -2983,7 +3147,7 @@ static struct cipher_speed des_speed_template[] = {
2983/* 3147/*
2984 * Digest speed tests 3148 * Digest speed tests
2985 */ 3149 */
2986static struct digest_speed generic_digest_speed_template[] = { 3150static struct hash_speed generic_hash_speed_template[] = {
2987 { .blen = 16, .plen = 16, }, 3151 { .blen = 16, .plen = 16, },
2988 { .blen = 64, .plen = 16, }, 3152 { .blen = 64, .plen = 16, },
2989 { .blen = 64, .plen = 64, }, 3153 { .blen = 64, .plen = 64, },
diff --git a/crypto/tea.c b/crypto/tea.c
index 5367adc82fc9..1c54e26fa529 100644
--- a/crypto/tea.c
+++ b/crypto/tea.c
@@ -46,16 +46,10 @@ struct xtea_ctx {
46}; 46};
47 47
48static int tea_setkey(struct crypto_tfm *tfm, const u8 *in_key, 48static int tea_setkey(struct crypto_tfm *tfm, const u8 *in_key,
49 unsigned int key_len, u32 *flags) 49 unsigned int key_len)
50{ 50{
51 struct tea_ctx *ctx = crypto_tfm_ctx(tfm); 51 struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
52 const __le32 *key = (const __le32 *)in_key; 52 const __le32 *key = (const __le32 *)in_key;
53
54 if (key_len != 16)
55 {
56 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
57 return -EINVAL;
58 }
59 53
60 ctx->KEY[0] = le32_to_cpu(key[0]); 54 ctx->KEY[0] = le32_to_cpu(key[0]);
61 ctx->KEY[1] = le32_to_cpu(key[1]); 55 ctx->KEY[1] = le32_to_cpu(key[1]);
@@ -125,16 +119,10 @@ static void tea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
125} 119}
126 120
127static int xtea_setkey(struct crypto_tfm *tfm, const u8 *in_key, 121static int xtea_setkey(struct crypto_tfm *tfm, const u8 *in_key,
128 unsigned int key_len, u32 *flags) 122 unsigned int key_len)
129{ 123{
130 struct xtea_ctx *ctx = crypto_tfm_ctx(tfm); 124 struct xtea_ctx *ctx = crypto_tfm_ctx(tfm);
131 const __le32 *key = (const __le32 *)in_key; 125 const __le32 *key = (const __le32 *)in_key;
132
133 if (key_len != 16)
134 {
135 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
136 return -EINVAL;
137 }
138 126
139 ctx->KEY[0] = le32_to_cpu(key[0]); 127 ctx->KEY[0] = le32_to_cpu(key[0]);
140 ctx->KEY[1] = le32_to_cpu(key[1]); 128 ctx->KEY[1] = le32_to_cpu(key[1]);
diff --git a/crypto/twofish.c b/crypto/twofish.c
index ec2488242e2d..4979a2be48a9 100644
--- a/crypto/twofish.c
+++ b/crypto/twofish.c
@@ -39,6 +39,7 @@
39 */ 39 */
40 40
41#include <asm/byteorder.h> 41#include <asm/byteorder.h>
42#include <crypto/twofish.h>
42#include <linux/module.h> 43#include <linux/module.h>
43#include <linux/init.h> 44#include <linux/init.h>
44#include <linux/types.h> 45#include <linux/types.h>
@@ -46,534 +47,6 @@
46#include <linux/crypto.h> 47#include <linux/crypto.h>
47#include <linux/bitops.h> 48#include <linux/bitops.h>
48 49
49
50/* The large precomputed tables for the Twofish cipher (twofish.c)
51 * Taken from the same source as twofish.c
52 * Marc Mutz <Marc@Mutz.com>
53 */
54
55/* These two tables are the q0 and q1 permutations, exactly as described in
56 * the Twofish paper. */
57
58static const u8 q0[256] = {
59 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
60 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
61 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
62 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
63 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
64 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
65 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
66 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
67 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
68 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
69 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
70 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
71 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
72 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
73 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
74 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
75 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
76 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
77 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
78 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
79 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
80 0x4A, 0x5E, 0xC1, 0xE0
81};
82
83static const u8 q1[256] = {
84 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
85 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
86 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
87 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
88 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
89 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
90 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
91 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
92 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
93 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
94 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
95 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
96 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
97 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
98 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
99 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
100 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
101 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
102 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
103 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
104 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
105 0x55, 0x09, 0xBE, 0x91
106};
107
108/* These MDS tables are actually tables of MDS composed with q0 and q1,
109 * because it is only ever used that way and we can save some time by
110 * precomputing. Of course the main saving comes from precomputing the
111 * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
112 * things up in these tables we reduce the matrix multiply to four lookups
113 * and three XORs. Semi-formally, the definition of these tables is:
114 * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T
115 * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T
116 * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
117 * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
118 * by Schneier et al, and I'm casually glossing over the byte/word
119 * conversion issues. */
120
121static const u32 mds[4][256] = {
122 {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
123 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
124 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
125 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
126 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
127 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
128 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
129 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
130 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
131 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
132 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
133 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
134 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
135 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
136 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
137 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
138 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
139 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
140 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
141 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
142 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
143 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
144 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
145 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
146 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
147 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
148 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
149 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
150 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
151 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
152 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
153 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
154 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
155 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
156 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
157 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
158 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
159 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
160 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
161 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
162 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
163 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
164 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
165
166 {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
167 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
168 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
169 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
170 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
171 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
172 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
173 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
174 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
175 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
176 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
177 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
178 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
179 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
180 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
181 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
182 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
183 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
184 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
185 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
186 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
187 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
188 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
189 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
190 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
191 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
192 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
193 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
194 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
195 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
196 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
197 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
198 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
199 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
200 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
201 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
202 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
203 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
204 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
205 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
206 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
207 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
208 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
209
210 {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
211 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
212 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
213 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
214 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
215 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
216 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
217 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
218 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
219 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
220 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
221 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
222 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
223 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
224 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
225 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
226 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
227 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
228 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
229 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
230 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
231 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
232 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
233 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
234 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
235 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
236 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
237 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
238 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
239 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
240 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
241 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
242 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
243 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
244 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
245 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
246 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
247 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
248 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
249 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
250 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
251 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
252 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
253
254 {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
255 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
256 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
257 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
258 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
259 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
260 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
261 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
262 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
263 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
264 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
265 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
266 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
267 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
268 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
269 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
270 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
271 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
272 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
273 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
274 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
275 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
276 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
277 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
278 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
279 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
280 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
281 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
282 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
283 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
284 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
285 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
286 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
287 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
288 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
289 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
290 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
291 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
292 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
293 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
294 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
295 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
296 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
297};
298
299/* The exp_to_poly and poly_to_exp tables are used to perform efficient
300 * operations in GF(2^8) represented as GF(2)[x]/w(x) where
301 * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the
302 * definition of the RS matrix in the key schedule. Elements of that field
303 * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
304 * which can be represented naturally by bytes (just substitute x=2). In that
305 * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
306 * multiplication is inefficient without hardware support. To multiply
307 * faster, I make use of the fact x is a generator for the nonzero elements,
308 * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
309 * some n in 0..254. Note that that caret is exponentiation in GF(2^8),
310 * *not* polynomial notation. So if I want to compute pq where p and q are
311 * in GF(2^8), I can just say:
312 * 1. if p=0 or q=0 then pq=0
313 * 2. otherwise, find m and n such that p=x^m and q=x^n
314 * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
315 * The translations in steps 2 and 3 are looked up in the tables
316 * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this
317 * in action, look at the CALC_S macro. As additional wrinkles, note that
318 * one of my operands is always a constant, so the poly_to_exp lookup on it
319 * is done in advance; I included the original values in the comments so
320 * readers can have some chance of recognizing that this *is* the RS matrix
321 * from the Twofish paper. I've only included the table entries I actually
322 * need; I never do a lookup on a variable input of zero and the biggest
323 * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
324 * never sum to more than 491. I'm repeating part of the exp_to_poly table
325 * so that I don't have to do mod-255 reduction in the exponent arithmetic.
326 * Since I know my constant operands are never zero, I only have to worry
327 * about zero values in the variable operand, and I do it with a simple
328 * conditional branch. I know conditionals are expensive, but I couldn't
329 * see a non-horrible way of avoiding them, and I did manage to group the
330 * statements so that each if covers four group multiplications. */
331
332static const u8 poly_to_exp[255] = {
333 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
334 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
335 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
336 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
337 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
338 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
339 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
340 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
341 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
342 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
343 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
344 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
345 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
346 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
347 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
348 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
349 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
350 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
351 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
352 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
353 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
354 0x85, 0xC8, 0xA1
355};
356
357static const u8 exp_to_poly[492] = {
358 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
359 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
360 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
361 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
362 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
363 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
364 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
365 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
366 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
367 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
368 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
369 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
370 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
371 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
372 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
373 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
374 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
375 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
376 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
377 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
378 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
379 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
380 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
381 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
382 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
383 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
384 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
385 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
386 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
387 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
388 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
389 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
390 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
391 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
392 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
393 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
394 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
395 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
396 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
397 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
398 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
399};
400
401
402/* The table constants are indices of
403 * S-box entries, preprocessed through q0 and q1. */
404static const u8 calc_sb_tbl[512] = {
405 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
406 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
407 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
408 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
409 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
410 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
411 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
412 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
413 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
414 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
415 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
416 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
417 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
418 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
419 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
420 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
421 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
422 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
423 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
424 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
425 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
426 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
427 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
428 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
429 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
430 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
431 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
432 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
433 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
434 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
435 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
436 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
437 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
438 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
439 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
440 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
441 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
442 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
443 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
444 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
445 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
446 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
447 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
448 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
449 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
450 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
451 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
452 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
453 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
454 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
455 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
456 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
457 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
458 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
459 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
460 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
461 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
462 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
463 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
464 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
465 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
466 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
467 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
468 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
469};
470
471/* Macro to perform one column of the RS matrix multiplication. The
472 * parameters a, b, c, and d are the four bytes of output; i is the index
473 * of the key bytes, and w, x, y, and z, are the column of constants from
474 * the RS matrix, preprocessed through the poly_to_exp table. */
475
476#define CALC_S(a, b, c, d, i, w, x, y, z) \
477 if (key[i]) { \
478 tmp = poly_to_exp[key[i] - 1]; \
479 (a) ^= exp_to_poly[tmp + (w)]; \
480 (b) ^= exp_to_poly[tmp + (x)]; \
481 (c) ^= exp_to_poly[tmp + (y)]; \
482 (d) ^= exp_to_poly[tmp + (z)]; \
483 }
484
485/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
486 * the S vector from CALC_S. CALC_SB_2 computes a single entry in all
487 * four S-boxes, where i is the index of the entry to compute, and a and b
488 * are the index numbers preprocessed through the q0 and q1 tables
489 * respectively. */
490
491#define CALC_SB_2(i, a, b) \
492 ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
493 ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
494 ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
495 ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
496
497/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
498
499#define CALC_SB192_2(i, a, b) \
500 ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
501 ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
502 ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
503 ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
504
505/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
506
507#define CALC_SB256_2(i, a, b) \
508 ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
509 ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
510 ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
511 ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
512
513/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the
514 * last two stages of the h() function for a given index (either 2i or 2i+1).
515 * a, b, c, and d are the four bytes going into the last two stages. For
516 * 128-bit keys, this is the entire h() function and a and c are the index
517 * preprocessed through q0 and q1 respectively; for longer keys they are the
518 * output of previous stages. j is the index of the first key byte to use.
519 * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
520 * twice, doing the Pseudo-Hadamard Transform, and doing the necessary
521 * rotations. Its parameters are: a, the array to write the results into,
522 * j, the index of the first output entry, k and l, the preprocessed indices
523 * for index 2i, and m and n, the preprocessed indices for index 2i+1.
524 * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
525 * additional lookup-and-XOR stage. The parameters a, b, c and d are the
526 * four bytes going into the last three stages. For 192-bit keys, c = d
527 * are the index preprocessed through q0, and a = b are the index
528 * preprocessed through q1; j is the index of the first key byte to use.
529 * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
530 * instead of CALC_K_2.
531 * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
532 * additional lookup-and-XOR stage. The parameters a and b are the index
533 * preprocessed through q0 and q1 respectively; j is the index of the first
534 * key byte to use. CALC_K256 is identical to CALC_K but for using the
535 * CALC_K256_2 macro instead of CALC_K_2. */
536
537#define CALC_K_2(a, b, c, d, j) \
538 mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
539 ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
540 ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
541 ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
542
543#define CALC_K(a, j, k, l, m, n) \
544 x = CALC_K_2 (k, l, k, l, 0); \
545 y = CALC_K_2 (m, n, m, n, 4); \
546 y = rol32(y, 8); \
547 x += y; y += x; ctx->a[j] = x; \
548 ctx->a[(j) + 1] = rol32(y, 9)
549
550#define CALC_K192_2(a, b, c, d, j) \
551 CALC_K_2 (q0[a ^ key[(j) + 16]], \
552 q1[b ^ key[(j) + 17]], \
553 q0[c ^ key[(j) + 18]], \
554 q1[d ^ key[(j) + 19]], j)
555
556#define CALC_K192(a, j, k, l, m, n) \
557 x = CALC_K192_2 (l, l, k, k, 0); \
558 y = CALC_K192_2 (n, n, m, m, 4); \
559 y = rol32(y, 8); \
560 x += y; y += x; ctx->a[j] = x; \
561 ctx->a[(j) + 1] = rol32(y, 9)
562
563#define CALC_K256_2(a, b, j) \
564 CALC_K192_2 (q1[b ^ key[(j) + 24]], \
565 q1[a ^ key[(j) + 25]], \
566 q0[a ^ key[(j) + 26]], \
567 q0[b ^ key[(j) + 27]], j)
568
569#define CALC_K256(a, j, k, l, m, n) \
570 x = CALC_K256_2 (k, l, 0); \
571 y = CALC_K256_2 (m, n, 4); \
572 y = rol32(y, 8); \
573 x += y; y += x; ctx->a[j] = x; \
574 ctx->a[(j) + 1] = rol32(y, 9)
575
576
577/* Macros to compute the g() function in the encryption and decryption 50/* Macros to compute the g() function in the encryption and decryption
578 * rounds. G1 is the straight g() function; G2 includes the 8-bit 51 * rounds. G1 is the straight g() function; G2 includes the 8-bit
579 * rotation for the high 32-bit word. */ 52 * rotation for the high 32-bit word. */
@@ -630,176 +103,7 @@ static const u8 calc_sb_tbl[512] = {
630 x ^= ctx->w[m]; \ 103 x ^= ctx->w[m]; \
631 dst[n] = cpu_to_le32(x) 104 dst[n] = cpu_to_le32(x)
632 105
633#define TF_MIN_KEY_SIZE 16
634#define TF_MAX_KEY_SIZE 32
635#define TF_BLOCK_SIZE 16
636
637/* Structure for an expanded Twofish key. s contains the key-dependent
638 * S-boxes composed with the MDS matrix; w contains the eight "whitening"
639 * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
640 * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
641struct twofish_ctx {
642 u32 s[4][256], w[8], k[32];
643};
644
645/* Perform the key setup. */
646static int twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
647 unsigned int key_len, u32 *flags)
648{
649
650 struct twofish_ctx *ctx = crypto_tfm_ctx(tfm);
651 106
652 int i, j, k;
653
654 /* Temporaries for CALC_K. */
655 u32 x, y;
656
657 /* The S vector used to key the S-boxes, split up into individual bytes.
658 * 128-bit keys use only sa through sh; 256-bit use all of them. */
659 u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
660 u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
661
662 /* Temporary for CALC_S. */
663 u8 tmp;
664
665 /* Check key length. */
666 if (key_len != 16 && key_len != 24 && key_len != 32)
667 {
668 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
669 return -EINVAL; /* unsupported key length */
670 }
671
672 /* Compute the first two words of the S vector. The magic numbers are
673 * the entries of the RS matrix, preprocessed through poly_to_exp. The
674 * numbers in the comments are the original (polynomial form) matrix
675 * entries. */
676 CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
677 CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
678 CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
679 CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
680 CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
681 CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
682 CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
683 CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
684 CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
685 CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
686 CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
687 CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
688 CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
689 CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
690 CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
691 CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
692
693 if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
694 /* Calculate the third word of the S vector */
695 CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
696 CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
697 CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
698 CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
699 CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
700 CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
701 CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
702 CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
703 }
704
705 if (key_len == 32) { /* 256-bit key */
706 /* Calculate the fourth word of the S vector */
707 CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
708 CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
709 CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
710 CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
711 CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
712 CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
713 CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
714 CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
715
716 /* Compute the S-boxes. */
717 for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
718 CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
719 }
720
721 /* Calculate whitening and round subkeys. The constants are
722 * indices of subkeys, preprocessed through q0 and q1. */
723 CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
724 CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
725 CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
726 CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
727 CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
728 CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
729 CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
730 CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
731 CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
732 CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
733 CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
734 CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
735 CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
736 CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
737 CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
738 CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
739 CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
740 CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
741 CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
742 CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
743 } else if (key_len == 24) { /* 192-bit key */
744 /* Compute the S-boxes. */
745 for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
746 CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
747 }
748
749 /* Calculate whitening and round subkeys. The constants are
750 * indices of subkeys, preprocessed through q0 and q1. */
751 CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
752 CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
753 CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
754 CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
755 CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
756 CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
757 CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
758 CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
759 CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
760 CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
761 CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
762 CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
763 CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
764 CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
765 CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
766 CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
767 CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
768 CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
769 CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
770 CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
771 } else { /* 128-bit key */
772 /* Compute the S-boxes. */
773 for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
774 CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
775 }
776
777 /* Calculate whitening and round subkeys. The constants are
778 * indices of subkeys, preprocessed through q0 and q1. */
779 CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
780 CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
781 CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
782 CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
783 CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
784 CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
785 CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
786 CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
787 CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
788 CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
789 CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
790 CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
791 CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
792 CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
793 CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
794 CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
795 CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
796 CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
797 CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
798 CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
799 }
800
801 return 0;
802}
803 107
804/* Encrypt one block. in and out may be the same. */ 108/* Encrypt one block. in and out may be the same. */
805static void twofish_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 109static void twofish_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
@@ -877,6 +181,8 @@ static void twofish_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
877 181
878static struct crypto_alg alg = { 182static struct crypto_alg alg = {
879 .cra_name = "twofish", 183 .cra_name = "twofish",
184 .cra_driver_name = "twofish-generic",
185 .cra_priority = 100,
880 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 186 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
881 .cra_blocksize = TF_BLOCK_SIZE, 187 .cra_blocksize = TF_BLOCK_SIZE,
882 .cra_ctxsize = sizeof(struct twofish_ctx), 188 .cra_ctxsize = sizeof(struct twofish_ctx),
diff --git a/crypto/twofish_common.c b/crypto/twofish_common.c
new file mode 100644
index 000000000000..b4b9c0c3f4ae
--- /dev/null
+++ b/crypto/twofish_common.c
@@ -0,0 +1,744 @@
1/*
2 * Common Twofish algorithm parts shared between the c and assembler
3 * implementations
4 *
5 * Originally Twofish for GPG
6 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
7 * 256-bit key length added March 20, 1999
8 * Some modifications to reduce the text size by Werner Koch, April, 1998
9 * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
10 * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
11 *
12 * The original author has disclaimed all copyright interest in this
13 * code and thus put it in the public domain. The subsequent authors
14 * have put this under the GNU General Public License.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29 * USA
30 *
31 * This code is a "clean room" implementation, written from the paper
32 * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
33 * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
34 * through http://www.counterpane.com/twofish.html
35 *
36 * For background information on multiplication in finite fields, used for
37 * the matrix operations in the key schedule, see the book _Contemporary
38 * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
39 * Third Edition.
40 */
41
42#include <crypto/twofish.h>
43#include <linux/bitops.h>
44#include <linux/crypto.h>
45#include <linux/errno.h>
46#include <linux/init.h>
47#include <linux/kernel.h>
48#include <linux/module.h>
49#include <linux/types.h>
50
51
52/* The large precomputed tables for the Twofish cipher (twofish.c)
53 * Taken from the same source as twofish.c
54 * Marc Mutz <Marc@Mutz.com>
55 */
56
57/* These two tables are the q0 and q1 permutations, exactly as described in
58 * the Twofish paper. */
59
60static const u8 q0[256] = {
61 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
62 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
63 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
64 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
65 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
66 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
67 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
68 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
69 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
70 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
71 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
72 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
73 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
74 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
75 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
76 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
77 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
78 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
79 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
80 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
81 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
82 0x4A, 0x5E, 0xC1, 0xE0
83};
84
85static const u8 q1[256] = {
86 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
87 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
88 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
89 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
90 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
91 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
92 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
93 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
94 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
95 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
96 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
97 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
98 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
99 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
100 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
101 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
102 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
103 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
104 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
105 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
106 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
107 0x55, 0x09, 0xBE, 0x91
108};
109
110/* These MDS tables are actually tables of MDS composed with q0 and q1,
111 * because it is only ever used that way and we can save some time by
112 * precomputing. Of course the main saving comes from precomputing the
113 * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
114 * things up in these tables we reduce the matrix multiply to four lookups
115 * and three XORs. Semi-formally, the definition of these tables is:
116 * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T
117 * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T
118 * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
119 * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
120 * by Schneier et al, and I'm casually glossing over the byte/word
121 * conversion issues. */
122
123static const u32 mds[4][256] = {
124 {
125 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
126 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
127 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
128 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
129 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
130 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
131 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
132 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
133 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
134 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
135 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
136 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
137 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
138 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
139 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
140 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
141 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
142 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
143 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
144 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
145 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
146 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
147 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
148 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
149 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
150 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
151 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
152 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
153 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
154 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
155 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
156 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
157 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
158 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
159 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
160 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
161 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
162 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
163 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
164 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
165 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
166 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
167 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
168
169 {
170 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
171 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
172 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
173 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
174 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
175 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
176 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
177 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
178 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
179 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
180 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
181 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
182 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
183 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
184 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
185 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
186 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
187 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
188 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
189 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
190 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
191 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
192 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
193 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
194 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
195 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
196 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
197 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
198 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
199 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
200 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
201 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
202 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
203 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
204 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
205 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
206 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
207 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
208 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
209 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
210 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
211 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
212 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
213
214 {
215 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
216 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
217 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
218 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
219 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
220 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
221 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
222 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
223 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
224 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
225 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
226 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
227 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
228 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
229 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
230 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
231 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
232 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
233 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
234 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
235 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
236 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
237 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
238 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
239 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
240 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
241 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
242 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
243 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
244 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
245 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
246 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
247 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
248 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
249 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
250 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
251 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
252 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
253 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
254 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
255 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
256 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
257 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
258
259 {
260 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
261 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
262 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
263 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
264 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
265 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
266 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
267 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
268 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
269 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
270 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
271 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
272 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
273 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
274 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
275 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
276 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
277 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
278 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
279 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
280 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
281 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
282 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
283 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
284 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
285 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
286 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
287 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
288 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
289 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
290 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
291 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
292 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
293 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
294 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
295 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
296 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
297 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
298 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
299 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
300 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
301 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
302 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
303};
304
305/* The exp_to_poly and poly_to_exp tables are used to perform efficient
306 * operations in GF(2^8) represented as GF(2)[x]/w(x) where
307 * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the
308 * definition of the RS matrix in the key schedule. Elements of that field
309 * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
310 * which can be represented naturally by bytes (just substitute x=2). In that
311 * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
312 * multiplication is inefficient without hardware support. To multiply
313 * faster, I make use of the fact x is a generator for the nonzero elements,
314 * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
315 * some n in 0..254. Note that that caret is exponentiation in GF(2^8),
316 * *not* polynomial notation. So if I want to compute pq where p and q are
317 * in GF(2^8), I can just say:
318 * 1. if p=0 or q=0 then pq=0
319 * 2. otherwise, find m and n such that p=x^m and q=x^n
320 * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
321 * The translations in steps 2 and 3 are looked up in the tables
322 * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this
323 * in action, look at the CALC_S macro. As additional wrinkles, note that
324 * one of my operands is always a constant, so the poly_to_exp lookup on it
325 * is done in advance; I included the original values in the comments so
326 * readers can have some chance of recognizing that this *is* the RS matrix
327 * from the Twofish paper. I've only included the table entries I actually
328 * need; I never do a lookup on a variable input of zero and the biggest
329 * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
330 * never sum to more than 491. I'm repeating part of the exp_to_poly table
331 * so that I don't have to do mod-255 reduction in the exponent arithmetic.
332 * Since I know my constant operands are never zero, I only have to worry
333 * about zero values in the variable operand, and I do it with a simple
334 * conditional branch. I know conditionals are expensive, but I couldn't
335 * see a non-horrible way of avoiding them, and I did manage to group the
336 * statements so that each if covers four group multiplications. */
337
338static const u8 poly_to_exp[255] = {
339 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
340 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
341 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
342 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
343 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
344 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
345 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
346 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
347 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
348 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
349 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
350 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
351 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
352 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
353 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
354 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
355 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
356 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
357 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
358 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
359 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
360 0x85, 0xC8, 0xA1
361};
362
363static const u8 exp_to_poly[492] = {
364 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
365 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
366 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
367 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
368 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
369 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
370 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
371 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
372 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
373 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
374 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
375 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
376 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
377 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
378 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
379 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
380 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
381 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
382 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
383 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
384 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
385 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
386 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
387 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
388 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
389 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
390 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
391 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
392 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
393 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
394 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
395 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
396 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
397 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
398 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
399 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
400 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
401 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
402 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
403 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
404 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
405};
406
407
408/* The table constants are indices of
409 * S-box entries, preprocessed through q0 and q1. */
410static const u8 calc_sb_tbl[512] = {
411 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
412 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
413 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
414 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
415 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
416 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
417 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
418 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
419 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
420 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
421 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
422 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
423 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
424 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
425 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
426 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
427 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
428 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
429 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
430 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
431 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
432 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
433 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
434 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
435 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
436 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
437 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
438 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
439 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
440 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
441 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
442 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
443 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
444 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
445 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
446 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
447 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
448 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
449 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
450 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
451 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
452 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
453 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
454 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
455 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
456 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
457 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
458 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
459 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
460 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
461 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
462 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
463 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
464 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
465 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
466 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
467 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
468 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
469 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
470 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
471 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
472 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
473 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
474 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
475};
476
477/* Macro to perform one column of the RS matrix multiplication. The
478 * parameters a, b, c, and d are the four bytes of output; i is the index
479 * of the key bytes, and w, x, y, and z, are the column of constants from
480 * the RS matrix, preprocessed through the poly_to_exp table. */
481
482#define CALC_S(a, b, c, d, i, w, x, y, z) \
483 if (key[i]) { \
484 tmp = poly_to_exp[key[i] - 1]; \
485 (a) ^= exp_to_poly[tmp + (w)]; \
486 (b) ^= exp_to_poly[tmp + (x)]; \
487 (c) ^= exp_to_poly[tmp + (y)]; \
488 (d) ^= exp_to_poly[tmp + (z)]; \
489 }
490
491/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
492 * the S vector from CALC_S. CALC_SB_2 computes a single entry in all
493 * four S-boxes, where i is the index of the entry to compute, and a and b
494 * are the index numbers preprocessed through the q0 and q1 tables
495 * respectively. */
496
497#define CALC_SB_2(i, a, b) \
498 ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
499 ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
500 ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
501 ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
502
503/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
504
505#define CALC_SB192_2(i, a, b) \
506 ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
507 ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
508 ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
509 ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
510
511/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
512
513#define CALC_SB256_2(i, a, b) \
514 ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
515 ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
516 ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
517 ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
518
519/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the
520 * last two stages of the h() function for a given index (either 2i or 2i+1).
521 * a, b, c, and d are the four bytes going into the last two stages. For
522 * 128-bit keys, this is the entire h() function and a and c are the index
523 * preprocessed through q0 and q1 respectively; for longer keys they are the
524 * output of previous stages. j is the index of the first key byte to use.
525 * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
526 * twice, doing the Pseudo-Hadamard Transform, and doing the necessary
527 * rotations. Its parameters are: a, the array to write the results into,
528 * j, the index of the first output entry, k and l, the preprocessed indices
529 * for index 2i, and m and n, the preprocessed indices for index 2i+1.
530 * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
531 * additional lookup-and-XOR stage. The parameters a, b, c and d are the
532 * four bytes going into the last three stages. For 192-bit keys, c = d
533 * are the index preprocessed through q0, and a = b are the index
534 * preprocessed through q1; j is the index of the first key byte to use.
535 * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
536 * instead of CALC_K_2.
537 * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
538 * additional lookup-and-XOR stage. The parameters a and b are the index
539 * preprocessed through q0 and q1 respectively; j is the index of the first
540 * key byte to use. CALC_K256 is identical to CALC_K but for using the
541 * CALC_K256_2 macro instead of CALC_K_2. */
542
543#define CALC_K_2(a, b, c, d, j) \
544 mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
545 ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
546 ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
547 ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
548
549#define CALC_K(a, j, k, l, m, n) \
550 x = CALC_K_2 (k, l, k, l, 0); \
551 y = CALC_K_2 (m, n, m, n, 4); \
552 y = rol32(y, 8); \
553 x += y; y += x; ctx->a[j] = x; \
554 ctx->a[(j) + 1] = rol32(y, 9)
555
556#define CALC_K192_2(a, b, c, d, j) \
557 CALC_K_2 (q0[a ^ key[(j) + 16]], \
558 q1[b ^ key[(j) + 17]], \
559 q0[c ^ key[(j) + 18]], \
560 q1[d ^ key[(j) + 19]], j)
561
562#define CALC_K192(a, j, k, l, m, n) \
563 x = CALC_K192_2 (l, l, k, k, 0); \
564 y = CALC_K192_2 (n, n, m, m, 4); \
565 y = rol32(y, 8); \
566 x += y; y += x; ctx->a[j] = x; \
567 ctx->a[(j) + 1] = rol32(y, 9)
568
569#define CALC_K256_2(a, b, j) \
570 CALC_K192_2 (q1[b ^ key[(j) + 24]], \
571 q1[a ^ key[(j) + 25]], \
572 q0[a ^ key[(j) + 26]], \
573 q0[b ^ key[(j) + 27]], j)
574
575#define CALC_K256(a, j, k, l, m, n) \
576 x = CALC_K256_2 (k, l, 0); \
577 y = CALC_K256_2 (m, n, 4); \
578 y = rol32(y, 8); \
579 x += y; y += x; ctx->a[j] = x; \
580 ctx->a[(j) + 1] = rol32(y, 9)
581
582/* Perform the key setup. */
583int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
584{
585
586 struct twofish_ctx *ctx = crypto_tfm_ctx(tfm);
587 u32 *flags = &tfm->crt_flags;
588
589 int i, j, k;
590
591 /* Temporaries for CALC_K. */
592 u32 x, y;
593
594 /* The S vector used to key the S-boxes, split up into individual bytes.
595 * 128-bit keys use only sa through sh; 256-bit use all of them. */
596 u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
597 u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
598
599 /* Temporary for CALC_S. */
600 u8 tmp;
601
602 /* Check key length. */
603 if (key_len % 8)
604 {
605 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
606 return -EINVAL; /* unsupported key length */
607 }
608
609 /* Compute the first two words of the S vector. The magic numbers are
610 * the entries of the RS matrix, preprocessed through poly_to_exp. The
611 * numbers in the comments are the original (polynomial form) matrix
612 * entries. */
613 CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
614 CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
615 CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
616 CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
617 CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
618 CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
619 CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
620 CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
621 CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
622 CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
623 CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
624 CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
625 CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
626 CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
627 CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
628 CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
629
630 if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
631 /* Calculate the third word of the S vector */
632 CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
633 CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
634 CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
635 CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
636 CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
637 CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
638 CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
639 CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
640 }
641
642 if (key_len == 32) { /* 256-bit key */
643 /* Calculate the fourth word of the S vector */
644 CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
645 CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
646 CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
647 CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
648 CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
649 CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
650 CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
651 CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
652
653 /* Compute the S-boxes. */
654 for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
655 CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
656 }
657
658 /* Calculate whitening and round subkeys. The constants are
659 * indices of subkeys, preprocessed through q0 and q1. */
660 CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
661 CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
662 CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
663 CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
664 CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
665 CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
666 CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
667 CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
668 CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
669 CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
670 CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
671 CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
672 CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
673 CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
674 CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
675 CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
676 CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
677 CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
678 CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
679 CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
680 } else if (key_len == 24) { /* 192-bit key */
681 /* Compute the S-boxes. */
682 for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
683 CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
684 }
685
686 /* Calculate whitening and round subkeys. The constants are
687 * indices of subkeys, preprocessed through q0 and q1. */
688 CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
689 CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
690 CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
691 CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
692 CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
693 CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
694 CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
695 CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
696 CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
697 CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
698 CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
699 CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
700 CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
701 CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
702 CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
703 CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
704 CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
705 CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
706 CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
707 CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
708 } else { /* 128-bit key */
709 /* Compute the S-boxes. */
710 for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
711 CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
712 }
713
714 /* Calculate whitening and round subkeys. The constants are
715 * indices of subkeys, preprocessed through q0 and q1. */
716 CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
717 CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
718 CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
719 CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
720 CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
721 CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
722 CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
723 CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
724 CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
725 CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
726 CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
727 CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
728 CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
729 CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
730 CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
731 CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
732 CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
733 CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
734 CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
735 CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
736 }
737
738 return 0;
739}
740
741EXPORT_SYMBOL_GPL(twofish_setkey);
742
743MODULE_LICENSE("GPL");
744MODULE_DESCRIPTION("Twofish cipher common functions");
diff --git a/drivers/base/hypervisor.c b/drivers/base/hypervisor.c
index 0c85e9d6a448..7080b413ddc9 100644
--- a/drivers/base/hypervisor.c
+++ b/drivers/base/hypervisor.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * hypervisor.c - /sys/hypervisor subsystem. 2 * hypervisor.c - /sys/hypervisor subsystem.
3 * 3 *
4 * This file is released under the GPLv2 4 * Copyright (C) IBM Corp. 2006
5 * 5 *
6 * This file is released under the GPLv2
6 */ 7 */
7 8
8#include <linux/kobject.h> 9#include <linux/kobject.h>
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 3d4261c39f16..40535036e893 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -40,11 +40,13 @@ static int
40cryptoloop_init(struct loop_device *lo, const struct loop_info64 *info) 40cryptoloop_init(struct loop_device *lo, const struct loop_info64 *info)
41{ 41{
42 int err = -EINVAL; 42 int err = -EINVAL;
43 int cipher_len;
44 int mode_len;
43 char cms[LO_NAME_SIZE]; /* cipher-mode string */ 45 char cms[LO_NAME_SIZE]; /* cipher-mode string */
44 char *cipher; 46 char *cipher;
45 char *mode; 47 char *mode;
46 char *cmsp = cms; /* c-m string pointer */ 48 char *cmsp = cms; /* c-m string pointer */
47 struct crypto_tfm *tfm = NULL; 49 struct crypto_blkcipher *tfm;
48 50
49 /* encryption breaks for non sector aligned offsets */ 51 /* encryption breaks for non sector aligned offsets */
50 52
@@ -53,20 +55,39 @@ cryptoloop_init(struct loop_device *lo, const struct loop_info64 *info)
53 55
54 strncpy(cms, info->lo_crypt_name, LO_NAME_SIZE); 56 strncpy(cms, info->lo_crypt_name, LO_NAME_SIZE);
55 cms[LO_NAME_SIZE - 1] = 0; 57 cms[LO_NAME_SIZE - 1] = 0;
56 cipher = strsep(&cmsp, "-"); 58
57 mode = strsep(&cmsp, "-"); 59 cipher = cmsp;
58 60 cipher_len = strcspn(cmsp, "-");
59 if (mode == NULL || strcmp(mode, "cbc") == 0) 61
60 tfm = crypto_alloc_tfm(cipher, CRYPTO_TFM_MODE_CBC | 62 mode = cmsp + cipher_len;
61 CRYPTO_TFM_REQ_MAY_SLEEP); 63 mode_len = 0;
62 else if (strcmp(mode, "ecb") == 0) 64 if (*mode) {
63 tfm = crypto_alloc_tfm(cipher, CRYPTO_TFM_MODE_ECB | 65 mode++;
64 CRYPTO_TFM_REQ_MAY_SLEEP); 66 mode_len = strcspn(mode, "-");
65 if (tfm == NULL) 67 }
68
69 if (!mode_len) {
70 mode = "cbc";
71 mode_len = 3;
72 }
73
74 if (cipher_len + mode_len + 3 > LO_NAME_SIZE)
66 return -EINVAL; 75 return -EINVAL;
67 76
68 err = tfm->crt_u.cipher.cit_setkey(tfm, info->lo_encrypt_key, 77 memmove(cms, mode, mode_len);
69 info->lo_encrypt_key_size); 78 cmsp = cms + mode_len;
79 *cmsp++ = '(';
80 memcpy(cmsp, info->lo_crypt_name, cipher_len);
81 cmsp += cipher_len;
82 *cmsp++ = ')';
83 *cmsp = 0;
84
85 tfm = crypto_alloc_blkcipher(cms, 0, CRYPTO_ALG_ASYNC);
86 if (IS_ERR(tfm))
87 return PTR_ERR(tfm);
88
89 err = crypto_blkcipher_setkey(tfm, info->lo_encrypt_key,
90 info->lo_encrypt_key_size);
70 91
71 if (err != 0) 92 if (err != 0)
72 goto out_free_tfm; 93 goto out_free_tfm;
@@ -75,99 +96,49 @@ cryptoloop_init(struct loop_device *lo, const struct loop_info64 *info)
75 return 0; 96 return 0;
76 97
77 out_free_tfm: 98 out_free_tfm:
78 crypto_free_tfm(tfm); 99 crypto_free_blkcipher(tfm);
79 100
80 out: 101 out:
81 return err; 102 return err;
82} 103}
83 104
84 105
85typedef int (*encdec_ecb_t)(struct crypto_tfm *tfm, 106typedef int (*encdec_cbc_t)(struct blkcipher_desc *desc,
86 struct scatterlist *sg_out, 107 struct scatterlist *sg_out,
87 struct scatterlist *sg_in, 108 struct scatterlist *sg_in,
88 unsigned int nsg); 109 unsigned int nsg);
89 110
90
91static int
92cryptoloop_transfer_ecb(struct loop_device *lo, int cmd,
93 struct page *raw_page, unsigned raw_off,
94 struct page *loop_page, unsigned loop_off,
95 int size, sector_t IV)
96{
97 struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data;
98 struct scatterlist sg_out = { NULL, };
99 struct scatterlist sg_in = { NULL, };
100
101 encdec_ecb_t encdecfunc;
102 struct page *in_page, *out_page;
103 unsigned in_offs, out_offs;
104
105 if (cmd == READ) {
106 in_page = raw_page;
107 in_offs = raw_off;
108 out_page = loop_page;
109 out_offs = loop_off;
110 encdecfunc = tfm->crt_u.cipher.cit_decrypt;
111 } else {
112 in_page = loop_page;
113 in_offs = loop_off;
114 out_page = raw_page;
115 out_offs = raw_off;
116 encdecfunc = tfm->crt_u.cipher.cit_encrypt;
117 }
118
119 while (size > 0) {
120 const int sz = min(size, LOOP_IV_SECTOR_SIZE);
121
122 sg_in.page = in_page;
123 sg_in.offset = in_offs;
124 sg_in.length = sz;
125
126 sg_out.page = out_page;
127 sg_out.offset = out_offs;
128 sg_out.length = sz;
129
130 encdecfunc(tfm, &sg_out, &sg_in, sz);
131
132 size -= sz;
133 in_offs += sz;
134 out_offs += sz;
135 }
136
137 return 0;
138}
139
140typedef int (*encdec_cbc_t)(struct crypto_tfm *tfm,
141 struct scatterlist *sg_out,
142 struct scatterlist *sg_in,
143 unsigned int nsg, u8 *iv);
144
145static int 111static int
146cryptoloop_transfer_cbc(struct loop_device *lo, int cmd, 112cryptoloop_transfer(struct loop_device *lo, int cmd,
147 struct page *raw_page, unsigned raw_off, 113 struct page *raw_page, unsigned raw_off,
148 struct page *loop_page, unsigned loop_off, 114 struct page *loop_page, unsigned loop_off,
149 int size, sector_t IV) 115 int size, sector_t IV)
150{ 116{
151 struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data; 117 struct crypto_blkcipher *tfm = lo->key_data;
118 struct blkcipher_desc desc = {
119 .tfm = tfm,
120 .flags = CRYPTO_TFM_REQ_MAY_SLEEP,
121 };
152 struct scatterlist sg_out = { NULL, }; 122 struct scatterlist sg_out = { NULL, };
153 struct scatterlist sg_in = { NULL, }; 123 struct scatterlist sg_in = { NULL, };
154 124
155 encdec_cbc_t encdecfunc; 125 encdec_cbc_t encdecfunc;
156 struct page *in_page, *out_page; 126 struct page *in_page, *out_page;
157 unsigned in_offs, out_offs; 127 unsigned in_offs, out_offs;
128 int err;
158 129
159 if (cmd == READ) { 130 if (cmd == READ) {
160 in_page = raw_page; 131 in_page = raw_page;
161 in_offs = raw_off; 132 in_offs = raw_off;
162 out_page = loop_page; 133 out_page = loop_page;
163 out_offs = loop_off; 134 out_offs = loop_off;
164 encdecfunc = tfm->crt_u.cipher.cit_decrypt_iv; 135 encdecfunc = crypto_blkcipher_crt(tfm)->decrypt;
165 } else { 136 } else {
166 in_page = loop_page; 137 in_page = loop_page;
167 in_offs = loop_off; 138 in_offs = loop_off;
168 out_page = raw_page; 139 out_page = raw_page;
169 out_offs = raw_off; 140 out_offs = raw_off;
170 encdecfunc = tfm->crt_u.cipher.cit_encrypt_iv; 141 encdecfunc = crypto_blkcipher_crt(tfm)->encrypt;
171 } 142 }
172 143
173 while (size > 0) { 144 while (size > 0) {
@@ -183,7 +154,10 @@ cryptoloop_transfer_cbc(struct loop_device *lo, int cmd,
183 sg_out.offset = out_offs; 154 sg_out.offset = out_offs;
184 sg_out.length = sz; 155 sg_out.length = sz;
185 156
186 encdecfunc(tfm, &sg_out, &sg_in, sz, (u8 *)iv); 157 desc.info = iv;
158 err = encdecfunc(&desc, &sg_out, &sg_in, sz);
159 if (err)
160 return err;
187 161
188 IV++; 162 IV++;
189 size -= sz; 163 size -= sz;
@@ -195,32 +169,6 @@ cryptoloop_transfer_cbc(struct loop_device *lo, int cmd,
195} 169}
196 170
197static int 171static int
198cryptoloop_transfer(struct loop_device *lo, int cmd,
199 struct page *raw_page, unsigned raw_off,
200 struct page *loop_page, unsigned loop_off,
201 int size, sector_t IV)
202{
203 struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data;
204 if(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB)
205 {
206 lo->transfer = cryptoloop_transfer_ecb;
207 return cryptoloop_transfer_ecb(lo, cmd, raw_page, raw_off,
208 loop_page, loop_off, size, IV);
209 }
210 if(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_CBC)
211 {
212 lo->transfer = cryptoloop_transfer_cbc;
213 return cryptoloop_transfer_cbc(lo, cmd, raw_page, raw_off,
214 loop_page, loop_off, size, IV);
215 }
216
217 /* This is not supposed to happen */
218
219 printk( KERN_ERR "cryptoloop: unsupported cipher mode in cryptoloop_transfer!\n");
220 return -EINVAL;
221}
222
223static int
224cryptoloop_ioctl(struct loop_device *lo, int cmd, unsigned long arg) 172cryptoloop_ioctl(struct loop_device *lo, int cmd, unsigned long arg)
225{ 173{
226 return -EINVAL; 174 return -EINVAL;
@@ -229,9 +177,9 @@ cryptoloop_ioctl(struct loop_device *lo, int cmd, unsigned long arg)
229static int 177static int
230cryptoloop_release(struct loop_device *lo) 178cryptoloop_release(struct loop_device *lo)
231{ 179{
232 struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data; 180 struct crypto_blkcipher *tfm = lo->key_data;
233 if (tfm != NULL) { 181 if (tfm != NULL) {
234 crypto_free_tfm(tfm); 182 crypto_free_blkcipher(tfm);
235 lo->key_data = NULL; 183 lo->key_data = NULL;
236 return 0; 184 return 0;
237 } 185 }
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index c40e487d9f5c..52ea94b891f5 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -495,6 +495,21 @@ config LEGACY_PTY_COUNT
495 When not in use, each legacy PTY occupies 12 bytes on 32-bit 495 When not in use, each legacy PTY occupies 12 bytes on 32-bit
496 architectures and 24 bytes on 64-bit architectures. 496 architectures and 24 bytes on 64-bit architectures.
497 497
498config BRIQ_PANEL
499 tristate 'Total Impact briQ front panel driver'
500 depends on PPC_CHRP
501 ---help---
502 The briQ is a small footprint CHRP computer with a frontpanel VFD, a
503 tristate led and two switches. It is the size of a CDROM drive.
504
505 If you have such one and want anything showing on the VFD then you
506 must answer Y here.
507
508 To compile this driver as a module, choose M here: the
509 module will be called briq_panel.
510
511 It's safe to say N here.
512
498config PRINTER 513config PRINTER
499 tristate "Parallel printer support" 514 tristate "Parallel printer support"
500 depends on PARPORT 515 depends on PARPORT
@@ -596,6 +611,13 @@ config HVC_CONSOLE
596 console. This driver allows each pSeries partition to have a console 611 console. This driver allows each pSeries partition to have a console
597 which is accessed via the HMC. 612 which is accessed via the HMC.
598 613
614config HVC_ISERIES
615 bool "iSeries Hypervisor Virtual Console support"
616 depends on PPC_ISERIES && !VIOCONS
617 select HVC_DRIVER
618 help
619 iSeries machines support a hypervisor virtual console.
620
599config HVC_RTAS 621config HVC_RTAS
600 bool "IBM RTAS Console support" 622 bool "IBM RTAS Console support"
601 depends on PPC_RTAS 623 depends on PPC_RTAS
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 6e0f4469d8bb..8c6dfc621520 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
42obj-$(CONFIG_SX) += sx.o generic_serial.o 42obj-$(CONFIG_SX) += sx.o generic_serial.o
43obj-$(CONFIG_RIO) += rio/ generic_serial.o 43obj-$(CONFIG_RIO) += rio/ generic_serial.o
44obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o 44obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o
45obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
45obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o 46obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
46obj-$(CONFIG_HVC_DRIVER) += hvc_console.o 47obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
47obj-$(CONFIG_RAW_DRIVER) += raw.o 48obj-$(CONFIG_RAW_DRIVER) += raw.o
@@ -51,6 +52,7 @@ obj-$(CONFIG_VIOCONS) += viocons.o
51obj-$(CONFIG_VIOTAPE) += viotape.o 52obj-$(CONFIG_VIOTAPE) += viotape.o
52obj-$(CONFIG_HVCS) += hvcs.o 53obj-$(CONFIG_HVCS) += hvcs.o
53obj-$(CONFIG_SGI_MBCS) += mbcs.o 54obj-$(CONFIG_SGI_MBCS) += mbcs.o
55obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
54 56
55obj-$(CONFIG_PRINTER) += lp.o 57obj-$(CONFIG_PRINTER) += lp.o
56obj-$(CONFIG_TIPAR) += tipar.o 58obj-$(CONFIG_TIPAR) += tipar.o
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 1de1b12043bf..91b71e750ee1 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -601,8 +601,8 @@ static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
601 uninorth_node = of_find_node_by_name(NULL, "u3"); 601 uninorth_node = of_find_node_by_name(NULL, "u3");
602 } 602 }
603 if (uninorth_node) { 603 if (uninorth_node) {
604 int *revprop = (int *) 604 const int *revprop = get_property(uninorth_node,
605 get_property(uninorth_node, "device-rev", NULL); 605 "device-rev", NULL);
606 if (revprop != NULL) 606 if (revprop != NULL)
607 uninorth_rev = *revprop & 0x3f; 607 uninorth_rev = *revprop & 0x3f;
608 of_node_put(uninorth_node); 608 of_node_put(uninorth_node);
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
new file mode 100644
index 000000000000..a0e5eac5f33a
--- /dev/null
+++ b/drivers/char/briq_panel.c
@@ -0,0 +1,268 @@
1/*
2 * Drivers for the Total Impact PPC based computer "BRIQ"
3 * by Dr. Karsten Jeppesen
4 *
5 */
6
7#include <linux/module.h>
8
9#include <linux/types.h>
10#include <linux/errno.h>
11#include <linux/sched.h>
12#include <linux/tty.h>
13#include <linux/timer.h>
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/wait.h>
17#include <linux/string.h>
18#include <linux/slab.h>
19#include <linux/ioport.h>
20#include <linux/delay.h>
21#include <linux/miscdevice.h>
22#include <linux/fs.h>
23#include <linux/mm.h>
24#include <linux/init.h>
25
26#include <asm/uaccess.h>
27#include <asm/io.h>
28#include <asm/prom.h>
29
30#define BRIQ_PANEL_MINOR 156
31#define BRIQ_PANEL_VFD_IOPORT 0x0390
32#define BRIQ_PANEL_LED_IOPORT 0x0398
33#define BRIQ_PANEL_VER "1.1 (04/20/2002)"
34#define BRIQ_PANEL_MSG0 "Loading Linux"
35
36static int vfd_is_open;
37static unsigned char vfd[40];
38static int vfd_cursor;
39static unsigned char ledpb, led;
40
41static void update_vfd(void)
42{
43 int i;
44
45 /* cursor home */
46 outb(0x02, BRIQ_PANEL_VFD_IOPORT);
47 for (i=0; i<20; i++)
48 outb(vfd[i], BRIQ_PANEL_VFD_IOPORT + 1);
49
50 /* cursor to next line */
51 outb(0xc0, BRIQ_PANEL_VFD_IOPORT);
52 for (i=20; i<40; i++)
53 outb(vfd[i], BRIQ_PANEL_VFD_IOPORT + 1);
54
55}
56
57static void set_led(char state)
58{
59 if (state == 'R')
60 led = 0x01;
61 else if (state == 'G')
62 led = 0x02;
63 else if (state == 'Y')
64 led = 0x03;
65 else if (state == 'X')
66 led = 0x00;
67 outb(led, BRIQ_PANEL_LED_IOPORT);
68}
69
70static int briq_panel_open(struct inode *ino, struct file *filep)
71{
72 /* enforce single access */
73 if (vfd_is_open)
74 return -EBUSY;
75 vfd_is_open = 1;
76
77 return 0;
78}
79
80static int briq_panel_release(struct inode *ino, struct file *filep)
81{
82 if (!vfd_is_open)
83 return -ENODEV;
84
85 vfd_is_open = 0;
86
87 return 0;
88}
89
90static ssize_t briq_panel_read(struct file *file, char *buf, size_t count,
91 loff_t *ppos)
92{
93 unsigned short c;
94 unsigned char cp;
95
96#if 0 /* Can't seek (pread) on this device */
97 if (ppos != &file->f_pos)
98 return -ESPIPE;
99#endif
100
101 if (!vfd_is_open)
102 return -ENODEV;
103
104 c = (inb(BRIQ_PANEL_LED_IOPORT) & 0x000c) | (ledpb & 0x0003);
105 set_led(' ');
106 /* upper button released */
107 if ((!(ledpb & 0x0004)) && (c & 0x0004)) {
108 cp = ' ';
109 ledpb = c;
110 if (copy_to_user(buf, &cp, 1))
111 return -EFAULT;
112 return 1;
113 }
114 /* lower button released */
115 else if ((!(ledpb & 0x0008)) && (c & 0x0008)) {
116 cp = '\r';
117 ledpb = c;
118 if (copy_to_user(buf, &cp, 1))
119 return -EFAULT;
120 return 1;
121 } else {
122 ledpb = c;
123 return 0;
124 }
125}
126
127static void scroll_vfd( void )
128{
129 int i;
130
131 for (i=0; i<20; i++) {
132 vfd[i] = vfd[i+20];
133 vfd[i+20] = ' ';
134 }
135 vfd_cursor = 20;
136}
137
138static ssize_t briq_panel_write(struct file *file, const char *buf, size_t len,
139 loff_t *ppos)
140{
141 size_t indx = len;
142 int i, esc = 0;
143
144#if 0 /* Can't seek (pwrite) on this device */
145 if (ppos != &file->f_pos)
146 return -ESPIPE;
147#endif
148
149 if (!vfd_is_open)
150 return -EBUSY;
151
152 for (;;) {
153 if (!indx)
154 break;
155 if (esc) {
156 set_led(*buf);
157 esc = 0;
158 } else if (*buf == 27) {
159 esc = 1;
160 } else if (*buf == 12) {
161 /* do a form feed */
162 for (i=0; i<40; i++)
163 vfd[i] = ' ';
164 vfd_cursor = 0;
165 } else if (*buf == 10) {
166 if (vfd_cursor < 20)
167 vfd_cursor = 20;
168 else if (vfd_cursor < 40)
169 vfd_cursor = 40;
170 else if (vfd_cursor < 60)
171 vfd_cursor = 60;
172 if (vfd_cursor > 59)
173 scroll_vfd();
174 } else {
175 /* just a character */
176 if (vfd_cursor > 39)
177 scroll_vfd();
178 vfd[vfd_cursor++] = *buf;
179 }
180 indx--;
181 buf++;
182 }
183 update_vfd();
184
185 return len;
186}
187
188static struct file_operations briq_panel_fops = {
189 .owner = THIS_MODULE,
190 .read = briq_panel_read,
191 .write = briq_panel_write,
192 .open = briq_panel_open,
193 .release = briq_panel_release,
194};
195
196static struct miscdevice briq_panel_miscdev = {
197 BRIQ_PANEL_MINOR,
198 "briq_panel",
199 &briq_panel_fops
200};
201
202static int __init briq_panel_init(void)
203{
204 struct device_node *root = find_path_device("/");
205 char *machine;
206 int i;
207
208 machine = get_property(root, "model", NULL);
209 if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0)
210 return -ENODEV;
211
212 printk(KERN_INFO
213 "briq_panel: v%s Dr. Karsten Jeppesen (kj@totalimpact.com)\n",
214 BRIQ_PANEL_VER);
215
216 if (!request_region(BRIQ_PANEL_VFD_IOPORT, 4, "BRIQ Front Panel"))
217 return -EBUSY;
218
219 if (!request_region(BRIQ_PANEL_LED_IOPORT, 2, "BRIQ Front Panel")) {
220 release_region(BRIQ_PANEL_VFD_IOPORT, 4);
221 return -EBUSY;
222 }
223 ledpb = inb(BRIQ_PANEL_LED_IOPORT) & 0x000c;
224
225 if (misc_register(&briq_panel_miscdev) < 0) {
226 release_region(BRIQ_PANEL_VFD_IOPORT, 4);
227 release_region(BRIQ_PANEL_LED_IOPORT, 2);
228 return -EBUSY;
229 }
230
231 outb(0x38, BRIQ_PANEL_VFD_IOPORT); /* Function set */
232 outb(0x01, BRIQ_PANEL_VFD_IOPORT); /* Clear display */
233 outb(0x0c, BRIQ_PANEL_VFD_IOPORT); /* Display on */
234 outb(0x06, BRIQ_PANEL_VFD_IOPORT); /* Entry normal */
235 for (i=0; i<40; i++)
236 vfd[i]=' ';
237#ifndef MODULE
238 vfd[0] = 'L';
239 vfd[1] = 'o';
240 vfd[2] = 'a';
241 vfd[3] = 'd';
242 vfd[4] = 'i';
243 vfd[5] = 'n';
244 vfd[6] = 'g';
245 vfd[7] = ' ';
246 vfd[8] = '.';
247 vfd[9] = '.';
248 vfd[10] = '.';
249#endif /* !MODULE */
250
251 update_vfd();
252
253 return 0;
254}
255
256static void __exit briq_panel_exit(void)
257{
258 misc_deregister(&briq_panel_miscdev);
259 release_region(BRIQ_PANEL_VFD_IOPORT, 4);
260 release_region(BRIQ_PANEL_LED_IOPORT, 2);
261}
262
263module_init(briq_panel_init);
264module_exit(briq_panel_exit);
265
266MODULE_LICENSE("GPL");
267MODULE_AUTHOR("Karsten Jeppesen <karsten@jeppesens.com>");
268MODULE_DESCRIPTION("Driver for the Total Impact briQ front panel");
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 613d67f1c7f0..a76d2c40dd5e 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -80,7 +80,8 @@ struct hvc_struct {
80 struct tty_struct *tty; 80 struct tty_struct *tty;
81 unsigned int count; 81 unsigned int count;
82 int do_wakeup; 82 int do_wakeup;
83 char outbuf[N_OUTBUF] __ALIGNED__; 83 char *outbuf;
84 int outbuf_size;
84 int n_outbuf; 85 int n_outbuf;
85 uint32_t vtermno; 86 uint32_t vtermno;
86 struct hv_ops *ops; 87 struct hv_ops *ops;
@@ -319,10 +320,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
319 struct kobject *kobjp; 320 struct kobject *kobjp;
320 321
321 /* Auto increments kobject reference if found. */ 322 /* Auto increments kobject reference if found. */
322 if (!(hp = hvc_get_by_index(tty->index))) { 323 if (!(hp = hvc_get_by_index(tty->index)))
323 printk(KERN_WARNING "hvc_console: tty open failed, no vty associated with tty.\n");
324 return -ENODEV; 324 return -ENODEV;
325 }
326 325
327 spin_lock_irqsave(&hp->lock, flags); 326 spin_lock_irqsave(&hp->lock, flags);
328 /* Check and then increment for fast path open. */ 327 /* Check and then increment for fast path open. */
@@ -505,7 +504,7 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
505 if (hp->n_outbuf > 0) 504 if (hp->n_outbuf > 0)
506 hvc_push(hp); 505 hvc_push(hp);
507 506
508 while (count > 0 && (rsize = N_OUTBUF - hp->n_outbuf) > 0) { 507 while (count > 0 && (rsize = hp->outbuf_size - hp->n_outbuf) > 0) {
509 if (rsize > count) 508 if (rsize > count)
510 rsize = count; 509 rsize = count;
511 memcpy(hp->outbuf + hp->n_outbuf, buf, rsize); 510 memcpy(hp->outbuf + hp->n_outbuf, buf, rsize);
@@ -538,7 +537,7 @@ static int hvc_write_room(struct tty_struct *tty)
538 if (!hp) 537 if (!hp)
539 return -1; 538 return -1;
540 539
541 return N_OUTBUF - hp->n_outbuf; 540 return hp->outbuf_size - hp->n_outbuf;
542} 541}
543 542
544static int hvc_chars_in_buffer(struct tty_struct *tty) 543static int hvc_chars_in_buffer(struct tty_struct *tty)
@@ -729,12 +728,13 @@ static struct kobj_type hvc_kobj_type = {
729}; 728};
730 729
731struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, 730struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
732 struct hv_ops *ops) 731 struct hv_ops *ops, int outbuf_size)
733{ 732{
734 struct hvc_struct *hp; 733 struct hvc_struct *hp;
735 int i; 734 int i;
736 735
737 hp = kmalloc(sizeof(*hp), GFP_KERNEL); 736 hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
737 GFP_KERNEL);
738 if (!hp) 738 if (!hp)
739 return ERR_PTR(-ENOMEM); 739 return ERR_PTR(-ENOMEM);
740 740
@@ -743,6 +743,8 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
743 hp->vtermno = vtermno; 743 hp->vtermno = vtermno;
744 hp->irq = irq; 744 hp->irq = irq;
745 hp->ops = ops; 745 hp->ops = ops;
746 hp->outbuf_size = outbuf_size;
747 hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
746 748
747 kobject_init(&hp->kobj); 749 kobject_init(&hp->kobj);
748 hp->kobj.ktype = &hvc_kobj_type; 750 hp->kobj.ktype = &hvc_kobj_type;
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h
index 96b7401319c1..8c59818050e6 100644
--- a/drivers/char/hvc_console.h
+++ b/drivers/char/hvc_console.h
@@ -56,7 +56,7 @@ extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
56 56
57/* register a vterm for hvc tty operation (module_init or hotplug add) */ 57/* register a vterm for hvc tty operation (module_init or hotplug add) */
58extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, 58extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
59 struct hv_ops *ops); 59 struct hv_ops *ops, int outbuf_size);
60/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ 60/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
61extern int __devexit hvc_remove(struct hvc_struct *hp); 61extern int __devexit hvc_remove(struct hvc_struct *hp);
62 62
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
new file mode 100644
index 000000000000..4747729459c7
--- /dev/null
+++ b/drivers/char/hvc_iseries.c
@@ -0,0 +1,594 @@
1/*
2 * iSeries vio driver interface to hvc_console.c
3 *
4 * This code is based heavily on hvc_vio.c and viocons.c
5 *
6 * Copyright (C) 2006 Stephen Rothwell, IBM Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#include <stdarg.h>
23#include <linux/types.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/spinlock.h>
27#include <linux/console.h>
28
29#include <asm/hvconsole.h>
30#include <asm/vio.h>
31#include <asm/prom.h>
32#include <asm/iseries/vio.h>
33#include <asm/iseries/hv_call.h>
34#include <asm/iseries/hv_lp_config.h>
35#include <asm/iseries/hv_lp_event.h>
36
37#include "hvc_console.h"
38
39#define VTTY_PORTS 10
40
41static DEFINE_SPINLOCK(consolelock);
42static DEFINE_SPINLOCK(consoleloglock);
43
44static const char hvc_driver_name[] = "hvc_console";
45
46#define IN_BUF_SIZE 200
47
48/*
49 * Our port information.
50 */
51static struct port_info {
52 HvLpIndex lp;
53 u64 seq; /* sequence number of last HV send */
54 u64 ack; /* last ack from HV */
55 struct hvc_struct *hp;
56 int in_start;
57 int in_end;
58 unsigned char in_buf[IN_BUF_SIZE];
59} port_info[VTTY_PORTS] = {
60 [ 0 ... VTTY_PORTS - 1 ] = {
61 .lp = HvLpIndexInvalid
62 }
63};
64
65#define viochar_is_console(pi) ((pi) == &port_info[0])
66
67static struct vio_device_id hvc_driver_table[] __devinitdata = {
68 {"serial", "IBM,iSeries-vty"},
69 { "", "" }
70};
71MODULE_DEVICE_TABLE(vio, hvc_driver_table);
72
73static void hvlog(char *fmt, ...)
74{
75 int i;
76 unsigned long flags;
77 va_list args;
78 static char buf[256];
79
80 spin_lock_irqsave(&consoleloglock, flags);
81 va_start(args, fmt);
82 i = vscnprintf(buf, sizeof(buf) - 1, fmt, args);
83 va_end(args);
84 buf[i++] = '\r';
85 HvCall_writeLogBuffer(buf, i);
86 spin_unlock_irqrestore(&consoleloglock, flags);
87}
88
89/*
90 * Initialize the common fields in a charLpEvent
91 */
92static void init_data_event(struct viocharlpevent *viochar, HvLpIndex lp)
93{
94 struct HvLpEvent *hev = &viochar->event;
95
96 memset(viochar, 0, sizeof(struct viocharlpevent));
97
98 hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK |
99 HV_LP_EVENT_INT;
100 hev->xType = HvLpEvent_Type_VirtualIo;
101 hev->xSubtype = viomajorsubtype_chario | viochardata;
102 hev->xSourceLp = HvLpConfig_getLpIndex();
103 hev->xTargetLp = lp;
104 hev->xSizeMinus1 = sizeof(struct viocharlpevent);
105 hev->xSourceInstanceId = viopath_sourceinst(lp);
106 hev->xTargetInstanceId = viopath_targetinst(lp);
107}
108
109static int get_chars(uint32_t vtermno, char *buf, int count)
110{
111 struct port_info *pi;
112 int n = 0;
113 unsigned long flags;
114
115 if (vtermno >= VTTY_PORTS)
116 return -EINVAL;
117 if (count == 0)
118 return 0;
119
120 pi = &port_info[vtermno];
121 spin_lock_irqsave(&consolelock, flags);
122
123 if (pi->in_end == 0)
124 goto done;
125
126 n = pi->in_end - pi->in_start;
127 if (n > count)
128 n = count;
129 memcpy(buf, &pi->in_buf[pi->in_start], n);
130 pi->in_start += n;
131 if (pi->in_start == pi->in_end) {
132 pi->in_start = 0;
133 pi->in_end = 0;
134 }
135done:
136 spin_unlock_irqrestore(&consolelock, flags);
137 return n;
138}
139
140static int put_chars(uint32_t vtermno, const char *buf, int count)
141{
142 struct viocharlpevent *viochar;
143 struct port_info *pi;
144 HvLpEvent_Rc hvrc;
145 unsigned long flags;
146 int sent = 0;
147
148 if (vtermno >= VTTY_PORTS)
149 return -EINVAL;
150
151 pi = &port_info[vtermno];
152
153 spin_lock_irqsave(&consolelock, flags);
154
155 if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) {
156 spin_lock_irqsave(&consoleloglock, flags);
157 HvCall_writeLogBuffer(buf, count);
158 spin_unlock_irqrestore(&consoleloglock, flags);
159 sent = count;
160 goto done;
161 }
162
163 viochar = vio_get_event_buffer(viomajorsubtype_chario);
164 if (viochar == NULL) {
165 hvlog("\n\rviocons: Can't get viochar buffer.");
166 goto done;
167 }
168
169 while ((count > 0) && ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
170 int len;
171
172 len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count;
173
174 if (viochar_is_console(pi)) {
175 spin_lock_irqsave(&consoleloglock, flags);
176 HvCall_writeLogBuffer(buf, len);
177 spin_unlock_irqrestore(&consoleloglock, flags);
178 }
179
180 init_data_event(viochar, pi->lp);
181
182 viochar->len = len;
183 viochar->event.xCorrelationToken = pi->seq++;
184 viochar->event.xSizeMinus1 =
185 offsetof(struct viocharlpevent, data) + len;
186
187 memcpy(viochar->data, buf, len);
188
189 hvrc = HvCallEvent_signalLpEvent(&viochar->event);
190 if (hvrc)
191 hvlog("\n\rerror sending event! return code %d\n\r",
192 (int)hvrc);
193 sent += len;
194 count -= len;
195 buf += len;
196 }
197
198 vio_free_event_buffer(viomajorsubtype_chario, viochar);
199done:
200 spin_unlock_irqrestore(&consolelock, flags);
201 return sent;
202}
203
204static struct hv_ops hvc_get_put_ops = {
205 .get_chars = get_chars,
206 .put_chars = put_chars,
207};
208
209static int __devinit hvc_vio_probe(struct vio_dev *vdev,
210 const struct vio_device_id *id)
211{
212 struct hvc_struct *hp;
213 struct port_info *pi;
214
215 /* probed with invalid parameters. */
216 if (!vdev || !id)
217 return -EPERM;
218
219 if (vdev->unit_address >= VTTY_PORTS)
220 return -ENODEV;
221
222 pi = &port_info[vdev->unit_address];
223
224 hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops,
225 VIOCHAR_MAX_DATA);
226 if (IS_ERR(hp))
227 return PTR_ERR(hp);
228 pi->hp = hp;
229 dev_set_drvdata(&vdev->dev, pi);
230
231 return 0;
232}
233
234static int __devexit hvc_vio_remove(struct vio_dev *vdev)
235{
236 struct port_info *pi = dev_get_drvdata(&vdev->dev);
237 struct hvc_struct *hp = pi->hp;
238
239 return hvc_remove(hp);
240}
241
242static struct vio_driver hvc_vio_driver = {
243 .id_table = hvc_driver_table,
244 .probe = hvc_vio_probe,
245 .remove = hvc_vio_remove,
246 .driver = {
247 .name = hvc_driver_name,
248 .owner = THIS_MODULE,
249 }
250};
251
252static void hvc_open_event(struct HvLpEvent *event)
253{
254 unsigned long flags;
255 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
256 u8 port = cevent->virtual_device;
257 struct port_info *pi;
258 int reject = 0;
259
260 if (hvlpevent_is_ack(event)) {
261 if (port >= VTTY_PORTS)
262 return;
263
264 spin_lock_irqsave(&consolelock, flags);
265
266 pi = &port_info[port];
267 if (event->xRc == HvLpEvent_Rc_Good) {
268 pi->seq = pi->ack = 0;
269 /*
270 * This line allows connections from the primary
271 * partition but once one is connected from the
272 * primary partition nothing short of a reboot
273 * of linux will allow access from the hosting
274 * partition again without a required iSeries fix.
275 */
276 pi->lp = event->xTargetLp;
277 }
278
279 spin_unlock_irqrestore(&consolelock, flags);
280 if (event->xRc != HvLpEvent_Rc_Good)
281 printk(KERN_WARNING
282 "hvc: handle_open_event: event->xRc == (%d).\n",
283 event->xRc);
284
285 if (event->xCorrelationToken != 0) {
286 atomic_t *aptr= (atomic_t *)event->xCorrelationToken;
287 atomic_set(aptr, 1);
288 } else
289 printk(KERN_WARNING
290 "hvc: weird...got open ack without atomic\n");
291 return;
292 }
293
294 /* This had better require an ack, otherwise complain */
295 if (!hvlpevent_need_ack(event)) {
296 printk(KERN_WARNING "hvc: viocharopen without ack bit!\n");
297 return;
298 }
299
300 spin_lock_irqsave(&consolelock, flags);
301
302 /* Make sure this is a good virtual tty */
303 if (port >= VTTY_PORTS) {
304 event->xRc = HvLpEvent_Rc_SubtypeError;
305 cevent->subtype_result_code = viorc_openRejected;
306 /*
307 * Flag state here since we can't printk while holding
308 * the consolelock spinlock.
309 */
310 reject = 1;
311 } else {
312 pi = &port_info[port];
313 if ((pi->lp != HvLpIndexInvalid) &&
314 (pi->lp != event->xSourceLp)) {
315 /*
316 * If this is tty is already connected to a different
317 * partition, fail.
318 */
319 event->xRc = HvLpEvent_Rc_SubtypeError;
320 cevent->subtype_result_code = viorc_openRejected;
321 reject = 2;
322 } else {
323 pi->lp = event->xSourceLp;
324 event->xRc = HvLpEvent_Rc_Good;
325 cevent->subtype_result_code = viorc_good;
326 pi->seq = pi->ack = 0;
327 }
328 }
329
330 spin_unlock_irqrestore(&consolelock, flags);
331
332 if (reject == 1)
333 printk(KERN_WARNING "hvc: open rejected: bad virtual tty.\n");
334 else if (reject == 2)
335 printk(KERN_WARNING "hvc: open rejected: console in exclusive "
336 "use by another partition.\n");
337
338 /* Return the acknowledgement */
339 HvCallEvent_ackLpEvent(event);
340}
341
342/*
343 * Handle a close charLpEvent. This should ONLY be an Interrupt because the
344 * virtual console should never actually issue a close event to the hypervisor
345 * because the virtual console never goes away. A close event coming from the
346 * hypervisor simply means that there are no client consoles connected to the
347 * virtual console.
348 */
349static void hvc_close_event(struct HvLpEvent *event)
350{
351 unsigned long flags;
352 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
353 u8 port = cevent->virtual_device;
354
355 if (!hvlpevent_is_int(event)) {
356 printk(KERN_WARNING
357 "hvc: got unexpected close acknowlegement\n");
358 return;
359 }
360
361 if (port >= VTTY_PORTS) {
362 printk(KERN_WARNING
363 "hvc: close message from invalid virtual device.\n");
364 return;
365 }
366
367 /* For closes, just mark the console partition invalid */
368 spin_lock_irqsave(&consolelock, flags);
369
370 if (port_info[port].lp == event->xSourceLp)
371 port_info[port].lp = HvLpIndexInvalid;
372
373 spin_unlock_irqrestore(&consolelock, flags);
374}
375
376static void hvc_data_event(struct HvLpEvent *event)
377{
378 unsigned long flags;
379 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
380 struct port_info *pi;
381 int n;
382 u8 port = cevent->virtual_device;
383
384 if (port >= VTTY_PORTS) {
385 printk(KERN_WARNING "hvc: data on invalid virtual device %d\n",
386 port);
387 return;
388 }
389 if (cevent->len == 0)
390 return;
391
392 /*
393 * Change 05/01/2003 - Ryan Arnold: If a partition other than
394 * the current exclusive partition tries to send us data
395 * events then just drop them on the floor because we don't
396 * want his stinking data. He isn't authorized to receive
397 * data because he wasn't the first one to get the console,
398 * therefore he shouldn't be allowed to send data either.
399 * This will work without an iSeries fix.
400 */
401 pi = &port_info[port];
402 if (pi->lp != event->xSourceLp)
403 return;
404
405 spin_lock_irqsave(&consolelock, flags);
406
407 n = IN_BUF_SIZE - pi->in_end;
408 if (n > cevent->len)
409 n = cevent->len;
410 if (n > 0) {
411 memcpy(&pi->in_buf[pi->in_end], cevent->data, n);
412 pi->in_end += n;
413 }
414 spin_unlock_irqrestore(&consolelock, flags);
415 if (n == 0)
416 printk(KERN_WARNING "hvc: input buffer overflow\n");
417}
418
419static void hvc_ack_event(struct HvLpEvent *event)
420{
421 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
422 unsigned long flags;
423 u8 port = cevent->virtual_device;
424
425 if (port >= VTTY_PORTS) {
426 printk(KERN_WARNING "hvc: data on invalid virtual device\n");
427 return;
428 }
429
430 spin_lock_irqsave(&consolelock, flags);
431 port_info[port].ack = event->xCorrelationToken;
432 spin_unlock_irqrestore(&consolelock, flags);
433}
434
435static void hvc_config_event(struct HvLpEvent *event)
436{
437 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
438
439 if (cevent->data[0] == 0x01)
440 printk(KERN_INFO "hvc: window resized to %d: %d: %d: %d\n",
441 cevent->data[1], cevent->data[2],
442 cevent->data[3], cevent->data[4]);
443 else
444 printk(KERN_WARNING "hvc: unknown config event\n");
445}
446
447static void hvc_handle_event(struct HvLpEvent *event)
448{
449 int charminor;
450
451 if (event == NULL)
452 return;
453
454 charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
455 switch (charminor) {
456 case viocharopen:
457 hvc_open_event(event);
458 break;
459 case viocharclose:
460 hvc_close_event(event);
461 break;
462 case viochardata:
463 hvc_data_event(event);
464 break;
465 case viocharack:
466 hvc_ack_event(event);
467 break;
468 case viocharconfig:
469 hvc_config_event(event);
470 break;
471 default:
472 if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
473 event->xRc = HvLpEvent_Rc_InvalidSubtype;
474 HvCallEvent_ackLpEvent(event);
475 }
476 }
477}
478
479static int send_open(HvLpIndex remoteLp, void *sem)
480{
481 return HvCallEvent_signalLpEventFast(remoteLp,
482 HvLpEvent_Type_VirtualIo,
483 viomajorsubtype_chario | viocharopen,
484 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
485 viopath_sourceinst(remoteLp),
486 viopath_targetinst(remoteLp),
487 (u64)(unsigned long)sem, VIOVERSION << 16,
488 0, 0, 0, 0);
489}
490
491static int hvc_vio_init(void)
492{
493 atomic_t wait_flag;
494 int rc;
495
496 /* +2 for fudge */
497 rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
498 viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
499 if (rc)
500 printk(KERN_WARNING "hvc: error opening to primary %d\n", rc);
501
502 if (viopath_hostLp == HvLpIndexInvalid)
503 vio_set_hostlp();
504
505 /*
506 * And if the primary is not the same as the hosting LP, open to the
507 * hosting lp
508 */
509 if ((viopath_hostLp != HvLpIndexInvalid) &&
510 (viopath_hostLp != HvLpConfig_getPrimaryLpIndex())) {
511 printk(KERN_INFO "hvc: open path to hosting (%d)\n",
512 viopath_hostLp);
513 rc = viopath_open(viopath_hostLp, viomajorsubtype_chario,
514 VIOCHAR_WINDOW + 2); /* +2 for fudge */
515 if (rc)
516 printk(KERN_WARNING
517 "error opening to partition %d: %d\n",
518 viopath_hostLp, rc);
519 }
520
521 if (vio_setHandler(viomajorsubtype_chario, hvc_handle_event) < 0)
522 printk(KERN_WARNING
523 "hvc: error seting handler for console events!\n");
524
525 /*
526 * First, try to open the console to the hosting lp.
527 * Wait on a semaphore for the response.
528 */
529 atomic_set(&wait_flag, 0);
530 if ((viopath_isactive(viopath_hostLp)) &&
531 (send_open(viopath_hostLp, &wait_flag) == 0)) {
532 printk(KERN_INFO "hvc: hosting partition %d\n", viopath_hostLp);
533 while (atomic_read(&wait_flag) == 0)
534 mb();
535 atomic_set(&wait_flag, 0);
536 }
537
538 /*
539 * If we don't have an active console, try the primary
540 */
541 if ((!viopath_isactive(port_info[0].lp)) &&
542 (viopath_isactive(HvLpConfig_getPrimaryLpIndex())) &&
543 (send_open(HvLpConfig_getPrimaryLpIndex(), &wait_flag) == 0)) {
544 printk(KERN_INFO "hvc: opening console to primary partition\n");
545 while (atomic_read(&wait_flag) == 0)
546 mb();
547 }
548
549 /* Register as a vio device to receive callbacks */
550 rc = vio_register_driver(&hvc_vio_driver);
551
552 return rc;
553}
554module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
555
556static void hvc_vio_exit(void)
557{
558 vio_unregister_driver(&hvc_vio_driver);
559}
560module_exit(hvc_vio_exit);
561
562/* the device tree order defines our numbering */
563static int hvc_find_vtys(void)
564{
565 struct device_node *vty;
566 int num_found = 0;
567
568 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
569 vty = of_find_node_by_name(vty, "vty")) {
570 uint32_t *vtermno;
571
572 /* We have statically defined space for only a certain number
573 * of console adapters.
574 */
575 if ((num_found >= MAX_NR_HVC_CONSOLES) ||
576 (num_found >= VTTY_PORTS))
577 break;
578
579 vtermno = (uint32_t *)get_property(vty, "reg", NULL);
580 if (!vtermno)
581 continue;
582
583 if (!device_is_compatible(vty, "IBM,iSeries-vty"))
584 continue;
585
586 if (num_found == 0)
587 add_preferred_console("hvc", 0, NULL);
588 hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
589 ++num_found;
590 }
591
592 return num_found;
593}
594console_initcall(hvc_find_vtys);
diff --git a/drivers/char/hvc_rtas.c b/drivers/char/hvc_rtas.c
index 57106e02fd2e..4b97eaf18602 100644
--- a/drivers/char/hvc_rtas.c
+++ b/drivers/char/hvc_rtas.c
@@ -94,7 +94,7 @@ static int hvc_rtas_init(void)
94 94
95 /* Allocate an hvc_struct for the console device we instantiated 95 /* Allocate an hvc_struct for the console device we instantiated
96 * earlier. Save off hp so that we can return it on exit */ 96 * earlier. Save off hp so that we can return it on exit */
97 hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops); 97 hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops, 16);
98 if (IS_ERR(hp)) 98 if (IS_ERR(hp))
99 return PTR_ERR(hp); 99 return PTR_ERR(hp);
100 100
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 9add81ceb440..cc95941148fb 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -90,7 +90,8 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev,
90 if (!vdev || !id) 90 if (!vdev || !id)
91 return -EPERM; 91 return -EPERM;
92 92
93 hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops); 93 hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops,
94 MAX_VIO_PUT_CHARS);
94 if (IS_ERR(hp)) 95 if (IS_ERR(hp))
95 return PTR_ERR(hp); 96 return PTR_ERR(hp);
96 dev_set_drvdata(&vdev->dev, hp); 97 dev_set_drvdata(&vdev->dev, hp);
@@ -140,7 +141,7 @@ static int hvc_find_vtys(void)
140 141
141 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL; 142 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
142 vty = of_find_node_by_name(vty, "vty")) { 143 vty = of_find_node_by_name(vty, "vty")) {
143 uint32_t *vtermno; 144 const uint32_t *vtermno;
144 145
145 /* We have statically defined space for only a certain number 146 /* We have statically defined space for only a certain number
146 * of console adapters. 147 * of console adapters.
@@ -148,7 +149,7 @@ static int hvc_find_vtys(void)
148 if (num_found >= MAX_NR_HVC_CONSOLES) 149 if (num_found >= MAX_NR_HVC_CONSOLES)
149 break; 150 break;
150 151
151 vtermno = (uint32_t *)get_property(vty, "reg", NULL); 152 vtermno = get_property(vty, "reg", NULL);
152 if (!vtermno) 153 if (!vtermno)
153 continue; 154 continue;
154 155
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index 017f755632a3..a89a95fb5e40 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -1274,11 +1274,10 @@ static int __init hvsi_console_init(void)
1274 vty != NULL; 1274 vty != NULL;
1275 vty = of_find_compatible_node(vty, "serial", "hvterm-protocol")) { 1275 vty = of_find_compatible_node(vty, "serial", "hvterm-protocol")) {
1276 struct hvsi_struct *hp; 1276 struct hvsi_struct *hp;
1277 uint32_t *vtermno; 1277 const uint32_t *vtermno, *irq;
1278 uint32_t *irq;
1279 1278
1280 vtermno = (uint32_t *)get_property(vty, "reg", NULL); 1279 vtermno = get_property(vty, "reg", NULL);
1281 irq = (uint32_t *)get_property(vty, "interrupts", NULL); 1280 irq = get_property(vty, "interrupts", NULL);
1282 if (!vtermno || !irq) 1281 if (!vtermno || !irq)
1283 continue; 1282 continue;
1284 1283
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
index 2e68eeb8a2cd..aefd683c60b7 100644
--- a/drivers/char/tpm/tpm_atmel.h
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -37,7 +37,7 @@ static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
37{ 37{
38 struct device_node *dn; 38 struct device_node *dn;
39 unsigned long address, size; 39 unsigned long address, size;
40 unsigned int *reg; 40 const unsigned int *reg;
41 int reglen; 41 int reglen;
42 int naddrc; 42 int naddrc;
43 int nsizec; 43 int nsizec;
@@ -52,7 +52,7 @@ static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
52 return NULL; 52 return NULL;
53 } 53 }
54 54
55 reg = (unsigned int *) get_property(dn, "reg", &reglen); 55 reg = get_property(dn, "reg", &reglen);
56 naddrc = prom_n_addr_cells(dn); 56 naddrc = prom_n_addr_cells(dn);
57 nsizec = prom_n_size_cells(dn); 57 nsizec = prom_n_size_cells(dn);
58 58
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 766f7864c6c6..f3efeaf2826e 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -43,7 +43,6 @@
43#include <linux/sysrq.h> 43#include <linux/sysrq.h>
44 44
45#include <asm/iseries/vio.h> 45#include <asm/iseries/vio.h>
46
47#include <asm/iseries/hv_lp_event.h> 46#include <asm/iseries/hv_lp_event.h>
48#include <asm/iseries/hv_call_event.h> 47#include <asm/iseries/hv_call_event.h>
49#include <asm/iseries/hv_lp_config.h> 48#include <asm/iseries/hv_lp_config.h>
@@ -67,35 +66,6 @@ static int vio_sysrq_pressed;
67extern int sysrq_enabled; 66extern int sysrq_enabled;
68#endif 67#endif
69 68
70/*
71 * The structure of the events that flow between us and OS/400. You can't
72 * mess with this unless the OS/400 side changes too
73 */
74struct viocharlpevent {
75 struct HvLpEvent event;
76 u32 reserved;
77 u16 version;
78 u16 subtype_result_code;
79 u8 virtual_device;
80 u8 len;
81 u8 data[VIOCHAR_MAX_DATA];
82};
83
84#define VIOCHAR_WINDOW 10
85#define VIOCHAR_HIGHWATERMARK 3
86
87enum viocharsubtype {
88 viocharopen = 0x0001,
89 viocharclose = 0x0002,
90 viochardata = 0x0003,
91 viocharack = 0x0004,
92 viocharconfig = 0x0005
93};
94
95enum viochar_rc {
96 viochar_rc_ebusy = 1
97};
98
99#define VIOCHAR_NUM_BUF 16 69#define VIOCHAR_NUM_BUF 16
100 70
101/* 71/*
@@ -1183,6 +1153,7 @@ static int __init viocons_init(void)
1183 port_info[i].magic = VIOTTY_MAGIC; 1153 port_info[i].magic = VIOTTY_MAGIC;
1184 } 1154 }
1185 HvCall_setLogBufferFormatAndCodepage(HvCall_LogBuffer_ASCII, 437); 1155 HvCall_setLogBufferFormatAndCodepage(HvCall_LogBuffer_ASCII, 437);
1156 add_preferred_console("viocons", 0, NULL);
1186 register_console(&viocons_early); 1157 register_console(&viocons_early);
1187 return 0; 1158 return 0;
1188} 1159}
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index b72b2049aaae..73c78bf75d7f 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -940,7 +940,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
940 940
941static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) 941static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
942{ 942{
943 char tapename[32];
944 int i = vdev->unit_address; 943 int i = vdev->unit_address;
945 int j; 944 int j;
946 945
@@ -956,10 +955,9 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
956 "iseries!vt%d", i); 955 "iseries!vt%d", i);
957 class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), 956 class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
958 NULL, "iseries!nvt%d", i); 957 NULL, "iseries!nvt%d", i);
959 sprintf(tapename, "iseries/vt%d", i); 958 printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
960 printk(VIOTAPE_KERN_INFO "tape %s is iSeries "
961 "resource %10.10s type %4.4s, model %3.3s\n", 959 "resource %10.10s type %4.4s, model %3.3s\n",
962 tapename, viotape_unitinfo[i].rsrcname, 960 i, viotape_unitinfo[i].rsrcname,
963 viotape_unitinfo[i].type, viotape_unitinfo[i].model); 961 viotape_unitinfo[i].type, viotape_unitinfo[i].model);
964 return 0; 962 return 0;
965} 963}
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 4263935443cc..adb554153f67 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -2,22 +2,53 @@ menu "Hardware crypto devices"
2 2
3config CRYPTO_DEV_PADLOCK 3config CRYPTO_DEV_PADLOCK
4 tristate "Support for VIA PadLock ACE" 4 tristate "Support for VIA PadLock ACE"
5 depends on CRYPTO && X86_32 5 depends on X86_32
6 select CRYPTO_ALGAPI
7 default m
6 help 8 help
7 Some VIA processors come with an integrated crypto engine 9 Some VIA processors come with an integrated crypto engine
8 (so called VIA PadLock ACE, Advanced Cryptography Engine) 10 (so called VIA PadLock ACE, Advanced Cryptography Engine)
9 that provides instructions for very fast {en,de}cryption 11 that provides instructions for very fast cryptographic
10 with some algorithms. 12 operations with supported algorithms.
11 13
12 The instructions are used only when the CPU supports them. 14 The instructions are used only when the CPU supports them.
13 Otherwise software encryption is used. If you are unsure, 15 Otherwise software encryption is used.
14 say Y. 16
17 Selecting M for this option will compile a helper module
18 padlock.ko that should autoload all below configured
19 algorithms. Don't worry if your hardware does not support
20 some or all of them. In such case padlock.ko will
21 simply write a single line into the kernel log informing
22 about its failure but everything will keep working fine.
23
24 If you are unsure, say M. The compiled module will be
25 called padlock.ko
15 26
16config CRYPTO_DEV_PADLOCK_AES 27config CRYPTO_DEV_PADLOCK_AES
17 bool "Support for AES in VIA PadLock" 28 tristate "PadLock driver for AES algorithm"
18 depends on CRYPTO_DEV_PADLOCK 29 depends on CRYPTO_DEV_PADLOCK
19 default y 30 select CRYPTO_BLKCIPHER
31 default m
20 help 32 help
21 Use VIA PadLock for AES algorithm. 33 Use VIA PadLock for AES algorithm.
22 34
35 Available in VIA C3 and newer CPUs.
36
37 If unsure say M. The compiled module will be
38 called padlock-aes.ko
39
40config CRYPTO_DEV_PADLOCK_SHA
41 tristate "PadLock driver for SHA1 and SHA256 algorithms"
42 depends on CRYPTO_DEV_PADLOCK
43 select CRYPTO_SHA1
44 select CRYPTO_SHA256
45 default m
46 help
47 Use VIA PadLock for SHA1/SHA256 algorithms.
48
49 Available in VIA C7 and newer processors.
50
51 If unsure say M. The compiled module will be
52 called padlock-sha.ko
53
23endmenu 54endmenu
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 45426ca19a23..4c3d0ec1cf80 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -1,7 +1,3 @@
1
2obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o 1obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o
3 2obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
4padlock-objs-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o 3obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o
5
6padlock-objs := padlock-generic.o $(padlock-objs-y)
7
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index b643d71298a9..d4501dc7e650 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -43,11 +43,11 @@
43 * --------------------------------------------------------------------------- 43 * ---------------------------------------------------------------------------
44 */ 44 */
45 45
46#include <crypto/algapi.h>
46#include <linux/module.h> 47#include <linux/module.h>
47#include <linux/init.h> 48#include <linux/init.h>
48#include <linux/types.h> 49#include <linux/types.h>
49#include <linux/errno.h> 50#include <linux/errno.h>
50#include <linux/crypto.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/kernel.h> 52#include <linux/kernel.h>
53#include <asm/byteorder.h> 53#include <asm/byteorder.h>
@@ -59,6 +59,17 @@
59#define AES_EXTENDED_KEY_SIZE 64 /* in uint32_t units */ 59#define AES_EXTENDED_KEY_SIZE 64 /* in uint32_t units */
60#define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t)) 60#define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))
61 61
62/* Control word. */
63struct cword {
64 unsigned int __attribute__ ((__packed__))
65 rounds:4,
66 algo:3,
67 keygen:1,
68 interm:1,
69 encdec:1,
70 ksize:2;
71} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT)));
72
62/* Whenever making any changes to the following 73/* Whenever making any changes to the following
63 * structure *make sure* you keep E, d_data 74 * structure *make sure* you keep E, d_data
64 * and cword aligned on 16 Bytes boundaries!!! */ 75 * and cword aligned on 16 Bytes boundaries!!! */
@@ -286,9 +297,9 @@ aes_hw_extkey_available(uint8_t key_len)
286 return 0; 297 return 0;
287} 298}
288 299
289static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm) 300static inline struct aes_ctx *aes_ctx_common(void *ctx)
290{ 301{
291 unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm); 302 unsigned long addr = (unsigned long)ctx;
292 unsigned long align = PADLOCK_ALIGNMENT; 303 unsigned long align = PADLOCK_ALIGNMENT;
293 304
294 if (align <= crypto_tfm_ctx_alignment()) 305 if (align <= crypto_tfm_ctx_alignment())
@@ -296,16 +307,27 @@ static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm)
296 return (struct aes_ctx *)ALIGN(addr, align); 307 return (struct aes_ctx *)ALIGN(addr, align);
297} 308}
298 309
310static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm)
311{
312 return aes_ctx_common(crypto_tfm_ctx(tfm));
313}
314
315static inline struct aes_ctx *blk_aes_ctx(struct crypto_blkcipher *tfm)
316{
317 return aes_ctx_common(crypto_blkcipher_ctx(tfm));
318}
319
299static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 320static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
300 unsigned int key_len, u32 *flags) 321 unsigned int key_len)
301{ 322{
302 struct aes_ctx *ctx = aes_ctx(tfm); 323 struct aes_ctx *ctx = aes_ctx(tfm);
303 const __le32 *key = (const __le32 *)in_key; 324 const __le32 *key = (const __le32 *)in_key;
325 u32 *flags = &tfm->crt_flags;
304 uint32_t i, t, u, v, w; 326 uint32_t i, t, u, v, w;
305 uint32_t P[AES_EXTENDED_KEY_SIZE]; 327 uint32_t P[AES_EXTENDED_KEY_SIZE];
306 uint32_t rounds; 328 uint32_t rounds;
307 329
308 if (key_len != 16 && key_len != 24 && key_len != 32) { 330 if (key_len % 8) {
309 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 331 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
310 return -EINVAL; 332 return -EINVAL;
311 } 333 }
@@ -430,80 +452,212 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
430 padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1); 452 padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1);
431} 453}
432 454
433static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, 455static struct crypto_alg aes_alg = {
434 const u8 *in, unsigned int nbytes) 456 .cra_name = "aes",
457 .cra_driver_name = "aes-padlock",
458 .cra_priority = PADLOCK_CRA_PRIORITY,
459 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
460 .cra_blocksize = AES_BLOCK_SIZE,
461 .cra_ctxsize = sizeof(struct aes_ctx),
462 .cra_alignmask = PADLOCK_ALIGNMENT - 1,
463 .cra_module = THIS_MODULE,
464 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
465 .cra_u = {
466 .cipher = {
467 .cia_min_keysize = AES_MIN_KEY_SIZE,
468 .cia_max_keysize = AES_MAX_KEY_SIZE,
469 .cia_setkey = aes_set_key,
470 .cia_encrypt = aes_encrypt,
471 .cia_decrypt = aes_decrypt,
472 }
473 }
474};
475
476static int ecb_aes_encrypt(struct blkcipher_desc *desc,
477 struct scatterlist *dst, struct scatterlist *src,
478 unsigned int nbytes)
435{ 479{
436 struct aes_ctx *ctx = aes_ctx(desc->tfm); 480 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
437 padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 481 struct blkcipher_walk walk;
438 nbytes / AES_BLOCK_SIZE); 482 int err;
439 return nbytes & ~(AES_BLOCK_SIZE - 1); 483
484 blkcipher_walk_init(&walk, dst, src, nbytes);
485 err = blkcipher_walk_virt(desc, &walk);
486
487 while ((nbytes = walk.nbytes)) {
488 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
489 ctx->E, &ctx->cword.encrypt,
490 nbytes / AES_BLOCK_SIZE);
491 nbytes &= AES_BLOCK_SIZE - 1;
492 err = blkcipher_walk_done(desc, &walk, nbytes);
493 }
494
495 return err;
440} 496}
441 497
442static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, 498static int ecb_aes_decrypt(struct blkcipher_desc *desc,
443 const u8 *in, unsigned int nbytes) 499 struct scatterlist *dst, struct scatterlist *src,
500 unsigned int nbytes)
444{ 501{
445 struct aes_ctx *ctx = aes_ctx(desc->tfm); 502 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
446 padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 503 struct blkcipher_walk walk;
447 nbytes / AES_BLOCK_SIZE); 504 int err;
448 return nbytes & ~(AES_BLOCK_SIZE - 1); 505
506 blkcipher_walk_init(&walk, dst, src, nbytes);
507 err = blkcipher_walk_virt(desc, &walk);
508
509 while ((nbytes = walk.nbytes)) {
510 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
511 ctx->D, &ctx->cword.decrypt,
512 nbytes / AES_BLOCK_SIZE);
513 nbytes &= AES_BLOCK_SIZE - 1;
514 err = blkcipher_walk_done(desc, &walk, nbytes);
515 }
516
517 return err;
449} 518}
450 519
451static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, 520static struct crypto_alg ecb_aes_alg = {
452 const u8 *in, unsigned int nbytes) 521 .cra_name = "ecb(aes)",
453{ 522 .cra_driver_name = "ecb-aes-padlock",
454 struct aes_ctx *ctx = aes_ctx(desc->tfm); 523 .cra_priority = PADLOCK_COMPOSITE_PRIORITY,
455 u8 *iv; 524 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
525 .cra_blocksize = AES_BLOCK_SIZE,
526 .cra_ctxsize = sizeof(struct aes_ctx),
527 .cra_alignmask = PADLOCK_ALIGNMENT - 1,
528 .cra_type = &crypto_blkcipher_type,
529 .cra_module = THIS_MODULE,
530 .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list),
531 .cra_u = {
532 .blkcipher = {
533 .min_keysize = AES_MIN_KEY_SIZE,
534 .max_keysize = AES_MAX_KEY_SIZE,
535 .setkey = aes_set_key,
536 .encrypt = ecb_aes_encrypt,
537 .decrypt = ecb_aes_decrypt,
538 }
539 }
540};
456 541
457 iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info, 542static int cbc_aes_encrypt(struct blkcipher_desc *desc,
458 &ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE); 543 struct scatterlist *dst, struct scatterlist *src,
459 memcpy(desc->info, iv, AES_BLOCK_SIZE); 544 unsigned int nbytes)
545{
546 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
547 struct blkcipher_walk walk;
548 int err;
549
550 blkcipher_walk_init(&walk, dst, src, nbytes);
551 err = blkcipher_walk_virt(desc, &walk);
552
553 while ((nbytes = walk.nbytes)) {
554 u8 *iv = padlock_xcrypt_cbc(walk.src.virt.addr,
555 walk.dst.virt.addr, ctx->E,
556 walk.iv, &ctx->cword.encrypt,
557 nbytes / AES_BLOCK_SIZE);
558 memcpy(walk.iv, iv, AES_BLOCK_SIZE);
559 nbytes &= AES_BLOCK_SIZE - 1;
560 err = blkcipher_walk_done(desc, &walk, nbytes);
561 }
460 562
461 return nbytes & ~(AES_BLOCK_SIZE - 1); 563 return err;
462} 564}
463 565
464static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, 566static int cbc_aes_decrypt(struct blkcipher_desc *desc,
465 const u8 *in, unsigned int nbytes) 567 struct scatterlist *dst, struct scatterlist *src,
568 unsigned int nbytes)
466{ 569{
467 struct aes_ctx *ctx = aes_ctx(desc->tfm); 570 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
468 padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt, 571 struct blkcipher_walk walk;
469 nbytes / AES_BLOCK_SIZE); 572 int err;
470 return nbytes & ~(AES_BLOCK_SIZE - 1); 573
574 blkcipher_walk_init(&walk, dst, src, nbytes);
575 err = blkcipher_walk_virt(desc, &walk);
576
577 while ((nbytes = walk.nbytes)) {
578 padlock_xcrypt_cbc(walk.src.virt.addr, walk.dst.virt.addr,
579 ctx->D, walk.iv, &ctx->cword.decrypt,
580 nbytes / AES_BLOCK_SIZE);
581 nbytes &= AES_BLOCK_SIZE - 1;
582 err = blkcipher_walk_done(desc, &walk, nbytes);
583 }
584
585 return err;
471} 586}
472 587
473static struct crypto_alg aes_alg = { 588static struct crypto_alg cbc_aes_alg = {
474 .cra_name = "aes", 589 .cra_name = "cbc(aes)",
475 .cra_driver_name = "aes-padlock", 590 .cra_driver_name = "cbc-aes-padlock",
476 .cra_priority = 300, 591 .cra_priority = PADLOCK_COMPOSITE_PRIORITY,
477 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 592 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
478 .cra_blocksize = AES_BLOCK_SIZE, 593 .cra_blocksize = AES_BLOCK_SIZE,
479 .cra_ctxsize = sizeof(struct aes_ctx), 594 .cra_ctxsize = sizeof(struct aes_ctx),
480 .cra_alignmask = PADLOCK_ALIGNMENT - 1, 595 .cra_alignmask = PADLOCK_ALIGNMENT - 1,
596 .cra_type = &crypto_blkcipher_type,
481 .cra_module = THIS_MODULE, 597 .cra_module = THIS_MODULE,
482 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), 598 .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
483 .cra_u = { 599 .cra_u = {
484 .cipher = { 600 .blkcipher = {
485 .cia_min_keysize = AES_MIN_KEY_SIZE, 601 .min_keysize = AES_MIN_KEY_SIZE,
486 .cia_max_keysize = AES_MAX_KEY_SIZE, 602 .max_keysize = AES_MAX_KEY_SIZE,
487 .cia_setkey = aes_set_key, 603 .ivsize = AES_BLOCK_SIZE,
488 .cia_encrypt = aes_encrypt, 604 .setkey = aes_set_key,
489 .cia_decrypt = aes_decrypt, 605 .encrypt = cbc_aes_encrypt,
490 .cia_encrypt_ecb = aes_encrypt_ecb, 606 .decrypt = cbc_aes_decrypt,
491 .cia_decrypt_ecb = aes_decrypt_ecb,
492 .cia_encrypt_cbc = aes_encrypt_cbc,
493 .cia_decrypt_cbc = aes_decrypt_cbc,
494 } 607 }
495 } 608 }
496}; 609};
497 610
498int __init padlock_init_aes(void) 611static int __init padlock_init(void)
499{ 612{
500 printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n"); 613 int ret;
614
615 if (!cpu_has_xcrypt) {
616 printk(KERN_ERR PFX "VIA PadLock not detected.\n");
617 return -ENODEV;
618 }
619
620 if (!cpu_has_xcrypt_enabled) {
621 printk(KERN_ERR PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");
622 return -ENODEV;
623 }
501 624
502 gen_tabs(); 625 gen_tabs();
503 return crypto_register_alg(&aes_alg); 626 if ((ret = crypto_register_alg(&aes_alg)))
627 goto aes_err;
628
629 if ((ret = crypto_register_alg(&ecb_aes_alg)))
630 goto ecb_aes_err;
631
632 if ((ret = crypto_register_alg(&cbc_aes_alg)))
633 goto cbc_aes_err;
634
635 printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n");
636
637out:
638 return ret;
639
640cbc_aes_err:
641 crypto_unregister_alg(&ecb_aes_alg);
642ecb_aes_err:
643 crypto_unregister_alg(&aes_alg);
644aes_err:
645 printk(KERN_ERR PFX "VIA PadLock AES initialization failed.\n");
646 goto out;
504} 647}
505 648
506void __exit padlock_fini_aes(void) 649static void __exit padlock_fini(void)
507{ 650{
651 crypto_unregister_alg(&cbc_aes_alg);
652 crypto_unregister_alg(&ecb_aes_alg);
508 crypto_unregister_alg(&aes_alg); 653 crypto_unregister_alg(&aes_alg);
509} 654}
655
656module_init(padlock_init);
657module_exit(padlock_fini);
658
659MODULE_DESCRIPTION("VIA PadLock AES algorithm support");
660MODULE_LICENSE("GPL");
661MODULE_AUTHOR("Michal Ludvig");
662
663MODULE_ALIAS("aes-padlock");
diff --git a/drivers/crypto/padlock-generic.c b/drivers/crypto/padlock-generic.c
deleted file mode 100644
index 18cf0e8274a7..000000000000
--- a/drivers/crypto/padlock-generic.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Cryptographic API.
3 *
4 * Support for VIA PadLock hardware crypto engine.
5 *
6 * Copyright (c) 2004 Michal Ludvig <michal@logix.cz>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/errno.h>
18#include <linux/crypto.h>
19#include <asm/byteorder.h>
20#include "padlock.h"
21
22static int __init
23padlock_init(void)
24{
25 int ret = -ENOSYS;
26
27 if (!cpu_has_xcrypt) {
28 printk(KERN_ERR PFX "VIA PadLock not detected.\n");
29 return -ENODEV;
30 }
31
32 if (!cpu_has_xcrypt_enabled) {
33 printk(KERN_ERR PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");
34 return -ENODEV;
35 }
36
37#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES
38 if ((ret = padlock_init_aes())) {
39 printk(KERN_ERR PFX "VIA PadLock AES initialization failed.\n");
40 return ret;
41 }
42#endif
43
44 if (ret == -ENOSYS)
45 printk(KERN_ERR PFX "Hmm, VIA PadLock was compiled without any algorithm.\n");
46
47 return ret;
48}
49
50static void __exit
51padlock_fini(void)
52{
53#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES
54 padlock_fini_aes();
55#endif
56}
57
58module_init(padlock_init);
59module_exit(padlock_fini);
60
61MODULE_DESCRIPTION("VIA PadLock crypto engine support.");
62MODULE_LICENSE("Dual BSD/GPL");
63MODULE_AUTHOR("Michal Ludvig");
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
new file mode 100644
index 000000000000..a781fd23b607
--- /dev/null
+++ b/drivers/crypto/padlock-sha.c
@@ -0,0 +1,318 @@
1/*
2 * Cryptographic API.
3 *
4 * Support for VIA PadLock hardware crypto engine.
5 *
6 * Copyright (c) 2006 Michal Ludvig <michal@logix.cz>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14
15#include <crypto/algapi.h>
16#include <linux/err.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/errno.h>
20#include <linux/cryptohash.h>
21#include <linux/interrupt.h>
22#include <linux/kernel.h>
23#include <linux/scatterlist.h>
24#include "padlock.h"
25
26#define SHA1_DEFAULT_FALLBACK "sha1-generic"
27#define SHA1_DIGEST_SIZE 20
28#define SHA1_HMAC_BLOCK_SIZE 64
29
30#define SHA256_DEFAULT_FALLBACK "sha256-generic"
31#define SHA256_DIGEST_SIZE 32
32#define SHA256_HMAC_BLOCK_SIZE 64
33
34struct padlock_sha_ctx {
35 char *data;
36 size_t used;
37 int bypass;
38 void (*f_sha_padlock)(const char *in, char *out, int count);
39 struct hash_desc fallback;
40};
41
42static inline struct padlock_sha_ctx *ctx(struct crypto_tfm *tfm)
43{
44 return crypto_tfm_ctx(tfm);
45}
46
47/* We'll need aligned address on the stack */
48#define NEAREST_ALIGNED(ptr) \
49 ((void *)ALIGN((size_t)(ptr), PADLOCK_ALIGNMENT))
50
51static struct crypto_alg sha1_alg, sha256_alg;
52
53static void padlock_sha_bypass(struct crypto_tfm *tfm)
54{
55 if (ctx(tfm)->bypass)
56 return;
57
58 crypto_hash_init(&ctx(tfm)->fallback);
59 if (ctx(tfm)->data && ctx(tfm)->used) {
60 struct scatterlist sg;
61
62 sg_set_buf(&sg, ctx(tfm)->data, ctx(tfm)->used);
63 crypto_hash_update(&ctx(tfm)->fallback, &sg, sg.length);
64 }
65
66 ctx(tfm)->used = 0;
67 ctx(tfm)->bypass = 1;
68}
69
70static void padlock_sha_init(struct crypto_tfm *tfm)
71{
72 ctx(tfm)->used = 0;
73 ctx(tfm)->bypass = 0;
74}
75
76static void padlock_sha_update(struct crypto_tfm *tfm,
77 const uint8_t *data, unsigned int length)
78{
79 /* Our buffer is always one page. */
80 if (unlikely(!ctx(tfm)->bypass &&
81 (ctx(tfm)->used + length > PAGE_SIZE)))
82 padlock_sha_bypass(tfm);
83
84 if (unlikely(ctx(tfm)->bypass)) {
85 struct scatterlist sg;
86 sg_set_buf(&sg, (uint8_t *)data, length);
87 crypto_hash_update(&ctx(tfm)->fallback, &sg, length);
88 return;
89 }
90
91 memcpy(ctx(tfm)->data + ctx(tfm)->used, data, length);
92 ctx(tfm)->used += length;
93}
94
95static inline void padlock_output_block(uint32_t *src,
96 uint32_t *dst, size_t count)
97{
98 while (count--)
99 *dst++ = swab32(*src++);
100}
101
102static void padlock_do_sha1(const char *in, char *out, int count)
103{
104 /* We can't store directly to *out as it may be unaligned. */
105 /* BTW Don't reduce the buffer size below 128 Bytes!
106 * PadLock microcode needs it that big. */
107 char buf[128+16];
108 char *result = NEAREST_ALIGNED(buf);
109
110 ((uint32_t *)result)[0] = 0x67452301;
111 ((uint32_t *)result)[1] = 0xEFCDAB89;
112 ((uint32_t *)result)[2] = 0x98BADCFE;
113 ((uint32_t *)result)[3] = 0x10325476;
114 ((uint32_t *)result)[4] = 0xC3D2E1F0;
115
116 asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" /* rep xsha1 */
117 : "+S"(in), "+D"(result)
118 : "c"(count), "a"(0));
119
120 padlock_output_block((uint32_t *)result, (uint32_t *)out, 5);
121}
122
123static void padlock_do_sha256(const char *in, char *out, int count)
124{
125 /* We can't store directly to *out as it may be unaligned. */
126 /* BTW Don't reduce the buffer size below 128 Bytes!
127 * PadLock microcode needs it that big. */
128 char buf[128+16];
129 char *result = NEAREST_ALIGNED(buf);
130
131 ((uint32_t *)result)[0] = 0x6A09E667;
132 ((uint32_t *)result)[1] = 0xBB67AE85;
133 ((uint32_t *)result)[2] = 0x3C6EF372;
134 ((uint32_t *)result)[3] = 0xA54FF53A;
135 ((uint32_t *)result)[4] = 0x510E527F;
136 ((uint32_t *)result)[5] = 0x9B05688C;
137 ((uint32_t *)result)[6] = 0x1F83D9AB;
138 ((uint32_t *)result)[7] = 0x5BE0CD19;
139
140 asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" /* rep xsha256 */
141 : "+S"(in), "+D"(result)
142 : "c"(count), "a"(0));
143
144 padlock_output_block((uint32_t *)result, (uint32_t *)out, 8);
145}
146
147static void padlock_sha_final(struct crypto_tfm *tfm, uint8_t *out)
148{
149 if (unlikely(ctx(tfm)->bypass)) {
150 crypto_hash_final(&ctx(tfm)->fallback, out);
151 ctx(tfm)->bypass = 0;
152 return;
153 }
154
155 /* Pass the input buffer to PadLock microcode... */
156 ctx(tfm)->f_sha_padlock(ctx(tfm)->data, out, ctx(tfm)->used);
157
158 ctx(tfm)->used = 0;
159}
160
161static int padlock_cra_init(struct crypto_tfm *tfm)
162{
163 const char *fallback_driver_name = tfm->__crt_alg->cra_name;
164 struct crypto_hash *fallback_tfm;
165
166 /* For now we'll allocate one page. This
167 * could eventually be configurable one day. */
168 ctx(tfm)->data = (char *)__get_free_page(GFP_KERNEL);
169 if (!ctx(tfm)->data)
170 return -ENOMEM;
171
172 /* Allocate a fallback and abort if it failed. */
173 fallback_tfm = crypto_alloc_hash(fallback_driver_name, 0,
174 CRYPTO_ALG_ASYNC |
175 CRYPTO_ALG_NEED_FALLBACK);
176 if (IS_ERR(fallback_tfm)) {
177 printk(KERN_WARNING PFX "Fallback driver '%s' could not be loaded!\n",
178 fallback_driver_name);
179 free_page((unsigned long)(ctx(tfm)->data));
180 return PTR_ERR(fallback_tfm);
181 }
182
183 ctx(tfm)->fallback.tfm = fallback_tfm;
184 return 0;
185}
186
187static int padlock_sha1_cra_init(struct crypto_tfm *tfm)
188{
189 ctx(tfm)->f_sha_padlock = padlock_do_sha1;
190
191 return padlock_cra_init(tfm);
192}
193
194static int padlock_sha256_cra_init(struct crypto_tfm *tfm)
195{
196 ctx(tfm)->f_sha_padlock = padlock_do_sha256;
197
198 return padlock_cra_init(tfm);
199}
200
201static void padlock_cra_exit(struct crypto_tfm *tfm)
202{
203 if (ctx(tfm)->data) {
204 free_page((unsigned long)(ctx(tfm)->data));
205 ctx(tfm)->data = NULL;
206 }
207
208 crypto_free_hash(ctx(tfm)->fallback.tfm);
209 ctx(tfm)->fallback.tfm = NULL;
210}
211
212static struct crypto_alg sha1_alg = {
213 .cra_name = "sha1",
214 .cra_driver_name = "sha1-padlock",
215 .cra_priority = PADLOCK_CRA_PRIORITY,
216 .cra_flags = CRYPTO_ALG_TYPE_DIGEST |
217 CRYPTO_ALG_NEED_FALLBACK,
218 .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
219 .cra_ctxsize = sizeof(struct padlock_sha_ctx),
220 .cra_module = THIS_MODULE,
221 .cra_list = LIST_HEAD_INIT(sha1_alg.cra_list),
222 .cra_init = padlock_sha1_cra_init,
223 .cra_exit = padlock_cra_exit,
224 .cra_u = {
225 .digest = {
226 .dia_digestsize = SHA1_DIGEST_SIZE,
227 .dia_init = padlock_sha_init,
228 .dia_update = padlock_sha_update,
229 .dia_final = padlock_sha_final,
230 }
231 }
232};
233
234static struct crypto_alg sha256_alg = {
235 .cra_name = "sha256",
236 .cra_driver_name = "sha256-padlock",
237 .cra_priority = PADLOCK_CRA_PRIORITY,
238 .cra_flags = CRYPTO_ALG_TYPE_DIGEST |
239 CRYPTO_ALG_NEED_FALLBACK,
240 .cra_blocksize = SHA256_HMAC_BLOCK_SIZE,
241 .cra_ctxsize = sizeof(struct padlock_sha_ctx),
242 .cra_module = THIS_MODULE,
243 .cra_list = LIST_HEAD_INIT(sha256_alg.cra_list),
244 .cra_init = padlock_sha256_cra_init,
245 .cra_exit = padlock_cra_exit,
246 .cra_u = {
247 .digest = {
248 .dia_digestsize = SHA256_DIGEST_SIZE,
249 .dia_init = padlock_sha_init,
250 .dia_update = padlock_sha_update,
251 .dia_final = padlock_sha_final,
252 }
253 }
254};
255
256static void __init padlock_sha_check_fallbacks(void)
257{
258 if (!crypto_has_hash("sha1", 0, CRYPTO_ALG_ASYNC |
259 CRYPTO_ALG_NEED_FALLBACK))
260 printk(KERN_WARNING PFX
261 "Couldn't load fallback module for sha1.\n");
262
263 if (!crypto_has_hash("sha256", 0, CRYPTO_ALG_ASYNC |
264 CRYPTO_ALG_NEED_FALLBACK))
265 printk(KERN_WARNING PFX
266 "Couldn't load fallback module for sha256.\n");
267}
268
269static int __init padlock_init(void)
270{
271 int rc = -ENODEV;
272
273 if (!cpu_has_phe) {
274 printk(KERN_ERR PFX "VIA PadLock Hash Engine not detected.\n");
275 return -ENODEV;
276 }
277
278 if (!cpu_has_phe_enabled) {
279 printk(KERN_ERR PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");
280 return -ENODEV;
281 }
282
283 padlock_sha_check_fallbacks();
284
285 rc = crypto_register_alg(&sha1_alg);
286 if (rc)
287 goto out;
288
289 rc = crypto_register_alg(&sha256_alg);
290 if (rc)
291 goto out_unreg1;
292
293 printk(KERN_NOTICE PFX "Using VIA PadLock ACE for SHA1/SHA256 algorithms.\n");
294
295 return 0;
296
297out_unreg1:
298 crypto_unregister_alg(&sha1_alg);
299out:
300 printk(KERN_ERR PFX "VIA PadLock SHA1/SHA256 initialization failed.\n");
301 return rc;
302}
303
304static void __exit padlock_fini(void)
305{
306 crypto_unregister_alg(&sha1_alg);
307 crypto_unregister_alg(&sha256_alg);
308}
309
310module_init(padlock_init);
311module_exit(padlock_fini);
312
313MODULE_DESCRIPTION("VIA PadLock SHA1/SHA256 algorithms support.");
314MODULE_LICENSE("GPL");
315MODULE_AUTHOR("Michal Ludvig");
316
317MODULE_ALIAS("sha1-padlock");
318MODULE_ALIAS("sha256-padlock");
diff --git a/drivers/crypto/padlock.c b/drivers/crypto/padlock.c
new file mode 100644
index 000000000000..d6d7dd5bb98c
--- /dev/null
+++ b/drivers/crypto/padlock.c
@@ -0,0 +1,58 @@
1/*
2 * Cryptographic API.
3 *
4 * Support for VIA PadLock hardware crypto engine.
5 *
6 * Copyright (c) 2006 Michal Ludvig <michal@logix.cz>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/crypto.h>
19#include <linux/cryptohash.h>
20#include <linux/interrupt.h>
21#include <linux/kernel.h>
22#include <linux/scatterlist.h>
23#include "padlock.h"
24
25static int __init padlock_init(void)
26{
27 int success = 0;
28
29 if (crypto_has_cipher("aes-padlock", 0, 0))
30 success++;
31
32 if (crypto_has_hash("sha1-padlock", 0, 0))
33 success++;
34
35 if (crypto_has_hash("sha256-padlock", 0, 0))
36 success++;
37
38 if (!success) {
39 printk(KERN_WARNING PFX "No VIA PadLock drivers have been loaded.\n");
40 return -ENODEV;
41 }
42
43 printk(KERN_NOTICE PFX "%d drivers are available.\n", success);
44
45 return 0;
46}
47
48static void __exit padlock_fini(void)
49{
50}
51
52module_init(padlock_init);
53module_exit(padlock_fini);
54
55MODULE_DESCRIPTION("Load all configured PadLock algorithms.");
56MODULE_LICENSE("GPL");
57MODULE_AUTHOR("Michal Ludvig");
58
diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h
index b78489bc298a..b728e4518bd1 100644
--- a/drivers/crypto/padlock.h
+++ b/drivers/crypto/padlock.h
@@ -15,22 +15,9 @@
15 15
16#define PADLOCK_ALIGNMENT 16 16#define PADLOCK_ALIGNMENT 16
17 17
18/* Control word. */
19struct cword {
20 unsigned int __attribute__ ((__packed__))
21 rounds:4,
22 algo:3,
23 keygen:1,
24 interm:1,
25 encdec:1,
26 ksize:2;
27} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT)));
28
29#define PFX "padlock: " 18#define PFX "padlock: "
30 19
31#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES 20#define PADLOCK_CRA_PRIORITY 300
32int padlock_init_aes(void); 21#define PADLOCK_COMPOSITE_PRIORITY 400
33void padlock_fini_aes(void);
34#endif
35 22
36#endif /* _CRYPTO_PADLOCK_H */ 23#endif /* _CRYPTO_PADLOCK_H */
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 53bb43593863..d658d9107955 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -207,7 +207,8 @@ static int i2c_powermac_probe(struct device *dev)
207 struct pmac_i2c_bus *bus = dev->platform_data; 207 struct pmac_i2c_bus *bus = dev->platform_data;
208 struct device_node *parent = NULL; 208 struct device_node *parent = NULL;
209 struct i2c_adapter *adapter; 209 struct i2c_adapter *adapter;
210 char name[32], *basename; 210 char name[32];
211 const char *basename;
211 int rc; 212 int rc;
212 213
213 if (bus == NULL) 214 if (bus == NULL)
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index ebf961f1718d..996c694341bc 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1154,7 +1154,7 @@ static int
1154pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) 1154pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
1155{ 1155{
1156 struct device_node *np = pmif->node; 1156 struct device_node *np = pmif->node;
1157 int *bidp; 1157 const int *bidp;
1158 1158
1159 pmif->cable_80 = 0; 1159 pmif->cable_80 = 0;
1160 pmif->broken_dma = pmif->broken_dma_warn = 0; 1160 pmif->broken_dma = pmif->broken_dma_warn = 0;
@@ -1176,14 +1176,14 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
1176 pmif->broken_dma = 1; 1176 pmif->broken_dma = 1;
1177 } 1177 }
1178 1178
1179 bidp = (int *)get_property(np, "AAPL,bus-id", NULL); 1179 bidp = get_property(np, "AAPL,bus-id", NULL);
1180 pmif->aapl_bus_id = bidp ? *bidp : 0; 1180 pmif->aapl_bus_id = bidp ? *bidp : 0;
1181 1181
1182 /* Get cable type from device-tree */ 1182 /* Get cable type from device-tree */
1183 if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6 1183 if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6
1184 || pmif->kind == controller_k2_ata6 1184 || pmif->kind == controller_k2_ata6
1185 || pmif->kind == controller_sh_ata6) { 1185 || pmif->kind == controller_sh_ata6) {
1186 char* cable = get_property(np, "cable-type", NULL); 1186 const char* cable = get_property(np, "cable-type", NULL);
1187 if (cable && !strncmp(cable, "80-", 3)) 1187 if (cable && !strncmp(cable, "80-", 3))
1188 pmif->cable_80 = 1; 1188 pmif->cable_80 = 1;
1189 } 1189 }
@@ -1326,7 +1326,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
1326 if (macio_irq_count(mdev) == 0) { 1326 if (macio_irq_count(mdev) == 0) {
1327 printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n", 1327 printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n",
1328 i, mdev->ofdev.node->full_name); 1328 i, mdev->ofdev.node->full_name);
1329 irq = 13; 1329 irq = irq_create_mapping(NULL, 13);
1330 } else 1330 } else
1331 irq = macio_irq(mdev, 0); 1331 irq = macio_irq(mdev, 0);
1332 1332
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 69a53d476b5b..9edfacee7d84 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -14,7 +14,7 @@ config INFINIBAND_USER_MAD
14 ---help--- 14 ---help---
15 Userspace InfiniBand Management Datagram (MAD) support. This 15 Userspace InfiniBand Management Datagram (MAD) support. This
16 is the kernel side of the userspace MAD support, which allows 16 is the kernel side of the userspace MAD support, which allows
17 userspace processes to send and receive MADs. You will also 17 userspace processes to send and receive MADs. You will also
18 need libibumad from <http://www.openib.org>. 18 need libibumad from <http://www.openib.org>.
19 19
20config INFINIBAND_USER_ACCESS 20config INFINIBAND_USER_ACCESS
@@ -36,6 +36,8 @@ config INFINIBAND_ADDR_TRANS
36 36
37source "drivers/infiniband/hw/mthca/Kconfig" 37source "drivers/infiniband/hw/mthca/Kconfig"
38source "drivers/infiniband/hw/ipath/Kconfig" 38source "drivers/infiniband/hw/ipath/Kconfig"
39source "drivers/infiniband/hw/ehca/Kconfig"
40source "drivers/infiniband/hw/amso1100/Kconfig"
39 41
40source "drivers/infiniband/ulp/ipoib/Kconfig" 42source "drivers/infiniband/ulp/ipoib/Kconfig"
41 43
diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile
index c7ff58c1d0e5..2b5d1098ef45 100644
--- a/drivers/infiniband/Makefile
+++ b/drivers/infiniband/Makefile
@@ -1,6 +1,8 @@
1obj-$(CONFIG_INFINIBAND) += core/ 1obj-$(CONFIG_INFINIBAND) += core/
2obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/ 2obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/
3obj-$(CONFIG_IPATH_CORE) += hw/ipath/ 3obj-$(CONFIG_INFINIBAND_IPATH) += hw/ipath/
4obj-$(CONFIG_INFINIBAND_EHCA) += hw/ehca/
5obj-$(CONFIG_INFINIBAND_AMSO1100) += hw/amso1100/
4obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ 6obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/
5obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ 7obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/
6obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/ 8obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index 68e73ec2d1f8..163d991eb8c9 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -1,7 +1,7 @@
1infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS) := ib_addr.o rdma_cm.o 1infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS) := ib_addr.o rdma_cm.o
2 2
3obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \ 3obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \
4 ib_cm.o $(infiniband-y) 4 ib_cm.o iw_cm.o $(infiniband-y)
5obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o 5obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o
6obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o 6obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o
7 7
@@ -14,6 +14,8 @@ ib_sa-y := sa_query.o
14 14
15ib_cm-y := cm.o 15ib_cm-y := cm.o
16 16
17iw_cm-y := iwcm.o
18
17rdma_cm-y := cma.o 19rdma_cm-y := cma.o
18 20
19ib_addr-y := addr.o 21ib_addr-y := addr.o
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 1205e8027829..9cbf09e2052f 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -61,12 +61,15 @@ static LIST_HEAD(req_list);
61static DECLARE_WORK(work, process_req, NULL); 61static DECLARE_WORK(work, process_req, NULL);
62static struct workqueue_struct *addr_wq; 62static struct workqueue_struct *addr_wq;
63 63
64static int copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, 64int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
65 unsigned char *dst_dev_addr) 65 const unsigned char *dst_dev_addr)
66{ 66{
67 switch (dev->type) { 67 switch (dev->type) {
68 case ARPHRD_INFINIBAND: 68 case ARPHRD_INFINIBAND:
69 dev_addr->dev_type = IB_NODE_CA; 69 dev_addr->dev_type = RDMA_NODE_IB_CA;
70 break;
71 case ARPHRD_ETHER:
72 dev_addr->dev_type = RDMA_NODE_RNIC;
70 break; 73 break;
71 default: 74 default:
72 return -EADDRNOTAVAIL; 75 return -EADDRNOTAVAIL;
@@ -78,6 +81,7 @@ static int copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
78 memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN); 81 memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN);
79 return 0; 82 return 0;
80} 83}
84EXPORT_SYMBOL(rdma_copy_addr);
81 85
82int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) 86int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
83{ 87{
@@ -89,7 +93,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
89 if (!dev) 93 if (!dev)
90 return -EADDRNOTAVAIL; 94 return -EADDRNOTAVAIL;
91 95
92 ret = copy_addr(dev_addr, dev, NULL); 96 ret = rdma_copy_addr(dev_addr, dev, NULL);
93 dev_put(dev); 97 dev_put(dev);
94 return ret; 98 return ret;
95} 99}
@@ -161,7 +165,7 @@ static int addr_resolve_remote(struct sockaddr_in *src_in,
161 165
162 /* If the device does ARP internally, return 'done' */ 166 /* If the device does ARP internally, return 'done' */
163 if (rt->idev->dev->flags & IFF_NOARP) { 167 if (rt->idev->dev->flags & IFF_NOARP) {
164 copy_addr(addr, rt->idev->dev, NULL); 168 rdma_copy_addr(addr, rt->idev->dev, NULL);
165 goto put; 169 goto put;
166 } 170 }
167 171
@@ -181,7 +185,7 @@ static int addr_resolve_remote(struct sockaddr_in *src_in,
181 src_in->sin_addr.s_addr = rt->rt_src; 185 src_in->sin_addr.s_addr = rt->rt_src;
182 } 186 }
183 187
184 ret = copy_addr(addr, neigh->dev, neigh->ha); 188 ret = rdma_copy_addr(addr, neigh->dev, neigh->ha);
185release: 189release:
186 neigh_release(neigh); 190 neigh_release(neigh);
187put: 191put:
@@ -245,7 +249,7 @@ static int addr_resolve_local(struct sockaddr_in *src_in,
245 if (ZERONET(src_ip)) { 249 if (ZERONET(src_ip)) {
246 src_in->sin_family = dst_in->sin_family; 250 src_in->sin_family = dst_in->sin_family;
247 src_in->sin_addr.s_addr = dst_ip; 251 src_in->sin_addr.s_addr = dst_ip;
248 ret = copy_addr(addr, dev, dev->dev_addr); 252 ret = rdma_copy_addr(addr, dev, dev->dev_addr);
249 } else if (LOOPBACK(src_ip)) { 253 } else if (LOOPBACK(src_ip)) {
250 ret = rdma_translate_ip((struct sockaddr *)dst_in, addr); 254 ret = rdma_translate_ip((struct sockaddr *)dst_in, addr);
251 if (!ret) 255 if (!ret)
@@ -327,10 +331,10 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr)
327} 331}
328EXPORT_SYMBOL(rdma_addr_cancel); 332EXPORT_SYMBOL(rdma_addr_cancel);
329 333
330static int netevent_callback(struct notifier_block *self, unsigned long event, 334static int netevent_callback(struct notifier_block *self, unsigned long event,
331 void *ctx) 335 void *ctx)
332{ 336{
333 if (event == NETEVENT_NEIGH_UPDATE) { 337 if (event == NETEVENT_NEIGH_UPDATE) {
334 struct neighbour *neigh = ctx; 338 struct neighbour *neigh = ctx;
335 339
336 if (neigh->dev->type == ARPHRD_INFINIBAND && 340 if (neigh->dev->type == ARPHRD_INFINIBAND &&
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 75313ade2e0d..20e9f64e67a6 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -62,12 +62,13 @@ struct ib_update_work {
62 62
63static inline int start_port(struct ib_device *device) 63static inline int start_port(struct ib_device *device)
64{ 64{
65 return device->node_type == IB_NODE_SWITCH ? 0 : 1; 65 return (device->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1;
66} 66}
67 67
68static inline int end_port(struct ib_device *device) 68static inline int end_port(struct ib_device *device)
69{ 69{
70 return device->node_type == IB_NODE_SWITCH ? 0 : device->phys_port_cnt; 70 return (device->node_type == RDMA_NODE_IB_SWITCH) ?
71 0 : device->phys_port_cnt;
71} 72}
72 73
73int ib_get_cached_gid(struct ib_device *device, 74int ib_get_cached_gid(struct ib_device *device,
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 0de335b7bfc2..f35fcc4c0638 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved. 2 * Copyright (c) 2004-2006 Intel Corporation. All rights reserved.
3 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 3 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
4 * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved. 4 * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
5 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 5 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
@@ -41,6 +41,7 @@
41#include <linux/idr.h> 41#include <linux/idr.h>
42#include <linux/interrupt.h> 42#include <linux/interrupt.h>
43#include <linux/pci.h> 43#include <linux/pci.h>
44#include <linux/random.h>
44#include <linux/rbtree.h> 45#include <linux/rbtree.h>
45#include <linux/spinlock.h> 46#include <linux/spinlock.h>
46#include <linux/workqueue.h> 47#include <linux/workqueue.h>
@@ -73,6 +74,7 @@ static struct ib_cm {
73 struct rb_root remote_id_table; 74 struct rb_root remote_id_table;
74 struct rb_root remote_sidr_table; 75 struct rb_root remote_sidr_table;
75 struct idr local_id_table; 76 struct idr local_id_table;
77 __be32 random_id_operand;
76 struct workqueue_struct *wq; 78 struct workqueue_struct *wq;
77} cm; 79} cm;
78 80
@@ -177,7 +179,7 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
177 if (IS_ERR(ah)) 179 if (IS_ERR(ah))
178 return PTR_ERR(ah); 180 return PTR_ERR(ah);
179 181
180 m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn, 182 m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn,
181 cm_id_priv->av.pkey_index, 183 cm_id_priv->av.pkey_index,
182 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, 184 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
183 GFP_ATOMIC); 185 GFP_ATOMIC);
@@ -299,15 +301,17 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
299static int cm_alloc_id(struct cm_id_private *cm_id_priv) 301static int cm_alloc_id(struct cm_id_private *cm_id_priv)
300{ 302{
301 unsigned long flags; 303 unsigned long flags;
302 int ret; 304 int ret, id;
303 static int next_id; 305 static int next_id;
304 306
305 do { 307 do {
306 spin_lock_irqsave(&cm.lock, flags); 308 spin_lock_irqsave(&cm.lock, flags);
307 ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, next_id++, 309 ret = idr_get_new_above(&cm.local_id_table, cm_id_priv,
308 (__force int *) &cm_id_priv->id.local_id); 310 next_id++, &id);
309 spin_unlock_irqrestore(&cm.lock, flags); 311 spin_unlock_irqrestore(&cm.lock, flags);
310 } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); 312 } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) );
313
314 cm_id_priv->id.local_id = (__force __be32) (id ^ cm.random_id_operand);
311 return ret; 315 return ret;
312} 316}
313 317
@@ -316,7 +320,8 @@ static void cm_free_id(__be32 local_id)
316 unsigned long flags; 320 unsigned long flags;
317 321
318 spin_lock_irqsave(&cm.lock, flags); 322 spin_lock_irqsave(&cm.lock, flags);
319 idr_remove(&cm.local_id_table, (__force int) local_id); 323 idr_remove(&cm.local_id_table,
324 (__force int) (local_id ^ cm.random_id_operand));
320 spin_unlock_irqrestore(&cm.lock, flags); 325 spin_unlock_irqrestore(&cm.lock, flags);
321} 326}
322 327
@@ -324,7 +329,8 @@ static struct cm_id_private * cm_get_id(__be32 local_id, __be32 remote_id)
324{ 329{
325 struct cm_id_private *cm_id_priv; 330 struct cm_id_private *cm_id_priv;
326 331
327 cm_id_priv = idr_find(&cm.local_id_table, (__force int) local_id); 332 cm_id_priv = idr_find(&cm.local_id_table,
333 (__force int) (local_id ^ cm.random_id_operand));
328 if (cm_id_priv) { 334 if (cm_id_priv) {
329 if (cm_id_priv->id.remote_id == remote_id) 335 if (cm_id_priv->id.remote_id == remote_id)
330 atomic_inc(&cm_id_priv->refcount); 336 atomic_inc(&cm_id_priv->refcount);
@@ -679,6 +685,8 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv)
679{ 685{
680 int wait_time; 686 int wait_time;
681 687
688 cm_cleanup_timewait(cm_id_priv->timewait_info);
689
682 /* 690 /*
683 * The cm_id could be destroyed by the user before we exit timewait. 691 * The cm_id could be destroyed by the user before we exit timewait.
684 * To protect against this, we search for the cm_id after exiting 692 * To protect against this, we search for the cm_id after exiting
@@ -1354,7 +1362,7 @@ static int cm_req_handler(struct cm_work *work)
1354 id.local_id); 1362 id.local_id);
1355 if (IS_ERR(cm_id_priv->timewait_info)) { 1363 if (IS_ERR(cm_id_priv->timewait_info)) {
1356 ret = PTR_ERR(cm_id_priv->timewait_info); 1364 ret = PTR_ERR(cm_id_priv->timewait_info);
1357 goto error1; 1365 goto destroy;
1358 } 1366 }
1359 cm_id_priv->timewait_info->work.remote_id = req_msg->local_comm_id; 1367 cm_id_priv->timewait_info->work.remote_id = req_msg->local_comm_id;
1360 cm_id_priv->timewait_info->remote_ca_guid = req_msg->local_ca_guid; 1368 cm_id_priv->timewait_info->remote_ca_guid = req_msg->local_ca_guid;
@@ -1363,7 +1371,8 @@ static int cm_req_handler(struct cm_work *work)
1363 listen_cm_id_priv = cm_match_req(work, cm_id_priv); 1371 listen_cm_id_priv = cm_match_req(work, cm_id_priv);
1364 if (!listen_cm_id_priv) { 1372 if (!listen_cm_id_priv) {
1365 ret = -EINVAL; 1373 ret = -EINVAL;
1366 goto error2; 1374 kfree(cm_id_priv->timewait_info);
1375 goto destroy;
1367 } 1376 }
1368 1377
1369 cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; 1378 cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler;
@@ -1373,12 +1382,22 @@ static int cm_req_handler(struct cm_work *work)
1373 1382
1374 cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]); 1383 cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
1375 ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); 1384 ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
1376 if (ret) 1385 if (ret) {
1377 goto error3; 1386 ib_get_cached_gid(work->port->cm_dev->device,
1387 work->port->port_num, 0, &work->path[0].sgid);
1388 ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
1389 &work->path[0].sgid, sizeof work->path[0].sgid,
1390 NULL, 0);
1391 goto rejected;
1392 }
1378 if (req_msg->alt_local_lid) { 1393 if (req_msg->alt_local_lid) {
1379 ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av); 1394 ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av);
1380 if (ret) 1395 if (ret) {
1381 goto error3; 1396 ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_ALT_GID,
1397 &work->path[0].sgid,
1398 sizeof work->path[0].sgid, NULL, 0);
1399 goto rejected;
1400 }
1382 } 1401 }
1383 cm_id_priv->tid = req_msg->hdr.tid; 1402 cm_id_priv->tid = req_msg->hdr.tid;
1384 cm_id_priv->timeout_ms = cm_convert_to_ms( 1403 cm_id_priv->timeout_ms = cm_convert_to_ms(
@@ -1400,12 +1419,11 @@ static int cm_req_handler(struct cm_work *work)
1400 cm_deref_id(listen_cm_id_priv); 1419 cm_deref_id(listen_cm_id_priv);
1401 return 0; 1420 return 0;
1402 1421
1403error3: atomic_dec(&cm_id_priv->refcount); 1422rejected:
1423 atomic_dec(&cm_id_priv->refcount);
1404 cm_deref_id(listen_cm_id_priv); 1424 cm_deref_id(listen_cm_id_priv);
1405 cm_cleanup_timewait(cm_id_priv->timewait_info); 1425destroy:
1406error2: kfree(cm_id_priv->timewait_info); 1426 ib_destroy_cm_id(cm_id);
1407 cm_id_priv->timewait_info = NULL;
1408error1: ib_destroy_cm_id(&cm_id_priv->id);
1409 return ret; 1427 return ret;
1410} 1428}
1411 1429
@@ -2072,8 +2090,9 @@ static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg)
2072 spin_unlock_irqrestore(&cm.lock, flags); 2090 spin_unlock_irqrestore(&cm.lock, flags);
2073 return NULL; 2091 return NULL;
2074 } 2092 }
2075 cm_id_priv = idr_find(&cm.local_id_table, 2093 cm_id_priv = idr_find(&cm.local_id_table, (__force int)
2076 (__force int) timewait_info->work.local_id); 2094 (timewait_info->work.local_id ^
2095 cm.random_id_operand));
2077 if (cm_id_priv) { 2096 if (cm_id_priv) {
2078 if (cm_id_priv->id.remote_id == remote_id) 2097 if (cm_id_priv->id.remote_id == remote_id)
2079 atomic_inc(&cm_id_priv->refcount); 2098 atomic_inc(&cm_id_priv->refcount);
@@ -3125,7 +3144,8 @@ static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv,
3125 qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE | 3144 qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE |
3126 IB_ACCESS_REMOTE_WRITE; 3145 IB_ACCESS_REMOTE_WRITE;
3127 if (cm_id_priv->responder_resources) 3146 if (cm_id_priv->responder_resources)
3128 qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ; 3147 qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ |
3148 IB_ACCESS_REMOTE_ATOMIC;
3129 qp_attr->pkey_index = cm_id_priv->av.pkey_index; 3149 qp_attr->pkey_index = cm_id_priv->av.pkey_index;
3130 qp_attr->port_num = cm_id_priv->av.port->port_num; 3150 qp_attr->port_num = cm_id_priv->av.port->port_num;
3131 ret = 0; 3151 ret = 0;
@@ -3262,6 +3282,9 @@ static void cm_add_one(struct ib_device *device)
3262 int ret; 3282 int ret;
3263 u8 i; 3283 u8 i;
3264 3284
3285 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
3286 return;
3287
3265 cm_dev = kmalloc(sizeof(*cm_dev) + sizeof(*port) * 3288 cm_dev = kmalloc(sizeof(*cm_dev) + sizeof(*port) *
3266 device->phys_port_cnt, GFP_KERNEL); 3289 device->phys_port_cnt, GFP_KERNEL);
3267 if (!cm_dev) 3290 if (!cm_dev)
@@ -3349,6 +3372,7 @@ static int __init ib_cm_init(void)
3349 cm.remote_qp_table = RB_ROOT; 3372 cm.remote_qp_table = RB_ROOT;
3350 cm.remote_sidr_table = RB_ROOT; 3373 cm.remote_sidr_table = RB_ROOT;
3351 idr_init(&cm.local_id_table); 3374 idr_init(&cm.local_id_table);
3375 get_random_bytes(&cm.random_id_operand, sizeof cm.random_id_operand);
3352 idr_pre_get(&cm.local_id_table, GFP_KERNEL); 3376 idr_pre_get(&cm.local_id_table, GFP_KERNEL);
3353 3377
3354 cm.wq = create_workqueue("ib_cm"); 3378 cm.wq = create_workqueue("ib_cm");
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 5d625a81193f..1178bd434d1b 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -35,6 +35,7 @@
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36#include <linux/random.h> 36#include <linux/random.h>
37#include <linux/idr.h> 37#include <linux/idr.h>
38#include <linux/inetdevice.h>
38 39
39#include <net/tcp.h> 40#include <net/tcp.h>
40 41
@@ -43,6 +44,7 @@
43#include <rdma/ib_cache.h> 44#include <rdma/ib_cache.h>
44#include <rdma/ib_cm.h> 45#include <rdma/ib_cm.h>
45#include <rdma/ib_sa.h> 46#include <rdma/ib_sa.h>
47#include <rdma/iw_cm.h>
46 48
47MODULE_AUTHOR("Sean Hefty"); 49MODULE_AUTHOR("Sean Hefty");
48MODULE_DESCRIPTION("Generic RDMA CM Agent"); 50MODULE_DESCRIPTION("Generic RDMA CM Agent");
@@ -60,6 +62,7 @@ static struct ib_client cma_client = {
60 .remove = cma_remove_one 62 .remove = cma_remove_one
61}; 63};
62 64
65static struct ib_sa_client sa_client;
63static LIST_HEAD(dev_list); 66static LIST_HEAD(dev_list);
64static LIST_HEAD(listen_any_list); 67static LIST_HEAD(listen_any_list);
65static DEFINE_MUTEX(lock); 68static DEFINE_MUTEX(lock);
@@ -124,6 +127,7 @@ struct rdma_id_private {
124 int query_id; 127 int query_id;
125 union { 128 union {
126 struct ib_cm_id *ib; 129 struct ib_cm_id *ib;
130 struct iw_cm_id *iw;
127 } cm_id; 131 } cm_id;
128 132
129 u32 seq_num; 133 u32 seq_num;
@@ -259,15 +263,24 @@ static void cma_detach_from_dev(struct rdma_id_private *id_priv)
259 id_priv->cma_dev = NULL; 263 id_priv->cma_dev = NULL;
260} 264}
261 265
262static int cma_acquire_ib_dev(struct rdma_id_private *id_priv) 266static int cma_acquire_dev(struct rdma_id_private *id_priv)
263{ 267{
268 enum rdma_node_type dev_type = id_priv->id.route.addr.dev_addr.dev_type;
264 struct cma_device *cma_dev; 269 struct cma_device *cma_dev;
265 union ib_gid gid; 270 union ib_gid gid;
266 int ret = -ENODEV; 271 int ret = -ENODEV;
267 272
268 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid), 273 switch (rdma_node_get_transport(dev_type)) {
274 case RDMA_TRANSPORT_IB:
275 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
276 break;
277 case RDMA_TRANSPORT_IWARP:
278 iw_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
279 break;
280 default:
281 return -ENODEV;
282 }
269 283
270 mutex_lock(&lock);
271 list_for_each_entry(cma_dev, &dev_list, list) { 284 list_for_each_entry(cma_dev, &dev_list, list) {
272 ret = ib_find_cached_gid(cma_dev->device, &gid, 285 ret = ib_find_cached_gid(cma_dev->device, &gid,
273 &id_priv->id.port_num, NULL); 286 &id_priv->id.port_num, NULL);
@@ -276,20 +289,9 @@ static int cma_acquire_ib_dev(struct rdma_id_private *id_priv)
276 break; 289 break;
277 } 290 }
278 } 291 }
279 mutex_unlock(&lock);
280 return ret; 292 return ret;
281} 293}
282 294
283static int cma_acquire_dev(struct rdma_id_private *id_priv)
284{
285 switch (id_priv->id.route.addr.dev_addr.dev_type) {
286 case IB_NODE_CA:
287 return cma_acquire_ib_dev(id_priv);
288 default:
289 return -ENODEV;
290 }
291}
292
293static void cma_deref_id(struct rdma_id_private *id_priv) 295static void cma_deref_id(struct rdma_id_private *id_priv)
294{ 296{
295 if (atomic_dec_and_test(&id_priv->refcount)) 297 if (atomic_dec_and_test(&id_priv->refcount))
@@ -347,6 +349,16 @@ static int cma_init_ib_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
347 IB_QP_PKEY_INDEX | IB_QP_PORT); 349 IB_QP_PKEY_INDEX | IB_QP_PORT);
348} 350}
349 351
352static int cma_init_iw_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
353{
354 struct ib_qp_attr qp_attr;
355
356 qp_attr.qp_state = IB_QPS_INIT;
357 qp_attr.qp_access_flags = IB_ACCESS_LOCAL_WRITE;
358
359 return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS);
360}
361
350int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd, 362int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
351 struct ib_qp_init_attr *qp_init_attr) 363 struct ib_qp_init_attr *qp_init_attr)
352{ 364{
@@ -362,10 +374,13 @@ int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
362 if (IS_ERR(qp)) 374 if (IS_ERR(qp))
363 return PTR_ERR(qp); 375 return PTR_ERR(qp);
364 376
365 switch (id->device->node_type) { 377 switch (rdma_node_get_transport(id->device->node_type)) {
366 case IB_NODE_CA: 378 case RDMA_TRANSPORT_IB:
367 ret = cma_init_ib_qp(id_priv, qp); 379 ret = cma_init_ib_qp(id_priv, qp);
368 break; 380 break;
381 case RDMA_TRANSPORT_IWARP:
382 ret = cma_init_iw_qp(id_priv, qp);
383 break;
369 default: 384 default:
370 ret = -ENOSYS; 385 ret = -ENOSYS;
371 break; 386 break;
@@ -451,13 +466,17 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
451 int ret; 466 int ret;
452 467
453 id_priv = container_of(id, struct rdma_id_private, id); 468 id_priv = container_of(id, struct rdma_id_private, id);
454 switch (id_priv->id.device->node_type) { 469 switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
455 case IB_NODE_CA: 470 case RDMA_TRANSPORT_IB:
456 ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr, 471 ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
457 qp_attr_mask); 472 qp_attr_mask);
458 if (qp_attr->qp_state == IB_QPS_RTR) 473 if (qp_attr->qp_state == IB_QPS_RTR)
459 qp_attr->rq_psn = id_priv->seq_num; 474 qp_attr->rq_psn = id_priv->seq_num;
460 break; 475 break;
476 case RDMA_TRANSPORT_IWARP:
477 ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
478 qp_attr_mask);
479 break;
461 default: 480 default:
462 ret = -ENOSYS; 481 ret = -ENOSYS;
463 break; 482 break;
@@ -590,8 +609,8 @@ static int cma_notify_user(struct rdma_id_private *id_priv,
590 609
591static void cma_cancel_route(struct rdma_id_private *id_priv) 610static void cma_cancel_route(struct rdma_id_private *id_priv)
592{ 611{
593 switch (id_priv->id.device->node_type) { 612 switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
594 case IB_NODE_CA: 613 case RDMA_TRANSPORT_IB:
595 if (id_priv->query) 614 if (id_priv->query)
596 ib_sa_cancel_query(id_priv->query_id, id_priv->query); 615 ib_sa_cancel_query(id_priv->query_id, id_priv->query);
597 break; 616 break;
@@ -611,11 +630,15 @@ static void cma_destroy_listen(struct rdma_id_private *id_priv)
611 cma_exch(id_priv, CMA_DESTROYING); 630 cma_exch(id_priv, CMA_DESTROYING);
612 631
613 if (id_priv->cma_dev) { 632 if (id_priv->cma_dev) {
614 switch (id_priv->id.device->node_type) { 633 switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
615 case IB_NODE_CA: 634 case RDMA_TRANSPORT_IB:
616 if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib)) 635 if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
617 ib_destroy_cm_id(id_priv->cm_id.ib); 636 ib_destroy_cm_id(id_priv->cm_id.ib);
618 break; 637 break;
638 case RDMA_TRANSPORT_IWARP:
639 if (id_priv->cm_id.iw && !IS_ERR(id_priv->cm_id.iw))
640 iw_destroy_cm_id(id_priv->cm_id.iw);
641 break;
619 default: 642 default:
620 break; 643 break;
621 } 644 }
@@ -689,19 +712,25 @@ void rdma_destroy_id(struct rdma_cm_id *id)
689 state = cma_exch(id_priv, CMA_DESTROYING); 712 state = cma_exch(id_priv, CMA_DESTROYING);
690 cma_cancel_operation(id_priv, state); 713 cma_cancel_operation(id_priv, state);
691 714
715 mutex_lock(&lock);
692 if (id_priv->cma_dev) { 716 if (id_priv->cma_dev) {
693 switch (id->device->node_type) { 717 mutex_unlock(&lock);
694 case IB_NODE_CA: 718 switch (rdma_node_get_transport(id->device->node_type)) {
695 if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib)) 719 case RDMA_TRANSPORT_IB:
720 if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
696 ib_destroy_cm_id(id_priv->cm_id.ib); 721 ib_destroy_cm_id(id_priv->cm_id.ib);
697 break; 722 break;
723 case RDMA_TRANSPORT_IWARP:
724 if (id_priv->cm_id.iw && !IS_ERR(id_priv->cm_id.iw))
725 iw_destroy_cm_id(id_priv->cm_id.iw);
726 break;
698 default: 727 default:
699 break; 728 break;
700 } 729 }
701 mutex_lock(&lock); 730 mutex_lock(&lock);
702 cma_detach_from_dev(id_priv); 731 cma_detach_from_dev(id_priv);
703 mutex_unlock(&lock);
704 } 732 }
733 mutex_unlock(&lock);
705 734
706 cma_release_port(id_priv); 735 cma_release_port(id_priv);
707 cma_deref_id(id_priv); 736 cma_deref_id(id_priv);
@@ -869,7 +898,7 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id,
869 ib_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid); 898 ib_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
870 ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); 899 ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
871 ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey)); 900 ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
872 rt->addr.dev_addr.dev_type = IB_NODE_CA; 901 rt->addr.dev_addr.dev_type = RDMA_NODE_IB_CA;
873 902
874 id_priv = container_of(id, struct rdma_id_private, id); 903 id_priv = container_of(id, struct rdma_id_private, id);
875 id_priv->state = CMA_CONNECT; 904 id_priv->state = CMA_CONNECT;
@@ -898,7 +927,9 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
898 } 927 }
899 928
900 atomic_inc(&conn_id->dev_remove); 929 atomic_inc(&conn_id->dev_remove);
901 ret = cma_acquire_ib_dev(conn_id); 930 mutex_lock(&lock);
931 ret = cma_acquire_dev(conn_id);
932 mutex_unlock(&lock);
902 if (ret) { 933 if (ret) {
903 ret = -ENODEV; 934 ret = -ENODEV;
904 cma_release_remove(conn_id); 935 cma_release_remove(conn_id);
@@ -982,6 +1013,130 @@ static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr,
982 } 1013 }
983} 1014}
984 1015
1016static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
1017{
1018 struct rdma_id_private *id_priv = iw_id->context;
1019 enum rdma_cm_event_type event = 0;
1020 struct sockaddr_in *sin;
1021 int ret = 0;
1022
1023 atomic_inc(&id_priv->dev_remove);
1024
1025 switch (iw_event->event) {
1026 case IW_CM_EVENT_CLOSE:
1027 event = RDMA_CM_EVENT_DISCONNECTED;
1028 break;
1029 case IW_CM_EVENT_CONNECT_REPLY:
1030 sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
1031 *sin = iw_event->local_addr;
1032 sin = (struct sockaddr_in *) &id_priv->id.route.addr.dst_addr;
1033 *sin = iw_event->remote_addr;
1034 if (iw_event->status)
1035 event = RDMA_CM_EVENT_REJECTED;
1036 else
1037 event = RDMA_CM_EVENT_ESTABLISHED;
1038 break;
1039 case IW_CM_EVENT_ESTABLISHED:
1040 event = RDMA_CM_EVENT_ESTABLISHED;
1041 break;
1042 default:
1043 BUG_ON(1);
1044 }
1045
1046 ret = cma_notify_user(id_priv, event, iw_event->status,
1047 iw_event->private_data,
1048 iw_event->private_data_len);
1049 if (ret) {
1050 /* Destroy the CM ID by returning a non-zero value. */
1051 id_priv->cm_id.iw = NULL;
1052 cma_exch(id_priv, CMA_DESTROYING);
1053 cma_release_remove(id_priv);
1054 rdma_destroy_id(&id_priv->id);
1055 return ret;
1056 }
1057
1058 cma_release_remove(id_priv);
1059 return ret;
1060}
1061
1062static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1063 struct iw_cm_event *iw_event)
1064{
1065 struct rdma_cm_id *new_cm_id;
1066 struct rdma_id_private *listen_id, *conn_id;
1067 struct sockaddr_in *sin;
1068 struct net_device *dev = NULL;
1069 int ret;
1070
1071 listen_id = cm_id->context;
1072 atomic_inc(&listen_id->dev_remove);
1073 if (!cma_comp(listen_id, CMA_LISTEN)) {
1074 ret = -ECONNABORTED;
1075 goto out;
1076 }
1077
1078 /* Create a new RDMA id for the new IW CM ID */
1079 new_cm_id = rdma_create_id(listen_id->id.event_handler,
1080 listen_id->id.context,
1081 RDMA_PS_TCP);
1082 if (!new_cm_id) {
1083 ret = -ENOMEM;
1084 goto out;
1085 }
1086 conn_id = container_of(new_cm_id, struct rdma_id_private, id);
1087 atomic_inc(&conn_id->dev_remove);
1088 conn_id->state = CMA_CONNECT;
1089
1090 dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr);
1091 if (!dev) {
1092 ret = -EADDRNOTAVAIL;
1093 cma_release_remove(conn_id);
1094 rdma_destroy_id(new_cm_id);
1095 goto out;
1096 }
1097 ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL);
1098 if (ret) {
1099 cma_release_remove(conn_id);
1100 rdma_destroy_id(new_cm_id);
1101 goto out;
1102 }
1103
1104 mutex_lock(&lock);
1105 ret = cma_acquire_dev(conn_id);
1106 mutex_unlock(&lock);
1107 if (ret) {
1108 cma_release_remove(conn_id);
1109 rdma_destroy_id(new_cm_id);
1110 goto out;
1111 }
1112
1113 conn_id->cm_id.iw = cm_id;
1114 cm_id->context = conn_id;
1115 cm_id->cm_handler = cma_iw_handler;
1116
1117 sin = (struct sockaddr_in *) &new_cm_id->route.addr.src_addr;
1118 *sin = iw_event->local_addr;
1119 sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr;
1120 *sin = iw_event->remote_addr;
1121
1122 ret = cma_notify_user(conn_id, RDMA_CM_EVENT_CONNECT_REQUEST, 0,
1123 iw_event->private_data,
1124 iw_event->private_data_len);
1125 if (ret) {
1126 /* User wants to destroy the CM ID */
1127 conn_id->cm_id.iw = NULL;
1128 cma_exch(conn_id, CMA_DESTROYING);
1129 cma_release_remove(conn_id);
1130 rdma_destroy_id(&conn_id->id);
1131 }
1132
1133out:
1134 if (dev)
1135 dev_put(dev);
1136 cma_release_remove(listen_id);
1137 return ret;
1138}
1139
985static int cma_ib_listen(struct rdma_id_private *id_priv) 1140static int cma_ib_listen(struct rdma_id_private *id_priv)
986{ 1141{
987 struct ib_cm_compare_data compare_data; 1142 struct ib_cm_compare_data compare_data;
@@ -1011,6 +1166,30 @@ static int cma_ib_listen(struct rdma_id_private *id_priv)
1011 return ret; 1166 return ret;
1012} 1167}
1013 1168
1169static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog)
1170{
1171 int ret;
1172 struct sockaddr_in *sin;
1173
1174 id_priv->cm_id.iw = iw_create_cm_id(id_priv->id.device,
1175 iw_conn_req_handler,
1176 id_priv);
1177 if (IS_ERR(id_priv->cm_id.iw))
1178 return PTR_ERR(id_priv->cm_id.iw);
1179
1180 sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
1181 id_priv->cm_id.iw->local_addr = *sin;
1182
1183 ret = iw_cm_listen(id_priv->cm_id.iw, backlog);
1184
1185 if (ret) {
1186 iw_destroy_cm_id(id_priv->cm_id.iw);
1187 id_priv->cm_id.iw = NULL;
1188 }
1189
1190 return ret;
1191}
1192
1014static int cma_listen_handler(struct rdma_cm_id *id, 1193static int cma_listen_handler(struct rdma_cm_id *id,
1015 struct rdma_cm_event *event) 1194 struct rdma_cm_event *event)
1016{ 1195{
@@ -1087,12 +1266,17 @@ int rdma_listen(struct rdma_cm_id *id, int backlog)
1087 1266
1088 id_priv->backlog = backlog; 1267 id_priv->backlog = backlog;
1089 if (id->device) { 1268 if (id->device) {
1090 switch (id->device->node_type) { 1269 switch (rdma_node_get_transport(id->device->node_type)) {
1091 case IB_NODE_CA: 1270 case RDMA_TRANSPORT_IB:
1092 ret = cma_ib_listen(id_priv); 1271 ret = cma_ib_listen(id_priv);
1093 if (ret) 1272 if (ret)
1094 goto err; 1273 goto err;
1095 break; 1274 break;
1275 case RDMA_TRANSPORT_IWARP:
1276 ret = cma_iw_listen(id_priv, backlog);
1277 if (ret)
1278 goto err;
1279 break;
1096 default: 1280 default:
1097 ret = -ENOSYS; 1281 ret = -ENOSYS;
1098 goto err; 1282 goto err;
@@ -1140,7 +1324,7 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
1140 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr)); 1324 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr));
1141 path_rec.numb_path = 1; 1325 path_rec.numb_path = 1;
1142 1326
1143 id_priv->query_id = ib_sa_path_rec_get(id_priv->id.device, 1327 id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device,
1144 id_priv->id.port_num, &path_rec, 1328 id_priv->id.port_num, &path_rec,
1145 IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | 1329 IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
1146 IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH, 1330 IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH,
@@ -1231,6 +1415,23 @@ err:
1231} 1415}
1232EXPORT_SYMBOL(rdma_set_ib_paths); 1416EXPORT_SYMBOL(rdma_set_ib_paths);
1233 1417
1418static int cma_resolve_iw_route(struct rdma_id_private *id_priv, int timeout_ms)
1419{
1420 struct cma_work *work;
1421
1422 work = kzalloc(sizeof *work, GFP_KERNEL);
1423 if (!work)
1424 return -ENOMEM;
1425
1426 work->id = id_priv;
1427 INIT_WORK(&work->work, cma_work_handler, work);
1428 work->old_state = CMA_ROUTE_QUERY;
1429 work->new_state = CMA_ROUTE_RESOLVED;
1430 work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
1431 queue_work(cma_wq, &work->work);
1432 return 0;
1433}
1434
1234int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms) 1435int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
1235{ 1436{
1236 struct rdma_id_private *id_priv; 1437 struct rdma_id_private *id_priv;
@@ -1241,10 +1442,13 @@ int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
1241 return -EINVAL; 1442 return -EINVAL;
1242 1443
1243 atomic_inc(&id_priv->refcount); 1444 atomic_inc(&id_priv->refcount);
1244 switch (id->device->node_type) { 1445 switch (rdma_node_get_transport(id->device->node_type)) {
1245 case IB_NODE_CA: 1446 case RDMA_TRANSPORT_IB:
1246 ret = cma_resolve_ib_route(id_priv, timeout_ms); 1447 ret = cma_resolve_ib_route(id_priv, timeout_ms);
1247 break; 1448 break;
1449 case RDMA_TRANSPORT_IWARP:
1450 ret = cma_resolve_iw_route(id_priv, timeout_ms);
1451 break;
1248 default: 1452 default:
1249 ret = -ENOSYS; 1453 ret = -ENOSYS;
1250 break; 1454 break;
@@ -1309,16 +1513,26 @@ static void addr_handler(int status, struct sockaddr *src_addr,
1309 enum rdma_cm_event_type event; 1513 enum rdma_cm_event_type event;
1310 1514
1311 atomic_inc(&id_priv->dev_remove); 1515 atomic_inc(&id_priv->dev_remove);
1312 if (!id_priv->cma_dev && !status) 1516
1517 /*
1518 * Grab mutex to block rdma_destroy_id() from removing the device while
1519 * we're trying to acquire it.
1520 */
1521 mutex_lock(&lock);
1522 if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED)) {
1523 mutex_unlock(&lock);
1524 goto out;
1525 }
1526
1527 if (!status && !id_priv->cma_dev)
1313 status = cma_acquire_dev(id_priv); 1528 status = cma_acquire_dev(id_priv);
1529 mutex_unlock(&lock);
1314 1530
1315 if (status) { 1531 if (status) {
1316 if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_BOUND)) 1532 if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ADDR_BOUND))
1317 goto out; 1533 goto out;
1318 event = RDMA_CM_EVENT_ADDR_ERROR; 1534 event = RDMA_CM_EVENT_ADDR_ERROR;
1319 } else { 1535 } else {
1320 if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED))
1321 goto out;
1322 memcpy(&id_priv->id.route.addr.src_addr, src_addr, 1536 memcpy(&id_priv->id.route.addr.src_addr, src_addr,
1323 ip_addr_size(src_addr)); 1537 ip_addr_size(src_addr));
1324 event = RDMA_CM_EVENT_ADDR_RESOLVED; 1538 event = RDMA_CM_EVENT_ADDR_RESOLVED;
@@ -1492,7 +1706,7 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
1492 hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { 1706 hlist_for_each_entry(cur_id, node, &bind_list->owners, node) {
1493 if (cma_any_addr(&cur_id->id.route.addr.src_addr)) 1707 if (cma_any_addr(&cur_id->id.route.addr.src_addr))
1494 return -EADDRNOTAVAIL; 1708 return -EADDRNOTAVAIL;
1495 1709
1496 cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr; 1710 cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr;
1497 if (sin->sin_addr.s_addr == cur_sin->sin_addr.s_addr) 1711 if (sin->sin_addr.s_addr == cur_sin->sin_addr.s_addr)
1498 return -EADDRINUSE; 1712 return -EADDRINUSE;
@@ -1542,8 +1756,11 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
1542 1756
1543 if (!cma_any_addr(addr)) { 1757 if (!cma_any_addr(addr)) {
1544 ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); 1758 ret = rdma_translate_ip(addr, &id->route.addr.dev_addr);
1545 if (!ret) 1759 if (!ret) {
1760 mutex_lock(&lock);
1546 ret = cma_acquire_dev(id_priv); 1761 ret = cma_acquire_dev(id_priv);
1762 mutex_unlock(&lock);
1763 }
1547 if (ret) 1764 if (ret)
1548 goto err; 1765 goto err;
1549 } 1766 }
@@ -1649,6 +1866,47 @@ out:
1649 return ret; 1866 return ret;
1650} 1867}
1651 1868
1869static int cma_connect_iw(struct rdma_id_private *id_priv,
1870 struct rdma_conn_param *conn_param)
1871{
1872 struct iw_cm_id *cm_id;
1873 struct sockaddr_in* sin;
1874 int ret;
1875 struct iw_cm_conn_param iw_param;
1876
1877 cm_id = iw_create_cm_id(id_priv->id.device, cma_iw_handler, id_priv);
1878 if (IS_ERR(cm_id)) {
1879 ret = PTR_ERR(cm_id);
1880 goto out;
1881 }
1882
1883 id_priv->cm_id.iw = cm_id;
1884
1885 sin = (struct sockaddr_in*) &id_priv->id.route.addr.src_addr;
1886 cm_id->local_addr = *sin;
1887
1888 sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr;
1889 cm_id->remote_addr = *sin;
1890
1891 ret = cma_modify_qp_rtr(&id_priv->id);
1892 if (ret) {
1893 iw_destroy_cm_id(cm_id);
1894 return ret;
1895 }
1896
1897 iw_param.ord = conn_param->initiator_depth;
1898 iw_param.ird = conn_param->responder_resources;
1899 iw_param.private_data = conn_param->private_data;
1900 iw_param.private_data_len = conn_param->private_data_len;
1901 if (id_priv->id.qp)
1902 iw_param.qpn = id_priv->qp_num;
1903 else
1904 iw_param.qpn = conn_param->qp_num;
1905 ret = iw_cm_connect(cm_id, &iw_param);
1906out:
1907 return ret;
1908}
1909
1652int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) 1910int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
1653{ 1911{
1654 struct rdma_id_private *id_priv; 1912 struct rdma_id_private *id_priv;
@@ -1664,10 +1922,13 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
1664 id_priv->srq = conn_param->srq; 1922 id_priv->srq = conn_param->srq;
1665 } 1923 }
1666 1924
1667 switch (id->device->node_type) { 1925 switch (rdma_node_get_transport(id->device->node_type)) {
1668 case IB_NODE_CA: 1926 case RDMA_TRANSPORT_IB:
1669 ret = cma_connect_ib(id_priv, conn_param); 1927 ret = cma_connect_ib(id_priv, conn_param);
1670 break; 1928 break;
1929 case RDMA_TRANSPORT_IWARP:
1930 ret = cma_connect_iw(id_priv, conn_param);
1931 break;
1671 default: 1932 default:
1672 ret = -ENOSYS; 1933 ret = -ENOSYS;
1673 break; 1934 break;
@@ -1708,6 +1969,28 @@ static int cma_accept_ib(struct rdma_id_private *id_priv,
1708 return ib_send_cm_rep(id_priv->cm_id.ib, &rep); 1969 return ib_send_cm_rep(id_priv->cm_id.ib, &rep);
1709} 1970}
1710 1971
1972static int cma_accept_iw(struct rdma_id_private *id_priv,
1973 struct rdma_conn_param *conn_param)
1974{
1975 struct iw_cm_conn_param iw_param;
1976 int ret;
1977
1978 ret = cma_modify_qp_rtr(&id_priv->id);
1979 if (ret)
1980 return ret;
1981
1982 iw_param.ord = conn_param->initiator_depth;
1983 iw_param.ird = conn_param->responder_resources;
1984 iw_param.private_data = conn_param->private_data;
1985 iw_param.private_data_len = conn_param->private_data_len;
1986 if (id_priv->id.qp) {
1987 iw_param.qpn = id_priv->qp_num;
1988 } else
1989 iw_param.qpn = conn_param->qp_num;
1990
1991 return iw_cm_accept(id_priv->cm_id.iw, &iw_param);
1992}
1993
1711int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) 1994int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
1712{ 1995{
1713 struct rdma_id_private *id_priv; 1996 struct rdma_id_private *id_priv;
@@ -1723,13 +2006,16 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
1723 id_priv->srq = conn_param->srq; 2006 id_priv->srq = conn_param->srq;
1724 } 2007 }
1725 2008
1726 switch (id->device->node_type) { 2009 switch (rdma_node_get_transport(id->device->node_type)) {
1727 case IB_NODE_CA: 2010 case RDMA_TRANSPORT_IB:
1728 if (conn_param) 2011 if (conn_param)
1729 ret = cma_accept_ib(id_priv, conn_param); 2012 ret = cma_accept_ib(id_priv, conn_param);
1730 else 2013 else
1731 ret = cma_rep_recv(id_priv); 2014 ret = cma_rep_recv(id_priv);
1732 break; 2015 break;
2016 case RDMA_TRANSPORT_IWARP:
2017 ret = cma_accept_iw(id_priv, conn_param);
2018 break;
1733 default: 2019 default:
1734 ret = -ENOSYS; 2020 ret = -ENOSYS;
1735 break; 2021 break;
@@ -1756,12 +2042,16 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data,
1756 if (!cma_comp(id_priv, CMA_CONNECT)) 2042 if (!cma_comp(id_priv, CMA_CONNECT))
1757 return -EINVAL; 2043 return -EINVAL;
1758 2044
1759 switch (id->device->node_type) { 2045 switch (rdma_node_get_transport(id->device->node_type)) {
1760 case IB_NODE_CA: 2046 case RDMA_TRANSPORT_IB:
1761 ret = ib_send_cm_rej(id_priv->cm_id.ib, 2047 ret = ib_send_cm_rej(id_priv->cm_id.ib,
1762 IB_CM_REJ_CONSUMER_DEFINED, NULL, 0, 2048 IB_CM_REJ_CONSUMER_DEFINED, NULL, 0,
1763 private_data, private_data_len); 2049 private_data, private_data_len);
1764 break; 2050 break;
2051 case RDMA_TRANSPORT_IWARP:
2052 ret = iw_cm_reject(id_priv->cm_id.iw,
2053 private_data, private_data_len);
2054 break;
1765 default: 2055 default:
1766 ret = -ENOSYS; 2056 ret = -ENOSYS;
1767 break; 2057 break;
@@ -1780,17 +2070,20 @@ int rdma_disconnect(struct rdma_cm_id *id)
1780 !cma_comp(id_priv, CMA_DISCONNECT)) 2070 !cma_comp(id_priv, CMA_DISCONNECT))
1781 return -EINVAL; 2071 return -EINVAL;
1782 2072
1783 ret = cma_modify_qp_err(id); 2073 switch (rdma_node_get_transport(id->device->node_type)) {
1784 if (ret) 2074 case RDMA_TRANSPORT_IB:
1785 goto out; 2075 ret = cma_modify_qp_err(id);
1786 2076 if (ret)
1787 switch (id->device->node_type) { 2077 goto out;
1788 case IB_NODE_CA:
1789 /* Initiate or respond to a disconnect. */ 2078 /* Initiate or respond to a disconnect. */
1790 if (ib_send_cm_dreq(id_priv->cm_id.ib, NULL, 0)) 2079 if (ib_send_cm_dreq(id_priv->cm_id.ib, NULL, 0))
1791 ib_send_cm_drep(id_priv->cm_id.ib, NULL, 0); 2080 ib_send_cm_drep(id_priv->cm_id.ib, NULL, 0);
1792 break; 2081 break;
2082 case RDMA_TRANSPORT_IWARP:
2083 ret = iw_cm_disconnect(id_priv->cm_id.iw, 0);
2084 break;
1793 default: 2085 default:
2086 ret = -EINVAL;
1794 break; 2087 break;
1795 } 2088 }
1796out: 2089out:
@@ -1907,12 +2200,15 @@ static int cma_init(void)
1907 if (!cma_wq) 2200 if (!cma_wq)
1908 return -ENOMEM; 2201 return -ENOMEM;
1909 2202
2203 ib_sa_register_client(&sa_client);
2204
1910 ret = ib_register_client(&cma_client); 2205 ret = ib_register_client(&cma_client);
1911 if (ret) 2206 if (ret)
1912 goto err; 2207 goto err;
1913 return 0; 2208 return 0;
1914 2209
1915err: 2210err:
2211 ib_sa_unregister_client(&sa_client);
1916 destroy_workqueue(cma_wq); 2212 destroy_workqueue(cma_wq);
1917 return ret; 2213 return ret;
1918} 2214}
@@ -1920,6 +2216,7 @@ err:
1920static void cma_cleanup(void) 2216static void cma_cleanup(void)
1921{ 2217{
1922 ib_unregister_client(&cma_client); 2218 ib_unregister_client(&cma_client);
2219 ib_sa_unregister_client(&sa_client);
1923 destroy_workqueue(cma_wq); 2220 destroy_workqueue(cma_wq);
1924 idr_destroy(&sdp_ps); 2221 idr_destroy(&sdp_ps);
1925 idr_destroy(&tcp_ps); 2222 idr_destroy(&tcp_ps);
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index b2f3cb91d9bc..63d2a39fb82c 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -385,7 +385,7 @@ void *ib_get_client_data(struct ib_device *device, struct ib_client *client)
385EXPORT_SYMBOL(ib_get_client_data); 385EXPORT_SYMBOL(ib_get_client_data);
386 386
387/** 387/**
388 * ib_set_client_data - Get IB client context 388 * ib_set_client_data - Set IB client context
389 * @device:Device to set context for 389 * @device:Device to set context for
390 * @client:Client to set context for 390 * @client:Client to set context for
391 * @data:Context to set 391 * @data:Context to set
@@ -505,7 +505,7 @@ int ib_query_port(struct ib_device *device,
505 u8 port_num, 505 u8 port_num,
506 struct ib_port_attr *port_attr) 506 struct ib_port_attr *port_attr)
507{ 507{
508 if (device->node_type == IB_NODE_SWITCH) { 508 if (device->node_type == RDMA_NODE_IB_SWITCH) {
509 if (port_num) 509 if (port_num)
510 return -EINVAL; 510 return -EINVAL;
511 } else if (port_num < 1 || port_num > device->phys_port_cnt) 511 } else if (port_num < 1 || port_num > device->phys_port_cnt)
@@ -580,7 +580,7 @@ int ib_modify_port(struct ib_device *device,
580 u8 port_num, int port_modify_mask, 580 u8 port_num, int port_modify_mask,
581 struct ib_port_modify *port_modify) 581 struct ib_port_modify *port_modify)
582{ 582{
583 if (device->node_type == IB_NODE_SWITCH) { 583 if (device->node_type == RDMA_NODE_IB_SWITCH) {
584 if (port_num) 584 if (port_num)
585 return -EINVAL; 585 return -EINVAL;
586 } else if (port_num < 1 || port_num > device->phys_port_cnt) 586 } else if (port_num < 1 || port_num > device->phys_port_cnt)
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
new file mode 100644
index 000000000000..c3fb304a4e86
--- /dev/null
+++ b/drivers/infiniband/core/iwcm.c
@@ -0,0 +1,1019 @@
1/*
2 * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
3 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
4 * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
5 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
6 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
7 * Copyright (c) 2005 Network Appliance, Inc. All rights reserved.
8 *
9 * This software is available to you under a choice of one of two
10 * licenses. You may choose to be licensed under the terms of the GNU
11 * General Public License (GPL) Version 2, available from the file
12 * COPYING in the main directory of this source tree, or the
13 * OpenIB.org BSD license below:
14 *
15 * Redistribution and use in source and binary forms, with or
16 * without modification, are permitted provided that the following
17 * conditions are met:
18 *
19 * - Redistributions of source code must retain the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer.
22 *
23 * - Redistributions in binary form must reproduce the above
24 * copyright notice, this list of conditions and the following
25 * disclaimer in the documentation and/or other materials
26 * provided with the distribution.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
32 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
33 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 * SOFTWARE.
36 *
37 */
38#include <linux/dma-mapping.h>
39#include <linux/err.h>
40#include <linux/idr.h>
41#include <linux/interrupt.h>
42#include <linux/pci.h>
43#include <linux/rbtree.h>
44#include <linux/spinlock.h>
45#include <linux/workqueue.h>
46#include <linux/completion.h>
47
48#include <rdma/iw_cm.h>
49#include <rdma/ib_addr.h>
50
51#include "iwcm.h"
52
53MODULE_AUTHOR("Tom Tucker");
54MODULE_DESCRIPTION("iWARP CM");
55MODULE_LICENSE("Dual BSD/GPL");
56
57static struct workqueue_struct *iwcm_wq;
58struct iwcm_work {
59 struct work_struct work;
60 struct iwcm_id_private *cm_id;
61 struct list_head list;
62 struct iw_cm_event event;
63 struct list_head free_list;
64};
65
66/*
67 * The following services provide a mechanism for pre-allocating iwcm_work
68 * elements. The design pre-allocates them based on the cm_id type:
69 * LISTENING IDS: Get enough elements preallocated to handle the
70 * listen backlog.
71 * ACTIVE IDS: 4: CONNECT_REPLY, ESTABLISHED, DISCONNECT, CLOSE
72 * PASSIVE IDS: 3: ESTABLISHED, DISCONNECT, CLOSE
73 *
74 * Allocating them in connect and listen avoids having to deal
75 * with allocation failures on the event upcall from the provider (which
76 * is called in the interrupt context).
77 *
78 * One exception is when creating the cm_id for incoming connection requests.
79 * There are two cases:
80 * 1) in the event upcall, cm_event_handler(), for a listening cm_id. If
81 * the backlog is exceeded, then no more connection request events will
82 * be processed. cm_event_handler() returns -ENOMEM in this case. Its up
83 * to the provider to reject the connectino request.
84 * 2) in the connection request workqueue handler, cm_conn_req_handler().
85 * If work elements cannot be allocated for the new connect request cm_id,
86 * then IWCM will call the provider reject method. This is ok since
87 * cm_conn_req_handler() runs in the workqueue thread context.
88 */
89
90static struct iwcm_work *get_work(struct iwcm_id_private *cm_id_priv)
91{
92 struct iwcm_work *work;
93
94 if (list_empty(&cm_id_priv->work_free_list))
95 return NULL;
96 work = list_entry(cm_id_priv->work_free_list.next, struct iwcm_work,
97 free_list);
98 list_del_init(&work->free_list);
99 return work;
100}
101
102static void put_work(struct iwcm_work *work)
103{
104 list_add(&work->free_list, &work->cm_id->work_free_list);
105}
106
107static void dealloc_work_entries(struct iwcm_id_private *cm_id_priv)
108{
109 struct list_head *e, *tmp;
110
111 list_for_each_safe(e, tmp, &cm_id_priv->work_free_list)
112 kfree(list_entry(e, struct iwcm_work, free_list));
113}
114
115static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count)
116{
117 struct iwcm_work *work;
118
119 BUG_ON(!list_empty(&cm_id_priv->work_free_list));
120 while (count--) {
121 work = kmalloc(sizeof(struct iwcm_work), GFP_KERNEL);
122 if (!work) {
123 dealloc_work_entries(cm_id_priv);
124 return -ENOMEM;
125 }
126 work->cm_id = cm_id_priv;
127 INIT_LIST_HEAD(&work->list);
128 put_work(work);
129 }
130 return 0;
131}
132
133/*
134 * Save private data from incoming connection requests in the
135 * cm_id_priv so the low level driver doesn't have to. Adjust
136 * the event ptr to point to the local copy.
137 */
138static int copy_private_data(struct iwcm_id_private *cm_id_priv,
139 struct iw_cm_event *event)
140{
141 void *p;
142
143 p = kmalloc(event->private_data_len, GFP_ATOMIC);
144 if (!p)
145 return -ENOMEM;
146 memcpy(p, event->private_data, event->private_data_len);
147 event->private_data = p;
148 return 0;
149}
150
151/*
152 * Release a reference on cm_id. If the last reference is being removed
153 * and iw_destroy_cm_id is waiting, wake up the waiting thread.
154 */
155static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
156{
157 int ret = 0;
158
159 BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
160 if (atomic_dec_and_test(&cm_id_priv->refcount)) {
161 BUG_ON(!list_empty(&cm_id_priv->work_list));
162 if (waitqueue_active(&cm_id_priv->destroy_comp.wait)) {
163 BUG_ON(cm_id_priv->state != IW_CM_STATE_DESTROYING);
164 BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY,
165 &cm_id_priv->flags));
166 ret = 1;
167 }
168 complete(&cm_id_priv->destroy_comp);
169 }
170
171 return ret;
172}
173
174static void add_ref(struct iw_cm_id *cm_id)
175{
176 struct iwcm_id_private *cm_id_priv;
177 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
178 atomic_inc(&cm_id_priv->refcount);
179}
180
181static void rem_ref(struct iw_cm_id *cm_id)
182{
183 struct iwcm_id_private *cm_id_priv;
184 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
185 iwcm_deref_id(cm_id_priv);
186}
187
188static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
189
190struct iw_cm_id *iw_create_cm_id(struct ib_device *device,
191 iw_cm_handler cm_handler,
192 void *context)
193{
194 struct iwcm_id_private *cm_id_priv;
195
196 cm_id_priv = kzalloc(sizeof(*cm_id_priv), GFP_KERNEL);
197 if (!cm_id_priv)
198 return ERR_PTR(-ENOMEM);
199
200 cm_id_priv->state = IW_CM_STATE_IDLE;
201 cm_id_priv->id.device = device;
202 cm_id_priv->id.cm_handler = cm_handler;
203 cm_id_priv->id.context = context;
204 cm_id_priv->id.event_handler = cm_event_handler;
205 cm_id_priv->id.add_ref = add_ref;
206 cm_id_priv->id.rem_ref = rem_ref;
207 spin_lock_init(&cm_id_priv->lock);
208 atomic_set(&cm_id_priv->refcount, 1);
209 init_waitqueue_head(&cm_id_priv->connect_wait);
210 init_completion(&cm_id_priv->destroy_comp);
211 INIT_LIST_HEAD(&cm_id_priv->work_list);
212 INIT_LIST_HEAD(&cm_id_priv->work_free_list);
213
214 return &cm_id_priv->id;
215}
216EXPORT_SYMBOL(iw_create_cm_id);
217
218
219static int iwcm_modify_qp_err(struct ib_qp *qp)
220{
221 struct ib_qp_attr qp_attr;
222
223 if (!qp)
224 return -EINVAL;
225
226 qp_attr.qp_state = IB_QPS_ERR;
227 return ib_modify_qp(qp, &qp_attr, IB_QP_STATE);
228}
229
230/*
231 * This is really the RDMAC CLOSING state. It is most similar to the
232 * IB SQD QP state.
233 */
234static int iwcm_modify_qp_sqd(struct ib_qp *qp)
235{
236 struct ib_qp_attr qp_attr;
237
238 BUG_ON(qp == NULL);
239 qp_attr.qp_state = IB_QPS_SQD;
240 return ib_modify_qp(qp, &qp_attr, IB_QP_STATE);
241}
242
243/*
244 * CM_ID <-- CLOSING
245 *
246 * Block if a passive or active connection is currenlty being processed. Then
247 * process the event as follows:
248 * - If we are ESTABLISHED, move to CLOSING and modify the QP state
249 * based on the abrupt flag
250 * - If the connection is already in the CLOSING or IDLE state, the peer is
251 * disconnecting concurrently with us and we've already seen the
252 * DISCONNECT event -- ignore the request and return 0
253 * - Disconnect on a listening endpoint returns -EINVAL
254 */
255int iw_cm_disconnect(struct iw_cm_id *cm_id, int abrupt)
256{
257 struct iwcm_id_private *cm_id_priv;
258 unsigned long flags;
259 int ret = 0;
260 struct ib_qp *qp = NULL;
261
262 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
263 /* Wait if we're currently in a connect or accept downcall */
264 wait_event(cm_id_priv->connect_wait,
265 !test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags));
266
267 spin_lock_irqsave(&cm_id_priv->lock, flags);
268 switch (cm_id_priv->state) {
269 case IW_CM_STATE_ESTABLISHED:
270 cm_id_priv->state = IW_CM_STATE_CLOSING;
271
272 /* QP could be <nul> for user-mode client */
273 if (cm_id_priv->qp)
274 qp = cm_id_priv->qp;
275 else
276 ret = -EINVAL;
277 break;
278 case IW_CM_STATE_LISTEN:
279 ret = -EINVAL;
280 break;
281 case IW_CM_STATE_CLOSING:
282 /* remote peer closed first */
283 case IW_CM_STATE_IDLE:
284 /* accept or connect returned !0 */
285 break;
286 case IW_CM_STATE_CONN_RECV:
287 /*
288 * App called disconnect before/without calling accept after
289 * connect_request event delivered.
290 */
291 break;
292 case IW_CM_STATE_CONN_SENT:
293 /* Can only get here if wait above fails */
294 default:
295 BUG();
296 }
297 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
298
299 if (qp) {
300 if (abrupt)
301 ret = iwcm_modify_qp_err(qp);
302 else
303 ret = iwcm_modify_qp_sqd(qp);
304
305 /*
306 * If both sides are disconnecting the QP could
307 * already be in ERR or SQD states
308 */
309 ret = 0;
310 }
311
312 return ret;
313}
314EXPORT_SYMBOL(iw_cm_disconnect);
315
316/*
317 * CM_ID <-- DESTROYING
318 *
319 * Clean up all resources associated with the connection and release
320 * the initial reference taken by iw_create_cm_id.
321 */
322static void destroy_cm_id(struct iw_cm_id *cm_id)
323{
324 struct iwcm_id_private *cm_id_priv;
325 unsigned long flags;
326 int ret;
327
328 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
329 /*
330 * Wait if we're currently in a connect or accept downcall. A
331 * listening endpoint should never block here.
332 */
333 wait_event(cm_id_priv->connect_wait,
334 !test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags));
335
336 spin_lock_irqsave(&cm_id_priv->lock, flags);
337 switch (cm_id_priv->state) {
338 case IW_CM_STATE_LISTEN:
339 cm_id_priv->state = IW_CM_STATE_DESTROYING;
340 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
341 /* destroy the listening endpoint */
342 ret = cm_id->device->iwcm->destroy_listen(cm_id);
343 spin_lock_irqsave(&cm_id_priv->lock, flags);
344 break;
345 case IW_CM_STATE_ESTABLISHED:
346 cm_id_priv->state = IW_CM_STATE_DESTROYING;
347 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
348 /* Abrupt close of the connection */
349 (void)iwcm_modify_qp_err(cm_id_priv->qp);
350 spin_lock_irqsave(&cm_id_priv->lock, flags);
351 break;
352 case IW_CM_STATE_IDLE:
353 case IW_CM_STATE_CLOSING:
354 cm_id_priv->state = IW_CM_STATE_DESTROYING;
355 break;
356 case IW_CM_STATE_CONN_RECV:
357 /*
358 * App called destroy before/without calling accept after
359 * receiving connection request event notification.
360 */
361 cm_id_priv->state = IW_CM_STATE_DESTROYING;
362 break;
363 case IW_CM_STATE_CONN_SENT:
364 case IW_CM_STATE_DESTROYING:
365 default:
366 BUG();
367 break;
368 }
369 if (cm_id_priv->qp) {
370 cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp);
371 cm_id_priv->qp = NULL;
372 }
373 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
374
375 (void)iwcm_deref_id(cm_id_priv);
376}
377
378/*
379 * This function is only called by the application thread and cannot
380 * be called by the event thread. The function will wait for all
381 * references to be released on the cm_id and then kfree the cm_id
382 * object.
383 */
384void iw_destroy_cm_id(struct iw_cm_id *cm_id)
385{
386 struct iwcm_id_private *cm_id_priv;
387
388 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
389 BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags));
390
391 destroy_cm_id(cm_id);
392
393 wait_for_completion(&cm_id_priv->destroy_comp);
394
395 dealloc_work_entries(cm_id_priv);
396
397 kfree(cm_id_priv);
398}
399EXPORT_SYMBOL(iw_destroy_cm_id);
400
401/*
402 * CM_ID <-- LISTEN
403 *
404 * Start listening for connect requests. Generates one CONNECT_REQUEST
405 * event for each inbound connect request.
406 */
407int iw_cm_listen(struct iw_cm_id *cm_id, int backlog)
408{
409 struct iwcm_id_private *cm_id_priv;
410 unsigned long flags;
411 int ret = 0;
412
413 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
414
415 ret = alloc_work_entries(cm_id_priv, backlog);
416 if (ret)
417 return ret;
418
419 spin_lock_irqsave(&cm_id_priv->lock, flags);
420 switch (cm_id_priv->state) {
421 case IW_CM_STATE_IDLE:
422 cm_id_priv->state = IW_CM_STATE_LISTEN;
423 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
424 ret = cm_id->device->iwcm->create_listen(cm_id, backlog);
425 if (ret)
426 cm_id_priv->state = IW_CM_STATE_IDLE;
427 spin_lock_irqsave(&cm_id_priv->lock, flags);
428 break;
429 default:
430 ret = -EINVAL;
431 }
432 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
433
434 return ret;
435}
436EXPORT_SYMBOL(iw_cm_listen);
437
438/*
439 * CM_ID <-- IDLE
440 *
441 * Rejects an inbound connection request. No events are generated.
442 */
443int iw_cm_reject(struct iw_cm_id *cm_id,
444 const void *private_data,
445 u8 private_data_len)
446{
447 struct iwcm_id_private *cm_id_priv;
448 unsigned long flags;
449 int ret;
450
451 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
452 set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
453
454 spin_lock_irqsave(&cm_id_priv->lock, flags);
455 if (cm_id_priv->state != IW_CM_STATE_CONN_RECV) {
456 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
457 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
458 wake_up_all(&cm_id_priv->connect_wait);
459 return -EINVAL;
460 }
461 cm_id_priv->state = IW_CM_STATE_IDLE;
462 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
463
464 ret = cm_id->device->iwcm->reject(cm_id, private_data,
465 private_data_len);
466
467 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
468 wake_up_all(&cm_id_priv->connect_wait);
469
470 return ret;
471}
472EXPORT_SYMBOL(iw_cm_reject);
473
474/*
475 * CM_ID <-- ESTABLISHED
476 *
477 * Accepts an inbound connection request and generates an ESTABLISHED
478 * event. Callers of iw_cm_disconnect and iw_destroy_cm_id will block
479 * until the ESTABLISHED event is received from the provider.
480 */
481int iw_cm_accept(struct iw_cm_id *cm_id,
482 struct iw_cm_conn_param *iw_param)
483{
484 struct iwcm_id_private *cm_id_priv;
485 struct ib_qp *qp;
486 unsigned long flags;
487 int ret;
488
489 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
490 set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
491
492 spin_lock_irqsave(&cm_id_priv->lock, flags);
493 if (cm_id_priv->state != IW_CM_STATE_CONN_RECV) {
494 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
495 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
496 wake_up_all(&cm_id_priv->connect_wait);
497 return -EINVAL;
498 }
499 /* Get the ib_qp given the QPN */
500 qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn);
501 if (!qp) {
502 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
503 return -EINVAL;
504 }
505 cm_id->device->iwcm->add_ref(qp);
506 cm_id_priv->qp = qp;
507 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
508
509 ret = cm_id->device->iwcm->accept(cm_id, iw_param);
510 if (ret) {
511 /* An error on accept precludes provider events */
512 BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV);
513 cm_id_priv->state = IW_CM_STATE_IDLE;
514 spin_lock_irqsave(&cm_id_priv->lock, flags);
515 if (cm_id_priv->qp) {
516 cm_id->device->iwcm->rem_ref(qp);
517 cm_id_priv->qp = NULL;
518 }
519 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
520 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
521 wake_up_all(&cm_id_priv->connect_wait);
522 }
523
524 return ret;
525}
526EXPORT_SYMBOL(iw_cm_accept);
527
528/*
529 * Active Side: CM_ID <-- CONN_SENT
530 *
531 * If successful, results in the generation of a CONNECT_REPLY
532 * event. iw_cm_disconnect and iw_cm_destroy will block until the
533 * CONNECT_REPLY event is received from the provider.
534 */
535int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
536{
537 struct iwcm_id_private *cm_id_priv;
538 int ret = 0;
539 unsigned long flags;
540 struct ib_qp *qp;
541
542 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
543
544 ret = alloc_work_entries(cm_id_priv, 4);
545 if (ret)
546 return ret;
547
548 set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
549 spin_lock_irqsave(&cm_id_priv->lock, flags);
550
551 if (cm_id_priv->state != IW_CM_STATE_IDLE) {
552 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
553 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
554 wake_up_all(&cm_id_priv->connect_wait);
555 return -EINVAL;
556 }
557
558 /* Get the ib_qp given the QPN */
559 qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn);
560 if (!qp) {
561 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
562 return -EINVAL;
563 }
564 cm_id->device->iwcm->add_ref(qp);
565 cm_id_priv->qp = qp;
566 cm_id_priv->state = IW_CM_STATE_CONN_SENT;
567 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
568
569 ret = cm_id->device->iwcm->connect(cm_id, iw_param);
570 if (ret) {
571 spin_lock_irqsave(&cm_id_priv->lock, flags);
572 if (cm_id_priv->qp) {
573 cm_id->device->iwcm->rem_ref(qp);
574 cm_id_priv->qp = NULL;
575 }
576 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
577 BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT);
578 cm_id_priv->state = IW_CM_STATE_IDLE;
579 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
580 wake_up_all(&cm_id_priv->connect_wait);
581 }
582
583 return ret;
584}
585EXPORT_SYMBOL(iw_cm_connect);
586
587/*
588 * Passive Side: new CM_ID <-- CONN_RECV
589 *
590 * Handles an inbound connect request. The function creates a new
591 * iw_cm_id to represent the new connection and inherits the client
592 * callback function and other attributes from the listening parent.
593 *
594 * The work item contains a pointer to the listen_cm_id and the event. The
595 * listen_cm_id contains the client cm_handler, context and
596 * device. These are copied when the device is cloned. The event
597 * contains the new four tuple.
598 *
599 * An error on the child should not affect the parent, so this
600 * function does not return a value.
601 */
602static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
603 struct iw_cm_event *iw_event)
604{
605 unsigned long flags;
606 struct iw_cm_id *cm_id;
607 struct iwcm_id_private *cm_id_priv;
608 int ret;
609
610 /*
611 * The provider should never generate a connection request
612 * event with a bad status.
613 */
614 BUG_ON(iw_event->status);
615
616 /*
617 * We could be destroying the listening id. If so, ignore this
618 * upcall.
619 */
620 spin_lock_irqsave(&listen_id_priv->lock, flags);
621 if (listen_id_priv->state != IW_CM_STATE_LISTEN) {
622 spin_unlock_irqrestore(&listen_id_priv->lock, flags);
623 return;
624 }
625 spin_unlock_irqrestore(&listen_id_priv->lock, flags);
626
627 cm_id = iw_create_cm_id(listen_id_priv->id.device,
628 listen_id_priv->id.cm_handler,
629 listen_id_priv->id.context);
630 /* If the cm_id could not be created, ignore the request */
631 if (IS_ERR(cm_id))
632 return;
633
634 cm_id->provider_data = iw_event->provider_data;
635 cm_id->local_addr = iw_event->local_addr;
636 cm_id->remote_addr = iw_event->remote_addr;
637
638 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
639 cm_id_priv->state = IW_CM_STATE_CONN_RECV;
640
641 ret = alloc_work_entries(cm_id_priv, 3);
642 if (ret) {
643 iw_cm_reject(cm_id, NULL, 0);
644 iw_destroy_cm_id(cm_id);
645 return;
646 }
647
648 /* Call the client CM handler */
649 ret = cm_id->cm_handler(cm_id, iw_event);
650 if (ret) {
651 set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
652 destroy_cm_id(cm_id);
653 if (atomic_read(&cm_id_priv->refcount)==0)
654 kfree(cm_id);
655 }
656
657 if (iw_event->private_data_len)
658 kfree(iw_event->private_data);
659}
660
661/*
662 * Passive Side: CM_ID <-- ESTABLISHED
663 *
664 * The provider generated an ESTABLISHED event which means that
665 * the MPA negotion has completed successfully and we are now in MPA
666 * FPDU mode.
667 *
668 * This event can only be received in the CONN_RECV state. If the
669 * remote peer closed, the ESTABLISHED event would be received followed
670 * by the CLOSE event. If the app closes, it will block until we wake
671 * it up after processing this event.
672 */
673static int cm_conn_est_handler(struct iwcm_id_private *cm_id_priv,
674 struct iw_cm_event *iw_event)
675{
676 unsigned long flags;
677 int ret = 0;
678
679 spin_lock_irqsave(&cm_id_priv->lock, flags);
680
681 /*
682 * We clear the CONNECT_WAIT bit here to allow the callback
683 * function to call iw_cm_disconnect. Calling iw_destroy_cm_id
684 * from a callback handler is not allowed.
685 */
686 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
687 BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV);
688 cm_id_priv->state = IW_CM_STATE_ESTABLISHED;
689 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
690 ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
691 wake_up_all(&cm_id_priv->connect_wait);
692
693 return ret;
694}
695
696/*
697 * Active Side: CM_ID <-- ESTABLISHED
698 *
699 * The app has called connect and is waiting for the established event to
700 * post it's requests to the server. This event will wake up anyone
701 * blocked in iw_cm_disconnect or iw_destroy_id.
702 */
703static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv,
704 struct iw_cm_event *iw_event)
705{
706 unsigned long flags;
707 int ret = 0;
708
709 spin_lock_irqsave(&cm_id_priv->lock, flags);
710 /*
711 * Clear the connect wait bit so a callback function calling
712 * iw_cm_disconnect will not wait and deadlock this thread
713 */
714 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
715 BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT);
716 if (iw_event->status == IW_CM_EVENT_STATUS_ACCEPTED) {
717 cm_id_priv->id.local_addr = iw_event->local_addr;
718 cm_id_priv->id.remote_addr = iw_event->remote_addr;
719 cm_id_priv->state = IW_CM_STATE_ESTABLISHED;
720 } else {
721 /* REJECTED or RESET */
722 cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp);
723 cm_id_priv->qp = NULL;
724 cm_id_priv->state = IW_CM_STATE_IDLE;
725 }
726 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
727 ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
728
729 if (iw_event->private_data_len)
730 kfree(iw_event->private_data);
731
732 /* Wake up waiters on connect complete */
733 wake_up_all(&cm_id_priv->connect_wait);
734
735 return ret;
736}
737
738/*
739 * CM_ID <-- CLOSING
740 *
741 * If in the ESTABLISHED state, move to CLOSING.
742 */
743static void cm_disconnect_handler(struct iwcm_id_private *cm_id_priv,
744 struct iw_cm_event *iw_event)
745{
746 unsigned long flags;
747
748 spin_lock_irqsave(&cm_id_priv->lock, flags);
749 if (cm_id_priv->state == IW_CM_STATE_ESTABLISHED)
750 cm_id_priv->state = IW_CM_STATE_CLOSING;
751 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
752}
753
754/*
755 * CM_ID <-- IDLE
756 *
757 * If in the ESTBLISHED or CLOSING states, the QP will have have been
758 * moved by the provider to the ERR state. Disassociate the CM_ID from
759 * the QP, move to IDLE, and remove the 'connected' reference.
760 *
761 * If in some other state, the cm_id was destroyed asynchronously.
762 * This is the last reference that will result in waking up
763 * the app thread blocked in iw_destroy_cm_id.
764 */
765static int cm_close_handler(struct iwcm_id_private *cm_id_priv,
766 struct iw_cm_event *iw_event)
767{
768 unsigned long flags;
769 int ret = 0;
770 spin_lock_irqsave(&cm_id_priv->lock, flags);
771
772 if (cm_id_priv->qp) {
773 cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp);
774 cm_id_priv->qp = NULL;
775 }
776 switch (cm_id_priv->state) {
777 case IW_CM_STATE_ESTABLISHED:
778 case IW_CM_STATE_CLOSING:
779 cm_id_priv->state = IW_CM_STATE_IDLE;
780 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
781 ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
782 spin_lock_irqsave(&cm_id_priv->lock, flags);
783 break;
784 case IW_CM_STATE_DESTROYING:
785 break;
786 default:
787 BUG();
788 }
789 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
790
791 return ret;
792}
793
794static int process_event(struct iwcm_id_private *cm_id_priv,
795 struct iw_cm_event *iw_event)
796{
797 int ret = 0;
798
799 switch (iw_event->event) {
800 case IW_CM_EVENT_CONNECT_REQUEST:
801 cm_conn_req_handler(cm_id_priv, iw_event);
802 break;
803 case IW_CM_EVENT_CONNECT_REPLY:
804 ret = cm_conn_rep_handler(cm_id_priv, iw_event);
805 break;
806 case IW_CM_EVENT_ESTABLISHED:
807 ret = cm_conn_est_handler(cm_id_priv, iw_event);
808 break;
809 case IW_CM_EVENT_DISCONNECT:
810 cm_disconnect_handler(cm_id_priv, iw_event);
811 break;
812 case IW_CM_EVENT_CLOSE:
813 ret = cm_close_handler(cm_id_priv, iw_event);
814 break;
815 default:
816 BUG();
817 }
818
819 return ret;
820}
821
822/*
823 * Process events on the work_list for the cm_id. If the callback
824 * function requests that the cm_id be deleted, a flag is set in the
825 * cm_id flags to indicate that when the last reference is
826 * removed, the cm_id is to be destroyed. This is necessary to
827 * distinguish between an object that will be destroyed by the app
828 * thread asleep on the destroy_comp list vs. an object destroyed
829 * here synchronously when the last reference is removed.
830 */
831static void cm_work_handler(void *arg)
832{
833 struct iwcm_work *work = arg, lwork;
834 struct iwcm_id_private *cm_id_priv = work->cm_id;
835 unsigned long flags;
836 int empty;
837 int ret = 0;
838
839 spin_lock_irqsave(&cm_id_priv->lock, flags);
840 empty = list_empty(&cm_id_priv->work_list);
841 while (!empty) {
842 work = list_entry(cm_id_priv->work_list.next,
843 struct iwcm_work, list);
844 list_del_init(&work->list);
845 empty = list_empty(&cm_id_priv->work_list);
846 lwork = *work;
847 put_work(work);
848 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
849
850 ret = process_event(cm_id_priv, &work->event);
851 if (ret) {
852 set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
853 destroy_cm_id(&cm_id_priv->id);
854 }
855 BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
856 if (iwcm_deref_id(cm_id_priv))
857 return;
858
859 if (atomic_read(&cm_id_priv->refcount)==0 &&
860 test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
861 dealloc_work_entries(cm_id_priv);
862 kfree(cm_id_priv);
863 return;
864 }
865 spin_lock_irqsave(&cm_id_priv->lock, flags);
866 }
867 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
868}
869
870/*
871 * This function is called on interrupt context. Schedule events on
872 * the iwcm_wq thread to allow callback functions to downcall into
873 * the CM and/or block. Events are queued to a per-CM_ID
874 * work_list. If this is the first event on the work_list, the work
875 * element is also queued on the iwcm_wq thread.
876 *
877 * Each event holds a reference on the cm_id. Until the last posted
878 * event has been delivered and processed, the cm_id cannot be
879 * deleted.
880 *
881 * Returns:
882 * 0 - the event was handled.
883 * -ENOMEM - the event was not handled due to lack of resources.
884 */
885static int cm_event_handler(struct iw_cm_id *cm_id,
886 struct iw_cm_event *iw_event)
887{
888 struct iwcm_work *work;
889 struct iwcm_id_private *cm_id_priv;
890 unsigned long flags;
891 int ret = 0;
892
893 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
894
895 spin_lock_irqsave(&cm_id_priv->lock, flags);
896 work = get_work(cm_id_priv);
897 if (!work) {
898 ret = -ENOMEM;
899 goto out;
900 }
901
902 INIT_WORK(&work->work, cm_work_handler, work);
903 work->cm_id = cm_id_priv;
904 work->event = *iw_event;
905
906 if ((work->event.event == IW_CM_EVENT_CONNECT_REQUEST ||
907 work->event.event == IW_CM_EVENT_CONNECT_REPLY) &&
908 work->event.private_data_len) {
909 ret = copy_private_data(cm_id_priv, &work->event);
910 if (ret) {
911 put_work(work);
912 goto out;
913 }
914 }
915
916 atomic_inc(&cm_id_priv->refcount);
917 if (list_empty(&cm_id_priv->work_list)) {
918 list_add_tail(&work->list, &cm_id_priv->work_list);
919 queue_work(iwcm_wq, &work->work);
920 } else
921 list_add_tail(&work->list, &cm_id_priv->work_list);
922out:
923 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
924 return ret;
925}
926
927static int iwcm_init_qp_init_attr(struct iwcm_id_private *cm_id_priv,
928 struct ib_qp_attr *qp_attr,
929 int *qp_attr_mask)
930{
931 unsigned long flags;
932 int ret;
933
934 spin_lock_irqsave(&cm_id_priv->lock, flags);
935 switch (cm_id_priv->state) {
936 case IW_CM_STATE_IDLE:
937 case IW_CM_STATE_CONN_SENT:
938 case IW_CM_STATE_CONN_RECV:
939 case IW_CM_STATE_ESTABLISHED:
940 *qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS;
941 qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE |
942 IB_ACCESS_REMOTE_WRITE|
943 IB_ACCESS_REMOTE_READ;
944 ret = 0;
945 break;
946 default:
947 ret = -EINVAL;
948 break;
949 }
950 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
951 return ret;
952}
953
954static int iwcm_init_qp_rts_attr(struct iwcm_id_private *cm_id_priv,
955 struct ib_qp_attr *qp_attr,
956 int *qp_attr_mask)
957{
958 unsigned long flags;
959 int ret;
960
961 spin_lock_irqsave(&cm_id_priv->lock, flags);
962 switch (cm_id_priv->state) {
963 case IW_CM_STATE_IDLE:
964 case IW_CM_STATE_CONN_SENT:
965 case IW_CM_STATE_CONN_RECV:
966 case IW_CM_STATE_ESTABLISHED:
967 *qp_attr_mask = 0;
968 ret = 0;
969 break;
970 default:
971 ret = -EINVAL;
972 break;
973 }
974 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
975 return ret;
976}
977
978int iw_cm_init_qp_attr(struct iw_cm_id *cm_id,
979 struct ib_qp_attr *qp_attr,
980 int *qp_attr_mask)
981{
982 struct iwcm_id_private *cm_id_priv;
983 int ret;
984
985 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
986 switch (qp_attr->qp_state) {
987 case IB_QPS_INIT:
988 case IB_QPS_RTR:
989 ret = iwcm_init_qp_init_attr(cm_id_priv,
990 qp_attr, qp_attr_mask);
991 break;
992 case IB_QPS_RTS:
993 ret = iwcm_init_qp_rts_attr(cm_id_priv,
994 qp_attr, qp_attr_mask);
995 break;
996 default:
997 ret = -EINVAL;
998 break;
999 }
1000 return ret;
1001}
1002EXPORT_SYMBOL(iw_cm_init_qp_attr);
1003
1004static int __init iw_cm_init(void)
1005{
1006 iwcm_wq = create_singlethread_workqueue("iw_cm_wq");
1007 if (!iwcm_wq)
1008 return -ENOMEM;
1009
1010 return 0;
1011}
1012
1013static void __exit iw_cm_cleanup(void)
1014{
1015 destroy_workqueue(iwcm_wq);
1016}
1017
1018module_init(iw_cm_init);
1019module_exit(iw_cm_cleanup);
diff --git a/drivers/infiniband/core/iwcm.h b/drivers/infiniband/core/iwcm.h
new file mode 100644
index 000000000000..3f6cc82564c8
--- /dev/null
+++ b/drivers/infiniband/core/iwcm.h
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 2005 Network Appliance, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#ifndef IWCM_H
34#define IWCM_H
35
36enum iw_cm_state {
37 IW_CM_STATE_IDLE, /* unbound, inactive */
38 IW_CM_STATE_LISTEN, /* listen waiting for connect */
39 IW_CM_STATE_CONN_RECV, /* inbound waiting for user accept */
40 IW_CM_STATE_CONN_SENT, /* outbound waiting for peer accept */
41 IW_CM_STATE_ESTABLISHED, /* established */
42 IW_CM_STATE_CLOSING, /* disconnect */
43 IW_CM_STATE_DESTROYING /* object being deleted */
44};
45
46struct iwcm_id_private {
47 struct iw_cm_id id;
48 enum iw_cm_state state;
49 unsigned long flags;
50 struct ib_qp *qp;
51 struct completion destroy_comp;
52 wait_queue_head_t connect_wait;
53 struct list_head work_list;
54 spinlock_t lock;
55 atomic_t refcount;
56 struct list_head work_free_list;
57};
58
59#define IWCM_F_CALLBACK_DESTROY 1
60#define IWCM_F_CONNECT_WAIT 2
61
62#endif /* IWCM_H */
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 1c3cfbbe6a97..082f03c158f0 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1246,8 +1246,8 @@ static int find_vendor_oui(struct ib_mad_mgmt_vendor_class *vendor_class,
1246 int i; 1246 int i;
1247 1247
1248 for (i = 0; i < MAX_MGMT_OUI; i++) 1248 for (i = 0; i < MAX_MGMT_OUI; i++)
1249 /* Is there matching OUI for this vendor class ? */ 1249 /* Is there matching OUI for this vendor class ? */
1250 if (!memcmp(vendor_class->oui[i], oui, 3)) 1250 if (!memcmp(vendor_class->oui[i], oui, 3))
1251 return i; 1251 return i;
1252 1252
1253 return -1; 1253 return -1;
@@ -2237,7 +2237,7 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv)
2237 list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr, 2237 list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr,
2238 &mad_agent_priv->send_list, agent_list) { 2238 &mad_agent_priv->send_list, agent_list) {
2239 if (mad_send_wr->status == IB_WC_SUCCESS) { 2239 if (mad_send_wr->status == IB_WC_SUCCESS) {
2240 mad_send_wr->status = IB_WC_WR_FLUSH_ERR; 2240 mad_send_wr->status = IB_WC_WR_FLUSH_ERR;
2241 mad_send_wr->refcount -= (mad_send_wr->timeout > 0); 2241 mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
2242 } 2242 }
2243 } 2243 }
@@ -2528,10 +2528,10 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
2528 } 2528 }
2529 } 2529 }
2530 sg_list.addr = dma_map_single(qp_info->port_priv-> 2530 sg_list.addr = dma_map_single(qp_info->port_priv->
2531 device->dma_device, 2531 device->dma_device,
2532 &mad_priv->grh, 2532 &mad_priv->grh,
2533 sizeof *mad_priv - 2533 sizeof *mad_priv -
2534 sizeof mad_priv->header, 2534 sizeof mad_priv->header,
2535 DMA_FROM_DEVICE); 2535 DMA_FROM_DEVICE);
2536 pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr); 2536 pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr);
2537 recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list; 2537 recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list;
@@ -2606,7 +2606,7 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv)
2606 struct ib_qp *qp; 2606 struct ib_qp *qp;
2607 2607
2608 attr = kmalloc(sizeof *attr, GFP_KERNEL); 2608 attr = kmalloc(sizeof *attr, GFP_KERNEL);
2609 if (!attr) { 2609 if (!attr) {
2610 printk(KERN_ERR PFX "Couldn't kmalloc ib_qp_attr\n"); 2610 printk(KERN_ERR PFX "Couldn't kmalloc ib_qp_attr\n");
2611 return -ENOMEM; 2611 return -ENOMEM;
2612 } 2612 }
@@ -2876,7 +2876,10 @@ static void ib_mad_init_device(struct ib_device *device)
2876{ 2876{
2877 int start, end, i; 2877 int start, end, i;
2878 2878
2879 if (device->node_type == IB_NODE_SWITCH) { 2879 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
2880 return;
2881
2882 if (device->node_type == RDMA_NODE_IB_SWITCH) {
2880 start = 0; 2883 start = 0;
2881 end = 0; 2884 end = 0;
2882 } else { 2885 } else {
@@ -2923,7 +2926,7 @@ static void ib_mad_remove_device(struct ib_device *device)
2923{ 2926{
2924 int i, num_ports, cur_port; 2927 int i, num_ports, cur_port;
2925 2928
2926 if (device->node_type == IB_NODE_SWITCH) { 2929 if (device->node_type == RDMA_NODE_IB_SWITCH) {
2927 num_ports = 1; 2930 num_ports = 1;
2928 cur_port = 0; 2931 cur_port = 0;
2929 } else { 2932 } else {
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
index d147f3bad2ce..1da9adbccaec 100644
--- a/drivers/infiniband/core/mad_priv.h
+++ b/drivers/infiniband/core/mad_priv.h
@@ -39,7 +39,6 @@
39 39
40#include <linux/completion.h> 40#include <linux/completion.h>
41#include <linux/pci.h> 41#include <linux/pci.h>
42#include <linux/kthread.h>
43#include <linux/workqueue.h> 42#include <linux/workqueue.h>
44#include <rdma/ib_mad.h> 43#include <rdma/ib_mad.h>
45#include <rdma/ib_smi.h> 44#include <rdma/ib_smi.h>
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index ebcd5b181770..1ef79d015a1e 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -33,8 +33,6 @@
33 * $Id: mad_rmpp.c 1921 2005-03-02 22:58:44Z sean.hefty $ 33 * $Id: mad_rmpp.c 1921 2005-03-02 22:58:44Z sean.hefty $
34 */ 34 */
35 35
36#include <linux/dma-mapping.h>
37
38#include "mad_priv.h" 36#include "mad_priv.h"
39#include "mad_rmpp.h" 37#include "mad_rmpp.h"
40 38
@@ -60,6 +58,7 @@ struct mad_rmpp_recv {
60 int last_ack; 58 int last_ack;
61 int seg_num; 59 int seg_num;
62 int newwin; 60 int newwin;
61 int repwin;
63 62
64 __be64 tid; 63 __be64 tid;
65 u32 src_qp; 64 u32 src_qp;
@@ -170,6 +169,32 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
170 return msg; 169 return msg;
171} 170}
172 171
172static void ack_ds_ack(struct ib_mad_agent_private *agent,
173 struct ib_mad_recv_wc *recv_wc)
174{
175 struct ib_mad_send_buf *msg;
176 struct ib_rmpp_mad *rmpp_mad;
177 int ret;
178
179 msg = alloc_response_msg(&agent->agent, recv_wc);
180 if (IS_ERR(msg))
181 return;
182
183 rmpp_mad = msg->mad;
184 memcpy(rmpp_mad, recv_wc->recv_buf.mad, msg->hdr_len);
185
186 rmpp_mad->mad_hdr.method ^= IB_MGMT_METHOD_RESP;
187 ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
188 rmpp_mad->rmpp_hdr.seg_num = 0;
189 rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(1);
190
191 ret = ib_post_send_mad(msg, NULL);
192 if (ret) {
193 ib_destroy_ah(msg->ah);
194 ib_free_send_mad(msg);
195 }
196}
197
173void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc) 198void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc)
174{ 199{
175 struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad; 200 struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad;
@@ -271,6 +296,7 @@ create_rmpp_recv(struct ib_mad_agent_private *agent,
271 rmpp_recv->newwin = 1; 296 rmpp_recv->newwin = 1;
272 rmpp_recv->seg_num = 1; 297 rmpp_recv->seg_num = 1;
273 rmpp_recv->last_ack = 0; 298 rmpp_recv->last_ack = 0;
299 rmpp_recv->repwin = 1;
274 300
275 mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr; 301 mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
276 rmpp_recv->tid = mad_hdr->tid; 302 rmpp_recv->tid = mad_hdr->tid;
@@ -365,7 +391,7 @@ static inline int window_size(struct ib_mad_agent_private *agent)
365static struct ib_mad_recv_buf * find_seg_location(struct list_head *rmpp_list, 391static struct ib_mad_recv_buf * find_seg_location(struct list_head *rmpp_list,
366 int seg_num) 392 int seg_num)
367{ 393{
368 struct ib_mad_recv_buf *seg_buf; 394 struct ib_mad_recv_buf *seg_buf;
369 int cur_seg_num; 395 int cur_seg_num;
370 396
371 list_for_each_entry_reverse(seg_buf, rmpp_list, list) { 397 list_for_each_entry_reverse(seg_buf, rmpp_list, list) {
@@ -591,6 +617,16 @@ static inline void adjust_last_ack(struct ib_mad_send_wr_private *wr,
591 break; 617 break;
592} 618}
593 619
620static void process_ds_ack(struct ib_mad_agent_private *agent,
621 struct ib_mad_recv_wc *mad_recv_wc, int newwin)
622{
623 struct mad_rmpp_recv *rmpp_recv;
624
625 rmpp_recv = find_rmpp_recv(agent, mad_recv_wc);
626 if (rmpp_recv && rmpp_recv->state == RMPP_STATE_COMPLETE)
627 rmpp_recv->repwin = newwin;
628}
629
594static void process_rmpp_ack(struct ib_mad_agent_private *agent, 630static void process_rmpp_ack(struct ib_mad_agent_private *agent,
595 struct ib_mad_recv_wc *mad_recv_wc) 631 struct ib_mad_recv_wc *mad_recv_wc)
596{ 632{
@@ -616,8 +652,18 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
616 652
617 spin_lock_irqsave(&agent->lock, flags); 653 spin_lock_irqsave(&agent->lock, flags);
618 mad_send_wr = ib_find_send_mad(agent, mad_recv_wc); 654 mad_send_wr = ib_find_send_mad(agent, mad_recv_wc);
619 if (!mad_send_wr) 655 if (!mad_send_wr) {
620 goto out; /* Unmatched ACK */ 656 if (!seg_num)
657 process_ds_ack(agent, mad_recv_wc, newwin);
658 goto out; /* Unmatched or DS RMPP ACK */
659 }
660
661 if ((mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) &&
662 (mad_send_wr->timeout)) {
663 spin_unlock_irqrestore(&agent->lock, flags);
664 ack_ds_ack(agent, mad_recv_wc);
665 return; /* Repeated ACK for DS RMPP transaction */
666 }
621 667
622 if ((mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) || 668 if ((mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) ||
623 (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) 669 (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS))
@@ -656,6 +702,9 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
656 if (mad_send_wr->refcount == 1) 702 if (mad_send_wr->refcount == 1)
657 ib_reset_mad_timeout(mad_send_wr, 703 ib_reset_mad_timeout(mad_send_wr,
658 mad_send_wr->send_buf.timeout_ms); 704 mad_send_wr->send_buf.timeout_ms);
705 spin_unlock_irqrestore(&agent->lock, flags);
706 ack_ds_ack(agent, mad_recv_wc);
707 return;
659 } else if (mad_send_wr->refcount == 1 && 708 } else if (mad_send_wr->refcount == 1 &&
660 mad_send_wr->seg_num < mad_send_wr->newwin && 709 mad_send_wr->seg_num < mad_send_wr->newwin &&
661 mad_send_wr->seg_num < mad_send_wr->send_buf.seg_count) { 710 mad_send_wr->seg_num < mad_send_wr->send_buf.seg_count) {
@@ -772,6 +821,39 @@ out:
772 return NULL; 821 return NULL;
773} 822}
774 823
824static int init_newwin(struct ib_mad_send_wr_private *mad_send_wr)
825{
826 struct ib_mad_agent_private *agent = mad_send_wr->mad_agent_priv;
827 struct ib_mad_hdr *mad_hdr = mad_send_wr->send_buf.mad;
828 struct mad_rmpp_recv *rmpp_recv;
829 struct ib_ah_attr ah_attr;
830 unsigned long flags;
831 int newwin = 1;
832
833 if (!(mad_hdr->method & IB_MGMT_METHOD_RESP))
834 goto out;
835
836 spin_lock_irqsave(&agent->lock, flags);
837 list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {
838 if (rmpp_recv->tid != mad_hdr->tid ||
839 rmpp_recv->mgmt_class != mad_hdr->mgmt_class ||
840 rmpp_recv->class_version != mad_hdr->class_version ||
841 (rmpp_recv->method & IB_MGMT_METHOD_RESP))
842 continue;
843
844 if (ib_query_ah(mad_send_wr->send_buf.ah, &ah_attr))
845 continue;
846
847 if (rmpp_recv->slid == ah_attr.dlid) {
848 newwin = rmpp_recv->repwin;
849 break;
850 }
851 }
852 spin_unlock_irqrestore(&agent->lock, flags);
853out:
854 return newwin;
855}
856
775int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr) 857int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr)
776{ 858{
777 struct ib_rmpp_mad *rmpp_mad; 859 struct ib_rmpp_mad *rmpp_mad;
@@ -787,7 +869,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr)
787 return IB_RMPP_RESULT_INTERNAL; 869 return IB_RMPP_RESULT_INTERNAL;
788 } 870 }
789 871
790 mad_send_wr->newwin = 1; 872 mad_send_wr->newwin = init_newwin(mad_send_wr);
791 873
792 /* We need to wait for the final ACK even if there isn't a response */ 874 /* We need to wait for the final ACK even if there isn't a response */
793 mad_send_wr->refcount += (mad_send_wr->timeout == 0); 875 mad_send_wr->refcount += (mad_send_wr->timeout == 0);
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index d6b84226bba7..1706d3c7e95e 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc.  All rights reserved. 3 * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
4 * Copyright (c) 2006 Intel Corporation. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -75,6 +76,7 @@ struct ib_sa_device {
75struct ib_sa_query { 76struct ib_sa_query {
76 void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *); 77 void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
77 void (*release)(struct ib_sa_query *); 78 void (*release)(struct ib_sa_query *);
79 struct ib_sa_client *client;
78 struct ib_sa_port *port; 80 struct ib_sa_port *port;
79 struct ib_mad_send_buf *mad_buf; 81 struct ib_mad_send_buf *mad_buf;
80 struct ib_sa_sm_ah *sm_ah; 82 struct ib_sa_sm_ah *sm_ah;
@@ -415,6 +417,31 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event
415 } 417 }
416} 418}
417 419
420void ib_sa_register_client(struct ib_sa_client *client)
421{
422 atomic_set(&client->users, 1);
423 init_completion(&client->comp);
424}
425EXPORT_SYMBOL(ib_sa_register_client);
426
427static inline void ib_sa_client_get(struct ib_sa_client *client)
428{
429 atomic_inc(&client->users);
430}
431
432static inline void ib_sa_client_put(struct ib_sa_client *client)
433{
434 if (atomic_dec_and_test(&client->users))
435 complete(&client->comp);
436}
437
438void ib_sa_unregister_client(struct ib_sa_client *client)
439{
440 ib_sa_client_put(client);
441 wait_for_completion(&client->comp);
442}
443EXPORT_SYMBOL(ib_sa_unregister_client);
444
418/** 445/**
419 * ib_sa_cancel_query - try to cancel an SA query 446 * ib_sa_cancel_query - try to cancel an SA query
420 * @id:ID of query to cancel 447 * @id:ID of query to cancel
@@ -557,6 +584,7 @@ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
557 584
558/** 585/**
559 * ib_sa_path_rec_get - Start a Path get query 586 * ib_sa_path_rec_get - Start a Path get query
587 * @client:SA client
560 * @device:device to send query on 588 * @device:device to send query on
561 * @port_num: port number to send query on 589 * @port_num: port number to send query on
562 * @rec:Path Record to send in query 590 * @rec:Path Record to send in query
@@ -579,7 +607,8 @@ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
579 * error code. Otherwise it is a query ID that can be used to cancel 607 * error code. Otherwise it is a query ID that can be used to cancel
580 * the query. 608 * the query.
581 */ 609 */
582int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, 610int ib_sa_path_rec_get(struct ib_sa_client *client,
611 struct ib_device *device, u8 port_num,
583 struct ib_sa_path_rec *rec, 612 struct ib_sa_path_rec *rec,
584 ib_sa_comp_mask comp_mask, 613 ib_sa_comp_mask comp_mask,
585 int timeout_ms, gfp_t gfp_mask, 614 int timeout_ms, gfp_t gfp_mask,
@@ -614,8 +643,10 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
614 goto err1; 643 goto err1;
615 } 644 }
616 645
617 query->callback = callback; 646 ib_sa_client_get(client);
618 query->context = context; 647 query->sa_query.client = client;
648 query->callback = callback;
649 query->context = context;
619 650
620 mad = query->sa_query.mad_buf->mad; 651 mad = query->sa_query.mad_buf->mad;
621 init_mad(mad, agent); 652 init_mad(mad, agent);
@@ -639,6 +670,7 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
639 670
640err2: 671err2:
641 *sa_query = NULL; 672 *sa_query = NULL;
673 ib_sa_client_put(query->sa_query.client);
642 ib_free_send_mad(query->sa_query.mad_buf); 674 ib_free_send_mad(query->sa_query.mad_buf);
643 675
644err1: 676err1:
@@ -671,6 +703,7 @@ static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
671 703
672/** 704/**
673 * ib_sa_service_rec_query - Start Service Record operation 705 * ib_sa_service_rec_query - Start Service Record operation
706 * @client:SA client
674 * @device:device to send request on 707 * @device:device to send request on
675 * @port_num: port number to send request on 708 * @port_num: port number to send request on
676 * @method:SA method - should be get, set, or delete 709 * @method:SA method - should be get, set, or delete
@@ -695,7 +728,8 @@ static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
695 * error code. Otherwise it is a request ID that can be used to cancel 728 * error code. Otherwise it is a request ID that can be used to cancel
696 * the query. 729 * the query.
697 */ 730 */
698int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method, 731int ib_sa_service_rec_query(struct ib_sa_client *client,
732 struct ib_device *device, u8 port_num, u8 method,
699 struct ib_sa_service_rec *rec, 733 struct ib_sa_service_rec *rec,
700 ib_sa_comp_mask comp_mask, 734 ib_sa_comp_mask comp_mask,
701 int timeout_ms, gfp_t gfp_mask, 735 int timeout_ms, gfp_t gfp_mask,
@@ -735,8 +769,10 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
735 goto err1; 769 goto err1;
736 } 770 }
737 771
738 query->callback = callback; 772 ib_sa_client_get(client);
739 query->context = context; 773 query->sa_query.client = client;
774 query->callback = callback;
775 query->context = context;
740 776
741 mad = query->sa_query.mad_buf->mad; 777 mad = query->sa_query.mad_buf->mad;
742 init_mad(mad, agent); 778 init_mad(mad, agent);
@@ -761,6 +797,7 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
761 797
762err2: 798err2:
763 *sa_query = NULL; 799 *sa_query = NULL;
800 ib_sa_client_put(query->sa_query.client);
764 ib_free_send_mad(query->sa_query.mad_buf); 801 ib_free_send_mad(query->sa_query.mad_buf);
765 802
766err1: 803err1:
@@ -791,7 +828,8 @@ static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
791 kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query)); 828 kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
792} 829}
793 830
794int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, 831int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
832 struct ib_device *device, u8 port_num,
795 u8 method, 833 u8 method,
796 struct ib_sa_mcmember_rec *rec, 834 struct ib_sa_mcmember_rec *rec,
797 ib_sa_comp_mask comp_mask, 835 ib_sa_comp_mask comp_mask,
@@ -827,8 +865,10 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
827 goto err1; 865 goto err1;
828 } 866 }
829 867
830 query->callback = callback; 868 ib_sa_client_get(client);
831 query->context = context; 869 query->sa_query.client = client;
870 query->callback = callback;
871 query->context = context;
832 872
833 mad = query->sa_query.mad_buf->mad; 873 mad = query->sa_query.mad_buf->mad;
834 init_mad(mad, agent); 874 init_mad(mad, agent);
@@ -853,6 +893,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
853 893
854err2: 894err2:
855 *sa_query = NULL; 895 *sa_query = NULL;
896 ib_sa_client_put(query->sa_query.client);
856 ib_free_send_mad(query->sa_query.mad_buf); 897 ib_free_send_mad(query->sa_query.mad_buf);
857 898
858err1: 899err1:
@@ -887,8 +928,9 @@ static void send_handler(struct ib_mad_agent *agent,
887 idr_remove(&query_idr, query->id); 928 idr_remove(&query_idr, query->id);
888 spin_unlock_irqrestore(&idr_lock, flags); 929 spin_unlock_irqrestore(&idr_lock, flags);
889 930
890 ib_free_send_mad(mad_send_wc->send_buf); 931 ib_free_send_mad(mad_send_wc->send_buf);
891 kref_put(&query->sm_ah->ref, free_sm_ah); 932 kref_put(&query->sm_ah->ref, free_sm_ah);
933 ib_sa_client_put(query->client);
892 query->release(query); 934 query->release(query);
893} 935}
894 936
@@ -919,7 +961,10 @@ static void ib_sa_add_one(struct ib_device *device)
919 struct ib_sa_device *sa_dev; 961 struct ib_sa_device *sa_dev;
920 int s, e, i; 962 int s, e, i;
921 963
922 if (device->node_type == IB_NODE_SWITCH) 964 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
965 return;
966
967 if (device->node_type == RDMA_NODE_IB_SWITCH)
923 s = e = 0; 968 s = e = 0;
924 else { 969 else {
925 s = 1; 970 s = 1;
diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c
index 35852e794e26..54b81e17ad50 100644
--- a/drivers/infiniband/core/smi.c
+++ b/drivers/infiniband/core/smi.c
@@ -64,7 +64,7 @@ int smi_handle_dr_smp_send(struct ib_smp *smp,
64 64
65 /* C14-9:2 */ 65 /* C14-9:2 */
66 if (hop_ptr && hop_ptr < hop_cnt) { 66 if (hop_ptr && hop_ptr < hop_cnt) {
67 if (node_type != IB_NODE_SWITCH) 67 if (node_type != RDMA_NODE_IB_SWITCH)
68 return 0; 68 return 0;
69 69
70 /* smp->return_path set when received */ 70 /* smp->return_path set when received */
@@ -77,7 +77,7 @@ int smi_handle_dr_smp_send(struct ib_smp *smp,
77 if (hop_ptr == hop_cnt) { 77 if (hop_ptr == hop_cnt) {
78 /* smp->return_path set when received */ 78 /* smp->return_path set when received */
79 smp->hop_ptr++; 79 smp->hop_ptr++;
80 return (node_type == IB_NODE_SWITCH || 80 return (node_type == RDMA_NODE_IB_SWITCH ||
81 smp->dr_dlid == IB_LID_PERMISSIVE); 81 smp->dr_dlid == IB_LID_PERMISSIVE);
82 } 82 }
83 83
@@ -95,7 +95,7 @@ int smi_handle_dr_smp_send(struct ib_smp *smp,
95 95
96 /* C14-13:2 */ 96 /* C14-13:2 */
97 if (2 <= hop_ptr && hop_ptr <= hop_cnt) { 97 if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
98 if (node_type != IB_NODE_SWITCH) 98 if (node_type != RDMA_NODE_IB_SWITCH)
99 return 0; 99 return 0;
100 100
101 smp->hop_ptr--; 101 smp->hop_ptr--;
@@ -107,7 +107,7 @@ int smi_handle_dr_smp_send(struct ib_smp *smp,
107 if (hop_ptr == 1) { 107 if (hop_ptr == 1) {
108 smp->hop_ptr--; 108 smp->hop_ptr--;
109 /* C14-13:3 -- SMPs destined for SM shouldn't be here */ 109 /* C14-13:3 -- SMPs destined for SM shouldn't be here */
110 return (node_type == IB_NODE_SWITCH || 110 return (node_type == RDMA_NODE_IB_SWITCH ||
111 smp->dr_slid == IB_LID_PERMISSIVE); 111 smp->dr_slid == IB_LID_PERMISSIVE);
112 } 112 }
113 113
@@ -142,7 +142,7 @@ int smi_handle_dr_smp_recv(struct ib_smp *smp,
142 142
143 /* C14-9:2 -- intermediate hop */ 143 /* C14-9:2 -- intermediate hop */
144 if (hop_ptr && hop_ptr < hop_cnt) { 144 if (hop_ptr && hop_ptr < hop_cnt) {
145 if (node_type != IB_NODE_SWITCH) 145 if (node_type != RDMA_NODE_IB_SWITCH)
146 return 0; 146 return 0;
147 147
148 smp->return_path[hop_ptr] = port_num; 148 smp->return_path[hop_ptr] = port_num;
@@ -156,7 +156,7 @@ int smi_handle_dr_smp_recv(struct ib_smp *smp,
156 smp->return_path[hop_ptr] = port_num; 156 smp->return_path[hop_ptr] = port_num;
157 /* smp->hop_ptr updated when sending */ 157 /* smp->hop_ptr updated when sending */
158 158
159 return (node_type == IB_NODE_SWITCH || 159 return (node_type == RDMA_NODE_IB_SWITCH ||
160 smp->dr_dlid == IB_LID_PERMISSIVE); 160 smp->dr_dlid == IB_LID_PERMISSIVE);
161 } 161 }
162 162
@@ -175,7 +175,7 @@ int smi_handle_dr_smp_recv(struct ib_smp *smp,
175 175
176 /* C14-13:2 */ 176 /* C14-13:2 */
177 if (2 <= hop_ptr && hop_ptr <= hop_cnt) { 177 if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
178 if (node_type != IB_NODE_SWITCH) 178 if (node_type != RDMA_NODE_IB_SWITCH)
179 return 0; 179 return 0;
180 180
181 /* smp->hop_ptr updated when sending */ 181 /* smp->hop_ptr updated when sending */
@@ -190,7 +190,7 @@ int smi_handle_dr_smp_recv(struct ib_smp *smp,
190 return 1; 190 return 1;
191 } 191 }
192 /* smp->hop_ptr updated when sending */ 192 /* smp->hop_ptr updated when sending */
193 return (node_type == IB_NODE_SWITCH); 193 return (node_type == RDMA_NODE_IB_SWITCH);
194 } 194 }
195 195
196 /* C14-13:4 -- hop_ptr = 0 -> give to SM */ 196 /* C14-13:4 -- hop_ptr = 0 -> give to SM */
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 21f9282c1b25..709323c14c5d 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -68,7 +68,7 @@ struct port_table_attribute {
68 int index; 68 int index;
69}; 69};
70 70
71static inline int ibdev_is_alive(const struct ib_device *dev) 71static inline int ibdev_is_alive(const struct ib_device *dev)
72{ 72{
73 return dev->reg_state == IB_DEV_REGISTERED; 73 return dev->reg_state == IB_DEV_REGISTERED;
74} 74}
@@ -589,10 +589,11 @@ static ssize_t show_node_type(struct class_device *cdev, char *buf)
589 return -ENODEV; 589 return -ENODEV;
590 590
591 switch (dev->node_type) { 591 switch (dev->node_type) {
592 case IB_NODE_CA: return sprintf(buf, "%d: CA\n", dev->node_type); 592 case RDMA_NODE_IB_CA: return sprintf(buf, "%d: CA\n", dev->node_type);
593 case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type); 593 case RDMA_NODE_RNIC: return sprintf(buf, "%d: RNIC\n", dev->node_type);
594 case IB_NODE_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type); 594 case RDMA_NODE_IB_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
595 default: return sprintf(buf, "%d: <unknown>\n", dev->node_type); 595 case RDMA_NODE_IB_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
596 default: return sprintf(buf, "%d: <unknown>\n", dev->node_type);
596 } 597 }
597} 598}
598 599
@@ -708,7 +709,7 @@ int ib_device_register_sysfs(struct ib_device *device)
708 if (ret) 709 if (ret)
709 goto err_put; 710 goto err_put;
710 711
711 if (device->node_type == IB_NODE_SWITCH) { 712 if (device->node_type == RDMA_NODE_IB_SWITCH) {
712 ret = add_port(device, 0); 713 ret = add_port(device, 0);
713 if (ret) 714 if (ret)
714 goto err_put; 715 goto err_put;
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index c1c6fda9452c..ad4f4d5c2924 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -309,9 +309,9 @@ static int ib_ucm_event_process(struct ib_cm_event *evt,
309 info = evt->param.apr_rcvd.apr_info; 309 info = evt->param.apr_rcvd.apr_info;
310 break; 310 break;
311 case IB_CM_SIDR_REQ_RECEIVED: 311 case IB_CM_SIDR_REQ_RECEIVED:
312 uvt->resp.u.sidr_req_resp.pkey = 312 uvt->resp.u.sidr_req_resp.pkey =
313 evt->param.sidr_req_rcvd.pkey; 313 evt->param.sidr_req_rcvd.pkey;
314 uvt->resp.u.sidr_req_resp.port = 314 uvt->resp.u.sidr_req_resp.port =
315 evt->param.sidr_req_rcvd.port; 315 evt->param.sidr_req_rcvd.port;
316 uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE; 316 uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE;
317 break; 317 break;
@@ -1237,7 +1237,7 @@ static struct class ucm_class = {
1237static ssize_t show_ibdev(struct class_device *class_dev, char *buf) 1237static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
1238{ 1238{
1239 struct ib_ucm_device *dev; 1239 struct ib_ucm_device *dev;
1240 1240
1241 dev = container_of(class_dev, struct ib_ucm_device, class_dev); 1241 dev = container_of(class_dev, struct ib_ucm_device, class_dev);
1242 return sprintf(buf, "%s\n", dev->ib_dev->name); 1242 return sprintf(buf, "%s\n", dev->ib_dev->name);
1243} 1243}
@@ -1247,7 +1247,8 @@ static void ib_ucm_add_one(struct ib_device *device)
1247{ 1247{
1248 struct ib_ucm_device *ucm_dev; 1248 struct ib_ucm_device *ucm_dev;
1249 1249
1250 if (!device->alloc_ucontext) 1250 if (!device->alloc_ucontext ||
1251 rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
1251 return; 1252 return;
1252 1253
1253 ucm_dev = kzalloc(sizeof *ucm_dev, GFP_KERNEL); 1254 ucm_dev = kzalloc(sizeof *ucm_dev, GFP_KERNEL);
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 1273f8807e84..807fbd6b8414 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5 * 5 *
6 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
@@ -1032,7 +1032,10 @@ static void ib_umad_add_one(struct ib_device *device)
1032 struct ib_umad_device *umad_dev; 1032 struct ib_umad_device *umad_dev;
1033 int s, e, i; 1033 int s, e, i;
1034 1034
1035 if (device->node_type == IB_NODE_SWITCH) 1035 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
1036 return;
1037
1038 if (device->node_type == RDMA_NODE_IB_SWITCH)
1036 s = e = 0; 1039 s = e = 0;
1037 else { 1040 else {
1038 s = 1; 1041 s = 1;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 30923eb68ec7..b72c7f69ca90 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -155,7 +155,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
155} 155}
156 156
157static struct ib_uobject *idr_read_uobj(struct idr *idr, int id, 157static struct ib_uobject *idr_read_uobj(struct idr *idr, int id,
158 struct ib_ucontext *context) 158 struct ib_ucontext *context, int nested)
159{ 159{
160 struct ib_uobject *uobj; 160 struct ib_uobject *uobj;
161 161
@@ -163,7 +163,10 @@ static struct ib_uobject *idr_read_uobj(struct idr *idr, int id,
163 if (!uobj) 163 if (!uobj)
164 return NULL; 164 return NULL;
165 165
166 down_read(&uobj->mutex); 166 if (nested)
167 down_read_nested(&uobj->mutex, SINGLE_DEPTH_NESTING);
168 else
169 down_read(&uobj->mutex);
167 if (!uobj->live) { 170 if (!uobj->live) {
168 put_uobj_read(uobj); 171 put_uobj_read(uobj);
169 return NULL; 172 return NULL;
@@ -190,17 +193,18 @@ static struct ib_uobject *idr_write_uobj(struct idr *idr, int id,
190 return uobj; 193 return uobj;
191} 194}
192 195
193static void *idr_read_obj(struct idr *idr, int id, struct ib_ucontext *context) 196static void *idr_read_obj(struct idr *idr, int id, struct ib_ucontext *context,
197 int nested)
194{ 198{
195 struct ib_uobject *uobj; 199 struct ib_uobject *uobj;
196 200
197 uobj = idr_read_uobj(idr, id, context); 201 uobj = idr_read_uobj(idr, id, context, nested);
198 return uobj ? uobj->object : NULL; 202 return uobj ? uobj->object : NULL;
199} 203}
200 204
201static struct ib_pd *idr_read_pd(int pd_handle, struct ib_ucontext *context) 205static struct ib_pd *idr_read_pd(int pd_handle, struct ib_ucontext *context)
202{ 206{
203 return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context); 207 return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context, 0);
204} 208}
205 209
206static void put_pd_read(struct ib_pd *pd) 210static void put_pd_read(struct ib_pd *pd)
@@ -208,9 +212,9 @@ static void put_pd_read(struct ib_pd *pd)
208 put_uobj_read(pd->uobject); 212 put_uobj_read(pd->uobject);
209} 213}
210 214
211static struct ib_cq *idr_read_cq(int cq_handle, struct ib_ucontext *context) 215static struct ib_cq *idr_read_cq(int cq_handle, struct ib_ucontext *context, int nested)
212{ 216{
213 return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context); 217 return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context, nested);
214} 218}
215 219
216static void put_cq_read(struct ib_cq *cq) 220static void put_cq_read(struct ib_cq *cq)
@@ -220,7 +224,7 @@ static void put_cq_read(struct ib_cq *cq)
220 224
221static struct ib_ah *idr_read_ah(int ah_handle, struct ib_ucontext *context) 225static struct ib_ah *idr_read_ah(int ah_handle, struct ib_ucontext *context)
222{ 226{
223 return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context); 227 return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context, 0);
224} 228}
225 229
226static void put_ah_read(struct ib_ah *ah) 230static void put_ah_read(struct ib_ah *ah)
@@ -230,7 +234,7 @@ static void put_ah_read(struct ib_ah *ah)
230 234
231static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context) 235static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context)
232{ 236{
233 return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context); 237 return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context, 0);
234} 238}
235 239
236static void put_qp_read(struct ib_qp *qp) 240static void put_qp_read(struct ib_qp *qp)
@@ -240,7 +244,7 @@ static void put_qp_read(struct ib_qp *qp)
240 244
241static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context) 245static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context)
242{ 246{
243 return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context); 247 return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context, 0);
244} 248}
245 249
246static void put_srq_read(struct ib_srq *srq) 250static void put_srq_read(struct ib_srq *srq)
@@ -837,7 +841,6 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
837err_copy: 841err_copy:
838 idr_remove_uobj(&ib_uverbs_cq_idr, &obj->uobject); 842 idr_remove_uobj(&ib_uverbs_cq_idr, &obj->uobject);
839 843
840
841err_free: 844err_free:
842 ib_destroy_cq(cq); 845 ib_destroy_cq(cq);
843 846
@@ -867,7 +870,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
867 (unsigned long) cmd.response + sizeof resp, 870 (unsigned long) cmd.response + sizeof resp,
868 in_len - sizeof cmd, out_len - sizeof resp); 871 in_len - sizeof cmd, out_len - sizeof resp);
869 872
870 cq = idr_read_cq(cmd.cq_handle, file->ucontext); 873 cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
871 if (!cq) 874 if (!cq)
872 return -EINVAL; 875 return -EINVAL;
873 876
@@ -875,11 +878,10 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
875 if (ret) 878 if (ret)
876 goto out; 879 goto out;
877 880
878 memset(&resp, 0, sizeof resp);
879 resp.cqe = cq->cqe; 881 resp.cqe = cq->cqe;
880 882
881 if (copy_to_user((void __user *) (unsigned long) cmd.response, 883 if (copy_to_user((void __user *) (unsigned long) cmd.response,
882 &resp, sizeof resp)) 884 &resp, sizeof resp.cqe))
883 ret = -EFAULT; 885 ret = -EFAULT;
884 886
885out: 887out:
@@ -894,7 +896,6 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
894{ 896{
895 struct ib_uverbs_poll_cq cmd; 897 struct ib_uverbs_poll_cq cmd;
896 struct ib_uverbs_poll_cq_resp *resp; 898 struct ib_uverbs_poll_cq_resp *resp;
897 struct ib_uobject *uobj;
898 struct ib_cq *cq; 899 struct ib_cq *cq;
899 struct ib_wc *wc; 900 struct ib_wc *wc;
900 int ret = 0; 901 int ret = 0;
@@ -915,16 +916,15 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
915 goto out_wc; 916 goto out_wc;
916 } 917 }
917 918
918 uobj = idr_read_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext); 919 cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
919 if (!uobj) { 920 if (!cq) {
920 ret = -EINVAL; 921 ret = -EINVAL;
921 goto out; 922 goto out;
922 } 923 }
923 cq = uobj->object;
924 924
925 resp->count = ib_poll_cq(cq, cmd.ne, wc); 925 resp->count = ib_poll_cq(cq, cmd.ne, wc);
926 926
927 put_uobj_read(uobj); 927 put_cq_read(cq);
928 928
929 for (i = 0; i < resp->count; i++) { 929 for (i = 0; i < resp->count; i++) {
930 resp->wc[i].wr_id = wc[i].wr_id; 930 resp->wc[i].wr_id = wc[i].wr_id;
@@ -959,21 +959,19 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
959 int out_len) 959 int out_len)
960{ 960{
961 struct ib_uverbs_req_notify_cq cmd; 961 struct ib_uverbs_req_notify_cq cmd;
962 struct ib_uobject *uobj;
963 struct ib_cq *cq; 962 struct ib_cq *cq;
964 963
965 if (copy_from_user(&cmd, buf, sizeof cmd)) 964 if (copy_from_user(&cmd, buf, sizeof cmd))
966 return -EFAULT; 965 return -EFAULT;
967 966
968 uobj = idr_read_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext); 967 cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
969 if (!uobj) 968 if (!cq)
970 return -EINVAL; 969 return -EINVAL;
971 cq = uobj->object;
972 970
973 ib_req_notify_cq(cq, cmd.solicited_only ? 971 ib_req_notify_cq(cq, cmd.solicited_only ?
974 IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); 972 IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
975 973
976 put_uobj_read(uobj); 974 put_cq_read(cq);
977 975
978 return in_len; 976 return in_len;
979} 977}
@@ -1064,9 +1062,9 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
1064 1062
1065 srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL; 1063 srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL;
1066 pd = idr_read_pd(cmd.pd_handle, file->ucontext); 1064 pd = idr_read_pd(cmd.pd_handle, file->ucontext);
1067 scq = idr_read_cq(cmd.send_cq_handle, file->ucontext); 1065 scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0);
1068 rcq = cmd.recv_cq_handle == cmd.send_cq_handle ? 1066 rcq = cmd.recv_cq_handle == cmd.send_cq_handle ?
1069 scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext); 1067 scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1);
1070 1068
1071 if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) { 1069 if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) {
1072 ret = -EINVAL; 1070 ret = -EINVAL;
@@ -1274,6 +1272,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1274 int out_len) 1272 int out_len)
1275{ 1273{
1276 struct ib_uverbs_modify_qp cmd; 1274 struct ib_uverbs_modify_qp cmd;
1275 struct ib_udata udata;
1277 struct ib_qp *qp; 1276 struct ib_qp *qp;
1278 struct ib_qp_attr *attr; 1277 struct ib_qp_attr *attr;
1279 int ret; 1278 int ret;
@@ -1281,6 +1280,9 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1281 if (copy_from_user(&cmd, buf, sizeof cmd)) 1280 if (copy_from_user(&cmd, buf, sizeof cmd))
1282 return -EFAULT; 1281 return -EFAULT;
1283 1282
1283 INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd,
1284 out_len);
1285
1284 attr = kmalloc(sizeof *attr, GFP_KERNEL); 1286 attr = kmalloc(sizeof *attr, GFP_KERNEL);
1285 if (!attr) 1287 if (!attr)
1286 return -ENOMEM; 1288 return -ENOMEM;
@@ -1337,7 +1339,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1337 attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0; 1339 attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
1338 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num; 1340 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
1339 1341
1340 ret = ib_modify_qp(qp, attr, cmd.attr_mask); 1342 ret = qp->device->modify_qp(qp, attr, cmd.attr_mask, &udata);
1341 1343
1342 put_qp_read(qp); 1344 put_qp_read(qp);
1343 1345
@@ -1674,7 +1676,6 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
1674 break; 1676 break;
1675 } 1677 }
1676 1678
1677
1678 if (copy_to_user((void __user *) (unsigned long) cmd.response, 1679 if (copy_to_user((void __user *) (unsigned long) cmd.response,
1679 &resp, sizeof resp)) 1680 &resp, sizeof resp))
1680 ret = -EFAULT; 1681 ret = -EFAULT;
@@ -1724,7 +1725,6 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
1724 break; 1725 break;
1725 } 1726 }
1726 1727
1727
1728 if (copy_to_user((void __user *) (unsigned long) cmd.response, 1728 if (copy_to_user((void __user *) (unsigned long) cmd.response,
1729 &resp, sizeof resp)) 1729 &resp, sizeof resp))
1730 ret = -EFAULT; 1730 ret = -EFAULT;
@@ -2055,6 +2055,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
2055 int out_len) 2055 int out_len)
2056{ 2056{
2057 struct ib_uverbs_modify_srq cmd; 2057 struct ib_uverbs_modify_srq cmd;
2058 struct ib_udata udata;
2058 struct ib_srq *srq; 2059 struct ib_srq *srq;
2059 struct ib_srq_attr attr; 2060 struct ib_srq_attr attr;
2060 int ret; 2061 int ret;
@@ -2062,6 +2063,9 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
2062 if (copy_from_user(&cmd, buf, sizeof cmd)) 2063 if (copy_from_user(&cmd, buf, sizeof cmd))
2063 return -EFAULT; 2064 return -EFAULT;
2064 2065
2066 INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd,
2067 out_len);
2068
2065 srq = idr_read_srq(cmd.srq_handle, file->ucontext); 2069 srq = idr_read_srq(cmd.srq_handle, file->ucontext);
2066 if (!srq) 2070 if (!srq)
2067 return -EINVAL; 2071 return -EINVAL;
@@ -2069,7 +2073,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
2069 attr.max_wr = cmd.max_wr; 2073 attr.max_wr = cmd.max_wr;
2070 attr.srq_limit = cmd.srq_limit; 2074 attr.srq_limit = cmd.srq_limit;
2071 2075
2072 ret = ib_modify_srq(srq, &attr, cmd.attr_mask); 2076 ret = srq->device->modify_srq(srq, &attr, cmd.attr_mask, &udata);
2073 2077
2074 put_srq_read(srq); 2078 put_srq_read(srq);
2075 2079
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 468999c38803..8b5dd3649bbf 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -79,6 +79,23 @@ enum ib_rate mult_to_ib_rate(int mult)
79} 79}
80EXPORT_SYMBOL(mult_to_ib_rate); 80EXPORT_SYMBOL(mult_to_ib_rate);
81 81
82enum rdma_transport_type
83rdma_node_get_transport(enum rdma_node_type node_type)
84{
85 switch (node_type) {
86 case RDMA_NODE_IB_CA:
87 case RDMA_NODE_IB_SWITCH:
88 case RDMA_NODE_IB_ROUTER:
89 return RDMA_TRANSPORT_IB;
90 case RDMA_NODE_RNIC:
91 return RDMA_TRANSPORT_IWARP;
92 default:
93 BUG();
94 return 0;
95 }
96}
97EXPORT_SYMBOL(rdma_node_get_transport);
98
82/* Protection domains */ 99/* Protection domains */
83 100
84struct ib_pd *ib_alloc_pd(struct ib_device *device) 101struct ib_pd *ib_alloc_pd(struct ib_device *device)
@@ -231,7 +248,7 @@ int ib_modify_srq(struct ib_srq *srq,
231 struct ib_srq_attr *srq_attr, 248 struct ib_srq_attr *srq_attr,
232 enum ib_srq_attr_mask srq_attr_mask) 249 enum ib_srq_attr_mask srq_attr_mask)
233{ 250{
234 return srq->device->modify_srq(srq, srq_attr, srq_attr_mask); 251 return srq->device->modify_srq(srq, srq_attr, srq_attr_mask, NULL);
235} 252}
236EXPORT_SYMBOL(ib_modify_srq); 253EXPORT_SYMBOL(ib_modify_srq);
237 254
@@ -547,7 +564,7 @@ int ib_modify_qp(struct ib_qp *qp,
547 struct ib_qp_attr *qp_attr, 564 struct ib_qp_attr *qp_attr,
548 int qp_attr_mask) 565 int qp_attr_mask)
549{ 566{
550 return qp->device->modify_qp(qp, qp_attr, qp_attr_mask); 567 return qp->device->modify_qp(qp, qp_attr, qp_attr_mask, NULL);
551} 568}
552EXPORT_SYMBOL(ib_modify_qp); 569EXPORT_SYMBOL(ib_modify_qp);
553 570
diff --git a/drivers/infiniband/hw/amso1100/Kbuild b/drivers/infiniband/hw/amso1100/Kbuild
new file mode 100644
index 000000000000..06964c4af849
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/Kbuild
@@ -0,0 +1,8 @@
1ifdef CONFIG_INFINIBAND_AMSO1100_DEBUG
2EXTRA_CFLAGS += -DDEBUG
3endif
4
5obj-$(CONFIG_INFINIBAND_AMSO1100) += iw_c2.o
6
7iw_c2-y := c2.o c2_provider.o c2_rnic.o c2_alloc.o c2_mq.o c2_ae.o c2_vq.o \
8 c2_intr.o c2_cq.o c2_qp.o c2_cm.o c2_mm.o c2_pd.o
diff --git a/drivers/infiniband/hw/amso1100/Kconfig b/drivers/infiniband/hw/amso1100/Kconfig
new file mode 100644
index 000000000000..809cb14ac6de
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/Kconfig
@@ -0,0 +1,15 @@
1config INFINIBAND_AMSO1100
2 tristate "Ammasso 1100 HCA support"
3 depends on PCI && INET && INFINIBAND
4 ---help---
5 This is a low-level driver for the Ammasso 1100 host
6 channel adapter (HCA).
7
8config INFINIBAND_AMSO1100_DEBUG
9 bool "Verbose debugging output"
10 depends on INFINIBAND_AMSO1100
11 default n
12 ---help---
13 This option causes the amso1100 driver to produce a bunch of
14 debug messages. Select this if you are developing the driver
15 or trying to diagnose a problem.
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
new file mode 100644
index 000000000000..9e9120f36019
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -0,0 +1,1255 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/pci.h>
36#include <linux/netdevice.h>
37#include <linux/etherdevice.h>
38#include <linux/inetdevice.h>
39#include <linux/delay.h>
40#include <linux/ethtool.h>
41#include <linux/mii.h>
42#include <linux/if_vlan.h>
43#include <linux/crc32.h>
44#include <linux/in.h>
45#include <linux/ip.h>
46#include <linux/tcp.h>
47#include <linux/init.h>
48#include <linux/dma-mapping.h>
49
50#include <asm/io.h>
51#include <asm/irq.h>
52#include <asm/byteorder.h>
53
54#include <rdma/ib_smi.h>
55#include "c2.h"
56#include "c2_provider.h"
57
58MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>");
59MODULE_DESCRIPTION("Ammasso AMSO1100 Low-level iWARP Driver");
60MODULE_LICENSE("Dual BSD/GPL");
61MODULE_VERSION(DRV_VERSION);
62
63static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
64 | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
65
66static int debug = -1; /* defaults above */
67module_param(debug, int, 0);
68MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
69
70static int c2_up(struct net_device *netdev);
71static int c2_down(struct net_device *netdev);
72static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
73static void c2_tx_interrupt(struct net_device *netdev);
74static void c2_rx_interrupt(struct net_device *netdev);
75static irqreturn_t c2_interrupt(int irq, void *dev_id, struct pt_regs *regs);
76static void c2_tx_timeout(struct net_device *netdev);
77static int c2_change_mtu(struct net_device *netdev, int new_mtu);
78static void c2_reset(struct c2_port *c2_port);
79static struct net_device_stats *c2_get_stats(struct net_device *netdev);
80
81static struct pci_device_id c2_pci_table[] = {
82 { PCI_DEVICE(0x18b8, 0xb001) },
83 { 0 }
84};
85
86MODULE_DEVICE_TABLE(pci, c2_pci_table);
87
88static void c2_print_macaddr(struct net_device *netdev)
89{
90 pr_debug("%s: MAC %02X:%02X:%02X:%02X:%02X:%02X, "
91 "IRQ %u\n", netdev->name,
92 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
93 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5],
94 netdev->irq);
95}
96
97static void c2_set_rxbufsize(struct c2_port *c2_port)
98{
99 struct net_device *netdev = c2_port->netdev;
100
101 if (netdev->mtu > RX_BUF_SIZE)
102 c2_port->rx_buf_size =
103 netdev->mtu + ETH_HLEN + sizeof(struct c2_rxp_hdr) +
104 NET_IP_ALIGN;
105 else
106 c2_port->rx_buf_size = sizeof(struct c2_rxp_hdr) + RX_BUF_SIZE;
107}
108
109/*
110 * Allocate TX ring elements and chain them together.
111 * One-to-one association of adapter descriptors with ring elements.
112 */
113static int c2_tx_ring_alloc(struct c2_ring *tx_ring, void *vaddr,
114 dma_addr_t base, void __iomem * mmio_txp_ring)
115{
116 struct c2_tx_desc *tx_desc;
117 struct c2_txp_desc __iomem *txp_desc;
118 struct c2_element *elem;
119 int i;
120
121 tx_ring->start = kmalloc(sizeof(*elem) * tx_ring->count, GFP_KERNEL);
122 if (!tx_ring->start)
123 return -ENOMEM;
124
125 elem = tx_ring->start;
126 tx_desc = vaddr;
127 txp_desc = mmio_txp_ring;
128 for (i = 0; i < tx_ring->count; i++, elem++, tx_desc++, txp_desc++) {
129 tx_desc->len = 0;
130 tx_desc->status = 0;
131
132 /* Set TXP_HTXD_UNINIT */
133 __raw_writeq(cpu_to_be64(0x1122334455667788ULL),
134 (void __iomem *) txp_desc + C2_TXP_ADDR);
135 __raw_writew(0, (void __iomem *) txp_desc + C2_TXP_LEN);
136 __raw_writew(cpu_to_be16(TXP_HTXD_UNINIT),
137 (void __iomem *) txp_desc + C2_TXP_FLAGS);
138
139 elem->skb = NULL;
140 elem->ht_desc = tx_desc;
141 elem->hw_desc = txp_desc;
142
143 if (i == tx_ring->count - 1) {
144 elem->next = tx_ring->start;
145 tx_desc->next_offset = base;
146 } else {
147 elem->next = elem + 1;
148 tx_desc->next_offset =
149 base + (i + 1) * sizeof(*tx_desc);
150 }
151 }
152
153 tx_ring->to_use = tx_ring->to_clean = tx_ring->start;
154
155 return 0;
156}
157
158/*
159 * Allocate RX ring elements and chain them together.
160 * One-to-one association of adapter descriptors with ring elements.
161 */
162static int c2_rx_ring_alloc(struct c2_ring *rx_ring, void *vaddr,
163 dma_addr_t base, void __iomem * mmio_rxp_ring)
164{
165 struct c2_rx_desc *rx_desc;
166 struct c2_rxp_desc __iomem *rxp_desc;
167 struct c2_element *elem;
168 int i;
169
170 rx_ring->start = kmalloc(sizeof(*elem) * rx_ring->count, GFP_KERNEL);
171 if (!rx_ring->start)
172 return -ENOMEM;
173
174 elem = rx_ring->start;
175 rx_desc = vaddr;
176 rxp_desc = mmio_rxp_ring;
177 for (i = 0; i < rx_ring->count; i++, elem++, rx_desc++, rxp_desc++) {
178 rx_desc->len = 0;
179 rx_desc->status = 0;
180
181 /* Set RXP_HRXD_UNINIT */
182 __raw_writew(cpu_to_be16(RXP_HRXD_OK),
183 (void __iomem *) rxp_desc + C2_RXP_STATUS);
184 __raw_writew(0, (void __iomem *) rxp_desc + C2_RXP_COUNT);
185 __raw_writew(0, (void __iomem *) rxp_desc + C2_RXP_LEN);
186 __raw_writeq(cpu_to_be64(0x99aabbccddeeffULL),
187 (void __iomem *) rxp_desc + C2_RXP_ADDR);
188 __raw_writew(cpu_to_be16(RXP_HRXD_UNINIT),
189 (void __iomem *) rxp_desc + C2_RXP_FLAGS);
190
191 elem->skb = NULL;
192 elem->ht_desc = rx_desc;
193 elem->hw_desc = rxp_desc;
194
195 if (i == rx_ring->count - 1) {
196 elem->next = rx_ring->start;
197 rx_desc->next_offset = base;
198 } else {
199 elem->next = elem + 1;
200 rx_desc->next_offset =
201 base + (i + 1) * sizeof(*rx_desc);
202 }
203 }
204
205 rx_ring->to_use = rx_ring->to_clean = rx_ring->start;
206
207 return 0;
208}
209
210/* Setup buffer for receiving */
211static inline int c2_rx_alloc(struct c2_port *c2_port, struct c2_element *elem)
212{
213 struct c2_dev *c2dev = c2_port->c2dev;
214 struct c2_rx_desc *rx_desc = elem->ht_desc;
215 struct sk_buff *skb;
216 dma_addr_t mapaddr;
217 u32 maplen;
218 struct c2_rxp_hdr *rxp_hdr;
219
220 skb = dev_alloc_skb(c2_port->rx_buf_size);
221 if (unlikely(!skb)) {
222 pr_debug("%s: out of memory for receive\n",
223 c2_port->netdev->name);
224 return -ENOMEM;
225 }
226
227 /* Zero out the rxp hdr in the sk_buff */
228 memset(skb->data, 0, sizeof(*rxp_hdr));
229
230 skb->dev = c2_port->netdev;
231
232 maplen = c2_port->rx_buf_size;
233 mapaddr =
234 pci_map_single(c2dev->pcidev, skb->data, maplen,
235 PCI_DMA_FROMDEVICE);
236
237 /* Set the sk_buff RXP_header to RXP_HRXD_READY */
238 rxp_hdr = (struct c2_rxp_hdr *) skb->data;
239 rxp_hdr->flags = RXP_HRXD_READY;
240
241 __raw_writew(0, elem->hw_desc + C2_RXP_STATUS);
242 __raw_writew(cpu_to_be16((u16) maplen - sizeof(*rxp_hdr)),
243 elem->hw_desc + C2_RXP_LEN);
244 __raw_writeq(cpu_to_be64(mapaddr), elem->hw_desc + C2_RXP_ADDR);
245 __raw_writew(cpu_to_be16(RXP_HRXD_READY), elem->hw_desc + C2_RXP_FLAGS);
246
247 elem->skb = skb;
248 elem->mapaddr = mapaddr;
249 elem->maplen = maplen;
250 rx_desc->len = maplen;
251
252 return 0;
253}
254
255/*
256 * Allocate buffers for the Rx ring
257 * For receive: rx_ring.to_clean is next received frame
258 */
259static int c2_rx_fill(struct c2_port *c2_port)
260{
261 struct c2_ring *rx_ring = &c2_port->rx_ring;
262 struct c2_element *elem;
263 int ret = 0;
264
265 elem = rx_ring->start;
266 do {
267 if (c2_rx_alloc(c2_port, elem)) {
268 ret = 1;
269 break;
270 }
271 } while ((elem = elem->next) != rx_ring->start);
272
273 rx_ring->to_clean = rx_ring->start;
274 return ret;
275}
276
277/* Free all buffers in RX ring, assumes receiver stopped */
278static void c2_rx_clean(struct c2_port *c2_port)
279{
280 struct c2_dev *c2dev = c2_port->c2dev;
281 struct c2_ring *rx_ring = &c2_port->rx_ring;
282 struct c2_element *elem;
283 struct c2_rx_desc *rx_desc;
284
285 elem = rx_ring->start;
286 do {
287 rx_desc = elem->ht_desc;
288 rx_desc->len = 0;
289
290 __raw_writew(0, elem->hw_desc + C2_RXP_STATUS);
291 __raw_writew(0, elem->hw_desc + C2_RXP_COUNT);
292 __raw_writew(0, elem->hw_desc + C2_RXP_LEN);
293 __raw_writeq(cpu_to_be64(0x99aabbccddeeffULL),
294 elem->hw_desc + C2_RXP_ADDR);
295 __raw_writew(cpu_to_be16(RXP_HRXD_UNINIT),
296 elem->hw_desc + C2_RXP_FLAGS);
297
298 if (elem->skb) {
299 pci_unmap_single(c2dev->pcidev, elem->mapaddr,
300 elem->maplen, PCI_DMA_FROMDEVICE);
301 dev_kfree_skb(elem->skb);
302 elem->skb = NULL;
303 }
304 } while ((elem = elem->next) != rx_ring->start);
305}
306
307static inline int c2_tx_free(struct c2_dev *c2dev, struct c2_element *elem)
308{
309 struct c2_tx_desc *tx_desc = elem->ht_desc;
310
311 tx_desc->len = 0;
312
313 pci_unmap_single(c2dev->pcidev, elem->mapaddr, elem->maplen,
314 PCI_DMA_TODEVICE);
315
316 if (elem->skb) {
317 dev_kfree_skb_any(elem->skb);
318 elem->skb = NULL;
319 }
320
321 return 0;
322}
323
324/* Free all buffers in TX ring, assumes transmitter stopped */
325static void c2_tx_clean(struct c2_port *c2_port)
326{
327 struct c2_ring *tx_ring = &c2_port->tx_ring;
328 struct c2_element *elem;
329 struct c2_txp_desc txp_htxd;
330 int retry;
331 unsigned long flags;
332
333 spin_lock_irqsave(&c2_port->tx_lock, flags);
334
335 elem = tx_ring->start;
336
337 do {
338 retry = 0;
339 do {
340 txp_htxd.flags =
341 readw(elem->hw_desc + C2_TXP_FLAGS);
342
343 if (txp_htxd.flags == TXP_HTXD_READY) {
344 retry = 1;
345 __raw_writew(0,
346 elem->hw_desc + C2_TXP_LEN);
347 __raw_writeq(0,
348 elem->hw_desc + C2_TXP_ADDR);
349 __raw_writew(cpu_to_be16(TXP_HTXD_DONE),
350 elem->hw_desc + C2_TXP_FLAGS);
351 c2_port->netstats.tx_dropped++;
352 break;
353 } else {
354 __raw_writew(0,
355 elem->hw_desc + C2_TXP_LEN);
356 __raw_writeq(cpu_to_be64(0x1122334455667788ULL),
357 elem->hw_desc + C2_TXP_ADDR);
358 __raw_writew(cpu_to_be16(TXP_HTXD_UNINIT),
359 elem->hw_desc + C2_TXP_FLAGS);
360 }
361
362 c2_tx_free(c2_port->c2dev, elem);
363
364 } while ((elem = elem->next) != tx_ring->start);
365 } while (retry);
366
367 c2_port->tx_avail = c2_port->tx_ring.count - 1;
368 c2_port->c2dev->cur_tx = tx_ring->to_use - tx_ring->start;
369
370 if (c2_port->tx_avail > MAX_SKB_FRAGS + 1)
371 netif_wake_queue(c2_port->netdev);
372
373 spin_unlock_irqrestore(&c2_port->tx_lock, flags);
374}
375
376/*
377 * Process transmit descriptors marked 'DONE' by the firmware,
378 * freeing up their unneeded sk_buffs.
379 */
380static void c2_tx_interrupt(struct net_device *netdev)
381{
382 struct c2_port *c2_port = netdev_priv(netdev);
383 struct c2_dev *c2dev = c2_port->c2dev;
384 struct c2_ring *tx_ring = &c2_port->tx_ring;
385 struct c2_element *elem;
386 struct c2_txp_desc txp_htxd;
387
388 spin_lock(&c2_port->tx_lock);
389
390 for (elem = tx_ring->to_clean; elem != tx_ring->to_use;
391 elem = elem->next) {
392 txp_htxd.flags =
393 be16_to_cpu(readw(elem->hw_desc + C2_TXP_FLAGS));
394
395 if (txp_htxd.flags != TXP_HTXD_DONE)
396 break;
397
398 if (netif_msg_tx_done(c2_port)) {
399 /* PCI reads are expensive in fast path */
400 txp_htxd.len =
401 be16_to_cpu(readw(elem->hw_desc + C2_TXP_LEN));
402 pr_debug("%s: tx done slot %3Zu status 0x%x len "
403 "%5u bytes\n",
404 netdev->name, elem - tx_ring->start,
405 txp_htxd.flags, txp_htxd.len);
406 }
407
408 c2_tx_free(c2dev, elem);
409 ++(c2_port->tx_avail);
410 }
411
412 tx_ring->to_clean = elem;
413
414 if (netif_queue_stopped(netdev)
415 && c2_port->tx_avail > MAX_SKB_FRAGS + 1)
416 netif_wake_queue(netdev);
417
418 spin_unlock(&c2_port->tx_lock);
419}
420
421static void c2_rx_error(struct c2_port *c2_port, struct c2_element *elem)
422{
423 struct c2_rx_desc *rx_desc = elem->ht_desc;
424 struct c2_rxp_hdr *rxp_hdr = (struct c2_rxp_hdr *) elem->skb->data;
425
426 if (rxp_hdr->status != RXP_HRXD_OK ||
427 rxp_hdr->len > (rx_desc->len - sizeof(*rxp_hdr))) {
428 pr_debug("BAD RXP_HRXD\n");
429 pr_debug(" rx_desc : %p\n", rx_desc);
430 pr_debug(" index : %Zu\n",
431 elem - c2_port->rx_ring.start);
432 pr_debug(" len : %u\n", rx_desc->len);
433 pr_debug(" rxp_hdr : %p [PA %p]\n", rxp_hdr,
434 (void *) __pa((unsigned long) rxp_hdr));
435 pr_debug(" flags : 0x%x\n", rxp_hdr->flags);
436 pr_debug(" status: 0x%x\n", rxp_hdr->status);
437 pr_debug(" len : %u\n", rxp_hdr->len);
438 pr_debug(" rsvd : 0x%x\n", rxp_hdr->rsvd);
439 }
440
441 /* Setup the skb for reuse since we're dropping this pkt */
442 elem->skb->tail = elem->skb->data = elem->skb->head;
443
444 /* Zero out the rxp hdr in the sk_buff */
445 memset(elem->skb->data, 0, sizeof(*rxp_hdr));
446
447 /* Write the descriptor to the adapter's rx ring */
448 __raw_writew(0, elem->hw_desc + C2_RXP_STATUS);
449 __raw_writew(0, elem->hw_desc + C2_RXP_COUNT);
450 __raw_writew(cpu_to_be16((u16) elem->maplen - sizeof(*rxp_hdr)),
451 elem->hw_desc + C2_RXP_LEN);
452 __raw_writeq(cpu_to_be64(elem->mapaddr), elem->hw_desc + C2_RXP_ADDR);
453 __raw_writew(cpu_to_be16(RXP_HRXD_READY), elem->hw_desc + C2_RXP_FLAGS);
454
455 pr_debug("packet dropped\n");
456 c2_port->netstats.rx_dropped++;
457}
458
459static void c2_rx_interrupt(struct net_device *netdev)
460{
461 struct c2_port *c2_port = netdev_priv(netdev);
462 struct c2_dev *c2dev = c2_port->c2dev;
463 struct c2_ring *rx_ring = &c2_port->rx_ring;
464 struct c2_element *elem;
465 struct c2_rx_desc *rx_desc;
466 struct c2_rxp_hdr *rxp_hdr;
467 struct sk_buff *skb;
468 dma_addr_t mapaddr;
469 u32 maplen, buflen;
470 unsigned long flags;
471
472 spin_lock_irqsave(&c2dev->lock, flags);
473
474 /* Begin where we left off */
475 rx_ring->to_clean = rx_ring->start + c2dev->cur_rx;
476
477 for (elem = rx_ring->to_clean; elem->next != rx_ring->to_clean;
478 elem = elem->next) {
479 rx_desc = elem->ht_desc;
480 mapaddr = elem->mapaddr;
481 maplen = elem->maplen;
482 skb = elem->skb;
483 rxp_hdr = (struct c2_rxp_hdr *) skb->data;
484
485 if (rxp_hdr->flags != RXP_HRXD_DONE)
486 break;
487 buflen = rxp_hdr->len;
488
489 /* Sanity check the RXP header */
490 if (rxp_hdr->status != RXP_HRXD_OK ||
491 buflen > (rx_desc->len - sizeof(*rxp_hdr))) {
492 c2_rx_error(c2_port, elem);
493 continue;
494 }
495
496 /*
497 * Allocate and map a new skb for replenishing the host
498 * RX desc
499 */
500 if (c2_rx_alloc(c2_port, elem)) {
501 c2_rx_error(c2_port, elem);
502 continue;
503 }
504
505 /* Unmap the old skb */
506 pci_unmap_single(c2dev->pcidev, mapaddr, maplen,
507 PCI_DMA_FROMDEVICE);
508
509 prefetch(skb->data);
510
511 /*
512 * Skip past the leading 8 bytes comprising of the
513 * "struct c2_rxp_hdr", prepended by the adapter
514 * to the usual Ethernet header ("struct ethhdr"),
515 * to the start of the raw Ethernet packet.
516 *
517 * Fix up the various fields in the sk_buff before
518 * passing it up to netif_rx(). The transfer size
519 * (in bytes) specified by the adapter len field of
520 * the "struct rxp_hdr_t" does NOT include the
521 * "sizeof(struct c2_rxp_hdr)".
522 */
523 skb->data += sizeof(*rxp_hdr);
524 skb->tail = skb->data + buflen;
525 skb->len = buflen;
526 skb->dev = netdev;
527 skb->protocol = eth_type_trans(skb, netdev);
528
529 netif_rx(skb);
530
531 netdev->last_rx = jiffies;
532 c2_port->netstats.rx_packets++;
533 c2_port->netstats.rx_bytes += buflen;
534 }
535
536 /* Save where we left off */
537 rx_ring->to_clean = elem;
538 c2dev->cur_rx = elem - rx_ring->start;
539 C2_SET_CUR_RX(c2dev, c2dev->cur_rx);
540
541 spin_unlock_irqrestore(&c2dev->lock, flags);
542}
543
544/*
545 * Handle netisr0 TX & RX interrupts.
546 */
547static irqreturn_t c2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
548{
549 unsigned int netisr0, dmaisr;
550 int handled = 0;
551 struct c2_dev *c2dev = (struct c2_dev *) dev_id;
552
553 /* Process CCILNET interrupts */
554 netisr0 = readl(c2dev->regs + C2_NISR0);
555 if (netisr0) {
556
557 /*
558 * There is an issue with the firmware that always
559 * provides the status of RX for both TX & RX
560 * interrupts. So process both queues here.
561 */
562 c2_rx_interrupt(c2dev->netdev);
563 c2_tx_interrupt(c2dev->netdev);
564
565 /* Clear the interrupt */
566 writel(netisr0, c2dev->regs + C2_NISR0);
567 handled++;
568 }
569
570 /* Process RNIC interrupts */
571 dmaisr = readl(c2dev->regs + C2_DISR);
572 if (dmaisr) {
573 writel(dmaisr, c2dev->regs + C2_DISR);
574 c2_rnic_interrupt(c2dev);
575 handled++;
576 }
577
578 if (handled) {
579 return IRQ_HANDLED;
580 } else {
581 return IRQ_NONE;
582 }
583}
584
585static int c2_up(struct net_device *netdev)
586{
587 struct c2_port *c2_port = netdev_priv(netdev);
588 struct c2_dev *c2dev = c2_port->c2dev;
589 struct c2_element *elem;
590 struct c2_rxp_hdr *rxp_hdr;
591 struct in_device *in_dev;
592 size_t rx_size, tx_size;
593 int ret, i;
594 unsigned int netimr0;
595
596 if (netif_msg_ifup(c2_port))
597 pr_debug("%s: enabling interface\n", netdev->name);
598
599 /* Set the Rx buffer size based on MTU */
600 c2_set_rxbufsize(c2_port);
601
602 /* Allocate DMA'able memory for Tx/Rx host descriptor rings */
603 rx_size = c2_port->rx_ring.count * sizeof(struct c2_rx_desc);
604 tx_size = c2_port->tx_ring.count * sizeof(struct c2_tx_desc);
605
606 c2_port->mem_size = tx_size + rx_size;
607 c2_port->mem = pci_alloc_consistent(c2dev->pcidev, c2_port->mem_size,
608 &c2_port->dma);
609 if (c2_port->mem == NULL) {
610 pr_debug("Unable to allocate memory for "
611 "host descriptor rings\n");
612 return -ENOMEM;
613 }
614
615 memset(c2_port->mem, 0, c2_port->mem_size);
616
617 /* Create the Rx host descriptor ring */
618 if ((ret =
619 c2_rx_ring_alloc(&c2_port->rx_ring, c2_port->mem, c2_port->dma,
620 c2dev->mmio_rxp_ring))) {
621 pr_debug("Unable to create RX ring\n");
622 goto bail0;
623 }
624
625 /* Allocate Rx buffers for the host descriptor ring */
626 if (c2_rx_fill(c2_port)) {
627 pr_debug("Unable to fill RX ring\n");
628 goto bail1;
629 }
630
631 /* Create the Tx host descriptor ring */
632 if ((ret = c2_tx_ring_alloc(&c2_port->tx_ring, c2_port->mem + rx_size,
633 c2_port->dma + rx_size,
634 c2dev->mmio_txp_ring))) {
635 pr_debug("Unable to create TX ring\n");
636 goto bail1;
637 }
638
639 /* Set the TX pointer to where we left off */
640 c2_port->tx_avail = c2_port->tx_ring.count - 1;
641 c2_port->tx_ring.to_use = c2_port->tx_ring.to_clean =
642 c2_port->tx_ring.start + c2dev->cur_tx;
643
644 /* missing: Initialize MAC */
645
646 BUG_ON(c2_port->tx_ring.to_use != c2_port->tx_ring.to_clean);
647
648 /* Reset the adapter, ensures the driver is in sync with the RXP */
649 c2_reset(c2_port);
650
651 /* Reset the READY bit in the sk_buff RXP headers & adapter HRXDQ */
652 for (i = 0, elem = c2_port->rx_ring.start; i < c2_port->rx_ring.count;
653 i++, elem++) {
654 rxp_hdr = (struct c2_rxp_hdr *) elem->skb->data;
655 rxp_hdr->flags = 0;
656 __raw_writew(cpu_to_be16(RXP_HRXD_READY),
657 elem->hw_desc + C2_RXP_FLAGS);
658 }
659
660 /* Enable network packets */
661 netif_start_queue(netdev);
662
663 /* Enable IRQ */
664 writel(0, c2dev->regs + C2_IDIS);
665 netimr0 = readl(c2dev->regs + C2_NIMR0);
666 netimr0 &= ~(C2_PCI_HTX_INT | C2_PCI_HRX_INT);
667 writel(netimr0, c2dev->regs + C2_NIMR0);
668
669 /* Tell the stack to ignore arp requests for ipaddrs bound to
670 * other interfaces. This is needed to prevent the host stack
671 * from responding to arp requests to the ipaddr bound on the
672 * rdma interface.
673 */
674 in_dev = in_dev_get(netdev);
675 in_dev->cnf.arp_ignore = 1;
676 in_dev_put(in_dev);
677
678 return 0;
679
680 bail1:
681 c2_rx_clean(c2_port);
682 kfree(c2_port->rx_ring.start);
683
684 bail0:
685 pci_free_consistent(c2dev->pcidev, c2_port->mem_size, c2_port->mem,
686 c2_port->dma);
687
688 return ret;
689}
690
691static int c2_down(struct net_device *netdev)
692{
693 struct c2_port *c2_port = netdev_priv(netdev);
694 struct c2_dev *c2dev = c2_port->c2dev;
695
696 if (netif_msg_ifdown(c2_port))
697 pr_debug("%s: disabling interface\n",
698 netdev->name);
699
700 /* Wait for all the queued packets to get sent */
701 c2_tx_interrupt(netdev);
702
703 /* Disable network packets */
704 netif_stop_queue(netdev);
705
706 /* Disable IRQs by clearing the interrupt mask */
707 writel(1, c2dev->regs + C2_IDIS);
708 writel(0, c2dev->regs + C2_NIMR0);
709
710 /* missing: Stop transmitter */
711
712 /* missing: Stop receiver */
713
714 /* Reset the adapter, ensures the driver is in sync with the RXP */
715 c2_reset(c2_port);
716
717 /* missing: Turn off LEDs here */
718
719 /* Free all buffers in the host descriptor rings */
720 c2_tx_clean(c2_port);
721 c2_rx_clean(c2_port);
722
723 /* Free the host descriptor rings */
724 kfree(c2_port->rx_ring.start);
725 kfree(c2_port->tx_ring.start);
726 pci_free_consistent(c2dev->pcidev, c2_port->mem_size, c2_port->mem,
727 c2_port->dma);
728
729 return 0;
730}
731
732static void c2_reset(struct c2_port *c2_port)
733{
734 struct c2_dev *c2dev = c2_port->c2dev;
735 unsigned int cur_rx = c2dev->cur_rx;
736
737 /* Tell the hardware to quiesce */
738 C2_SET_CUR_RX(c2dev, cur_rx | C2_PCI_HRX_QUI);
739
740 /*
741 * The hardware will reset the C2_PCI_HRX_QUI bit once
742 * the RXP is quiesced. Wait 2 seconds for this.
743 */
744 ssleep(2);
745
746 cur_rx = C2_GET_CUR_RX(c2dev);
747
748 if (cur_rx & C2_PCI_HRX_QUI)
749 pr_debug("c2_reset: failed to quiesce the hardware!\n");
750
751 cur_rx &= ~C2_PCI_HRX_QUI;
752
753 c2dev->cur_rx = cur_rx;
754
755 pr_debug("Current RX: %u\n", c2dev->cur_rx);
756}
757
758static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
759{
760 struct c2_port *c2_port = netdev_priv(netdev);
761 struct c2_dev *c2dev = c2_port->c2dev;
762 struct c2_ring *tx_ring = &c2_port->tx_ring;
763 struct c2_element *elem;
764 dma_addr_t mapaddr;
765 u32 maplen;
766 unsigned long flags;
767 unsigned int i;
768
769 spin_lock_irqsave(&c2_port->tx_lock, flags);
770
771 if (unlikely(c2_port->tx_avail < (skb_shinfo(skb)->nr_frags + 1))) {
772 netif_stop_queue(netdev);
773 spin_unlock_irqrestore(&c2_port->tx_lock, flags);
774
775 pr_debug("%s: Tx ring full when queue awake!\n",
776 netdev->name);
777 return NETDEV_TX_BUSY;
778 }
779
780 maplen = skb_headlen(skb);
781 mapaddr =
782 pci_map_single(c2dev->pcidev, skb->data, maplen, PCI_DMA_TODEVICE);
783
784 elem = tx_ring->to_use;
785 elem->skb = skb;
786 elem->mapaddr = mapaddr;
787 elem->maplen = maplen;
788
789 /* Tell HW to xmit */
790 __raw_writeq(cpu_to_be64(mapaddr), elem->hw_desc + C2_TXP_ADDR);
791 __raw_writew(cpu_to_be16(maplen), elem->hw_desc + C2_TXP_LEN);
792 __raw_writew(cpu_to_be16(TXP_HTXD_READY), elem->hw_desc + C2_TXP_FLAGS);
793
794 c2_port->netstats.tx_packets++;
795 c2_port->netstats.tx_bytes += maplen;
796
797 /* Loop thru additional data fragments and queue them */
798 if (skb_shinfo(skb)->nr_frags) {
799 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
800 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
801 maplen = frag->size;
802 mapaddr =
803 pci_map_page(c2dev->pcidev, frag->page,
804 frag->page_offset, maplen,
805 PCI_DMA_TODEVICE);
806
807 elem = elem->next;
808 elem->skb = NULL;
809 elem->mapaddr = mapaddr;
810 elem->maplen = maplen;
811
812 /* Tell HW to xmit */
813 __raw_writeq(cpu_to_be64(mapaddr),
814 elem->hw_desc + C2_TXP_ADDR);
815 __raw_writew(cpu_to_be16(maplen),
816 elem->hw_desc + C2_TXP_LEN);
817 __raw_writew(cpu_to_be16(TXP_HTXD_READY),
818 elem->hw_desc + C2_TXP_FLAGS);
819
820 c2_port->netstats.tx_packets++;
821 c2_port->netstats.tx_bytes += maplen;
822 }
823 }
824
825 tx_ring->to_use = elem->next;
826 c2_port->tx_avail -= (skb_shinfo(skb)->nr_frags + 1);
827
828 if (c2_port->tx_avail <= MAX_SKB_FRAGS + 1) {
829 netif_stop_queue(netdev);
830 if (netif_msg_tx_queued(c2_port))
831 pr_debug("%s: transmit queue full\n",
832 netdev->name);
833 }
834
835 spin_unlock_irqrestore(&c2_port->tx_lock, flags);
836
837 netdev->trans_start = jiffies;
838
839 return NETDEV_TX_OK;
840}
841
842static struct net_device_stats *c2_get_stats(struct net_device *netdev)
843{
844 struct c2_port *c2_port = netdev_priv(netdev);
845
846 return &c2_port->netstats;
847}
848
849static void c2_tx_timeout(struct net_device *netdev)
850{
851 struct c2_port *c2_port = netdev_priv(netdev);
852
853 if (netif_msg_timer(c2_port))
854 pr_debug("%s: tx timeout\n", netdev->name);
855
856 c2_tx_clean(c2_port);
857}
858
859static int c2_change_mtu(struct net_device *netdev, int new_mtu)
860{
861 int ret = 0;
862
863 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
864 return -EINVAL;
865
866 netdev->mtu = new_mtu;
867
868 if (netif_running(netdev)) {
869 c2_down(netdev);
870
871 c2_up(netdev);
872 }
873
874 return ret;
875}
876
877/* Initialize network device */
878static struct net_device *c2_devinit(struct c2_dev *c2dev,
879 void __iomem * mmio_addr)
880{
881 struct c2_port *c2_port = NULL;
882 struct net_device *netdev = alloc_etherdev(sizeof(*c2_port));
883
884 if (!netdev) {
885 pr_debug("c2_port etherdev alloc failed");
886 return NULL;
887 }
888
889 SET_MODULE_OWNER(netdev);
890 SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);
891
892 netdev->open = c2_up;
893 netdev->stop = c2_down;
894 netdev->hard_start_xmit = c2_xmit_frame;
895 netdev->get_stats = c2_get_stats;
896 netdev->tx_timeout = c2_tx_timeout;
897 netdev->change_mtu = c2_change_mtu;
898 netdev->watchdog_timeo = C2_TX_TIMEOUT;
899 netdev->irq = c2dev->pcidev->irq;
900
901 c2_port = netdev_priv(netdev);
902 c2_port->netdev = netdev;
903 c2_port->c2dev = c2dev;
904 c2_port->msg_enable = netif_msg_init(debug, default_msg);
905 c2_port->tx_ring.count = C2_NUM_TX_DESC;
906 c2_port->rx_ring.count = C2_NUM_RX_DESC;
907
908 spin_lock_init(&c2_port->tx_lock);
909
910 /* Copy our 48-bit ethernet hardware address */
911 memcpy_fromio(netdev->dev_addr, mmio_addr + C2_REGS_ENADDR, 6);
912
913 /* Validate the MAC address */
914 if (!is_valid_ether_addr(netdev->dev_addr)) {
915 pr_debug("Invalid MAC Address\n");
916 c2_print_macaddr(netdev);
917 free_netdev(netdev);
918 return NULL;
919 }
920
921 c2dev->netdev = netdev;
922
923 return netdev;
924}
925
926static int __devinit c2_probe(struct pci_dev *pcidev,
927 const struct pci_device_id *ent)
928{
929 int ret = 0, i;
930 unsigned long reg0_start, reg0_flags, reg0_len;
931 unsigned long reg2_start, reg2_flags, reg2_len;
932 unsigned long reg4_start, reg4_flags, reg4_len;
933 unsigned kva_map_size;
934 struct net_device *netdev = NULL;
935 struct c2_dev *c2dev = NULL;
936 void __iomem *mmio_regs = NULL;
937
938 printk(KERN_INFO PFX "AMSO1100 Gigabit Ethernet driver v%s loaded\n",
939 DRV_VERSION);
940
941 /* Enable PCI device */
942 ret = pci_enable_device(pcidev);
943 if (ret) {
944 printk(KERN_ERR PFX "%s: Unable to enable PCI device\n",
945 pci_name(pcidev));
946 goto bail0;
947 }
948
949 reg0_start = pci_resource_start(pcidev, BAR_0);
950 reg0_len = pci_resource_len(pcidev, BAR_0);
951 reg0_flags = pci_resource_flags(pcidev, BAR_0);
952
953 reg2_start = pci_resource_start(pcidev, BAR_2);
954 reg2_len = pci_resource_len(pcidev, BAR_2);
955 reg2_flags = pci_resource_flags(pcidev, BAR_2);
956
957 reg4_start = pci_resource_start(pcidev, BAR_4);
958 reg4_len = pci_resource_len(pcidev, BAR_4);
959 reg4_flags = pci_resource_flags(pcidev, BAR_4);
960
961 pr_debug("BAR0 size = 0x%lX bytes\n", reg0_len);
962 pr_debug("BAR2 size = 0x%lX bytes\n", reg2_len);
963 pr_debug("BAR4 size = 0x%lX bytes\n", reg4_len);
964
965 /* Make sure PCI base addr are MMIO */
966 if (!(reg0_flags & IORESOURCE_MEM) ||
967 !(reg2_flags & IORESOURCE_MEM) || !(reg4_flags & IORESOURCE_MEM)) {
968 printk(KERN_ERR PFX "PCI regions not an MMIO resource\n");
969 ret = -ENODEV;
970 goto bail1;
971 }
972
973 /* Check for weird/broken PCI region reporting */
974 if ((reg0_len < C2_REG0_SIZE) ||
975 (reg2_len < C2_REG2_SIZE) || (reg4_len < C2_REG4_SIZE)) {
976 printk(KERN_ERR PFX "Invalid PCI region sizes\n");
977 ret = -ENODEV;
978 goto bail1;
979 }
980
981 /* Reserve PCI I/O and memory resources */
982 ret = pci_request_regions(pcidev, DRV_NAME);
983 if (ret) {
984 printk(KERN_ERR PFX "%s: Unable to request regions\n",
985 pci_name(pcidev));
986 goto bail1;
987 }
988
989 if ((sizeof(dma_addr_t) > 4)) {
990 ret = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
991 if (ret < 0) {
992 printk(KERN_ERR PFX "64b DMA configuration failed\n");
993 goto bail2;
994 }
995 } else {
996 ret = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
997 if (ret < 0) {
998 printk(KERN_ERR PFX "32b DMA configuration failed\n");
999 goto bail2;
1000 }
1001 }
1002
1003 /* Enables bus-mastering on the device */
1004 pci_set_master(pcidev);
1005
1006 /* Remap the adapter PCI registers in BAR4 */
1007 mmio_regs = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET,
1008 sizeof(struct c2_adapter_pci_regs));
1009 if (mmio_regs == 0UL) {
1010 printk(KERN_ERR PFX
1011 "Unable to remap adapter PCI registers in BAR4\n");
1012 ret = -EIO;
1013 goto bail2;
1014 }
1015
1016 /* Validate PCI regs magic */
1017 for (i = 0; i < sizeof(c2_magic); i++) {
1018 if (c2_magic[i] != readb(mmio_regs + C2_REGS_MAGIC + i)) {
1019 printk(KERN_ERR PFX "Downlevel Firmware boot loader "
1020 "[%d/%Zd: got 0x%x, exp 0x%x]. Use the cc_flash "
1021 "utility to update your boot loader\n",
1022 i + 1, sizeof(c2_magic),
1023 readb(mmio_regs + C2_REGS_MAGIC + i),
1024 c2_magic[i]);
1025 printk(KERN_ERR PFX "Adapter not claimed\n");
1026 iounmap(mmio_regs);
1027 ret = -EIO;
1028 goto bail2;
1029 }
1030 }
1031
1032 /* Validate the adapter version */
1033 if (be32_to_cpu(readl(mmio_regs + C2_REGS_VERS)) != C2_VERSION) {
1034 printk(KERN_ERR PFX "Version mismatch "
1035 "[fw=%u, c2=%u], Adapter not claimed\n",
1036 be32_to_cpu(readl(mmio_regs + C2_REGS_VERS)),
1037 C2_VERSION);
1038 ret = -EINVAL;
1039 iounmap(mmio_regs);
1040 goto bail2;
1041 }
1042
1043 /* Validate the adapter IVN */
1044 if (be32_to_cpu(readl(mmio_regs + C2_REGS_IVN)) != C2_IVN) {
1045 printk(KERN_ERR PFX "Downlevel FIrmware level. You should be using "
1046 "the OpenIB device support kit. "
1047 "[fw=0x%x, c2=0x%x], Adapter not claimed\n",
1048 be32_to_cpu(readl(mmio_regs + C2_REGS_IVN)),
1049 C2_IVN);
1050 ret = -EINVAL;
1051 iounmap(mmio_regs);
1052 goto bail2;
1053 }
1054
1055 /* Allocate hardware structure */
1056 c2dev = (struct c2_dev *) ib_alloc_device(sizeof(*c2dev));
1057 if (!c2dev) {
1058 printk(KERN_ERR PFX "%s: Unable to alloc hardware struct\n",
1059 pci_name(pcidev));
1060 ret = -ENOMEM;
1061 iounmap(mmio_regs);
1062 goto bail2;
1063 }
1064
1065 memset(c2dev, 0, sizeof(*c2dev));
1066 spin_lock_init(&c2dev->lock);
1067 c2dev->pcidev = pcidev;
1068 c2dev->cur_tx = 0;
1069
1070 /* Get the last RX index */
1071 c2dev->cur_rx =
1072 (be32_to_cpu(readl(mmio_regs + C2_REGS_HRX_CUR)) -
1073 0xffffc000) / sizeof(struct c2_rxp_desc);
1074
1075 /* Request an interrupt line for the driver */
1076 ret = request_irq(pcidev->irq, c2_interrupt, SA_SHIRQ, DRV_NAME, c2dev);
1077 if (ret) {
1078 printk(KERN_ERR PFX "%s: requested IRQ %u is busy\n",
1079 pci_name(pcidev), pcidev->irq);
1080 iounmap(mmio_regs);
1081 goto bail3;
1082 }
1083
1084 /* Set driver specific data */
1085 pci_set_drvdata(pcidev, c2dev);
1086
1087 /* Initialize network device */
1088 if ((netdev = c2_devinit(c2dev, mmio_regs)) == NULL) {
1089 iounmap(mmio_regs);
1090 goto bail4;
1091 }
1092
1093 /* Save off the actual size prior to unmapping mmio_regs */
1094 kva_map_size = be32_to_cpu(readl(mmio_regs + C2_REGS_PCI_WINSIZE));
1095
1096 /* Unmap the adapter PCI registers in BAR4 */
1097 iounmap(mmio_regs);
1098
1099 /* Register network device */
1100 ret = register_netdev(netdev);
1101 if (ret) {
1102 printk(KERN_ERR PFX "Unable to register netdev, ret = %d\n",
1103 ret);
1104 goto bail5;
1105 }
1106
1107 /* Disable network packets */
1108 netif_stop_queue(netdev);
1109
1110 /* Remap the adapter HRXDQ PA space to kernel VA space */
1111 c2dev->mmio_rxp_ring = ioremap_nocache(reg4_start + C2_RXP_HRXDQ_OFFSET,
1112 C2_RXP_HRXDQ_SIZE);
1113 if (c2dev->mmio_rxp_ring == 0UL) {
1114 printk(KERN_ERR PFX "Unable to remap MMIO HRXDQ region\n");
1115 ret = -EIO;
1116 goto bail6;
1117 }
1118
1119 /* Remap the adapter HTXDQ PA space to kernel VA space */
1120 c2dev->mmio_txp_ring = ioremap_nocache(reg4_start + C2_TXP_HTXDQ_OFFSET,
1121 C2_TXP_HTXDQ_SIZE);
1122 if (c2dev->mmio_txp_ring == 0UL) {
1123 printk(KERN_ERR PFX "Unable to remap MMIO HTXDQ region\n");
1124 ret = -EIO;
1125 goto bail7;
1126 }
1127
1128 /* Save off the current RX index in the last 4 bytes of the TXP Ring */
1129 C2_SET_CUR_RX(c2dev, c2dev->cur_rx);
1130
1131 /* Remap the PCI registers in adapter BAR0 to kernel VA space */
1132 c2dev->regs = ioremap_nocache(reg0_start, reg0_len);
1133 if (c2dev->regs == 0UL) {
1134 printk(KERN_ERR PFX "Unable to remap BAR0\n");
1135 ret = -EIO;
1136 goto bail8;
1137 }
1138
1139 /* Remap the PCI registers in adapter BAR4 to kernel VA space */
1140 c2dev->pa = reg4_start + C2_PCI_REGS_OFFSET;
1141 c2dev->kva = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET,
1142 kva_map_size);
1143 if (c2dev->kva == 0UL) {
1144 printk(KERN_ERR PFX "Unable to remap BAR4\n");
1145 ret = -EIO;
1146 goto bail9;
1147 }
1148
1149 /* Print out the MAC address */
1150 c2_print_macaddr(netdev);
1151
1152 ret = c2_rnic_init(c2dev);
1153 if (ret) {
1154 printk(KERN_ERR PFX "c2_rnic_init failed: %d\n", ret);
1155 goto bail10;
1156 }
1157
1158 c2_register_device(c2dev);
1159
1160 return 0;
1161
1162 bail10:
1163 iounmap(c2dev->kva);
1164
1165 bail9:
1166 iounmap(c2dev->regs);
1167
1168 bail8:
1169 iounmap(c2dev->mmio_txp_ring);
1170
1171 bail7:
1172 iounmap(c2dev->mmio_rxp_ring);
1173
1174 bail6:
1175 unregister_netdev(netdev);
1176
1177 bail5:
1178 free_netdev(netdev);
1179
1180 bail4:
1181 free_irq(pcidev->irq, c2dev);
1182
1183 bail3:
1184 ib_dealloc_device(&c2dev->ibdev);
1185
1186 bail2:
1187 pci_release_regions(pcidev);
1188
1189 bail1:
1190 pci_disable_device(pcidev);
1191
1192 bail0:
1193 return ret;
1194}
1195
1196static void __devexit c2_remove(struct pci_dev *pcidev)
1197{
1198 struct c2_dev *c2dev = pci_get_drvdata(pcidev);
1199 struct net_device *netdev = c2dev->netdev;
1200
1201 /* Unregister with OpenIB */
1202 c2_unregister_device(c2dev);
1203
1204 /* Clean up the RNIC resources */
1205 c2_rnic_term(c2dev);
1206
1207 /* Remove network device from the kernel */
1208 unregister_netdev(netdev);
1209
1210 /* Free network device */
1211 free_netdev(netdev);
1212
1213 /* Free the interrupt line */
1214 free_irq(pcidev->irq, c2dev);
1215
1216 /* missing: Turn LEDs off here */
1217
1218 /* Unmap adapter PA space */
1219 iounmap(c2dev->kva);
1220 iounmap(c2dev->regs);
1221 iounmap(c2dev->mmio_txp_ring);
1222 iounmap(c2dev->mmio_rxp_ring);
1223
1224 /* Free the hardware structure */
1225 ib_dealloc_device(&c2dev->ibdev);
1226
1227 /* Release reserved PCI I/O and memory resources */
1228 pci_release_regions(pcidev);
1229
1230 /* Disable PCI device */
1231 pci_disable_device(pcidev);
1232
1233 /* Clear driver specific data */
1234 pci_set_drvdata(pcidev, NULL);
1235}
1236
1237static struct pci_driver c2_pci_driver = {
1238 .name = DRV_NAME,
1239 .id_table = c2_pci_table,
1240 .probe = c2_probe,
1241 .remove = __devexit_p(c2_remove),
1242};
1243
1244static int __init c2_init_module(void)
1245{
1246 return pci_module_init(&c2_pci_driver);
1247}
1248
1249static void __exit c2_exit_module(void)
1250{
1251 pci_unregister_driver(&c2_pci_driver);
1252}
1253
1254module_init(c2_init_module);
1255module_exit(c2_exit_module);
diff --git a/drivers/infiniband/hw/amso1100/c2.h b/drivers/infiniband/hw/amso1100/c2.h
new file mode 100644
index 000000000000..1b17dcdd0505
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2.h
@@ -0,0 +1,551 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34#ifndef __C2_H
35#define __C2_H
36
37#include <linux/netdevice.h>
38#include <linux/spinlock.h>
39#include <linux/kernel.h>
40#include <linux/pci.h>
41#include <linux/dma-mapping.h>
42#include <linux/idr.h>
43#include <asm/semaphore.h>
44
45#include "c2_provider.h"
46#include "c2_mq.h"
47#include "c2_status.h"
48
49#define DRV_NAME "c2"
50#define DRV_VERSION "1.1"
51#define PFX DRV_NAME ": "
52
53#define BAR_0 0
54#define BAR_2 2
55#define BAR_4 4
56
57#define RX_BUF_SIZE (1536 + 8)
58#define ETH_JUMBO_MTU 9000
59#define C2_MAGIC "CEPHEUS"
60#define C2_VERSION 4
61#define C2_IVN (18 & 0x7fffffff)
62
63#define C2_REG0_SIZE (16 * 1024)
64#define C2_REG2_SIZE (2 * 1024 * 1024)
65#define C2_REG4_SIZE (256 * 1024 * 1024)
66#define C2_NUM_TX_DESC 341
67#define C2_NUM_RX_DESC 256
68#define C2_PCI_REGS_OFFSET (0x10000)
69#define C2_RXP_HRXDQ_OFFSET (((C2_REG4_SIZE)/2))
70#define C2_RXP_HRXDQ_SIZE (4096)
71#define C2_TXP_HTXDQ_OFFSET (((C2_REG4_SIZE)/2) + C2_RXP_HRXDQ_SIZE)
72#define C2_TXP_HTXDQ_SIZE (4096)
73#define C2_TX_TIMEOUT (6*HZ)
74
75/* CEPHEUS */
76static const u8 c2_magic[] = {
77 0x43, 0x45, 0x50, 0x48, 0x45, 0x55, 0x53
78};
79
80enum adapter_pci_regs {
81 C2_REGS_MAGIC = 0x0000,
82 C2_REGS_VERS = 0x0008,
83 C2_REGS_IVN = 0x000C,
84 C2_REGS_PCI_WINSIZE = 0x0010,
85 C2_REGS_Q0_QSIZE = 0x0014,
86 C2_REGS_Q0_MSGSIZE = 0x0018,
87 C2_REGS_Q0_POOLSTART = 0x001C,
88 C2_REGS_Q0_SHARED = 0x0020,
89 C2_REGS_Q1_QSIZE = 0x0024,
90 C2_REGS_Q1_MSGSIZE = 0x0028,
91 C2_REGS_Q1_SHARED = 0x0030,
92 C2_REGS_Q2_QSIZE = 0x0034,
93 C2_REGS_Q2_MSGSIZE = 0x0038,
94 C2_REGS_Q2_SHARED = 0x0040,
95 C2_REGS_ENADDR = 0x004C,
96 C2_REGS_RDMA_ENADDR = 0x0054,
97 C2_REGS_HRX_CUR = 0x006C,
98};
99
100struct c2_adapter_pci_regs {
101 char reg_magic[8];
102 u32 version;
103 u32 ivn;
104 u32 pci_window_size;
105 u32 q0_q_size;
106 u32 q0_msg_size;
107 u32 q0_pool_start;
108 u32 q0_shared;
109 u32 q1_q_size;
110 u32 q1_msg_size;
111 u32 q1_pool_start;
112 u32 q1_shared;
113 u32 q2_q_size;
114 u32 q2_msg_size;
115 u32 q2_pool_start;
116 u32 q2_shared;
117 u32 log_start;
118 u32 log_size;
119 u8 host_enaddr[8];
120 u8 rdma_enaddr[8];
121 u32 crash_entry;
122 u32 crash_ready[2];
123 u32 fw_txd_cur;
124 u32 fw_hrxd_cur;
125 u32 fw_rxd_cur;
126};
127
128enum pci_regs {
129 C2_HISR = 0x0000,
130 C2_DISR = 0x0004,
131 C2_HIMR = 0x0008,
132 C2_DIMR = 0x000C,
133 C2_NISR0 = 0x0010,
134 C2_NISR1 = 0x0014,
135 C2_NIMR0 = 0x0018,
136 C2_NIMR1 = 0x001C,
137 C2_IDIS = 0x0020,
138};
139
140enum {
141 C2_PCI_HRX_INT = 1 << 8,
142 C2_PCI_HTX_INT = 1 << 17,
143 C2_PCI_HRX_QUI = 1 << 31,
144};
145
146/*
147 * Cepheus registers in BAR0.
148 */
149struct c2_pci_regs {
150 u32 hostisr;
151 u32 dmaisr;
152 u32 hostimr;
153 u32 dmaimr;
154 u32 netisr0;
155 u32 netisr1;
156 u32 netimr0;
157 u32 netimr1;
158 u32 int_disable;
159};
160
161/* TXP flags */
162enum c2_txp_flags {
163 TXP_HTXD_DONE = 0,
164 TXP_HTXD_READY = 1 << 0,
165 TXP_HTXD_UNINIT = 1 << 1,
166};
167
168/* RXP flags */
169enum c2_rxp_flags {
170 RXP_HRXD_UNINIT = 0,
171 RXP_HRXD_READY = 1 << 0,
172 RXP_HRXD_DONE = 1 << 1,
173};
174
175/* RXP status */
176enum c2_rxp_status {
177 RXP_HRXD_ZERO = 0,
178 RXP_HRXD_OK = 1 << 0,
179 RXP_HRXD_BUF_OV = 1 << 1,
180};
181
182/* TXP descriptor fields */
183enum txp_desc {
184 C2_TXP_FLAGS = 0x0000,
185 C2_TXP_LEN = 0x0002,
186 C2_TXP_ADDR = 0x0004,
187};
188
189/* RXP descriptor fields */
190enum rxp_desc {
191 C2_RXP_FLAGS = 0x0000,
192 C2_RXP_STATUS = 0x0002,
193 C2_RXP_COUNT = 0x0004,
194 C2_RXP_LEN = 0x0006,
195 C2_RXP_ADDR = 0x0008,
196};
197
198struct c2_txp_desc {
199 u16 flags;
200 u16 len;
201 u64 addr;
202} __attribute__ ((packed));
203
204struct c2_rxp_desc {
205 u16 flags;
206 u16 status;
207 u16 count;
208 u16 len;
209 u64 addr;
210} __attribute__ ((packed));
211
212struct c2_rxp_hdr {
213 u16 flags;
214 u16 status;
215 u16 len;
216 u16 rsvd;
217} __attribute__ ((packed));
218
219struct c2_tx_desc {
220 u32 len;
221 u32 status;
222 dma_addr_t next_offset;
223};
224
225struct c2_rx_desc {
226 u32 len;
227 u32 status;
228 dma_addr_t next_offset;
229};
230
231struct c2_alloc {
232 u32 last;
233 u32 max;
234 spinlock_t lock;
235 unsigned long *table;
236};
237
238struct c2_array {
239 struct {
240 void **page;
241 int used;
242 } *page_list;
243};
244
245/*
246 * The MQ shared pointer pool is organized as a linked list of
247 * chunks. Each chunk contains a linked list of free shared pointers
248 * that can be allocated to a given user mode client.
249 *
250 */
251struct sp_chunk {
252 struct sp_chunk *next;
253 dma_addr_t dma_addr;
254 DECLARE_PCI_UNMAP_ADDR(mapping);
255 u16 head;
256 u16 shared_ptr[0];
257};
258
259struct c2_pd_table {
260 u32 last;
261 u32 max;
262 spinlock_t lock;
263 unsigned long *table;
264};
265
266struct c2_qp_table {
267 struct idr idr;
268 spinlock_t lock;
269 int last;
270};
271
272struct c2_element {
273 struct c2_element *next;
274 void *ht_desc; /* host descriptor */
275 void __iomem *hw_desc; /* hardware descriptor */
276 struct sk_buff *skb;
277 dma_addr_t mapaddr;
278 u32 maplen;
279};
280
281struct c2_ring {
282 struct c2_element *to_clean;
283 struct c2_element *to_use;
284 struct c2_element *start;
285 unsigned long count;
286};
287
288struct c2_dev {
289 struct ib_device ibdev;
290 void __iomem *regs;
291 void __iomem *mmio_txp_ring; /* remapped adapter memory for hw rings */
292 void __iomem *mmio_rxp_ring;
293 spinlock_t lock;
294 struct pci_dev *pcidev;
295 struct net_device *netdev;
296 struct net_device *pseudo_netdev;
297 unsigned int cur_tx;
298 unsigned int cur_rx;
299 u32 adapter_handle;
300 int device_cap_flags;
301 void __iomem *kva; /* KVA device memory */
302 unsigned long pa; /* PA device memory */
303 void **qptr_array;
304
305 kmem_cache_t *host_msg_cache;
306
307 struct list_head cca_link; /* adapter list */
308 struct list_head eh_wakeup_list; /* event wakeup list */
309 wait_queue_head_t req_vq_wo;
310
311 /* Cached RNIC properties */
312 struct ib_device_attr props;
313
314 struct c2_pd_table pd_table;
315 struct c2_qp_table qp_table;
316 int ports; /* num of GigE ports */
317 int devnum;
318 spinlock_t vqlock; /* sync vbs req MQ */
319
320 /* Verbs Queues */
321 struct c2_mq req_vq; /* Verbs Request MQ */
322 struct c2_mq rep_vq; /* Verbs Reply MQ */
323 struct c2_mq aeq; /* Async Events MQ */
324
325 /* Kernel client MQs */
326 struct sp_chunk *kern_mqsp_pool;
327
328 /* Device updates these values when posting messages to a host
329 * target queue */
330 u16 req_vq_shared;
331 u16 rep_vq_shared;
332 u16 aeq_shared;
333 u16 irq_claimed;
334
335 /*
336 * Shared host target pages for user-accessible MQs.
337 */
338 int hthead; /* index of first free entry */
339 void *htpages; /* kernel vaddr */
340 int htlen; /* length of htpages memory */
341 void *htuva; /* user mapped vaddr */
342 spinlock_t htlock; /* serialize allocation */
343
344 u64 adapter_hint_uva; /* access to the activity FIFO */
345
346 // spinlock_t aeq_lock;
347 // spinlock_t rnic_lock;
348
349 u16 *hint_count;
350 dma_addr_t hint_count_dma;
351 u16 hints_read;
352
353 int init; /* TRUE if it's ready */
354 char ae_cache_name[16];
355 char vq_cache_name[16];
356};
357
358struct c2_port {
359 u32 msg_enable;
360 struct c2_dev *c2dev;
361 struct net_device *netdev;
362
363 spinlock_t tx_lock;
364 u32 tx_avail;
365 struct c2_ring tx_ring;
366 struct c2_ring rx_ring;
367
368 void *mem; /* PCI memory for host rings */
369 dma_addr_t dma;
370 unsigned long mem_size;
371
372 u32 rx_buf_size;
373
374 struct net_device_stats netstats;
375};
376
377/*
378 * Activity FIFO registers in BAR0.
379 */
380#define PCI_BAR0_HOST_HINT 0x100
381#define PCI_BAR0_ADAPTER_HINT 0x2000
382
383/*
384 * Ammasso PCI vendor id and Cepheus PCI device id.
385 */
386#define CQ_ARMED 0x01
387#define CQ_WAIT_FOR_DMA 0x80
388
389/*
390 * The format of a hint is as follows:
391 * Lower 16 bits are the count of hints for the queue.
392 * Next 15 bits are the qp_index
393 * Upper most bit depends on who reads it:
394 * If read by producer, then it means Full (1) or Not-Full (0)
395 * If read by consumer, then it means Empty (1) or Not-Empty (0)
396 */
397#define C2_HINT_MAKE(q_index, hint_count) (((q_index) << 16) | hint_count)
398#define C2_HINT_GET_INDEX(hint) (((hint) & 0x7FFF0000) >> 16)
399#define C2_HINT_GET_COUNT(hint) ((hint) & 0x0000FFFF)
400
401
402/*
403 * The following defines the offset in SDRAM for the c2_adapter_pci_regs_t
404 * struct.
405 */
406#define C2_ADAPTER_PCI_REGS_OFFSET 0x10000
407
408#ifndef readq
409static inline u64 readq(const void __iomem * addr)
410{
411 u64 ret = readl(addr + 4);
412 ret <<= 32;
413 ret |= readl(addr);
414
415 return ret;
416}
417#endif
418
419#ifndef writeq
420static inline void __raw_writeq(u64 val, void __iomem * addr)
421{
422 __raw_writel((u32) (val), addr);
423 __raw_writel((u32) (val >> 32), (addr + 4));
424}
425#endif
426
427#define C2_SET_CUR_RX(c2dev, cur_rx) \
428 __raw_writel(cpu_to_be32(cur_rx), c2dev->mmio_txp_ring + 4092)
429
430#define C2_GET_CUR_RX(c2dev) \
431 be32_to_cpu(readl(c2dev->mmio_txp_ring + 4092))
432
433static inline struct c2_dev *to_c2dev(struct ib_device *ibdev)
434{
435 return container_of(ibdev, struct c2_dev, ibdev);
436}
437
438static inline int c2_errno(void *reply)
439{
440 switch (c2_wr_get_result(reply)) {
441 case C2_OK:
442 return 0;
443 case CCERR_NO_BUFS:
444 case CCERR_INSUFFICIENT_RESOURCES:
445 case CCERR_ZERO_RDMA_READ_RESOURCES:
446 return -ENOMEM;
447 case CCERR_MR_IN_USE:
448 case CCERR_QP_IN_USE:
449 return -EBUSY;
450 case CCERR_ADDR_IN_USE:
451 return -EADDRINUSE;
452 case CCERR_ADDR_NOT_AVAIL:
453 return -EADDRNOTAVAIL;
454 case CCERR_CONN_RESET:
455 return -ECONNRESET;
456 case CCERR_NOT_IMPLEMENTED:
457 case CCERR_INVALID_WQE:
458 return -ENOSYS;
459 case CCERR_QP_NOT_PRIVILEGED:
460 return -EPERM;
461 case CCERR_STACK_ERROR:
462 return -EPROTO;
463 case CCERR_ACCESS_VIOLATION:
464 case CCERR_BASE_AND_BOUNDS_VIOLATION:
465 return -EFAULT;
466 case CCERR_STAG_STATE_NOT_INVALID:
467 case CCERR_INVALID_ADDRESS:
468 case CCERR_INVALID_CQ:
469 case CCERR_INVALID_EP:
470 case CCERR_INVALID_MODIFIER:
471 case CCERR_INVALID_MTU:
472 case CCERR_INVALID_PD_ID:
473 case CCERR_INVALID_QP:
474 case CCERR_INVALID_RNIC:
475 case CCERR_INVALID_STAG:
476 return -EINVAL;
477 default:
478 return -EAGAIN;
479 }
480}
481
482/* Device */
483extern int c2_register_device(struct c2_dev *c2dev);
484extern void c2_unregister_device(struct c2_dev *c2dev);
485extern int c2_rnic_init(struct c2_dev *c2dev);
486extern void c2_rnic_term(struct c2_dev *c2dev);
487extern void c2_rnic_interrupt(struct c2_dev *c2dev);
488extern int c2_del_addr(struct c2_dev *c2dev, u32 inaddr, u32 inmask);
489extern int c2_add_addr(struct c2_dev *c2dev, u32 inaddr, u32 inmask);
490
491/* QPs */
492extern int c2_alloc_qp(struct c2_dev *c2dev, struct c2_pd *pd,
493 struct ib_qp_init_attr *qp_attrs, struct c2_qp *qp);
494extern void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp);
495extern struct ib_qp *c2_get_qp(struct ib_device *device, int qpn);
496extern int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp,
497 struct ib_qp_attr *attr, int attr_mask);
498extern int c2_qp_set_read_limits(struct c2_dev *c2dev, struct c2_qp *qp,
499 int ord, int ird);
500extern int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
501 struct ib_send_wr **bad_wr);
502extern int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
503 struct ib_recv_wr **bad_wr);
504extern void __devinit c2_init_qp_table(struct c2_dev *c2dev);
505extern void __devexit c2_cleanup_qp_table(struct c2_dev *c2dev);
506extern void c2_set_qp_state(struct c2_qp *, int);
507extern struct c2_qp *c2_find_qpn(struct c2_dev *c2dev, int qpn);
508
509/* PDs */
510extern int c2_pd_alloc(struct c2_dev *c2dev, int privileged, struct c2_pd *pd);
511extern void c2_pd_free(struct c2_dev *c2dev, struct c2_pd *pd);
512extern int __devinit c2_init_pd_table(struct c2_dev *c2dev);
513extern void __devexit c2_cleanup_pd_table(struct c2_dev *c2dev);
514
515/* CQs */
516extern int c2_init_cq(struct c2_dev *c2dev, int entries,
517 struct c2_ucontext *ctx, struct c2_cq *cq);
518extern void c2_free_cq(struct c2_dev *c2dev, struct c2_cq *cq);
519extern void c2_cq_event(struct c2_dev *c2dev, u32 mq_index);
520extern void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index);
521extern int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry);
522extern int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify);
523
524/* CM */
525extern int c2_llp_connect(struct iw_cm_id *cm_id,
526 struct iw_cm_conn_param *iw_param);
527extern int c2_llp_accept(struct iw_cm_id *cm_id,
528 struct iw_cm_conn_param *iw_param);
529extern int c2_llp_reject(struct iw_cm_id *cm_id, const void *pdata,
530 u8 pdata_len);
531extern int c2_llp_service_create(struct iw_cm_id *cm_id, int backlog);
532extern int c2_llp_service_destroy(struct iw_cm_id *cm_id);
533
534/* MM */
535extern int c2_nsmr_register_phys_kern(struct c2_dev *c2dev, u64 *addr_list,
536 int page_size, int pbl_depth, u32 length,
537 u32 off, u64 *va, enum c2_acf acf,
538 struct c2_mr *mr);
539extern int c2_stag_dealloc(struct c2_dev *c2dev, u32 stag_index);
540
541/* AE */
542extern void c2_ae_event(struct c2_dev *c2dev, u32 mq_index);
543
544/* MQSP Allocator */
545extern int c2_init_mqsp_pool(struct c2_dev *c2dev, gfp_t gfp_mask,
546 struct sp_chunk **root);
547extern void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root);
548extern u16 *c2_alloc_mqsp(struct c2_dev *c2dev, struct sp_chunk *head,
549 dma_addr_t *dma_addr, gfp_t gfp_mask);
550extern void c2_free_mqsp(u16 * mqsp);
551#endif
diff --git a/drivers/infiniband/hw/amso1100/c2_ae.c b/drivers/infiniband/hw/amso1100/c2_ae.c
new file mode 100644
index 000000000000..08f46c83a3a4
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_ae.c
@@ -0,0 +1,321 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#include "c2.h"
34#include <rdma/iw_cm.h>
35#include "c2_status.h"
36#include "c2_ae.h"
37
38static int c2_convert_cm_status(u32 c2_status)
39{
40 switch (c2_status) {
41 case C2_CONN_STATUS_SUCCESS:
42 return 0;
43 case C2_CONN_STATUS_REJECTED:
44 return -ENETRESET;
45 case C2_CONN_STATUS_REFUSED:
46 return -ECONNREFUSED;
47 case C2_CONN_STATUS_TIMEDOUT:
48 return -ETIMEDOUT;
49 case C2_CONN_STATUS_NETUNREACH:
50 return -ENETUNREACH;
51 case C2_CONN_STATUS_HOSTUNREACH:
52 return -EHOSTUNREACH;
53 case C2_CONN_STATUS_INVALID_RNIC:
54 return -EINVAL;
55 case C2_CONN_STATUS_INVALID_QP:
56 return -EINVAL;
57 case C2_CONN_STATUS_INVALID_QP_STATE:
58 return -EINVAL;
59 case C2_CONN_STATUS_ADDR_NOT_AVAIL:
60 return -EADDRNOTAVAIL;
61 default:
62 printk(KERN_ERR PFX
63 "%s - Unable to convert CM status: %d\n",
64 __FUNCTION__, c2_status);
65 return -EIO;
66 }
67}
68
69#ifdef DEBUG
70static const char* to_event_str(int event)
71{
72 static const char* event_str[] = {
73 "CCAE_REMOTE_SHUTDOWN",
74 "CCAE_ACTIVE_CONNECT_RESULTS",
75 "CCAE_CONNECTION_REQUEST",
76 "CCAE_LLP_CLOSE_COMPLETE",
77 "CCAE_TERMINATE_MESSAGE_RECEIVED",
78 "CCAE_LLP_CONNECTION_RESET",
79 "CCAE_LLP_CONNECTION_LOST",
80 "CCAE_LLP_SEGMENT_SIZE_INVALID",
81 "CCAE_LLP_INVALID_CRC",
82 "CCAE_LLP_BAD_FPDU",
83 "CCAE_INVALID_DDP_VERSION",
84 "CCAE_INVALID_RDMA_VERSION",
85 "CCAE_UNEXPECTED_OPCODE",
86 "CCAE_INVALID_DDP_QUEUE_NUMBER",
87 "CCAE_RDMA_READ_NOT_ENABLED",
88 "CCAE_RDMA_WRITE_NOT_ENABLED",
89 "CCAE_RDMA_READ_TOO_SMALL",
90 "CCAE_NO_L_BIT",
91 "CCAE_TAGGED_INVALID_STAG",
92 "CCAE_TAGGED_BASE_BOUNDS_VIOLATION",
93 "CCAE_TAGGED_ACCESS_RIGHTS_VIOLATION",
94 "CCAE_TAGGED_INVALID_PD",
95 "CCAE_WRAP_ERROR",
96 "CCAE_BAD_CLOSE",
97 "CCAE_BAD_LLP_CLOSE",
98 "CCAE_INVALID_MSN_RANGE",
99 "CCAE_INVALID_MSN_GAP",
100 "CCAE_IRRQ_OVERFLOW",
101 "CCAE_IRRQ_MSN_GAP",
102 "CCAE_IRRQ_MSN_RANGE",
103 "CCAE_IRRQ_INVALID_STAG",
104 "CCAE_IRRQ_BASE_BOUNDS_VIOLATION",
105 "CCAE_IRRQ_ACCESS_RIGHTS_VIOLATION",
106 "CCAE_IRRQ_INVALID_PD",
107 "CCAE_IRRQ_WRAP_ERROR",
108 "CCAE_CQ_SQ_COMPLETION_OVERFLOW",
109 "CCAE_CQ_RQ_COMPLETION_ERROR",
110 "CCAE_QP_SRQ_WQE_ERROR",
111 "CCAE_QP_LOCAL_CATASTROPHIC_ERROR",
112 "CCAE_CQ_OVERFLOW",
113 "CCAE_CQ_OPERATION_ERROR",
114 "CCAE_SRQ_LIMIT_REACHED",
115 "CCAE_QP_RQ_LIMIT_REACHED",
116 "CCAE_SRQ_CATASTROPHIC_ERROR",
117 "CCAE_RNIC_CATASTROPHIC_ERROR"
118 };
119
120 if (event < CCAE_REMOTE_SHUTDOWN ||
121 event > CCAE_RNIC_CATASTROPHIC_ERROR)
122 return "<invalid event>";
123
124 event -= CCAE_REMOTE_SHUTDOWN;
125 return event_str[event];
126}
127
128static const char *to_qp_state_str(int state)
129{
130 switch (state) {
131 case C2_QP_STATE_IDLE:
132 return "C2_QP_STATE_IDLE";
133 case C2_QP_STATE_CONNECTING:
134 return "C2_QP_STATE_CONNECTING";
135 case C2_QP_STATE_RTS:
136 return "C2_QP_STATE_RTS";
137 case C2_QP_STATE_CLOSING:
138 return "C2_QP_STATE_CLOSING";
139 case C2_QP_STATE_TERMINATE:
140 return "C2_QP_STATE_TERMINATE";
141 case C2_QP_STATE_ERROR:
142 return "C2_QP_STATE_ERROR";
143 default:
144 return "<invalid QP state>";
145 };
146}
147#endif
148
149void c2_ae_event(struct c2_dev *c2dev, u32 mq_index)
150{
151 struct c2_mq *mq = c2dev->qptr_array[mq_index];
152 union c2wr *wr;
153 void *resource_user_context;
154 struct iw_cm_event cm_event;
155 struct ib_event ib_event;
156 enum c2_resource_indicator resource_indicator;
157 enum c2_event_id event_id;
158 unsigned long flags;
159 int status;
160
161 /*
162 * retreive the message
163 */
164 wr = c2_mq_consume(mq);
165 if (!wr)
166 return;
167
168 memset(&ib_event, 0, sizeof(ib_event));
169 memset(&cm_event, 0, sizeof(cm_event));
170
171 event_id = c2_wr_get_id(wr);
172 resource_indicator = be32_to_cpu(wr->ae.ae_generic.resource_type);
173 resource_user_context =
174 (void *) (unsigned long) wr->ae.ae_generic.user_context;
175
176 status = cm_event.status = c2_convert_cm_status(c2_wr_get_result(wr));
177
178 pr_debug("event received c2_dev=%p, event_id=%d, "
179 "resource_indicator=%d, user_context=%p, status = %d\n",
180 c2dev, event_id, resource_indicator, resource_user_context,
181 status);
182
183 switch (resource_indicator) {
184 case C2_RES_IND_QP:{
185
186 struct c2_qp *qp = (struct c2_qp *)resource_user_context;
187 struct iw_cm_id *cm_id = qp->cm_id;
188 struct c2wr_ae_active_connect_results *res;
189
190 if (!cm_id) {
191 pr_debug("event received, but cm_id is <nul>, qp=%p!\n",
192 qp);
193 goto ignore_it;
194 }
195 pr_debug("%s: event = %s, user_context=%llx, "
196 "resource_type=%x, "
197 "resource=%x, qp_state=%s\n",
198 __FUNCTION__,
199 to_event_str(event_id),
200 be64_to_cpu(wr->ae.ae_generic.user_context),
201 be32_to_cpu(wr->ae.ae_generic.resource_type),
202 be32_to_cpu(wr->ae.ae_generic.resource),
203 to_qp_state_str(be32_to_cpu(wr->ae.ae_generic.qp_state)));
204
205 c2_set_qp_state(qp, be32_to_cpu(wr->ae.ae_generic.qp_state));
206
207 switch (event_id) {
208 case CCAE_ACTIVE_CONNECT_RESULTS:
209 res = &wr->ae.ae_active_connect_results;
210 cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
211 cm_event.local_addr.sin_addr.s_addr = res->laddr;
212 cm_event.remote_addr.sin_addr.s_addr = res->raddr;
213 cm_event.local_addr.sin_port = res->lport;
214 cm_event.remote_addr.sin_port = res->rport;
215 if (status == 0) {
216 cm_event.private_data_len =
217 be32_to_cpu(res->private_data_length);
218 cm_event.private_data = res->private_data;
219 } else {
220 spin_lock_irqsave(&qp->lock, flags);
221 if (qp->cm_id) {
222 qp->cm_id->rem_ref(qp->cm_id);
223 qp->cm_id = NULL;
224 }
225 spin_unlock_irqrestore(&qp->lock, flags);
226 cm_event.private_data_len = 0;
227 cm_event.private_data = NULL;
228 }
229 if (cm_id->event_handler)
230 cm_id->event_handler(cm_id, &cm_event);
231 break;
232 case CCAE_TERMINATE_MESSAGE_RECEIVED:
233 case CCAE_CQ_SQ_COMPLETION_OVERFLOW:
234 ib_event.device = &c2dev->ibdev;
235 ib_event.element.qp = &qp->ibqp;
236 ib_event.event = IB_EVENT_QP_REQ_ERR;
237
238 if (qp->ibqp.event_handler)
239 qp->ibqp.event_handler(&ib_event,
240 qp->ibqp.
241 qp_context);
242 break;
243 case CCAE_BAD_CLOSE:
244 case CCAE_LLP_CLOSE_COMPLETE:
245 case CCAE_LLP_CONNECTION_RESET:
246 case CCAE_LLP_CONNECTION_LOST:
247 BUG_ON(cm_id->event_handler==(void*)0x6b6b6b6b);
248
249 spin_lock_irqsave(&qp->lock, flags);
250 if (qp->cm_id) {
251 qp->cm_id->rem_ref(qp->cm_id);
252 qp->cm_id = NULL;
253 }
254 spin_unlock_irqrestore(&qp->lock, flags);
255 cm_event.event = IW_CM_EVENT_CLOSE;
256 cm_event.status = 0;
257 if (cm_id->event_handler)
258 cm_id->event_handler(cm_id, &cm_event);
259 break;
260 default:
261 BUG_ON(1);
262 pr_debug("%s:%d Unexpected event_id=%d on QP=%p, "
263 "CM_ID=%p\n",
264 __FUNCTION__, __LINE__,
265 event_id, qp, cm_id);
266 break;
267 }
268 break;
269 }
270
271 case C2_RES_IND_EP:{
272
273 struct c2wr_ae_connection_request *req =
274 &wr->ae.ae_connection_request;
275 struct iw_cm_id *cm_id =
276 (struct iw_cm_id *)resource_user_context;
277
278 pr_debug("C2_RES_IND_EP event_id=%d\n", event_id);
279 if (event_id != CCAE_CONNECTION_REQUEST) {
280 pr_debug("%s: Invalid event_id: %d\n",
281 __FUNCTION__, event_id);
282 break;
283 }
284 cm_event.event = IW_CM_EVENT_CONNECT_REQUEST;
285 cm_event.provider_data = (void*)(unsigned long)req->cr_handle;
286 cm_event.local_addr.sin_addr.s_addr = req->laddr;
287 cm_event.remote_addr.sin_addr.s_addr = req->raddr;
288 cm_event.local_addr.sin_port = req->lport;
289 cm_event.remote_addr.sin_port = req->rport;
290 cm_event.private_data_len =
291 be32_to_cpu(req->private_data_length);
292 cm_event.private_data = req->private_data;
293
294 if (cm_id->event_handler)
295 cm_id->event_handler(cm_id, &cm_event);
296 break;
297 }
298
299 case C2_RES_IND_CQ:{
300 struct c2_cq *cq =
301 (struct c2_cq *) resource_user_context;
302
303 pr_debug("IB_EVENT_CQ_ERR\n");
304 ib_event.device = &c2dev->ibdev;
305 ib_event.element.cq = &cq->ibcq;
306 ib_event.event = IB_EVENT_CQ_ERR;
307
308 if (cq->ibcq.event_handler)
309 cq->ibcq.event_handler(&ib_event,
310 cq->ibcq.cq_context);
311 }
312
313 default:
314 printk("Bad resource indicator = %d\n",
315 resource_indicator);
316 break;
317 }
318
319 ignore_it:
320 c2_mq_free(mq);
321}
diff --git a/drivers/infiniband/hw/amso1100/c2_ae.h b/drivers/infiniband/hw/amso1100/c2_ae.h
new file mode 100644
index 000000000000..3a065c33b83b
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_ae.h
@@ -0,0 +1,108 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#ifndef _C2_AE_H_
34#define _C2_AE_H_
35
36/*
37 * WARNING: If you change this file, also bump C2_IVN_BASE
38 * in common/include/clustercore/c2_ivn.h.
39 */
40
41/*
42 * Asynchronous Event Identifiers
43 *
44 * These start at 0x80 only so it's obvious from inspection that
45 * they are not work-request statuses. This isn't critical.
46 *
47 * NOTE: these event id's must fit in eight bits.
48 */
49enum c2_event_id {
50 CCAE_REMOTE_SHUTDOWN = 0x80,
51 CCAE_ACTIVE_CONNECT_RESULTS,
52 CCAE_CONNECTION_REQUEST,
53 CCAE_LLP_CLOSE_COMPLETE,
54 CCAE_TERMINATE_MESSAGE_RECEIVED,
55 CCAE_LLP_CONNECTION_RESET,
56 CCAE_LLP_CONNECTION_LOST,
57 CCAE_LLP_SEGMENT_SIZE_INVALID,
58 CCAE_LLP_INVALID_CRC,
59 CCAE_LLP_BAD_FPDU,
60 CCAE_INVALID_DDP_VERSION,
61 CCAE_INVALID_RDMA_VERSION,
62 CCAE_UNEXPECTED_OPCODE,
63 CCAE_INVALID_DDP_QUEUE_NUMBER,
64 CCAE_RDMA_READ_NOT_ENABLED,
65 CCAE_RDMA_WRITE_NOT_ENABLED,
66 CCAE_RDMA_READ_TOO_SMALL,
67 CCAE_NO_L_BIT,
68 CCAE_TAGGED_INVALID_STAG,
69 CCAE_TAGGED_BASE_BOUNDS_VIOLATION,
70 CCAE_TAGGED_ACCESS_RIGHTS_VIOLATION,
71 CCAE_TAGGED_INVALID_PD,
72 CCAE_WRAP_ERROR,
73 CCAE_BAD_CLOSE,
74 CCAE_BAD_LLP_CLOSE,
75 CCAE_INVALID_MSN_RANGE,
76 CCAE_INVALID_MSN_GAP,
77 CCAE_IRRQ_OVERFLOW,
78 CCAE_IRRQ_MSN_GAP,
79 CCAE_IRRQ_MSN_RANGE,
80 CCAE_IRRQ_INVALID_STAG,
81 CCAE_IRRQ_BASE_BOUNDS_VIOLATION,
82 CCAE_IRRQ_ACCESS_RIGHTS_VIOLATION,
83 CCAE_IRRQ_INVALID_PD,
84 CCAE_IRRQ_WRAP_ERROR,
85 CCAE_CQ_SQ_COMPLETION_OVERFLOW,
86 CCAE_CQ_RQ_COMPLETION_ERROR,
87 CCAE_QP_SRQ_WQE_ERROR,
88 CCAE_QP_LOCAL_CATASTROPHIC_ERROR,
89 CCAE_CQ_OVERFLOW,
90 CCAE_CQ_OPERATION_ERROR,
91 CCAE_SRQ_LIMIT_REACHED,
92 CCAE_QP_RQ_LIMIT_REACHED,
93 CCAE_SRQ_CATASTROPHIC_ERROR,
94 CCAE_RNIC_CATASTROPHIC_ERROR
95/* WARNING If you add more id's, make sure their values fit in eight bits. */
96};
97
98/*
99 * Resource Indicators and Identifiers
100 */
101enum c2_resource_indicator {
102 C2_RES_IND_QP = 1,
103 C2_RES_IND_EP,
104 C2_RES_IND_CQ,
105 C2_RES_IND_SRQ,
106};
107
108#endif /* _C2_AE_H_ */
diff --git a/drivers/infiniband/hw/amso1100/c2_alloc.c b/drivers/infiniband/hw/amso1100/c2_alloc.c
new file mode 100644
index 000000000000..1d2529992c0c
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_alloc.c
@@ -0,0 +1,144 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34#include <linux/errno.h>
35#include <linux/slab.h>
36#include <linux/bitmap.h>
37
38#include "c2.h"
39
40static int c2_alloc_mqsp_chunk(struct c2_dev *c2dev, gfp_t gfp_mask,
41 struct sp_chunk **head)
42{
43 int i;
44 struct sp_chunk *new_head;
45
46 new_head = (struct sp_chunk *) __get_free_page(gfp_mask);
47 if (new_head == NULL)
48 return -ENOMEM;
49
50 new_head->dma_addr = dma_map_single(c2dev->ibdev.dma_device, new_head,
51 PAGE_SIZE, DMA_FROM_DEVICE);
52 pci_unmap_addr_set(new_head, mapping, new_head->dma_addr);
53
54 new_head->next = NULL;
55 new_head->head = 0;
56
57 /* build list where each index is the next free slot */
58 for (i = 0;
59 i < (PAGE_SIZE - sizeof(struct sp_chunk) -
60 sizeof(u16)) / sizeof(u16) - 1;
61 i++) {
62 new_head->shared_ptr[i] = i + 1;
63 }
64 /* terminate list */
65 new_head->shared_ptr[i] = 0xFFFF;
66
67 *head = new_head;
68 return 0;
69}
70
71int c2_init_mqsp_pool(struct c2_dev *c2dev, gfp_t gfp_mask,
72 struct sp_chunk **root)
73{
74 return c2_alloc_mqsp_chunk(c2dev, gfp_mask, root);
75}
76
77void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root)
78{
79 struct sp_chunk *next;
80
81 while (root) {
82 next = root->next;
83 dma_unmap_single(c2dev->ibdev.dma_device,
84 pci_unmap_addr(root, mapping), PAGE_SIZE,
85 DMA_FROM_DEVICE);
86 __free_page((struct page *) root);
87 root = next;
88 }
89}
90
91u16 *c2_alloc_mqsp(struct c2_dev *c2dev, struct sp_chunk *head,
92 dma_addr_t *dma_addr, gfp_t gfp_mask)
93{
94 u16 mqsp;
95
96 while (head) {
97 mqsp = head->head;
98 if (mqsp != 0xFFFF) {
99 head->head = head->shared_ptr[mqsp];
100 break;
101 } else if (head->next == NULL) {
102 if (c2_alloc_mqsp_chunk(c2dev, gfp_mask, &head->next) ==
103 0) {
104 head = head->next;
105 mqsp = head->head;
106 head->head = head->shared_ptr[mqsp];
107 break;
108 } else
109 return NULL;
110 } else
111 head = head->next;
112 }
113 if (head) {
114 *dma_addr = head->dma_addr +
115 ((unsigned long) &(head->shared_ptr[mqsp]) -
116 (unsigned long) head);
117 pr_debug("%s addr %p dma_addr %llx\n", __FUNCTION__,
118 &(head->shared_ptr[mqsp]), (u64)*dma_addr);
119 return &(head->shared_ptr[mqsp]);
120 }
121 return NULL;
122}
123
124void c2_free_mqsp(u16 * mqsp)
125{
126 struct sp_chunk *head;
127 u16 idx;
128
129 /* The chunk containing this ptr begins at the page boundary */
130 head = (struct sp_chunk *) ((unsigned long) mqsp & PAGE_MASK);
131
132 /* Link head to new mqsp */
133 *mqsp = head->head;
134
135 /* Compute the shared_ptr index */
136 idx = ((unsigned long) mqsp & ~PAGE_MASK) >> 1;
137 idx -= (unsigned long) &(((struct sp_chunk *) 0)->shared_ptr[0]) >> 1;
138
139 /* Point this index at the head */
140 head->shared_ptr[idx] = head->head;
141
142 /* Point head at this index */
143 head->head = idx;
144}
diff --git a/drivers/infiniband/hw/amso1100/c2_cm.c b/drivers/infiniband/hw/amso1100/c2_cm.c
new file mode 100644
index 000000000000..485254efdd1e
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_cm.c
@@ -0,0 +1,452 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34#include "c2.h"
35#include "c2_wr.h"
36#include "c2_vq.h"
37#include <rdma/iw_cm.h>
38
39int c2_llp_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
40{
41 struct c2_dev *c2dev = to_c2dev(cm_id->device);
42 struct ib_qp *ibqp;
43 struct c2_qp *qp;
44 struct c2wr_qp_connect_req *wr; /* variable size needs a malloc. */
45 struct c2_vq_req *vq_req;
46 int err;
47
48 ibqp = c2_get_qp(cm_id->device, iw_param->qpn);
49 if (!ibqp)
50 return -EINVAL;
51 qp = to_c2qp(ibqp);
52
53 /* Associate QP <--> CM_ID */
54 cm_id->provider_data = qp;
55 cm_id->add_ref(cm_id);
56 qp->cm_id = cm_id;
57
58 /*
59 * only support the max private_data length
60 */
61 if (iw_param->private_data_len > C2_MAX_PRIVATE_DATA_SIZE) {
62 err = -EINVAL;
63 goto bail0;
64 }
65 /*
66 * Set the rdma read limits
67 */
68 err = c2_qp_set_read_limits(c2dev, qp, iw_param->ord, iw_param->ird);
69 if (err)
70 goto bail0;
71
72 /*
73 * Create and send a WR_QP_CONNECT...
74 */
75 wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL);
76 if (!wr) {
77 err = -ENOMEM;
78 goto bail0;
79 }
80
81 vq_req = vq_req_alloc(c2dev);
82 if (!vq_req) {
83 err = -ENOMEM;
84 goto bail1;
85 }
86
87 c2_wr_set_id(wr, CCWR_QP_CONNECT);
88 wr->hdr.context = 0;
89 wr->rnic_handle = c2dev->adapter_handle;
90 wr->qp_handle = qp->adapter_handle;
91
92 wr->remote_addr = cm_id->remote_addr.sin_addr.s_addr;
93 wr->remote_port = cm_id->remote_addr.sin_port;
94
95 /*
96 * Move any private data from the callers's buf into
97 * the WR.
98 */
99 if (iw_param->private_data) {
100 wr->private_data_length =
101 cpu_to_be32(iw_param->private_data_len);
102 memcpy(&wr->private_data[0], iw_param->private_data,
103 iw_param->private_data_len);
104 } else
105 wr->private_data_length = 0;
106
107 /*
108 * Send WR to adapter. NOTE: There is no synch reply from
109 * the adapter.
110 */
111 err = vq_send_wr(c2dev, (union c2wr *) wr);
112 vq_req_free(c2dev, vq_req);
113
114 bail1:
115 kfree(wr);
116 bail0:
117 if (err) {
118 /*
119 * If we fail, release reference on QP and
120 * disassociate QP from CM_ID
121 */
122 cm_id->provider_data = NULL;
123 qp->cm_id = NULL;
124 cm_id->rem_ref(cm_id);
125 }
126 return err;
127}
128
129int c2_llp_service_create(struct iw_cm_id *cm_id, int backlog)
130{
131 struct c2_dev *c2dev;
132 struct c2wr_ep_listen_create_req wr;
133 struct c2wr_ep_listen_create_rep *reply;
134 struct c2_vq_req *vq_req;
135 int err;
136
137 c2dev = to_c2dev(cm_id->device);
138 if (c2dev == NULL)
139 return -EINVAL;
140
141 /*
142 * Allocate verbs request.
143 */
144 vq_req = vq_req_alloc(c2dev);
145 if (!vq_req)
146 return -ENOMEM;
147
148 /*
149 * Build the WR
150 */
151 c2_wr_set_id(&wr, CCWR_EP_LISTEN_CREATE);
152 wr.hdr.context = (u64) (unsigned long) vq_req;
153 wr.rnic_handle = c2dev->adapter_handle;
154 wr.local_addr = cm_id->local_addr.sin_addr.s_addr;
155 wr.local_port = cm_id->local_addr.sin_port;
156 wr.backlog = cpu_to_be32(backlog);
157 wr.user_context = (u64) (unsigned long) cm_id;
158
159 /*
160 * Reference the request struct. Dereferenced in the int handler.
161 */
162 vq_req_get(c2dev, vq_req);
163
164 /*
165 * Send WR to adapter
166 */
167 err = vq_send_wr(c2dev, (union c2wr *) & wr);
168 if (err) {
169 vq_req_put(c2dev, vq_req);
170 goto bail0;
171 }
172
173 /*
174 * Wait for reply from adapter
175 */
176 err = vq_wait_for_reply(c2dev, vq_req);
177 if (err)
178 goto bail0;
179
180 /*
181 * Process reply
182 */
183 reply =
184 (struct c2wr_ep_listen_create_rep *) (unsigned long) vq_req->reply_msg;
185 if (!reply) {
186 err = -ENOMEM;
187 goto bail1;
188 }
189
190 if ((err = c2_errno(reply)) != 0)
191 goto bail1;
192
193 /*
194 * Keep the adapter handle. Used in subsequent destroy
195 */
196 cm_id->provider_data = (void*)(unsigned long) reply->ep_handle;
197
198 /*
199 * free vq stuff
200 */
201 vq_repbuf_free(c2dev, reply);
202 vq_req_free(c2dev, vq_req);
203
204 return 0;
205
206 bail1:
207 vq_repbuf_free(c2dev, reply);
208 bail0:
209 vq_req_free(c2dev, vq_req);
210 return err;
211}
212
213
214int c2_llp_service_destroy(struct iw_cm_id *cm_id)
215{
216
217 struct c2_dev *c2dev;
218 struct c2wr_ep_listen_destroy_req wr;
219 struct c2wr_ep_listen_destroy_rep *reply;
220 struct c2_vq_req *vq_req;
221 int err;
222
223 c2dev = to_c2dev(cm_id->device);
224 if (c2dev == NULL)
225 return -EINVAL;
226
227 /*
228 * Allocate verbs request.
229 */
230 vq_req = vq_req_alloc(c2dev);
231 if (!vq_req)
232 return -ENOMEM;
233
234 /*
235 * Build the WR
236 */
237 c2_wr_set_id(&wr, CCWR_EP_LISTEN_DESTROY);
238 wr.hdr.context = (unsigned long) vq_req;
239 wr.rnic_handle = c2dev->adapter_handle;
240 wr.ep_handle = (u32)(unsigned long)cm_id->provider_data;
241
242 /*
243 * reference the request struct. dereferenced in the int handler.
244 */
245 vq_req_get(c2dev, vq_req);
246
247 /*
248 * Send WR to adapter
249 */
250 err = vq_send_wr(c2dev, (union c2wr *) & wr);
251 if (err) {
252 vq_req_put(c2dev, vq_req);
253 goto bail0;
254 }
255
256 /*
257 * Wait for reply from adapter
258 */
259 err = vq_wait_for_reply(c2dev, vq_req);
260 if (err)
261 goto bail0;
262
263 /*
264 * Process reply
265 */
266 reply=(struct c2wr_ep_listen_destroy_rep *)(unsigned long)vq_req->reply_msg;
267 if (!reply) {
268 err = -ENOMEM;
269 goto bail0;
270 }
271 if ((err = c2_errno(reply)) != 0)
272 goto bail1;
273
274 bail1:
275 vq_repbuf_free(c2dev, reply);
276 bail0:
277 vq_req_free(c2dev, vq_req);
278 return err;
279}
280
281int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
282{
283 struct c2_dev *c2dev = to_c2dev(cm_id->device);
284 struct c2_qp *qp;
285 struct ib_qp *ibqp;
286 struct c2wr_cr_accept_req *wr; /* variable length WR */
287 struct c2_vq_req *vq_req;
288 struct c2wr_cr_accept_rep *reply; /* VQ Reply msg ptr. */
289 int err;
290
291 ibqp = c2_get_qp(cm_id->device, iw_param->qpn);
292 if (!ibqp)
293 return -EINVAL;
294 qp = to_c2qp(ibqp);
295
296 /* Set the RDMA read limits */
297 err = c2_qp_set_read_limits(c2dev, qp, iw_param->ord, iw_param->ird);
298 if (err)
299 goto bail0;
300
301 /* Allocate verbs request. */
302 vq_req = vq_req_alloc(c2dev);
303 if (!vq_req) {
304 err = -ENOMEM;
305 goto bail1;
306 }
307 vq_req->qp = qp;
308 vq_req->cm_id = cm_id;
309 vq_req->event = IW_CM_EVENT_ESTABLISHED;
310
311 wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL);
312 if (!wr) {
313 err = -ENOMEM;
314 goto bail2;
315 }
316
317 /* Build the WR */
318 c2_wr_set_id(wr, CCWR_CR_ACCEPT);
319 wr->hdr.context = (unsigned long) vq_req;
320 wr->rnic_handle = c2dev->adapter_handle;
321 wr->ep_handle = (u32) (unsigned long) cm_id->provider_data;
322 wr->qp_handle = qp->adapter_handle;
323
324 /* Replace the cr_handle with the QP after accept */
325 cm_id->provider_data = qp;
326 cm_id->add_ref(cm_id);
327 qp->cm_id = cm_id;
328
329 cm_id->provider_data = qp;
330
331 /* Validate private_data length */
332 if (iw_param->private_data_len > C2_MAX_PRIVATE_DATA_SIZE) {
333 err = -EINVAL;
334 goto bail2;
335 }
336
337 if (iw_param->private_data) {
338 wr->private_data_length = cpu_to_be32(iw_param->private_data_len);
339 memcpy(&wr->private_data[0],
340 iw_param->private_data, iw_param->private_data_len);
341 } else
342 wr->private_data_length = 0;
343
344 /* Reference the request struct. Dereferenced in the int handler. */
345 vq_req_get(c2dev, vq_req);
346
347 /* Send WR to adapter */
348 err = vq_send_wr(c2dev, (union c2wr *) wr);
349 if (err) {
350 vq_req_put(c2dev, vq_req);
351 goto bail2;
352 }
353
354 /* Wait for reply from adapter */
355 err = vq_wait_for_reply(c2dev, vq_req);
356 if (err)
357 goto bail2;
358
359 /* Check that reply is present */
360 reply = (struct c2wr_cr_accept_rep *) (unsigned long) vq_req->reply_msg;
361 if (!reply) {
362 err = -ENOMEM;
363 goto bail2;
364 }
365
366 err = c2_errno(reply);
367 vq_repbuf_free(c2dev, reply);
368
369 if (!err)
370 c2_set_qp_state(qp, C2_QP_STATE_RTS);
371 bail2:
372 kfree(wr);
373 bail1:
374 vq_req_free(c2dev, vq_req);
375 bail0:
376 if (err) {
377 /*
378 * If we fail, release reference on QP and
379 * disassociate QP from CM_ID
380 */
381 cm_id->provider_data = NULL;
382 qp->cm_id = NULL;
383 cm_id->rem_ref(cm_id);
384 }
385 return err;
386}
387
388int c2_llp_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
389{
390 struct c2_dev *c2dev;
391 struct c2wr_cr_reject_req wr;
392 struct c2_vq_req *vq_req;
393 struct c2wr_cr_reject_rep *reply;
394 int err;
395
396 c2dev = to_c2dev(cm_id->device);
397
398 /*
399 * Allocate verbs request.
400 */
401 vq_req = vq_req_alloc(c2dev);
402 if (!vq_req)
403 return -ENOMEM;
404
405 /*
406 * Build the WR
407 */
408 c2_wr_set_id(&wr, CCWR_CR_REJECT);
409 wr.hdr.context = (unsigned long) vq_req;
410 wr.rnic_handle = c2dev->adapter_handle;
411 wr.ep_handle = (u32) (unsigned long) cm_id->provider_data;
412
413 /*
414 * reference the request struct. dereferenced in the int handler.
415 */
416 vq_req_get(c2dev, vq_req);
417
418 /*
419 * Send WR to adapter
420 */
421 err = vq_send_wr(c2dev, (union c2wr *) & wr);
422 if (err) {
423 vq_req_put(c2dev, vq_req);
424 goto bail0;
425 }
426
427 /*
428 * Wait for reply from adapter
429 */
430 err = vq_wait_for_reply(c2dev, vq_req);
431 if (err)
432 goto bail0;
433
434 /*
435 * Process reply
436 */
437 reply = (struct c2wr_cr_reject_rep *) (unsigned long)
438 vq_req->reply_msg;
439 if (!reply) {
440 err = -ENOMEM;
441 goto bail0;
442 }
443 err = c2_errno(reply);
444 /*
445 * free vq stuff
446 */
447 vq_repbuf_free(c2dev, reply);
448
449 bail0:
450 vq_req_free(c2dev, vq_req);
451 return err;
452}
diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c
new file mode 100644
index 000000000000..9d7bcc5ade93
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_cq.c
@@ -0,0 +1,433 @@
1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
7 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
8 *
9 * This software is available to you under a choice of one of two
10 * licenses. You may choose to be licensed under the terms of the GNU
11 * General Public License (GPL) Version 2, available from the file
12 * COPYING in the main directory of this source tree, or the
13 * OpenIB.org BSD license below:
14 *
15 * Redistribution and use in source and binary forms, with or
16 * without modification, are permitted provided that the following
17 * conditions are met:
18 *
19 * - Redistributions of source code must retain the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer.
22 *
23 * - Redistributions in binary form must reproduce the above
24 * copyright notice, this list of conditions and the following
25 * disclaimer in the documentation and/or other materials
26 * provided with the distribution.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
32 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
33 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 * SOFTWARE.
36 *
37 */
38#include "c2.h"
39#include "c2_vq.h"
40#include "c2_status.h"
41
42#define C2_CQ_MSG_SIZE ((sizeof(struct c2wr_ce) + 32-1) & ~(32-1))
43
44static struct c2_cq *c2_cq_get(struct c2_dev *c2dev, int cqn)
45{
46 struct c2_cq *cq;
47 unsigned long flags;
48
49 spin_lock_irqsave(&c2dev->lock, flags);
50 cq = c2dev->qptr_array[cqn];
51 if (!cq) {
52 spin_unlock_irqrestore(&c2dev->lock, flags);
53 return NULL;
54 }
55 atomic_inc(&cq->refcount);
56 spin_unlock_irqrestore(&c2dev->lock, flags);
57 return cq;
58}
59
60static void c2_cq_put(struct c2_cq *cq)
61{
62 if (atomic_dec_and_test(&cq->refcount))
63 wake_up(&cq->wait);
64}
65
66void c2_cq_event(struct c2_dev *c2dev, u32 mq_index)
67{
68 struct c2_cq *cq;
69
70 cq = c2_cq_get(c2dev, mq_index);
71 if (!cq) {
72 printk("discarding events on destroyed CQN=%d\n", mq_index);
73 return;
74 }
75
76 (*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context);
77 c2_cq_put(cq);
78}
79
80void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index)
81{
82 struct c2_cq *cq;
83 struct c2_mq *q;
84
85 cq = c2_cq_get(c2dev, mq_index);
86 if (!cq)
87 return;
88
89 spin_lock_irq(&cq->lock);
90 q = &cq->mq;
91 if (q && !c2_mq_empty(q)) {
92 u16 priv = q->priv;
93 struct c2wr_ce *msg;
94
95 while (priv != be16_to_cpu(*q->shared)) {
96 msg = (struct c2wr_ce *)
97 (q->msg_pool.host + priv * q->msg_size);
98 if (msg->qp_user_context == (u64) (unsigned long) qp) {
99 msg->qp_user_context = (u64) 0;
100 }
101 priv = (priv + 1) % q->q_size;
102 }
103 }
104 spin_unlock_irq(&cq->lock);
105 c2_cq_put(cq);
106}
107
108static inline enum ib_wc_status c2_cqe_status_to_openib(u8 status)
109{
110 switch (status) {
111 case C2_OK:
112 return IB_WC_SUCCESS;
113 case CCERR_FLUSHED:
114 return IB_WC_WR_FLUSH_ERR;
115 case CCERR_BASE_AND_BOUNDS_VIOLATION:
116 return IB_WC_LOC_PROT_ERR;
117 case CCERR_ACCESS_VIOLATION:
118 return IB_WC_LOC_ACCESS_ERR;
119 case CCERR_TOTAL_LENGTH_TOO_BIG:
120 return IB_WC_LOC_LEN_ERR;
121 case CCERR_INVALID_WINDOW:
122 return IB_WC_MW_BIND_ERR;
123 default:
124 return IB_WC_GENERAL_ERR;
125 }
126}
127
128
129static inline int c2_poll_one(struct c2_dev *c2dev,
130 struct c2_cq *cq, struct ib_wc *entry)
131{
132 struct c2wr_ce *ce;
133 struct c2_qp *qp;
134 int is_recv = 0;
135
136 ce = (struct c2wr_ce *) c2_mq_consume(&cq->mq);
137 if (!ce) {
138 return -EAGAIN;
139 }
140
141 /*
142 * if the qp returned is null then this qp has already
143 * been freed and we are unable process the completion.
144 * try pulling the next message
145 */
146 while ((qp =
147 (struct c2_qp *) (unsigned long) ce->qp_user_context) == NULL) {
148 c2_mq_free(&cq->mq);
149 ce = (struct c2wr_ce *) c2_mq_consume(&cq->mq);
150 if (!ce)
151 return -EAGAIN;
152 }
153
154 entry->status = c2_cqe_status_to_openib(c2_wr_get_result(ce));
155 entry->wr_id = ce->hdr.context;
156 entry->qp_num = ce->handle;
157 entry->wc_flags = 0;
158 entry->slid = 0;
159 entry->sl = 0;
160 entry->src_qp = 0;
161 entry->dlid_path_bits = 0;
162 entry->pkey_index = 0;
163
164 switch (c2_wr_get_id(ce)) {
165 case C2_WR_TYPE_SEND:
166 entry->opcode = IB_WC_SEND;
167 break;
168 case C2_WR_TYPE_RDMA_WRITE:
169 entry->opcode = IB_WC_RDMA_WRITE;
170 break;
171 case C2_WR_TYPE_RDMA_READ:
172 entry->opcode = IB_WC_RDMA_READ;
173 break;
174 case C2_WR_TYPE_BIND_MW:
175 entry->opcode = IB_WC_BIND_MW;
176 break;
177 case C2_WR_TYPE_RECV:
178 entry->byte_len = be32_to_cpu(ce->bytes_rcvd);
179 entry->opcode = IB_WC_RECV;
180 is_recv = 1;
181 break;
182 default:
183 break;
184 }
185
186 /* consume the WQEs */
187 if (is_recv)
188 c2_mq_lconsume(&qp->rq_mq, 1);
189 else
190 c2_mq_lconsume(&qp->sq_mq,
191 be32_to_cpu(c2_wr_get_wqe_count(ce)) + 1);
192
193 /* free the message */
194 c2_mq_free(&cq->mq);
195
196 return 0;
197}
198
199int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
200{
201 struct c2_dev *c2dev = to_c2dev(ibcq->device);
202 struct c2_cq *cq = to_c2cq(ibcq);
203 unsigned long flags;
204 int npolled, err;
205
206 spin_lock_irqsave(&cq->lock, flags);
207
208 for (npolled = 0; npolled < num_entries; ++npolled) {
209
210 err = c2_poll_one(c2dev, cq, entry + npolled);
211 if (err)
212 break;
213 }
214
215 spin_unlock_irqrestore(&cq->lock, flags);
216
217 return npolled;
218}
219
220int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
221{
222 struct c2_mq_shared __iomem *shared;
223 struct c2_cq *cq;
224
225 cq = to_c2cq(ibcq);
226 shared = cq->mq.peer;
227
228 if (notify == IB_CQ_NEXT_COMP)
229 writeb(C2_CQ_NOTIFICATION_TYPE_NEXT, &shared->notification_type);
230 else if (notify == IB_CQ_SOLICITED)
231 writeb(C2_CQ_NOTIFICATION_TYPE_NEXT_SE, &shared->notification_type);
232 else
233 return -EINVAL;
234
235 writeb(CQ_WAIT_FOR_DMA | CQ_ARMED, &shared->armed);
236
237 /*
238 * Now read back shared->armed to make the PCI
239 * write synchronous. This is necessary for
240 * correct cq notification semantics.
241 */
242 readb(&shared->armed);
243
244 return 0;
245}
246
247static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq)
248{
249
250 dma_unmap_single(c2dev->ibdev.dma_device, pci_unmap_addr(mq, mapping),
251 mq->q_size * mq->msg_size, DMA_FROM_DEVICE);
252 free_pages((unsigned long) mq->msg_pool.host,
253 get_order(mq->q_size * mq->msg_size));
254}
255
256static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size,
257 int msg_size)
258{
259 unsigned long pool_start;
260
261 pool_start = __get_free_pages(GFP_KERNEL,
262 get_order(q_size * msg_size));
263 if (!pool_start)
264 return -ENOMEM;
265
266 c2_mq_rep_init(mq,
267 0, /* index (currently unknown) */
268 q_size,
269 msg_size,
270 (u8 *) pool_start,
271 NULL, /* peer (currently unknown) */
272 C2_MQ_HOST_TARGET);
273
274 mq->host_dma = dma_map_single(c2dev->ibdev.dma_device,
275 (void *)pool_start,
276 q_size * msg_size, DMA_FROM_DEVICE);
277 pci_unmap_addr_set(mq, mapping, mq->host_dma);
278
279 return 0;
280}
281
282int c2_init_cq(struct c2_dev *c2dev, int entries,
283 struct c2_ucontext *ctx, struct c2_cq *cq)
284{
285 struct c2wr_cq_create_req wr;
286 struct c2wr_cq_create_rep *reply;
287 unsigned long peer_pa;
288 struct c2_vq_req *vq_req;
289 int err;
290
291 might_sleep();
292
293 cq->ibcq.cqe = entries - 1;
294 cq->is_kernel = !ctx;
295
296 /* Allocate a shared pointer */
297 cq->mq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
298 &cq->mq.shared_dma, GFP_KERNEL);
299 if (!cq->mq.shared)
300 return -ENOMEM;
301
302 /* Allocate pages for the message pool */
303 err = c2_alloc_cq_buf(c2dev, &cq->mq, entries + 1, C2_CQ_MSG_SIZE);
304 if (err)
305 goto bail0;
306
307 vq_req = vq_req_alloc(c2dev);
308 if (!vq_req) {
309 err = -ENOMEM;
310 goto bail1;
311 }
312
313 memset(&wr, 0, sizeof(wr));
314 c2_wr_set_id(&wr, CCWR_CQ_CREATE);
315 wr.hdr.context = (unsigned long) vq_req;
316 wr.rnic_handle = c2dev->adapter_handle;
317 wr.msg_size = cpu_to_be32(cq->mq.msg_size);
318 wr.depth = cpu_to_be32(cq->mq.q_size);
319 wr.shared_ht = cpu_to_be64(cq->mq.shared_dma);
320 wr.msg_pool = cpu_to_be64(cq->mq.host_dma);
321 wr.user_context = (u64) (unsigned long) (cq);
322
323 vq_req_get(c2dev, vq_req);
324
325 err = vq_send_wr(c2dev, (union c2wr *) & wr);
326 if (err) {
327 vq_req_put(c2dev, vq_req);
328 goto bail2;
329 }
330
331 err = vq_wait_for_reply(c2dev, vq_req);
332 if (err)
333 goto bail2;
334
335 reply = (struct c2wr_cq_create_rep *) (unsigned long) (vq_req->reply_msg);
336 if (!reply) {
337 err = -ENOMEM;
338 goto bail2;
339 }
340
341 if ((err = c2_errno(reply)) != 0)
342 goto bail3;
343
344 cq->adapter_handle = reply->cq_handle;
345 cq->mq.index = be32_to_cpu(reply->mq_index);
346
347 peer_pa = c2dev->pa + be32_to_cpu(reply->adapter_shared);
348 cq->mq.peer = ioremap_nocache(peer_pa, PAGE_SIZE);
349 if (!cq->mq.peer) {
350 err = -ENOMEM;
351 goto bail3;
352 }
353
354 vq_repbuf_free(c2dev, reply);
355 vq_req_free(c2dev, vq_req);
356
357 spin_lock_init(&cq->lock);
358 atomic_set(&cq->refcount, 1);
359 init_waitqueue_head(&cq->wait);
360
361 /*
362 * Use the MQ index allocated by the adapter to
363 * store the CQ in the qptr_array
364 */
365 cq->cqn = cq->mq.index;
366 c2dev->qptr_array[cq->cqn] = cq;
367
368 return 0;
369
370 bail3:
371 vq_repbuf_free(c2dev, reply);
372 bail2:
373 vq_req_free(c2dev, vq_req);
374 bail1:
375 c2_free_cq_buf(c2dev, &cq->mq);
376 bail0:
377 c2_free_mqsp(cq->mq.shared);
378
379 return err;
380}
381
382void c2_free_cq(struct c2_dev *c2dev, struct c2_cq *cq)
383{
384 int err;
385 struct c2_vq_req *vq_req;
386 struct c2wr_cq_destroy_req wr;
387 struct c2wr_cq_destroy_rep *reply;
388
389 might_sleep();
390
391 /* Clear CQ from the qptr array */
392 spin_lock_irq(&c2dev->lock);
393 c2dev->qptr_array[cq->mq.index] = NULL;
394 atomic_dec(&cq->refcount);
395 spin_unlock_irq(&c2dev->lock);
396
397 wait_event(cq->wait, !atomic_read(&cq->refcount));
398
399 vq_req = vq_req_alloc(c2dev);
400 if (!vq_req) {
401 goto bail0;
402 }
403
404 memset(&wr, 0, sizeof(wr));
405 c2_wr_set_id(&wr, CCWR_CQ_DESTROY);
406 wr.hdr.context = (unsigned long) vq_req;
407 wr.rnic_handle = c2dev->adapter_handle;
408 wr.cq_handle = cq->adapter_handle;
409
410 vq_req_get(c2dev, vq_req);
411
412 err = vq_send_wr(c2dev, (union c2wr *) & wr);
413 if (err) {
414 vq_req_put(c2dev, vq_req);
415 goto bail1;
416 }
417
418 err = vq_wait_for_reply(c2dev, vq_req);
419 if (err)
420 goto bail1;
421
422 reply = (struct c2wr_cq_destroy_rep *) (unsigned long) (vq_req->reply_msg);
423
424 vq_repbuf_free(c2dev, reply);
425 bail1:
426 vq_req_free(c2dev, vq_req);
427 bail0:
428 if (cq->is_kernel) {
429 c2_free_cq_buf(c2dev, &cq->mq);
430 }
431
432 return;
433}
diff --git a/drivers/infiniband/hw/amso1100/c2_intr.c b/drivers/infiniband/hw/amso1100/c2_intr.c
new file mode 100644
index 000000000000..0d0bc33ca30a
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_intr.c
@@ -0,0 +1,209 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#include "c2.h"
34#include <rdma/iw_cm.h>
35#include "c2_vq.h"
36
37static void handle_mq(struct c2_dev *c2dev, u32 index);
38static void handle_vq(struct c2_dev *c2dev, u32 mq_index);
39
40/*
41 * Handle RNIC interrupts
42 */
43void c2_rnic_interrupt(struct c2_dev *c2dev)
44{
45 unsigned int mq_index;
46
47 while (c2dev->hints_read != be16_to_cpu(*c2dev->hint_count)) {
48 mq_index = readl(c2dev->regs + PCI_BAR0_HOST_HINT);
49 if (mq_index & 0x80000000) {
50 break;
51 }
52
53 c2dev->hints_read++;
54 handle_mq(c2dev, mq_index);
55 }
56
57}
58
59/*
60 * Top level MQ handler
61 */
62static void handle_mq(struct c2_dev *c2dev, u32 mq_index)
63{
64 if (c2dev->qptr_array[mq_index] == NULL) {
65 pr_debug(KERN_INFO "handle_mq: stray activity for mq_index=%d\n",
66 mq_index);
67 return;
68 }
69
70 switch (mq_index) {
71 case (0):
72 /*
73 * An index of 0 in the activity queue
74 * indicates the req vq now has messages
75 * available...
76 *
77 * Wake up any waiters waiting on req VQ
78 * message availability.
79 */
80 wake_up(&c2dev->req_vq_wo);
81 break;
82 case (1):
83 handle_vq(c2dev, mq_index);
84 break;
85 case (2):
86 /* We have to purge the VQ in case there are pending
87 * accept reply requests that would result in the
88 * generation of an ESTABLISHED event. If we don't
89 * generate these first, a CLOSE event could end up
90 * being delivered before the ESTABLISHED event.
91 */
92 handle_vq(c2dev, 1);
93
94 c2_ae_event(c2dev, mq_index);
95 break;
96 default:
97 /* There is no event synchronization between CQ events
98 * and AE or CM events. In fact, CQE could be
99 * delivered for all of the I/O up to and including the
100 * FLUSH for a peer disconenct prior to the ESTABLISHED
101 * event being delivered to the app. The reason for this
102 * is that CM events are delivered on a thread, while AE
103 * and CM events are delivered on interrupt context.
104 */
105 c2_cq_event(c2dev, mq_index);
106 break;
107 }
108
109 return;
110}
111
112/*
113 * Handles verbs WR replies.
114 */
115static void handle_vq(struct c2_dev *c2dev, u32 mq_index)
116{
117 void *adapter_msg, *reply_msg;
118 struct c2wr_hdr *host_msg;
119 struct c2wr_hdr tmp;
120 struct c2_mq *reply_vq;
121 struct c2_vq_req *req;
122 struct iw_cm_event cm_event;
123 int err;
124
125 reply_vq = (struct c2_mq *) c2dev->qptr_array[mq_index];
126
127 /*
128 * get next msg from mq_index into adapter_msg.
129 * don't free it yet.
130 */
131 adapter_msg = c2_mq_consume(reply_vq);
132 if (adapter_msg == NULL) {
133 return;
134 }
135
136 host_msg = vq_repbuf_alloc(c2dev);
137
138 /*
139 * If we can't get a host buffer, then we'll still
140 * wakeup the waiter, we just won't give him the msg.
141 * It is assumed the waiter will deal with this...
142 */
143 if (!host_msg) {
144 pr_debug("handle_vq: no repbufs!\n");
145
146 /*
147 * just copy the WR header into a local variable.
148 * this allows us to still demux on the context
149 */
150 host_msg = &tmp;
151 memcpy(host_msg, adapter_msg, sizeof(tmp));
152 reply_msg = NULL;
153 } else {
154 memcpy(host_msg, adapter_msg, reply_vq->msg_size);
155 reply_msg = host_msg;
156 }
157
158 /*
159 * consume the msg from the MQ
160 */
161 c2_mq_free(reply_vq);
162
163 /*
164 * wakeup the waiter.
165 */
166 req = (struct c2_vq_req *) (unsigned long) host_msg->context;
167 if (req == NULL) {
168 /*
169 * We should never get here, as the adapter should
170 * never send us a reply that we're not expecting.
171 */
172 vq_repbuf_free(c2dev, host_msg);
173 pr_debug("handle_vq: UNEXPECTEDLY got NULL req\n");
174 return;
175 }
176
177 err = c2_errno(reply_msg);
178 if (!err) switch (req->event) {
179 case IW_CM_EVENT_ESTABLISHED:
180 c2_set_qp_state(req->qp,
181 C2_QP_STATE_RTS);
182 case IW_CM_EVENT_CLOSE:
183
184 /*
185 * Move the QP to RTS if this is
186 * the established event
187 */
188 cm_event.event = req->event;
189 cm_event.status = 0;
190 cm_event.local_addr = req->cm_id->local_addr;
191 cm_event.remote_addr = req->cm_id->remote_addr;
192 cm_event.private_data = NULL;
193 cm_event.private_data_len = 0;
194 req->cm_id->event_handler(req->cm_id, &cm_event);
195 break;
196 default:
197 break;
198 }
199
200 req->reply_msg = (u64) (unsigned long) (reply_msg);
201 atomic_set(&req->reply_ready, 1);
202 wake_up(&req->wait_object);
203
204 /*
205 * If the request was cancelled, then this put will
206 * free the vq_req memory...and reply_msg!!!
207 */
208 vq_req_put(c2dev, req);
209}
diff --git a/drivers/infiniband/hw/amso1100/c2_mm.c b/drivers/infiniband/hw/amso1100/c2_mm.c
new file mode 100644
index 000000000000..1e4f46493fcb
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_mm.c
@@ -0,0 +1,375 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#include "c2.h"
34#include "c2_vq.h"
35
36#define PBL_VIRT 1
37#define PBL_PHYS 2
38
39/*
40 * Send all the PBL messages to convey the remainder of the PBL
41 * Wait for the adapter's reply on the last one.
42 * This is indicated by setting the MEM_PBL_COMPLETE in the flags.
43 *
44 * NOTE: vq_req is _not_ freed by this function. The VQ Host
45 * Reply buffer _is_ freed by this function.
46 */
47static int
48send_pbl_messages(struct c2_dev *c2dev, u32 stag_index,
49 unsigned long va, u32 pbl_depth,
50 struct c2_vq_req *vq_req, int pbl_type)
51{
52 u32 pbe_count; /* amt that fits in a PBL msg */
53 u32 count; /* amt in this PBL MSG. */
54 struct c2wr_nsmr_pbl_req *wr; /* PBL WR ptr */
55 struct c2wr_nsmr_pbl_rep *reply; /* reply ptr */
56 int err, pbl_virt, pbl_index, i;
57
58 switch (pbl_type) {
59 case PBL_VIRT:
60 pbl_virt = 1;
61 break;
62 case PBL_PHYS:
63 pbl_virt = 0;
64 break;
65 default:
66 return -EINVAL;
67 break;
68 }
69
70 pbe_count = (c2dev->req_vq.msg_size -
71 sizeof(struct c2wr_nsmr_pbl_req)) / sizeof(u64);
72 wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL);
73 if (!wr) {
74 return -ENOMEM;
75 }
76 c2_wr_set_id(wr, CCWR_NSMR_PBL);
77
78 /*
79 * Only the last PBL message will generate a reply from the verbs,
80 * so we set the context to 0 indicating there is no kernel verbs
81 * handler blocked awaiting this reply.
82 */
83 wr->hdr.context = 0;
84 wr->rnic_handle = c2dev->adapter_handle;
85 wr->stag_index = stag_index; /* already swapped */
86 wr->flags = 0;
87 pbl_index = 0;
88 while (pbl_depth) {
89 count = min(pbe_count, pbl_depth);
90 wr->addrs_length = cpu_to_be32(count);
91
92 /*
93 * If this is the last message, then reference the
94 * vq request struct cuz we're gonna wait for a reply.
95 * also make this PBL msg as the last one.
96 */
97 if (count == pbl_depth) {
98 /*
99 * reference the request struct. dereferenced in the
100 * int handler.
101 */
102 vq_req_get(c2dev, vq_req);
103 wr->flags = cpu_to_be32(MEM_PBL_COMPLETE);
104
105 /*
106 * This is the last PBL message.
107 * Set the context to our VQ Request Object so we can
108 * wait for the reply.
109 */
110 wr->hdr.context = (unsigned long) vq_req;
111 }
112
113 /*
114 * If pbl_virt is set then va is a virtual address
115 * that describes a virtually contiguous memory
116 * allocation. The wr needs the start of each virtual page
117 * to be converted to the corresponding physical address
118 * of the page. If pbl_virt is not set then va is an array
119 * of physical addresses and there is no conversion to do.
120 * Just fill in the wr with what is in the array.
121 */
122 for (i = 0; i < count; i++) {
123 if (pbl_virt) {
124 va += PAGE_SIZE;
125 } else {
126 wr->paddrs[i] =
127 cpu_to_be64(((u64 *)va)[pbl_index + i]);
128 }
129 }
130
131 /*
132 * Send WR to adapter
133 */
134 err = vq_send_wr(c2dev, (union c2wr *) wr);
135 if (err) {
136 if (count <= pbe_count) {
137 vq_req_put(c2dev, vq_req);
138 }
139 goto bail0;
140 }
141 pbl_depth -= count;
142 pbl_index += count;
143 }
144
145 /*
146 * Now wait for the reply...
147 */
148 err = vq_wait_for_reply(c2dev, vq_req);
149 if (err) {
150 goto bail0;
151 }
152
153 /*
154 * Process reply
155 */
156 reply = (struct c2wr_nsmr_pbl_rep *) (unsigned long) vq_req->reply_msg;
157 if (!reply) {
158 err = -ENOMEM;
159 goto bail0;
160 }
161
162 err = c2_errno(reply);
163
164 vq_repbuf_free(c2dev, reply);
165 bail0:
166 kfree(wr);
167 return err;
168}
169
170#define C2_PBL_MAX_DEPTH 131072
171int
172c2_nsmr_register_phys_kern(struct c2_dev *c2dev, u64 *addr_list,
173 int page_size, int pbl_depth, u32 length,
174 u32 offset, u64 *va, enum c2_acf acf,
175 struct c2_mr *mr)
176{
177 struct c2_vq_req *vq_req;
178 struct c2wr_nsmr_register_req *wr;
179 struct c2wr_nsmr_register_rep *reply;
180 u16 flags;
181 int i, pbe_count, count;
182 int err;
183
184 if (!va || !length || !addr_list || !pbl_depth)
185 return -EINTR;
186
187 /*
188 * Verify PBL depth is within rnic max
189 */
190 if (pbl_depth > C2_PBL_MAX_DEPTH) {
191 return -EINTR;
192 }
193
194 /*
195 * allocate verbs request object
196 */
197 vq_req = vq_req_alloc(c2dev);
198 if (!vq_req)
199 return -ENOMEM;
200
201 wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL);
202 if (!wr) {
203 err = -ENOMEM;
204 goto bail0;
205 }
206
207 /*
208 * build the WR
209 */
210 c2_wr_set_id(wr, CCWR_NSMR_REGISTER);
211 wr->hdr.context = (unsigned long) vq_req;
212 wr->rnic_handle = c2dev->adapter_handle;
213
214 flags = (acf | MEM_VA_BASED | MEM_REMOTE);
215
216 /*
217 * compute how many pbes can fit in the message
218 */
219 pbe_count = (c2dev->req_vq.msg_size -
220 sizeof(struct c2wr_nsmr_register_req)) / sizeof(u64);
221
222 if (pbl_depth <= pbe_count) {
223 flags |= MEM_PBL_COMPLETE;
224 }
225 wr->flags = cpu_to_be16(flags);
226 wr->stag_key = 0; //stag_key;
227 wr->va = cpu_to_be64(*va);
228 wr->pd_id = mr->pd->pd_id;
229 wr->pbe_size = cpu_to_be32(page_size);
230 wr->length = cpu_to_be32(length);
231 wr->pbl_depth = cpu_to_be32(pbl_depth);
232 wr->fbo = cpu_to_be32(offset);
233 count = min(pbl_depth, pbe_count);
234 wr->addrs_length = cpu_to_be32(count);
235
236 /*
237 * fill out the PBL for this message
238 */
239 for (i = 0; i < count; i++) {
240 wr->paddrs[i] = cpu_to_be64(addr_list[i]);
241 }
242
243 /*
244 * regerence the request struct
245 */
246 vq_req_get(c2dev, vq_req);
247
248 /*
249 * send the WR to the adapter
250 */
251 err = vq_send_wr(c2dev, (union c2wr *) wr);
252 if (err) {
253 vq_req_put(c2dev, vq_req);
254 goto bail1;
255 }
256
257 /*
258 * wait for reply from adapter
259 */
260 err = vq_wait_for_reply(c2dev, vq_req);
261 if (err) {
262 goto bail1;
263 }
264
265 /*
266 * process reply
267 */
268 reply =
269 (struct c2wr_nsmr_register_rep *) (unsigned long) (vq_req->reply_msg);
270 if (!reply) {
271 err = -ENOMEM;
272 goto bail1;
273 }
274 if ((err = c2_errno(reply))) {
275 goto bail2;
276 }
277 //*p_pb_entries = be32_to_cpu(reply->pbl_depth);
278 mr->ibmr.lkey = mr->ibmr.rkey = be32_to_cpu(reply->stag_index);
279 vq_repbuf_free(c2dev, reply);
280
281 /*
282 * if there are still more PBEs we need to send them to
283 * the adapter and wait for a reply on the final one.
284 * reuse vq_req for this purpose.
285 */
286 pbl_depth -= count;
287 if (pbl_depth) {
288
289 vq_req->reply_msg = (unsigned long) NULL;
290 atomic_set(&vq_req->reply_ready, 0);
291 err = send_pbl_messages(c2dev,
292 cpu_to_be32(mr->ibmr.lkey),
293 (unsigned long) &addr_list[i],
294 pbl_depth, vq_req, PBL_PHYS);
295 if (err) {
296 goto bail1;
297 }
298 }
299
300 vq_req_free(c2dev, vq_req);
301 kfree(wr);
302
303 return err;
304
305 bail2:
306 vq_repbuf_free(c2dev, reply);
307 bail1:
308 kfree(wr);
309 bail0:
310 vq_req_free(c2dev, vq_req);
311 return err;
312}
313
314int c2_stag_dealloc(struct c2_dev *c2dev, u32 stag_index)
315{
316 struct c2_vq_req *vq_req; /* verbs request object */
317 struct c2wr_stag_dealloc_req wr; /* work request */
318 struct c2wr_stag_dealloc_rep *reply; /* WR reply */
319 int err;
320
321
322 /*
323 * allocate verbs request object
324 */
325 vq_req = vq_req_alloc(c2dev);
326 if (!vq_req) {
327 return -ENOMEM;
328 }
329
330 /*
331 * Build the WR
332 */
333 c2_wr_set_id(&wr, CCWR_STAG_DEALLOC);
334 wr.hdr.context = (u64) (unsigned long) vq_req;
335 wr.rnic_handle = c2dev->adapter_handle;
336 wr.stag_index = cpu_to_be32(stag_index);
337
338 /*
339 * reference the request struct. dereferenced in the int handler.
340 */
341 vq_req_get(c2dev, vq_req);
342
343 /*
344 * Send WR to adapter
345 */
346 err = vq_send_wr(c2dev, (union c2wr *) & wr);
347 if (err) {
348 vq_req_put(c2dev, vq_req);
349 goto bail0;
350 }
351
352 /*
353 * Wait for reply from adapter
354 */
355 err = vq_wait_for_reply(c2dev, vq_req);
356 if (err) {
357 goto bail0;
358 }
359
360 /*
361 * Process reply
362 */
363 reply = (struct c2wr_stag_dealloc_rep *) (unsigned long) vq_req->reply_msg;
364 if (!reply) {
365 err = -ENOMEM;
366 goto bail0;
367 }
368
369 err = c2_errno(reply);
370
371 vq_repbuf_free(c2dev, reply);
372 bail0:
373 vq_req_free(c2dev, vq_req);
374 return err;
375}
diff --git a/drivers/infiniband/hw/amso1100/c2_mq.c b/drivers/infiniband/hw/amso1100/c2_mq.c
new file mode 100644
index 000000000000..b88a75592102
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_mq.c
@@ -0,0 +1,174 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#include "c2.h"
34#include "c2_mq.h"
35
36void *c2_mq_alloc(struct c2_mq *q)
37{
38 BUG_ON(q->magic != C2_MQ_MAGIC);
39 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET);
40
41 if (c2_mq_full(q)) {
42 return NULL;
43 } else {
44#ifdef DEBUG
45 struct c2wr_hdr *m =
46 (struct c2wr_hdr *) (q->msg_pool.host + q->priv * q->msg_size);
47#ifdef CCMSGMAGIC
48 BUG_ON(m->magic != be32_to_cpu(~CCWR_MAGIC));
49 m->magic = cpu_to_be32(CCWR_MAGIC);
50#endif
51 return m;
52#else
53 return q->msg_pool.host + q->priv * q->msg_size;
54#endif
55 }
56}
57
58void c2_mq_produce(struct c2_mq *q)
59{
60 BUG_ON(q->magic != C2_MQ_MAGIC);
61 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET);
62
63 if (!c2_mq_full(q)) {
64 q->priv = (q->priv + 1) % q->q_size;
65 q->hint_count++;
66 /* Update peer's offset. */
67 __raw_writew(cpu_to_be16(q->priv), &q->peer->shared);
68 }
69}
70
71void *c2_mq_consume(struct c2_mq *q)
72{
73 BUG_ON(q->magic != C2_MQ_MAGIC);
74 BUG_ON(q->type != C2_MQ_HOST_TARGET);
75
76 if (c2_mq_empty(q)) {
77 return NULL;
78 } else {
79#ifdef DEBUG
80 struct c2wr_hdr *m = (struct c2wr_hdr *)
81 (q->msg_pool.host + q->priv * q->msg_size);
82#ifdef CCMSGMAGIC
83 BUG_ON(m->magic != be32_to_cpu(CCWR_MAGIC));
84#endif
85 return m;
86#else
87 return q->msg_pool.host + q->priv * q->msg_size;
88#endif
89 }
90}
91
92void c2_mq_free(struct c2_mq *q)
93{
94 BUG_ON(q->magic != C2_MQ_MAGIC);
95 BUG_ON(q->type != C2_MQ_HOST_TARGET);
96
97 if (!c2_mq_empty(q)) {
98
99#ifdef CCMSGMAGIC
100 {
101 struct c2wr_hdr __iomem *m = (struct c2wr_hdr __iomem *)
102 (q->msg_pool.adapter + q->priv * q->msg_size);
103 __raw_writel(cpu_to_be32(~CCWR_MAGIC), &m->magic);
104 }
105#endif
106 q->priv = (q->priv + 1) % q->q_size;
107 /* Update peer's offset. */
108 __raw_writew(cpu_to_be16(q->priv), &q->peer->shared);
109 }
110}
111
112
113void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count)
114{
115 BUG_ON(q->magic != C2_MQ_MAGIC);
116 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET);
117
118 while (wqe_count--) {
119 BUG_ON(c2_mq_empty(q));
120 *q->shared = cpu_to_be16((be16_to_cpu(*q->shared)+1) % q->q_size);
121 }
122}
123
124#if 0
125u32 c2_mq_count(struct c2_mq *q)
126{
127 s32 count;
128
129 if (q->type == C2_MQ_HOST_TARGET)
130 count = be16_to_cpu(*q->shared) - q->priv;
131 else
132 count = q->priv - be16_to_cpu(*q->shared);
133
134 if (count < 0)
135 count += q->q_size;
136
137 return (u32) count;
138}
139#endif /* 0 */
140
141void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size,
142 u8 __iomem *pool_start, u16 __iomem *peer, u32 type)
143{
144 BUG_ON(!q->shared);
145
146 /* This code assumes the byte swapping has already been done! */
147 q->index = index;
148 q->q_size = q_size;
149 q->msg_size = msg_size;
150 q->msg_pool.adapter = pool_start;
151 q->peer = (struct c2_mq_shared __iomem *) peer;
152 q->magic = C2_MQ_MAGIC;
153 q->type = type;
154 q->priv = 0;
155 q->hint_count = 0;
156 return;
157}
158void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size,
159 u8 *pool_start, u16 __iomem *peer, u32 type)
160{
161 BUG_ON(!q->shared);
162
163 /* This code assumes the byte swapping has already been done! */
164 q->index = index;
165 q->q_size = q_size;
166 q->msg_size = msg_size;
167 q->msg_pool.host = pool_start;
168 q->peer = (struct c2_mq_shared __iomem *) peer;
169 q->magic = C2_MQ_MAGIC;
170 q->type = type;
171 q->priv = 0;
172 q->hint_count = 0;
173 return;
174}
diff --git a/drivers/infiniband/hw/amso1100/c2_mq.h b/drivers/infiniband/hw/amso1100/c2_mq.h
new file mode 100644
index 000000000000..9185bbb21658
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_mq.h
@@ -0,0 +1,106 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34#ifndef _C2_MQ_H_
35#define _C2_MQ_H_
36#include <linux/kernel.h>
37#include <linux/dma-mapping.h>
38#include "c2_wr.h"
39
40enum c2_shared_regs {
41
42 C2_SHARED_ARMED = 0x10,
43 C2_SHARED_NOTIFY = 0x18,
44 C2_SHARED_SHARED = 0x40,
45};
46
47struct c2_mq_shared {
48 u16 unused1;
49 u8 armed;
50 u8 notification_type;
51 u32 unused2;
52 u16 shared;
53 /* Pad to 64 bytes. */
54 u8 pad[64 - sizeof(u16) - 2 * sizeof(u8) - sizeof(u32) - sizeof(u16)];
55};
56
57enum c2_mq_type {
58 C2_MQ_HOST_TARGET = 1,
59 C2_MQ_ADAPTER_TARGET = 2,
60};
61
62/*
63 * c2_mq_t is for kernel-mode MQs like the VQs Cand the AEQ.
64 * c2_user_mq_t (which is the same format) is for user-mode MQs...
65 */
66#define C2_MQ_MAGIC 0x4d512020 /* 'MQ ' */
67struct c2_mq {
68 u32 magic;
69 union {
70 u8 *host;
71 u8 __iomem *adapter;
72 } msg_pool;
73 dma_addr_t host_dma;
74 DECLARE_PCI_UNMAP_ADDR(mapping);
75 u16 hint_count;
76 u16 priv;
77 struct c2_mq_shared __iomem *peer;
78 u16 *shared;
79 dma_addr_t shared_dma;
80 u32 q_size;
81 u32 msg_size;
82 u32 index;
83 enum c2_mq_type type;
84};
85
86static __inline__ int c2_mq_empty(struct c2_mq *q)
87{
88 return q->priv == be16_to_cpu(*q->shared);
89}
90
91static __inline__ int c2_mq_full(struct c2_mq *q)
92{
93 return q->priv == (be16_to_cpu(*q->shared) + q->q_size - 1) % q->q_size;
94}
95
96extern void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count);
97extern void *c2_mq_alloc(struct c2_mq *q);
98extern void c2_mq_produce(struct c2_mq *q);
99extern void *c2_mq_consume(struct c2_mq *q);
100extern void c2_mq_free(struct c2_mq *q);
101extern void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size,
102 u8 __iomem *pool_start, u16 __iomem *peer, u32 type);
103extern void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size,
104 u8 *pool_start, u16 __iomem *peer, u32 type);
105
106#endif /* _C2_MQ_H_ */
diff --git a/drivers/infiniband/hw/amso1100/c2_pd.c b/drivers/infiniband/hw/amso1100/c2_pd.c
new file mode 100644
index 000000000000..00c709926c8d
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_pd.c
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
5 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
6 *
7 * This software is available to you under a choice of one of two
8 * licenses. You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * OpenIB.org BSD license below:
12 *
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
15 * conditions are met:
16 *
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer.
20 *
21 * - Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials
24 * provided with the distribution.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 * SOFTWARE.
34 */
35
36#include <linux/init.h>
37#include <linux/errno.h>
38
39#include "c2.h"
40#include "c2_provider.h"
41
42int c2_pd_alloc(struct c2_dev *c2dev, int privileged, struct c2_pd *pd)
43{
44 u32 obj;
45 int ret = 0;
46
47 spin_lock(&c2dev->pd_table.lock);
48 obj = find_next_zero_bit(c2dev->pd_table.table, c2dev->pd_table.max,
49 c2dev->pd_table.last);
50 if (obj >= c2dev->pd_table.max)
51 obj = find_first_zero_bit(c2dev->pd_table.table,
52 c2dev->pd_table.max);
53 if (obj < c2dev->pd_table.max) {
54 pd->pd_id = obj;
55 __set_bit(obj, c2dev->pd_table.table);
56 c2dev->pd_table.last = obj+1;
57 if (c2dev->pd_table.last >= c2dev->pd_table.max)
58 c2dev->pd_table.last = 0;
59 } else
60 ret = -ENOMEM;
61 spin_unlock(&c2dev->pd_table.lock);
62 return ret;
63}
64
65void c2_pd_free(struct c2_dev *c2dev, struct c2_pd *pd)
66{
67 spin_lock(&c2dev->pd_table.lock);
68 __clear_bit(pd->pd_id, c2dev->pd_table.table);
69 spin_unlock(&c2dev->pd_table.lock);
70}
71
72int __devinit c2_init_pd_table(struct c2_dev *c2dev)
73{
74
75 c2dev->pd_table.last = 0;
76 c2dev->pd_table.max = c2dev->props.max_pd;
77 spin_lock_init(&c2dev->pd_table.lock);
78 c2dev->pd_table.table = kmalloc(BITS_TO_LONGS(c2dev->props.max_pd) *
79 sizeof(long), GFP_KERNEL);
80 if (!c2dev->pd_table.table)
81 return -ENOMEM;
82 bitmap_zero(c2dev->pd_table.table, c2dev->props.max_pd);
83 return 0;
84}
85
86void __devexit c2_cleanup_pd_table(struct c2_dev *c2dev)
87{
88 kfree(c2dev->pd_table.table);
89}
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
new file mode 100644
index 000000000000..8fddc8cccdf3
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -0,0 +1,869 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/pci.h>
38#include <linux/netdevice.h>
39#include <linux/etherdevice.h>
40#include <linux/inetdevice.h>
41#include <linux/delay.h>
42#include <linux/ethtool.h>
43#include <linux/mii.h>
44#include <linux/if_vlan.h>
45#include <linux/crc32.h>
46#include <linux/in.h>
47#include <linux/ip.h>
48#include <linux/tcp.h>
49#include <linux/init.h>
50#include <linux/dma-mapping.h>
51#include <linux/if_arp.h>
52
53#include <asm/io.h>
54#include <asm/irq.h>
55#include <asm/byteorder.h>
56
57#include <rdma/ib_smi.h>
58#include <rdma/ib_user_verbs.h>
59#include "c2.h"
60#include "c2_provider.h"
61#include "c2_user.h"
62
63static int c2_query_device(struct ib_device *ibdev,
64 struct ib_device_attr *props)
65{
66 struct c2_dev *c2dev = to_c2dev(ibdev);
67
68 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
69
70 *props = c2dev->props;
71 return 0;
72}
73
74static int c2_query_port(struct ib_device *ibdev,
75 u8 port, struct ib_port_attr *props)
76{
77 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
78
79 props->max_mtu = IB_MTU_4096;
80 props->lid = 0;
81 props->lmc = 0;
82 props->sm_lid = 0;
83 props->sm_sl = 0;
84 props->state = IB_PORT_ACTIVE;
85 props->phys_state = 0;
86 props->port_cap_flags =
87 IB_PORT_CM_SUP |
88 IB_PORT_REINIT_SUP |
89 IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
90 props->gid_tbl_len = 1;
91 props->pkey_tbl_len = 1;
92 props->qkey_viol_cntr = 0;
93 props->active_width = 1;
94 props->active_speed = 1;
95
96 return 0;
97}
98
99static int c2_modify_port(struct ib_device *ibdev,
100 u8 port, int port_modify_mask,
101 struct ib_port_modify *props)
102{
103 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
104 return 0;
105}
106
107static int c2_query_pkey(struct ib_device *ibdev,
108 u8 port, u16 index, u16 * pkey)
109{
110 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
111 *pkey = 0;
112 return 0;
113}
114
115static int c2_query_gid(struct ib_device *ibdev, u8 port,
116 int index, union ib_gid *gid)
117{
118 struct c2_dev *c2dev = to_c2dev(ibdev);
119
120 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
121 memset(&(gid->raw[0]), 0, sizeof(gid->raw));
122 memcpy(&(gid->raw[0]), c2dev->pseudo_netdev->dev_addr, 6);
123
124 return 0;
125}
126
127/* Allocate the user context data structure. This keeps track
128 * of all objects associated with a particular user-mode client.
129 */
130static struct ib_ucontext *c2_alloc_ucontext(struct ib_device *ibdev,
131 struct ib_udata *udata)
132{
133 struct c2_ucontext *context;
134
135 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
136 context = kmalloc(sizeof(*context), GFP_KERNEL);
137 if (!context)
138 return ERR_PTR(-ENOMEM);
139
140 return &context->ibucontext;
141}
142
143static int c2_dealloc_ucontext(struct ib_ucontext *context)
144{
145 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
146 kfree(context);
147 return 0;
148}
149
150static int c2_mmap_uar(struct ib_ucontext *context, struct vm_area_struct *vma)
151{
152 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
153 return -ENOSYS;
154}
155
156static struct ib_pd *c2_alloc_pd(struct ib_device *ibdev,
157 struct ib_ucontext *context,
158 struct ib_udata *udata)
159{
160 struct c2_pd *pd;
161 int err;
162
163 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
164
165 pd = kmalloc(sizeof(*pd), GFP_KERNEL);
166 if (!pd)
167 return ERR_PTR(-ENOMEM);
168
169 err = c2_pd_alloc(to_c2dev(ibdev), !context, pd);
170 if (err) {
171 kfree(pd);
172 return ERR_PTR(err);
173 }
174
175 if (context) {
176 if (ib_copy_to_udata(udata, &pd->pd_id, sizeof(__u32))) {
177 c2_pd_free(to_c2dev(ibdev), pd);
178 kfree(pd);
179 return ERR_PTR(-EFAULT);
180 }
181 }
182
183 return &pd->ibpd;
184}
185
186static int c2_dealloc_pd(struct ib_pd *pd)
187{
188 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
189 c2_pd_free(to_c2dev(pd->device), to_c2pd(pd));
190 kfree(pd);
191
192 return 0;
193}
194
195static struct ib_ah *c2_ah_create(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
196{
197 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
198 return ERR_PTR(-ENOSYS);
199}
200
201static int c2_ah_destroy(struct ib_ah *ah)
202{
203 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
204 return -ENOSYS;
205}
206
207static void c2_add_ref(struct ib_qp *ibqp)
208{
209 struct c2_qp *qp;
210 BUG_ON(!ibqp);
211 qp = to_c2qp(ibqp);
212 atomic_inc(&qp->refcount);
213}
214
215static void c2_rem_ref(struct ib_qp *ibqp)
216{
217 struct c2_qp *qp;
218 BUG_ON(!ibqp);
219 qp = to_c2qp(ibqp);
220 if (atomic_dec_and_test(&qp->refcount))
221 wake_up(&qp->wait);
222}
223
224struct ib_qp *c2_get_qp(struct ib_device *device, int qpn)
225{
226 struct c2_dev* c2dev = to_c2dev(device);
227 struct c2_qp *qp;
228
229 qp = c2_find_qpn(c2dev, qpn);
230 pr_debug("%s Returning QP=%p for QPN=%d, device=%p, refcount=%d\n",
231 __FUNCTION__, qp, qpn, device,
232 (qp?atomic_read(&qp->refcount):0));
233
234 return (qp?&qp->ibqp:NULL);
235}
236
237static struct ib_qp *c2_create_qp(struct ib_pd *pd,
238 struct ib_qp_init_attr *init_attr,
239 struct ib_udata *udata)
240{
241 struct c2_qp *qp;
242 int err;
243
244 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
245
246 switch (init_attr->qp_type) {
247 case IB_QPT_RC:
248 qp = kzalloc(sizeof(*qp), GFP_KERNEL);
249 if (!qp) {
250 pr_debug("%s: Unable to allocate QP\n", __FUNCTION__);
251 return ERR_PTR(-ENOMEM);
252 }
253 spin_lock_init(&qp->lock);
254 if (pd->uobject) {
255 /* userspace specific */
256 }
257
258 err = c2_alloc_qp(to_c2dev(pd->device),
259 to_c2pd(pd), init_attr, qp);
260
261 if (err && pd->uobject) {
262 /* userspace specific */
263 }
264
265 break;
266 default:
267 pr_debug("%s: Invalid QP type: %d\n", __FUNCTION__,
268 init_attr->qp_type);
269 return ERR_PTR(-EINVAL);
270 break;
271 }
272
273 if (err) {
274 kfree(qp);
275 return ERR_PTR(err);
276 }
277
278 return &qp->ibqp;
279}
280
281static int c2_destroy_qp(struct ib_qp *ib_qp)
282{
283 struct c2_qp *qp = to_c2qp(ib_qp);
284
285 pr_debug("%s:%u qp=%p,qp->state=%d\n",
286 __FUNCTION__, __LINE__,ib_qp,qp->state);
287 c2_free_qp(to_c2dev(ib_qp->device), qp);
288 kfree(qp);
289 return 0;
290}
291
292static struct ib_cq *c2_create_cq(struct ib_device *ibdev, int entries,
293 struct ib_ucontext *context,
294 struct ib_udata *udata)
295{
296 struct c2_cq *cq;
297 int err;
298
299 cq = kmalloc(sizeof(*cq), GFP_KERNEL);
300 if (!cq) {
301 pr_debug("%s: Unable to allocate CQ\n", __FUNCTION__);
302 return ERR_PTR(-ENOMEM);
303 }
304
305 err = c2_init_cq(to_c2dev(ibdev), entries, NULL, cq);
306 if (err) {
307 pr_debug("%s: error initializing CQ\n", __FUNCTION__);
308 kfree(cq);
309 return ERR_PTR(err);
310 }
311
312 return &cq->ibcq;
313}
314
315static int c2_destroy_cq(struct ib_cq *ib_cq)
316{
317 struct c2_cq *cq = to_c2cq(ib_cq);
318
319 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
320
321 c2_free_cq(to_c2dev(ib_cq->device), cq);
322 kfree(cq);
323
324 return 0;
325}
326
327static inline u32 c2_convert_access(int acc)
328{
329 return (acc & IB_ACCESS_REMOTE_WRITE ? C2_ACF_REMOTE_WRITE : 0) |
330 (acc & IB_ACCESS_REMOTE_READ ? C2_ACF_REMOTE_READ : 0) |
331 (acc & IB_ACCESS_LOCAL_WRITE ? C2_ACF_LOCAL_WRITE : 0) |
332 C2_ACF_LOCAL_READ | C2_ACF_WINDOW_BIND;
333}
334
335static struct ib_mr *c2_reg_phys_mr(struct ib_pd *ib_pd,
336 struct ib_phys_buf *buffer_list,
337 int num_phys_buf, int acc, u64 * iova_start)
338{
339 struct c2_mr *mr;
340 u64 *page_list;
341 u32 total_len;
342 int err, i, j, k, page_shift, pbl_depth;
343
344 pbl_depth = 0;
345 total_len = 0;
346
347 page_shift = PAGE_SHIFT;
348 /*
349 * If there is only 1 buffer we assume this could
350 * be a map of all phy mem...use a 32k page_shift.
351 */
352 if (num_phys_buf == 1)
353 page_shift += 3;
354
355 for (i = 0; i < num_phys_buf; i++) {
356
357 if (buffer_list[i].addr & ~PAGE_MASK) {
358 pr_debug("Unaligned Memory Buffer: 0x%x\n",
359 (unsigned int) buffer_list[i].addr);
360 return ERR_PTR(-EINVAL);
361 }
362
363 if (!buffer_list[i].size) {
364 pr_debug("Invalid Buffer Size\n");
365 return ERR_PTR(-EINVAL);
366 }
367
368 total_len += buffer_list[i].size;
369 pbl_depth += ALIGN(buffer_list[i].size,
370 (1 << page_shift)) >> page_shift;
371 }
372
373 page_list = vmalloc(sizeof(u64) * pbl_depth);
374 if (!page_list) {
375 pr_debug("couldn't vmalloc page_list of size %zd\n",
376 (sizeof(u64) * pbl_depth));
377 return ERR_PTR(-ENOMEM);
378 }
379
380 for (i = 0, j = 0; i < num_phys_buf; i++) {
381
382 int naddrs;
383
384 naddrs = ALIGN(buffer_list[i].size,
385 (1 << page_shift)) >> page_shift;
386 for (k = 0; k < naddrs; k++)
387 page_list[j++] = (buffer_list[i].addr +
388 (k << page_shift));
389 }
390
391 mr = kmalloc(sizeof(*mr), GFP_KERNEL);
392 if (!mr)
393 return ERR_PTR(-ENOMEM);
394
395 mr->pd = to_c2pd(ib_pd);
396 pr_debug("%s - page shift %d, pbl_depth %d, total_len %u, "
397 "*iova_start %llx, first pa %llx, last pa %llx\n",
398 __FUNCTION__, page_shift, pbl_depth, total_len,
399 *iova_start, page_list[0], page_list[pbl_depth-1]);
400 err = c2_nsmr_register_phys_kern(to_c2dev(ib_pd->device), page_list,
401 (1 << page_shift), pbl_depth,
402 total_len, 0, iova_start,
403 c2_convert_access(acc), mr);
404 vfree(page_list);
405 if (err) {
406 kfree(mr);
407 return ERR_PTR(err);
408 }
409
410 return &mr->ibmr;
411}
412
413static struct ib_mr *c2_get_dma_mr(struct ib_pd *pd, int acc)
414{
415 struct ib_phys_buf bl;
416 u64 kva = 0;
417
418 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
419
420 /* AMSO1100 limit */
421 bl.size = 0xffffffff;
422 bl.addr = 0;
423 return c2_reg_phys_mr(pd, &bl, 1, acc, &kva);
424}
425
426static struct ib_mr *c2_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
427 int acc, struct ib_udata *udata)
428{
429 u64 *pages;
430 u64 kva = 0;
431 int shift, n, len;
432 int i, j, k;
433 int err = 0;
434 struct ib_umem_chunk *chunk;
435 struct c2_pd *c2pd = to_c2pd(pd);
436 struct c2_mr *c2mr;
437
438 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
439 shift = ffs(region->page_size) - 1;
440
441 c2mr = kmalloc(sizeof(*c2mr), GFP_KERNEL);
442 if (!c2mr)
443 return ERR_PTR(-ENOMEM);
444 c2mr->pd = c2pd;
445
446 n = 0;
447 list_for_each_entry(chunk, &region->chunk_list, list)
448 n += chunk->nents;
449
450 pages = kmalloc(n * sizeof(u64), GFP_KERNEL);
451 if (!pages) {
452 err = -ENOMEM;
453 goto err;
454 }
455
456 i = 0;
457 list_for_each_entry(chunk, &region->chunk_list, list) {
458 for (j = 0; j < chunk->nmap; ++j) {
459 len = sg_dma_len(&chunk->page_list[j]) >> shift;
460 for (k = 0; k < len; ++k) {
461 pages[i++] =
462 sg_dma_address(&chunk->page_list[j]) +
463 (region->page_size * k);
464 }
465 }
466 }
467
468 kva = (u64)region->virt_base;
469 err = c2_nsmr_register_phys_kern(to_c2dev(pd->device),
470 pages,
471 region->page_size,
472 i,
473 region->length,
474 region->offset,
475 &kva,
476 c2_convert_access(acc),
477 c2mr);
478 kfree(pages);
479 if (err) {
480 kfree(c2mr);
481 return ERR_PTR(err);
482 }
483 return &c2mr->ibmr;
484
485err:
486 kfree(c2mr);
487 return ERR_PTR(err);
488}
489
490static int c2_dereg_mr(struct ib_mr *ib_mr)
491{
492 struct c2_mr *mr = to_c2mr(ib_mr);
493 int err;
494
495 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
496
497 err = c2_stag_dealloc(to_c2dev(ib_mr->device), ib_mr->lkey);
498 if (err)
499 pr_debug("c2_stag_dealloc failed: %d\n", err);
500 else
501 kfree(mr);
502
503 return err;
504}
505
506static ssize_t show_rev(struct class_device *cdev, char *buf)
507{
508 struct c2_dev *dev = container_of(cdev, struct c2_dev, ibdev.class_dev);
509 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
510 return sprintf(buf, "%x\n", dev->props.hw_ver);
511}
512
513static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
514{
515 struct c2_dev *dev = container_of(cdev, struct c2_dev, ibdev.class_dev);
516 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
517 return sprintf(buf, "%x.%x.%x\n",
518 (int) (dev->props.fw_ver >> 32),
519 (int) (dev->props.fw_ver >> 16) & 0xffff,
520 (int) (dev->props.fw_ver & 0xffff));
521}
522
523static ssize_t show_hca(struct class_device *cdev, char *buf)
524{
525 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
526 return sprintf(buf, "AMSO1100\n");
527}
528
529static ssize_t show_board(struct class_device *cdev, char *buf)
530{
531 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
532 return sprintf(buf, "%.*s\n", 32, "AMSO1100 Board ID");
533}
534
535static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
536static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
537static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
538static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
539
540static struct class_device_attribute *c2_class_attributes[] = {
541 &class_device_attr_hw_rev,
542 &class_device_attr_fw_ver,
543 &class_device_attr_hca_type,
544 &class_device_attr_board_id
545};
546
547static int c2_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
548 int attr_mask, struct ib_udata *udata)
549{
550 int err;
551
552 err =
553 c2_qp_modify(to_c2dev(ibqp->device), to_c2qp(ibqp), attr,
554 attr_mask);
555
556 return err;
557}
558
559static int c2_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
560{
561 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
562 return -ENOSYS;
563}
564
565static int c2_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
566{
567 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
568 return -ENOSYS;
569}
570
571static int c2_process_mad(struct ib_device *ibdev,
572 int mad_flags,
573 u8 port_num,
574 struct ib_wc *in_wc,
575 struct ib_grh *in_grh,
576 struct ib_mad *in_mad, struct ib_mad *out_mad)
577{
578 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
579 return -ENOSYS;
580}
581
582static int c2_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
583{
584 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
585
586 /* Request a connection */
587 return c2_llp_connect(cm_id, iw_param);
588}
589
590static int c2_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
591{
592 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
593
594 /* Accept the new connection */
595 return c2_llp_accept(cm_id, iw_param);
596}
597
598static int c2_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
599{
600 int err;
601
602 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
603
604 err = c2_llp_reject(cm_id, pdata, pdata_len);
605 return err;
606}
607
608static int c2_service_create(struct iw_cm_id *cm_id, int backlog)
609{
610 int err;
611
612 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
613 err = c2_llp_service_create(cm_id, backlog);
614 pr_debug("%s:%u err=%d\n",
615 __FUNCTION__, __LINE__,
616 err);
617 return err;
618}
619
620static int c2_service_destroy(struct iw_cm_id *cm_id)
621{
622 int err;
623 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
624
625 err = c2_llp_service_destroy(cm_id);
626
627 return err;
628}
629
630static int c2_pseudo_up(struct net_device *netdev)
631{
632 struct in_device *ind;
633 struct c2_dev *c2dev = netdev->priv;
634
635 ind = in_dev_get(netdev);
636 if (!ind)
637 return 0;
638
639 pr_debug("adding...\n");
640 for_ifa(ind) {
641#ifdef DEBUG
642 u8 *ip = (u8 *) & ifa->ifa_address;
643
644 pr_debug("%s: %d.%d.%d.%d\n",
645 ifa->ifa_label, ip[0], ip[1], ip[2], ip[3]);
646#endif
647 c2_add_addr(c2dev, ifa->ifa_address, ifa->ifa_mask);
648 }
649 endfor_ifa(ind);
650 in_dev_put(ind);
651
652 return 0;
653}
654
655static int c2_pseudo_down(struct net_device *netdev)
656{
657 struct in_device *ind;
658 struct c2_dev *c2dev = netdev->priv;
659
660 ind = in_dev_get(netdev);
661 if (!ind)
662 return 0;
663
664 pr_debug("deleting...\n");
665 for_ifa(ind) {
666#ifdef DEBUG
667 u8 *ip = (u8 *) & ifa->ifa_address;
668
669 pr_debug("%s: %d.%d.%d.%d\n",
670 ifa->ifa_label, ip[0], ip[1], ip[2], ip[3]);
671#endif
672 c2_del_addr(c2dev, ifa->ifa_address, ifa->ifa_mask);
673 }
674 endfor_ifa(ind);
675 in_dev_put(ind);
676
677 return 0;
678}
679
680static int c2_pseudo_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
681{
682 kfree_skb(skb);
683 return NETDEV_TX_OK;
684}
685
686static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu)
687{
688 int ret = 0;
689
690 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
691 return -EINVAL;
692
693 netdev->mtu = new_mtu;
694
695 /* TODO: Tell rnic about new rmda interface mtu */
696 return ret;
697}
698
699static void setup(struct net_device *netdev)
700{
701 SET_MODULE_OWNER(netdev);
702 netdev->open = c2_pseudo_up;
703 netdev->stop = c2_pseudo_down;
704 netdev->hard_start_xmit = c2_pseudo_xmit_frame;
705 netdev->get_stats = NULL;
706 netdev->tx_timeout = NULL;
707 netdev->set_mac_address = NULL;
708 netdev->change_mtu = c2_pseudo_change_mtu;
709 netdev->watchdog_timeo = 0;
710 netdev->type = ARPHRD_ETHER;
711 netdev->mtu = 1500;
712 netdev->hard_header_len = ETH_HLEN;
713 netdev->addr_len = ETH_ALEN;
714 netdev->tx_queue_len = 0;
715 netdev->flags |= IFF_NOARP;
716 return;
717}
718
719static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
720{
721 char name[IFNAMSIZ];
722 struct net_device *netdev;
723
724 /* change ethxxx to iwxxx */
725 strcpy(name, "iw");
726 strcat(name, &c2dev->netdev->name[3]);
727 netdev = alloc_netdev(sizeof(*netdev), name, setup);
728 if (!netdev) {
729 printk(KERN_ERR PFX "%s - etherdev alloc failed",
730 __FUNCTION__);
731 return NULL;
732 }
733
734 netdev->priv = c2dev;
735
736 SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);
737
738 memcpy_fromio(netdev->dev_addr, c2dev->kva + C2_REGS_RDMA_ENADDR, 6);
739
740 /* Print out the MAC address */
741 pr_debug("%s: MAC %02X:%02X:%02X:%02X:%02X:%02X\n",
742 netdev->name,
743 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
744 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
745
746#if 0
747 /* Disable network packets */
748 netif_stop_queue(netdev);
749#endif
750 return netdev;
751}
752
753int c2_register_device(struct c2_dev *dev)
754{
755 int ret;
756 int i;
757
758 /* Register pseudo network device */
759 dev->pseudo_netdev = c2_pseudo_netdev_init(dev);
760 if (dev->pseudo_netdev) {
761 ret = register_netdev(dev->pseudo_netdev);
762 if (ret) {
763 printk(KERN_ERR PFX
764 "Unable to register netdev, ret = %d\n", ret);
765 free_netdev(dev->pseudo_netdev);
766 return ret;
767 }
768 }
769
770 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
771 strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX);
772 dev->ibdev.owner = THIS_MODULE;
773 dev->ibdev.uverbs_cmd_mask =
774 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
775 (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
776 (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
777 (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
778 (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
779 (1ull << IB_USER_VERBS_CMD_REG_MR) |
780 (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
781 (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
782 (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
783 (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
784 (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) |
785 (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
786 (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
787 (1ull << IB_USER_VERBS_CMD_POLL_CQ) |
788 (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
789 (1ull << IB_USER_VERBS_CMD_POST_SEND) |
790 (1ull << IB_USER_VERBS_CMD_POST_RECV);
791
792 dev->ibdev.node_type = RDMA_NODE_RNIC;
793 memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid));
794 memcpy(&dev->ibdev.node_guid, dev->pseudo_netdev->dev_addr, 6);
795 dev->ibdev.phys_port_cnt = 1;
796 dev->ibdev.dma_device = &dev->pcidev->dev;
797 dev->ibdev.class_dev.dev = &dev->pcidev->dev;
798 dev->ibdev.query_device = c2_query_device;
799 dev->ibdev.query_port = c2_query_port;
800 dev->ibdev.modify_port = c2_modify_port;
801 dev->ibdev.query_pkey = c2_query_pkey;
802 dev->ibdev.query_gid = c2_query_gid;
803 dev->ibdev.alloc_ucontext = c2_alloc_ucontext;
804 dev->ibdev.dealloc_ucontext = c2_dealloc_ucontext;
805 dev->ibdev.mmap = c2_mmap_uar;
806 dev->ibdev.alloc_pd = c2_alloc_pd;
807 dev->ibdev.dealloc_pd = c2_dealloc_pd;
808 dev->ibdev.create_ah = c2_ah_create;
809 dev->ibdev.destroy_ah = c2_ah_destroy;
810 dev->ibdev.create_qp = c2_create_qp;
811 dev->ibdev.modify_qp = c2_modify_qp;
812 dev->ibdev.destroy_qp = c2_destroy_qp;
813 dev->ibdev.create_cq = c2_create_cq;
814 dev->ibdev.destroy_cq = c2_destroy_cq;
815 dev->ibdev.poll_cq = c2_poll_cq;
816 dev->ibdev.get_dma_mr = c2_get_dma_mr;
817 dev->ibdev.reg_phys_mr = c2_reg_phys_mr;
818 dev->ibdev.reg_user_mr = c2_reg_user_mr;
819 dev->ibdev.dereg_mr = c2_dereg_mr;
820
821 dev->ibdev.alloc_fmr = NULL;
822 dev->ibdev.unmap_fmr = NULL;
823 dev->ibdev.dealloc_fmr = NULL;
824 dev->ibdev.map_phys_fmr = NULL;
825
826 dev->ibdev.attach_mcast = c2_multicast_attach;
827 dev->ibdev.detach_mcast = c2_multicast_detach;
828 dev->ibdev.process_mad = c2_process_mad;
829
830 dev->ibdev.req_notify_cq = c2_arm_cq;
831 dev->ibdev.post_send = c2_post_send;
832 dev->ibdev.post_recv = c2_post_receive;
833
834 dev->ibdev.iwcm = kmalloc(sizeof(*dev->ibdev.iwcm), GFP_KERNEL);
835 dev->ibdev.iwcm->add_ref = c2_add_ref;
836 dev->ibdev.iwcm->rem_ref = c2_rem_ref;
837 dev->ibdev.iwcm->get_qp = c2_get_qp;
838 dev->ibdev.iwcm->connect = c2_connect;
839 dev->ibdev.iwcm->accept = c2_accept;
840 dev->ibdev.iwcm->reject = c2_reject;
841 dev->ibdev.iwcm->create_listen = c2_service_create;
842 dev->ibdev.iwcm->destroy_listen = c2_service_destroy;
843
844 ret = ib_register_device(&dev->ibdev);
845 if (ret)
846 return ret;
847
848 for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) {
849 ret = class_device_create_file(&dev->ibdev.class_dev,
850 c2_class_attributes[i]);
851 if (ret) {
852 unregister_netdev(dev->pseudo_netdev);
853 free_netdev(dev->pseudo_netdev);
854 ib_unregister_device(&dev->ibdev);
855 return ret;
856 }
857 }
858
859 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
860 return 0;
861}
862
863void c2_unregister_device(struct c2_dev *dev)
864{
865 pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
866 unregister_netdev(dev->pseudo_netdev);
867 free_netdev(dev->pseudo_netdev);
868 ib_unregister_device(&dev->ibdev);
869}
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.h b/drivers/infiniband/hw/amso1100/c2_provider.h
new file mode 100644
index 000000000000..fc906223220f
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_provider.h
@@ -0,0 +1,181 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34
35#ifndef C2_PROVIDER_H
36#define C2_PROVIDER_H
37#include <linux/inetdevice.h>
38
39#include <rdma/ib_verbs.h>
40#include <rdma/ib_pack.h>
41
42#include "c2_mq.h"
43#include <rdma/iw_cm.h>
44
45#define C2_MPT_FLAG_ATOMIC (1 << 14)
46#define C2_MPT_FLAG_REMOTE_WRITE (1 << 13)
47#define C2_MPT_FLAG_REMOTE_READ (1 << 12)
48#define C2_MPT_FLAG_LOCAL_WRITE (1 << 11)
49#define C2_MPT_FLAG_LOCAL_READ (1 << 10)
50
51struct c2_buf_list {
52 void *buf;
53 DECLARE_PCI_UNMAP_ADDR(mapping)
54};
55
56
57/* The user context keeps track of objects allocated for a
58 * particular user-mode client. */
59struct c2_ucontext {
60 struct ib_ucontext ibucontext;
61};
62
63struct c2_mtt;
64
65/* All objects associated with a PD are kept in the
66 * associated user context if present.
67 */
68struct c2_pd {
69 struct ib_pd ibpd;
70 u32 pd_id;
71};
72
73struct c2_mr {
74 struct ib_mr ibmr;
75 struct c2_pd *pd;
76};
77
78struct c2_av;
79
80enum c2_ah_type {
81 C2_AH_ON_HCA,
82 C2_AH_PCI_POOL,
83 C2_AH_KMALLOC
84};
85
86struct c2_ah {
87 struct ib_ah ibah;
88};
89
90struct c2_cq {
91 struct ib_cq ibcq;
92 spinlock_t lock;
93 atomic_t refcount;
94 int cqn;
95 int is_kernel;
96 wait_queue_head_t wait;
97
98 u32 adapter_handle;
99 struct c2_mq mq;
100};
101
102struct c2_wq {
103 spinlock_t lock;
104};
105struct iw_cm_id;
106struct c2_qp {
107 struct ib_qp ibqp;
108 struct iw_cm_id *cm_id;
109 spinlock_t lock;
110 atomic_t refcount;
111 wait_queue_head_t wait;
112 int qpn;
113
114 u32 adapter_handle;
115 u32 send_sgl_depth;
116 u32 recv_sgl_depth;
117 u32 rdma_write_sgl_depth;
118 u8 state;
119
120 struct c2_mq sq_mq;
121 struct c2_mq rq_mq;
122};
123
124struct c2_cr_query_attrs {
125 u32 local_addr;
126 u32 remote_addr;
127 u16 local_port;
128 u16 remote_port;
129};
130
131static inline struct c2_pd *to_c2pd(struct ib_pd *ibpd)
132{
133 return container_of(ibpd, struct c2_pd, ibpd);
134}
135
136static inline struct c2_ucontext *to_c2ucontext(struct ib_ucontext *ibucontext)
137{
138 return container_of(ibucontext, struct c2_ucontext, ibucontext);
139}
140
141static inline struct c2_mr *to_c2mr(struct ib_mr *ibmr)
142{
143 return container_of(ibmr, struct c2_mr, ibmr);
144}
145
146
147static inline struct c2_ah *to_c2ah(struct ib_ah *ibah)
148{
149 return container_of(ibah, struct c2_ah, ibah);
150}
151
152static inline struct c2_cq *to_c2cq(struct ib_cq *ibcq)
153{
154 return container_of(ibcq, struct c2_cq, ibcq);
155}
156
157static inline struct c2_qp *to_c2qp(struct ib_qp *ibqp)
158{
159 return container_of(ibqp, struct c2_qp, ibqp);
160}
161
162static inline int is_rnic_addr(struct net_device *netdev, u32 addr)
163{
164 struct in_device *ind;
165 int ret = 0;
166
167 ind = in_dev_get(netdev);
168 if (!ind)
169 return 0;
170
171 for_ifa(ind) {
172 if (ifa->ifa_address == addr) {
173 ret = 1;
174 break;
175 }
176 }
177 endfor_ifa(ind);
178 in_dev_put(ind);
179 return ret;
180}
181#endif /* C2_PROVIDER_H */
diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c
new file mode 100644
index 000000000000..12261132b077
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_qp.c
@@ -0,0 +1,975 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
5 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
6 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 *
36 */
37
38#include "c2.h"
39#include "c2_vq.h"
40#include "c2_status.h"
41
42#define C2_MAX_ORD_PER_QP 128
43#define C2_MAX_IRD_PER_QP 128
44
45#define C2_HINT_MAKE(q_index, hint_count) (((q_index) << 16) | hint_count)
46#define C2_HINT_GET_INDEX(hint) (((hint) & 0x7FFF0000) >> 16)
47#define C2_HINT_GET_COUNT(hint) ((hint) & 0x0000FFFF)
48
49#define NO_SUPPORT -1
50static const u8 c2_opcode[] = {
51 [IB_WR_SEND] = C2_WR_TYPE_SEND,
52 [IB_WR_SEND_WITH_IMM] = NO_SUPPORT,
53 [IB_WR_RDMA_WRITE] = C2_WR_TYPE_RDMA_WRITE,
54 [IB_WR_RDMA_WRITE_WITH_IMM] = NO_SUPPORT,
55 [IB_WR_RDMA_READ] = C2_WR_TYPE_RDMA_READ,
56 [IB_WR_ATOMIC_CMP_AND_SWP] = NO_SUPPORT,
57 [IB_WR_ATOMIC_FETCH_AND_ADD] = NO_SUPPORT,
58};
59
60static int to_c2_state(enum ib_qp_state ib_state)
61{
62 switch (ib_state) {
63 case IB_QPS_RESET:
64 return C2_QP_STATE_IDLE;
65 case IB_QPS_RTS:
66 return C2_QP_STATE_RTS;
67 case IB_QPS_SQD:
68 return C2_QP_STATE_CLOSING;
69 case IB_QPS_SQE:
70 return C2_QP_STATE_CLOSING;
71 case IB_QPS_ERR:
72 return C2_QP_STATE_ERROR;
73 default:
74 return -1;
75 }
76}
77
78static int to_ib_state(enum c2_qp_state c2_state)
79{
80 switch (c2_state) {
81 case C2_QP_STATE_IDLE:
82 return IB_QPS_RESET;
83 case C2_QP_STATE_CONNECTING:
84 return IB_QPS_RTR;
85 case C2_QP_STATE_RTS:
86 return IB_QPS_RTS;
87 case C2_QP_STATE_CLOSING:
88 return IB_QPS_SQD;
89 case C2_QP_STATE_ERROR:
90 return IB_QPS_ERR;
91 case C2_QP_STATE_TERMINATE:
92 return IB_QPS_SQE;
93 default:
94 return -1;
95 }
96}
97
98static const char *to_ib_state_str(int ib_state)
99{
100 static const char *state_str[] = {
101 "IB_QPS_RESET",
102 "IB_QPS_INIT",
103 "IB_QPS_RTR",
104 "IB_QPS_RTS",
105 "IB_QPS_SQD",
106 "IB_QPS_SQE",
107 "IB_QPS_ERR"
108 };
109 if (ib_state < IB_QPS_RESET ||
110 ib_state > IB_QPS_ERR)
111 return "<invalid IB QP state>";
112
113 ib_state -= IB_QPS_RESET;
114 return state_str[ib_state];
115}
116
117void c2_set_qp_state(struct c2_qp *qp, int c2_state)
118{
119 int new_state = to_ib_state(c2_state);
120
121 pr_debug("%s: qp[%p] state modify %s --> %s\n",
122 __FUNCTION__,
123 qp,
124 to_ib_state_str(qp->state),
125 to_ib_state_str(new_state));
126 qp->state = new_state;
127}
128
129#define C2_QP_NO_ATTR_CHANGE 0xFFFFFFFF
130
131int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp,
132 struct ib_qp_attr *attr, int attr_mask)
133{
134 struct c2wr_qp_modify_req wr;
135 struct c2wr_qp_modify_rep *reply;
136 struct c2_vq_req *vq_req;
137 unsigned long flags;
138 u8 next_state;
139 int err;
140
141 pr_debug("%s:%d qp=%p, %s --> %s\n",
142 __FUNCTION__, __LINE__,
143 qp,
144 to_ib_state_str(qp->state),
145 to_ib_state_str(attr->qp_state));
146
147 vq_req = vq_req_alloc(c2dev);
148 if (!vq_req)
149 return -ENOMEM;
150
151 c2_wr_set_id(&wr, CCWR_QP_MODIFY);
152 wr.hdr.context = (unsigned long) vq_req;
153 wr.rnic_handle = c2dev->adapter_handle;
154 wr.qp_handle = qp->adapter_handle;
155 wr.ord = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
156 wr.ird = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
157 wr.sq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
158 wr.rq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
159
160 if (attr_mask & IB_QP_STATE) {
161 /* Ensure the state is valid */
162 if (attr->qp_state < 0 || attr->qp_state > IB_QPS_ERR)
163 return -EINVAL;
164
165 wr.next_qp_state = cpu_to_be32(to_c2_state(attr->qp_state));
166
167 if (attr->qp_state == IB_QPS_ERR) {
168 spin_lock_irqsave(&qp->lock, flags);
169 if (qp->cm_id && qp->state == IB_QPS_RTS) {
170 pr_debug("Generating CLOSE event for QP-->ERR, "
171 "qp=%p, cm_id=%p\n",qp,qp->cm_id);
172 /* Generate an CLOSE event */
173 vq_req->cm_id = qp->cm_id;
174 vq_req->event = IW_CM_EVENT_CLOSE;
175 }
176 spin_unlock_irqrestore(&qp->lock, flags);
177 }
178 next_state = attr->qp_state;
179
180 } else if (attr_mask & IB_QP_CUR_STATE) {
181
182 if (attr->cur_qp_state != IB_QPS_RTR &&
183 attr->cur_qp_state != IB_QPS_RTS &&
184 attr->cur_qp_state != IB_QPS_SQD &&
185 attr->cur_qp_state != IB_QPS_SQE)
186 return -EINVAL;
187 else
188 wr.next_qp_state =
189 cpu_to_be32(to_c2_state(attr->cur_qp_state));
190
191 next_state = attr->cur_qp_state;
192
193 } else {
194 err = 0;
195 goto bail0;
196 }
197
198 /* reference the request struct */
199 vq_req_get(c2dev, vq_req);
200
201 err = vq_send_wr(c2dev, (union c2wr *) & wr);
202 if (err) {
203 vq_req_put(c2dev, vq_req);
204 goto bail0;
205 }
206
207 err = vq_wait_for_reply(c2dev, vq_req);
208 if (err)
209 goto bail0;
210
211 reply = (struct c2wr_qp_modify_rep *) (unsigned long) vq_req->reply_msg;
212 if (!reply) {
213 err = -ENOMEM;
214 goto bail0;
215 }
216
217 err = c2_errno(reply);
218 if (!err)
219 qp->state = next_state;
220#ifdef DEBUG
221 else
222 pr_debug("%s: c2_errno=%d\n", __FUNCTION__, err);
223#endif
224 /*
225 * If we're going to error and generating the event here, then
226 * we need to remove the reference because there will be no
227 * close event generated by the adapter
228 */
229 spin_lock_irqsave(&qp->lock, flags);
230 if (vq_req->event==IW_CM_EVENT_CLOSE && qp->cm_id) {
231 qp->cm_id->rem_ref(qp->cm_id);
232 qp->cm_id = NULL;
233 }
234 spin_unlock_irqrestore(&qp->lock, flags);
235
236 vq_repbuf_free(c2dev, reply);
237 bail0:
238 vq_req_free(c2dev, vq_req);
239
240 pr_debug("%s:%d qp=%p, cur_state=%s\n",
241 __FUNCTION__, __LINE__,
242 qp,
243 to_ib_state_str(qp->state));
244 return err;
245}
246
247int c2_qp_set_read_limits(struct c2_dev *c2dev, struct c2_qp *qp,
248 int ord, int ird)
249{
250 struct c2wr_qp_modify_req wr;
251 struct c2wr_qp_modify_rep *reply;
252 struct c2_vq_req *vq_req;
253 int err;
254
255 vq_req = vq_req_alloc(c2dev);
256 if (!vq_req)
257 return -ENOMEM;
258
259 c2_wr_set_id(&wr, CCWR_QP_MODIFY);
260 wr.hdr.context = (unsigned long) vq_req;
261 wr.rnic_handle = c2dev->adapter_handle;
262 wr.qp_handle = qp->adapter_handle;
263 wr.ord = cpu_to_be32(ord);
264 wr.ird = cpu_to_be32(ird);
265 wr.sq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
266 wr.rq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
267 wr.next_qp_state = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
268
269 /* reference the request struct */
270 vq_req_get(c2dev, vq_req);
271
272 err = vq_send_wr(c2dev, (union c2wr *) & wr);
273 if (err) {
274 vq_req_put(c2dev, vq_req);
275 goto bail0;
276 }
277
278 err = vq_wait_for_reply(c2dev, vq_req);
279 if (err)
280 goto bail0;
281
282 reply = (struct c2wr_qp_modify_rep *) (unsigned long)
283 vq_req->reply_msg;
284 if (!reply) {
285 err = -ENOMEM;
286 goto bail0;
287 }
288
289 err = c2_errno(reply);
290 vq_repbuf_free(c2dev, reply);
291 bail0:
292 vq_req_free(c2dev, vq_req);
293 return err;
294}
295
296static int destroy_qp(struct c2_dev *c2dev, struct c2_qp *qp)
297{
298 struct c2_vq_req *vq_req;
299 struct c2wr_qp_destroy_req wr;
300 struct c2wr_qp_destroy_rep *reply;
301 unsigned long flags;
302 int err;
303
304 /*
305 * Allocate a verb request message
306 */
307 vq_req = vq_req_alloc(c2dev);
308 if (!vq_req) {
309 return -ENOMEM;
310 }
311
312 /*
313 * Initialize the WR
314 */
315 c2_wr_set_id(&wr, CCWR_QP_DESTROY);
316 wr.hdr.context = (unsigned long) vq_req;
317 wr.rnic_handle = c2dev->adapter_handle;
318 wr.qp_handle = qp->adapter_handle;
319
320 /*
321 * reference the request struct. dereferenced in the int handler.
322 */
323 vq_req_get(c2dev, vq_req);
324
325 spin_lock_irqsave(&qp->lock, flags);
326 if (qp->cm_id && qp->state == IB_QPS_RTS) {
327 pr_debug("destroy_qp: generating CLOSE event for QP-->ERR, "
328 "qp=%p, cm_id=%p\n",qp,qp->cm_id);
329 /* Generate an CLOSE event */
330 vq_req->qp = qp;
331 vq_req->cm_id = qp->cm_id;
332 vq_req->event = IW_CM_EVENT_CLOSE;
333 }
334 spin_unlock_irqrestore(&qp->lock, flags);
335
336 /*
337 * Send WR to adapter
338 */
339 err = vq_send_wr(c2dev, (union c2wr *) & wr);
340 if (err) {
341 vq_req_put(c2dev, vq_req);
342 goto bail0;
343 }
344
345 /*
346 * Wait for reply from adapter
347 */
348 err = vq_wait_for_reply(c2dev, vq_req);
349 if (err) {
350 goto bail0;
351 }
352
353 /*
354 * Process reply
355 */
356 reply = (struct c2wr_qp_destroy_rep *) (unsigned long) (vq_req->reply_msg);
357 if (!reply) {
358 err = -ENOMEM;
359 goto bail0;
360 }
361
362 spin_lock_irqsave(&qp->lock, flags);
363 if (qp->cm_id) {
364 qp->cm_id->rem_ref(qp->cm_id);
365 qp->cm_id = NULL;
366 }
367 spin_unlock_irqrestore(&qp->lock, flags);
368
369 vq_repbuf_free(c2dev, reply);
370 bail0:
371 vq_req_free(c2dev, vq_req);
372 return err;
373}
374
375static int c2_alloc_qpn(struct c2_dev *c2dev, struct c2_qp *qp)
376{
377 int ret;
378
379 do {
380 spin_lock_irq(&c2dev->qp_table.lock);
381 ret = idr_get_new_above(&c2dev->qp_table.idr, qp,
382 c2dev->qp_table.last++, &qp->qpn);
383 spin_unlock_irq(&c2dev->qp_table.lock);
384 } while ((ret == -EAGAIN) &&
385 idr_pre_get(&c2dev->qp_table.idr, GFP_KERNEL));
386 return ret;
387}
388
389static void c2_free_qpn(struct c2_dev *c2dev, int qpn)
390{
391 spin_lock_irq(&c2dev->qp_table.lock);
392 idr_remove(&c2dev->qp_table.idr, qpn);
393 spin_unlock_irq(&c2dev->qp_table.lock);
394}
395
396struct c2_qp *c2_find_qpn(struct c2_dev *c2dev, int qpn)
397{
398 unsigned long flags;
399 struct c2_qp *qp;
400
401 spin_lock_irqsave(&c2dev->qp_table.lock, flags);
402 qp = idr_find(&c2dev->qp_table.idr, qpn);
403 spin_unlock_irqrestore(&c2dev->qp_table.lock, flags);
404 return qp;
405}
406
407int c2_alloc_qp(struct c2_dev *c2dev,
408 struct c2_pd *pd,
409 struct ib_qp_init_attr *qp_attrs, struct c2_qp *qp)
410{
411 struct c2wr_qp_create_req wr;
412 struct c2wr_qp_create_rep *reply;
413 struct c2_vq_req *vq_req;
414 struct c2_cq *send_cq = to_c2cq(qp_attrs->send_cq);
415 struct c2_cq *recv_cq = to_c2cq(qp_attrs->recv_cq);
416 unsigned long peer_pa;
417 u32 q_size, msg_size, mmap_size;
418 void __iomem *mmap;
419 int err;
420
421 err = c2_alloc_qpn(c2dev, qp);
422 if (err)
423 return err;
424 qp->ibqp.qp_num = qp->qpn;
425 qp->ibqp.qp_type = IB_QPT_RC;
426
427 /* Allocate the SQ and RQ shared pointers */
428 qp->sq_mq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
429 &qp->sq_mq.shared_dma, GFP_KERNEL);
430 if (!qp->sq_mq.shared) {
431 err = -ENOMEM;
432 goto bail0;
433 }
434
435 qp->rq_mq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
436 &qp->rq_mq.shared_dma, GFP_KERNEL);
437 if (!qp->rq_mq.shared) {
438 err = -ENOMEM;
439 goto bail1;
440 }
441
442 /* Allocate the verbs request */
443 vq_req = vq_req_alloc(c2dev);
444 if (vq_req == NULL) {
445 err = -ENOMEM;
446 goto bail2;
447 }
448
449 /* Initialize the work request */
450 memset(&wr, 0, sizeof(wr));
451 c2_wr_set_id(&wr, CCWR_QP_CREATE);
452 wr.hdr.context = (unsigned long) vq_req;
453 wr.rnic_handle = c2dev->adapter_handle;
454 wr.sq_cq_handle = send_cq->adapter_handle;
455 wr.rq_cq_handle = recv_cq->adapter_handle;
456 wr.sq_depth = cpu_to_be32(qp_attrs->cap.max_send_wr + 1);
457 wr.rq_depth = cpu_to_be32(qp_attrs->cap.max_recv_wr + 1);
458 wr.srq_handle = 0;
459 wr.flags = cpu_to_be32(QP_RDMA_READ | QP_RDMA_WRITE | QP_MW_BIND |
460 QP_ZERO_STAG | QP_RDMA_READ_RESPONSE);
461 wr.send_sgl_depth = cpu_to_be32(qp_attrs->cap.max_send_sge);
462 wr.recv_sgl_depth = cpu_to_be32(qp_attrs->cap.max_recv_sge);
463 wr.rdma_write_sgl_depth = cpu_to_be32(qp_attrs->cap.max_send_sge);
464 wr.shared_sq_ht = cpu_to_be64(qp->sq_mq.shared_dma);
465 wr.shared_rq_ht = cpu_to_be64(qp->rq_mq.shared_dma);
466 wr.ord = cpu_to_be32(C2_MAX_ORD_PER_QP);
467 wr.ird = cpu_to_be32(C2_MAX_IRD_PER_QP);
468 wr.pd_id = pd->pd_id;
469 wr.user_context = (unsigned long) qp;
470
471 vq_req_get(c2dev, vq_req);
472
473 /* Send the WR to the adapter */
474 err = vq_send_wr(c2dev, (union c2wr *) & wr);
475 if (err) {
476 vq_req_put(c2dev, vq_req);
477 goto bail3;
478 }
479
480 /* Wait for the verb reply */
481 err = vq_wait_for_reply(c2dev, vq_req);
482 if (err) {
483 goto bail3;
484 }
485
486 /* Process the reply */
487 reply = (struct c2wr_qp_create_rep *) (unsigned long) (vq_req->reply_msg);
488 if (!reply) {
489 err = -ENOMEM;
490 goto bail3;
491 }
492
493 if ((err = c2_wr_get_result(reply)) != 0) {
494 goto bail4;
495 }
496
497 /* Fill in the kernel QP struct */
498 atomic_set(&qp->refcount, 1);
499 qp->adapter_handle = reply->qp_handle;
500 qp->state = IB_QPS_RESET;
501 qp->send_sgl_depth = qp_attrs->cap.max_send_sge;
502 qp->rdma_write_sgl_depth = qp_attrs->cap.max_send_sge;
503 qp->recv_sgl_depth = qp_attrs->cap.max_recv_sge;
504
505 /* Initialize the SQ MQ */
506 q_size = be32_to_cpu(reply->sq_depth);
507 msg_size = be32_to_cpu(reply->sq_msg_size);
508 peer_pa = c2dev->pa + be32_to_cpu(reply->sq_mq_start);
509 mmap_size = PAGE_ALIGN(sizeof(struct c2_mq_shared) + msg_size * q_size);
510 mmap = ioremap_nocache(peer_pa, mmap_size);
511 if (!mmap) {
512 err = -ENOMEM;
513 goto bail5;
514 }
515
516 c2_mq_req_init(&qp->sq_mq,
517 be32_to_cpu(reply->sq_mq_index),
518 q_size,
519 msg_size,
520 mmap + sizeof(struct c2_mq_shared), /* pool start */
521 mmap, /* peer */
522 C2_MQ_ADAPTER_TARGET);
523
524 /* Initialize the RQ mq */
525 q_size = be32_to_cpu(reply->rq_depth);
526 msg_size = be32_to_cpu(reply->rq_msg_size);
527 peer_pa = c2dev->pa + be32_to_cpu(reply->rq_mq_start);
528 mmap_size = PAGE_ALIGN(sizeof(struct c2_mq_shared) + msg_size * q_size);
529 mmap = ioremap_nocache(peer_pa, mmap_size);
530 if (!mmap) {
531 err = -ENOMEM;
532 goto bail6;
533 }
534
535 c2_mq_req_init(&qp->rq_mq,
536 be32_to_cpu(reply->rq_mq_index),
537 q_size,
538 msg_size,
539 mmap + sizeof(struct c2_mq_shared), /* pool start */
540 mmap, /* peer */
541 C2_MQ_ADAPTER_TARGET);
542
543 vq_repbuf_free(c2dev, reply);
544 vq_req_free(c2dev, vq_req);
545
546 return 0;
547
548 bail6:
549 iounmap(qp->sq_mq.peer);
550 bail5:
551 destroy_qp(c2dev, qp);
552 bail4:
553 vq_repbuf_free(c2dev, reply);
554 bail3:
555 vq_req_free(c2dev, vq_req);
556 bail2:
557 c2_free_mqsp(qp->rq_mq.shared);
558 bail1:
559 c2_free_mqsp(qp->sq_mq.shared);
560 bail0:
561 c2_free_qpn(c2dev, qp->qpn);
562 return err;
563}
564
565void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp)
566{
567 struct c2_cq *send_cq;
568 struct c2_cq *recv_cq;
569
570 send_cq = to_c2cq(qp->ibqp.send_cq);
571 recv_cq = to_c2cq(qp->ibqp.recv_cq);
572
573 /*
574 * Lock CQs here, so that CQ polling code can do QP lookup
575 * without taking a lock.
576 */
577 spin_lock_irq(&send_cq->lock);
578 if (send_cq != recv_cq)
579 spin_lock(&recv_cq->lock);
580
581 c2_free_qpn(c2dev, qp->qpn);
582
583 if (send_cq != recv_cq)
584 spin_unlock(&recv_cq->lock);
585 spin_unlock_irq(&send_cq->lock);
586
587 /*
588 * Destory qp in the rnic...
589 */
590 destroy_qp(c2dev, qp);
591
592 /*
593 * Mark any unreaped CQEs as null and void.
594 */
595 c2_cq_clean(c2dev, qp, send_cq->cqn);
596 if (send_cq != recv_cq)
597 c2_cq_clean(c2dev, qp, recv_cq->cqn);
598 /*
599 * Unmap the MQs and return the shared pointers
600 * to the message pool.
601 */
602 iounmap(qp->sq_mq.peer);
603 iounmap(qp->rq_mq.peer);
604 c2_free_mqsp(qp->sq_mq.shared);
605 c2_free_mqsp(qp->rq_mq.shared);
606
607 atomic_dec(&qp->refcount);
608 wait_event(qp->wait, !atomic_read(&qp->refcount));
609}
610
611/*
612 * Function: move_sgl
613 *
614 * Description:
615 * Move an SGL from the user's work request struct into a CCIL Work Request
616 * message, swapping to WR byte order and ensure the total length doesn't
617 * overflow.
618 *
619 * IN:
620 * dst - ptr to CCIL Work Request message SGL memory.
621 * src - ptr to the consumers SGL memory.
622 *
623 * OUT: none
624 *
625 * Return:
626 * CCIL status codes.
627 */
628static int
629move_sgl(struct c2_data_addr * dst, struct ib_sge *src, int count, u32 * p_len,
630 u8 * actual_count)
631{
632 u32 tot = 0; /* running total */
633 u8 acount = 0; /* running total non-0 len sge's */
634
635 while (count > 0) {
636 /*
637 * If the addition of this SGE causes the
638 * total SGL length to exceed 2^32-1, then
639 * fail-n-bail.
640 *
641 * If the current total plus the next element length
642 * wraps, then it will go negative and be less than the
643 * current total...
644 */
645 if ((tot + src->length) < tot) {
646 return -EINVAL;
647 }
648 /*
649 * Bug: 1456 (as well as 1498 & 1643)
650 * Skip over any sge's supplied with len=0
651 */
652 if (src->length) {
653 tot += src->length;
654 dst->stag = cpu_to_be32(src->lkey);
655 dst->to = cpu_to_be64(src->addr);
656 dst->length = cpu_to_be32(src->length);
657 dst++;
658 acount++;
659 }
660 src++;
661 count--;
662 }
663
664 if (acount == 0) {
665 /*
666 * Bug: 1476 (as well as 1498, 1456 and 1643)
667 * Setup the SGL in the WR to make it easier for the RNIC.
668 * This way, the FW doesn't have to deal with special cases.
669 * Setting length=0 should be sufficient.
670 */
671 dst->stag = 0;
672 dst->to = 0;
673 dst->length = 0;
674 }
675
676 *p_len = tot;
677 *actual_count = acount;
678 return 0;
679}
680
681/*
682 * Function: c2_activity (private function)
683 *
684 * Description:
685 * Post an mq index to the host->adapter activity fifo.
686 *
687 * IN:
688 * c2dev - ptr to c2dev structure
689 * mq_index - mq index to post
690 * shared - value most recently written to shared
691 *
692 * OUT:
693 *
694 * Return:
695 * none
696 */
697static inline void c2_activity(struct c2_dev *c2dev, u32 mq_index, u16 shared)
698{
699 /*
700 * First read the register to see if the FIFO is full, and if so,
701 * spin until it's not. This isn't perfect -- there is no
702 * synchronization among the clients of the register, but in
703 * practice it prevents multiple CPU from hammering the bus
704 * with PCI RETRY. Note that when this does happen, the card
705 * cannot get on the bus and the card and system hang in a
706 * deadlock -- thus the need for this code. [TOT]
707 */
708 while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000) {
709 set_current_state(TASK_UNINTERRUPTIBLE);
710 schedule_timeout(0);
711 }
712
713 __raw_writel(C2_HINT_MAKE(mq_index, shared),
714 c2dev->regs + PCI_BAR0_ADAPTER_HINT);
715}
716
717/*
718 * Function: qp_wr_post
719 *
720 * Description:
721 * This in-line function allocates a MQ msg, then moves the host-copy of
722 * the completed WR into msg. Then it posts the message.
723 *
724 * IN:
725 * q - ptr to user MQ.
726 * wr - ptr to host-copy of the WR.
727 * qp - ptr to user qp
728 * size - Number of bytes to post. Assumed to be divisible by 4.
729 *
730 * OUT: none
731 *
732 * Return:
733 * CCIL status codes.
734 */
735static int qp_wr_post(struct c2_mq *q, union c2wr * wr, struct c2_qp *qp, u32 size)
736{
737 union c2wr *msg;
738
739 msg = c2_mq_alloc(q);
740 if (msg == NULL) {
741 return -EINVAL;
742 }
743#ifdef CCMSGMAGIC
744 ((c2wr_hdr_t *) wr)->magic = cpu_to_be32(CCWR_MAGIC);
745#endif
746
747 /*
748 * Since all header fields in the WR are the same as the
749 * CQE, set the following so the adapter need not.
750 */
751 c2_wr_set_result(wr, CCERR_PENDING);
752
753 /*
754 * Copy the wr down to the adapter
755 */
756 memcpy((void *) msg, (void *) wr, size);
757
758 c2_mq_produce(q);
759 return 0;
760}
761
762
763int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
764 struct ib_send_wr **bad_wr)
765{
766 struct c2_dev *c2dev = to_c2dev(ibqp->device);
767 struct c2_qp *qp = to_c2qp(ibqp);
768 union c2wr wr;
769 int err = 0;
770
771 u32 flags;
772 u32 tot_len;
773 u8 actual_sge_count;
774 u32 msg_size;
775
776 if (qp->state > IB_QPS_RTS)
777 return -EINVAL;
778
779 while (ib_wr) {
780
781 flags = 0;
782 wr.sqwr.sq_hdr.user_hdr.hdr.context = ib_wr->wr_id;
783 if (ib_wr->send_flags & IB_SEND_SIGNALED) {
784 flags |= SQ_SIGNALED;
785 }
786
787 switch (ib_wr->opcode) {
788 case IB_WR_SEND:
789 if (ib_wr->send_flags & IB_SEND_SOLICITED) {
790 c2_wr_set_id(&wr, C2_WR_TYPE_SEND_SE);
791 msg_size = sizeof(struct c2wr_send_req);
792 } else {
793 c2_wr_set_id(&wr, C2_WR_TYPE_SEND);
794 msg_size = sizeof(struct c2wr_send_req);
795 }
796
797 wr.sqwr.send.remote_stag = 0;
798 msg_size += sizeof(struct c2_data_addr) * ib_wr->num_sge;
799 if (ib_wr->num_sge > qp->send_sgl_depth) {
800 err = -EINVAL;
801 break;
802 }
803 if (ib_wr->send_flags & IB_SEND_FENCE) {
804 flags |= SQ_READ_FENCE;
805 }
806 err = move_sgl((struct c2_data_addr *) & (wr.sqwr.send.data),
807 ib_wr->sg_list,
808 ib_wr->num_sge,
809 &tot_len, &actual_sge_count);
810 wr.sqwr.send.sge_len = cpu_to_be32(tot_len);
811 c2_wr_set_sge_count(&wr, actual_sge_count);
812 break;
813 case IB_WR_RDMA_WRITE:
814 c2_wr_set_id(&wr, C2_WR_TYPE_RDMA_WRITE);
815 msg_size = sizeof(struct c2wr_rdma_write_req) +
816 (sizeof(struct c2_data_addr) * ib_wr->num_sge);
817 if (ib_wr->num_sge > qp->rdma_write_sgl_depth) {
818 err = -EINVAL;
819 break;
820 }
821 if (ib_wr->send_flags & IB_SEND_FENCE) {
822 flags |= SQ_READ_FENCE;
823 }
824 wr.sqwr.rdma_write.remote_stag =
825 cpu_to_be32(ib_wr->wr.rdma.rkey);
826 wr.sqwr.rdma_write.remote_to =
827 cpu_to_be64(ib_wr->wr.rdma.remote_addr);
828 err = move_sgl((struct c2_data_addr *)
829 & (wr.sqwr.rdma_write.data),
830 ib_wr->sg_list,
831 ib_wr->num_sge,
832 &tot_len, &actual_sge_count);
833 wr.sqwr.rdma_write.sge_len = cpu_to_be32(tot_len);
834 c2_wr_set_sge_count(&wr, actual_sge_count);
835 break;
836 case IB_WR_RDMA_READ:
837 c2_wr_set_id(&wr, C2_WR_TYPE_RDMA_READ);
838 msg_size = sizeof(struct c2wr_rdma_read_req);
839
840 /* IWarp only suppots 1 sge for RDMA reads */
841 if (ib_wr->num_sge > 1) {
842 err = -EINVAL;
843 break;
844 }
845
846 /*
847 * Move the local and remote stag/to/len into the WR.
848 */
849 wr.sqwr.rdma_read.local_stag =
850 cpu_to_be32(ib_wr->sg_list->lkey);
851 wr.sqwr.rdma_read.local_to =
852 cpu_to_be64(ib_wr->sg_list->addr);
853 wr.sqwr.rdma_read.remote_stag =
854 cpu_to_be32(ib_wr->wr.rdma.rkey);
855 wr.sqwr.rdma_read.remote_to =
856 cpu_to_be64(ib_wr->wr.rdma.remote_addr);
857 wr.sqwr.rdma_read.length =
858 cpu_to_be32(ib_wr->sg_list->length);
859 break;
860 default:
861 /* error */
862 msg_size = 0;
863 err = -EINVAL;
864 break;
865 }
866
867 /*
868 * If we had an error on the last wr build, then
869 * break out. Possible errors include bogus WR
870 * type, and a bogus SGL length...
871 */
872 if (err) {
873 break;
874 }
875
876 /*
877 * Store flags
878 */
879 c2_wr_set_flags(&wr, flags);
880
881 /*
882 * Post the puppy!
883 */
884 err = qp_wr_post(&qp->sq_mq, &wr, qp, msg_size);
885 if (err) {
886 break;
887 }
888
889 /*
890 * Enqueue mq index to activity FIFO.
891 */
892 c2_activity(c2dev, qp->sq_mq.index, qp->sq_mq.hint_count);
893
894 ib_wr = ib_wr->next;
895 }
896
897 if (err)
898 *bad_wr = ib_wr;
899 return err;
900}
901
902int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
903 struct ib_recv_wr **bad_wr)
904{
905 struct c2_dev *c2dev = to_c2dev(ibqp->device);
906 struct c2_qp *qp = to_c2qp(ibqp);
907 union c2wr wr;
908 int err = 0;
909
910 if (qp->state > IB_QPS_RTS)
911 return -EINVAL;
912
913 /*
914 * Try and post each work request
915 */
916 while (ib_wr) {
917 u32 tot_len;
918 u8 actual_sge_count;
919
920 if (ib_wr->num_sge > qp->recv_sgl_depth) {
921 err = -EINVAL;
922 break;
923 }
924
925 /*
926 * Create local host-copy of the WR
927 */
928 wr.rqwr.rq_hdr.user_hdr.hdr.context = ib_wr->wr_id;
929 c2_wr_set_id(&wr, CCWR_RECV);
930 c2_wr_set_flags(&wr, 0);
931
932 /* sge_count is limited to eight bits. */
933 BUG_ON(ib_wr->num_sge >= 256);
934 err = move_sgl((struct c2_data_addr *) & (wr.rqwr.data),
935 ib_wr->sg_list,
936 ib_wr->num_sge, &tot_len, &actual_sge_count);
937 c2_wr_set_sge_count(&wr, actual_sge_count);
938
939 /*
940 * If we had an error on the last wr build, then
941 * break out. Possible errors include bogus WR
942 * type, and a bogus SGL length...
943 */
944 if (err) {
945 break;
946 }
947
948 err = qp_wr_post(&qp->rq_mq, &wr, qp, qp->rq_mq.msg_size);
949 if (err) {
950 break;
951 }
952
953 /*
954 * Enqueue mq index to activity FIFO
955 */
956 c2_activity(c2dev, qp->rq_mq.index, qp->rq_mq.hint_count);
957
958 ib_wr = ib_wr->next;
959 }
960
961 if (err)
962 *bad_wr = ib_wr;
963 return err;
964}
965
966void __devinit c2_init_qp_table(struct c2_dev *c2dev)
967{
968 spin_lock_init(&c2dev->qp_table.lock);
969 idr_init(&c2dev->qp_table.idr);
970}
971
972void __devexit c2_cleanup_qp_table(struct c2_dev *c2dev)
973{
974 idr_destroy(&c2dev->qp_table.idr);
975}
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c
new file mode 100644
index 000000000000..1c3c9d65ecea
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_rnic.c
@@ -0,0 +1,663 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34
35
36#include <linux/module.h>
37#include <linux/moduleparam.h>
38#include <linux/pci.h>
39#include <linux/netdevice.h>
40#include <linux/etherdevice.h>
41#include <linux/delay.h>
42#include <linux/ethtool.h>
43#include <linux/mii.h>
44#include <linux/if_vlan.h>
45#include <linux/crc32.h>
46#include <linux/in.h>
47#include <linux/ip.h>
48#include <linux/tcp.h>
49#include <linux/init.h>
50#include <linux/dma-mapping.h>
51#include <linux/mm.h>
52#include <linux/inet.h>
53
54#include <linux/route.h>
55
56#include <asm/io.h>
57#include <asm/irq.h>
58#include <asm/byteorder.h>
59#include <rdma/ib_smi.h>
60#include "c2.h"
61#include "c2_vq.h"
62
63/* Device capabilities */
64#define C2_MIN_PAGESIZE 1024
65
66#define C2_MAX_MRS 32768
67#define C2_MAX_QPS 16000
68#define C2_MAX_WQE_SZ 256
69#define C2_MAX_QP_WR ((128*1024)/C2_MAX_WQE_SZ)
70#define C2_MAX_SGES 4
71#define C2_MAX_SGE_RD 1
72#define C2_MAX_CQS 32768
73#define C2_MAX_CQES 4096
74#define C2_MAX_PDS 16384
75
76/*
77 * Send the adapter INIT message to the amso1100
78 */
79static int c2_adapter_init(struct c2_dev *c2dev)
80{
81 struct c2wr_init_req wr;
82 int err;
83
84 memset(&wr, 0, sizeof(wr));
85 c2_wr_set_id(&wr, CCWR_INIT);
86 wr.hdr.context = 0;
87 wr.hint_count = cpu_to_be64(c2dev->hint_count_dma);
88 wr.q0_host_shared = cpu_to_be64(c2dev->req_vq.shared_dma);
89 wr.q1_host_shared = cpu_to_be64(c2dev->rep_vq.shared_dma);
90 wr.q1_host_msg_pool = cpu_to_be64(c2dev->rep_vq.host_dma);
91 wr.q2_host_shared = cpu_to_be64(c2dev->aeq.shared_dma);
92 wr.q2_host_msg_pool = cpu_to_be64(c2dev->aeq.host_dma);
93
94 /* Post the init message */
95 err = vq_send_wr(c2dev, (union c2wr *) & wr);
96
97 return err;
98}
99
100/*
101 * Send the adapter TERM message to the amso1100
102 */
103static void c2_adapter_term(struct c2_dev *c2dev)
104{
105 struct c2wr_init_req wr;
106
107 memset(&wr, 0, sizeof(wr));
108 c2_wr_set_id(&wr, CCWR_TERM);
109 wr.hdr.context = 0;
110
111 /* Post the init message */
112 vq_send_wr(c2dev, (union c2wr *) & wr);
113 c2dev->init = 0;
114
115 return;
116}
117
118/*
119 * Query the adapter
120 */
121static int c2_rnic_query(struct c2_dev *c2dev, struct ib_device_attr *props)
122{
123 struct c2_vq_req *vq_req;
124 struct c2wr_rnic_query_req wr;
125 struct c2wr_rnic_query_rep *reply;
126 int err;
127
128 vq_req = vq_req_alloc(c2dev);
129 if (!vq_req)
130 return -ENOMEM;
131
132 c2_wr_set_id(&wr, CCWR_RNIC_QUERY);
133 wr.hdr.context = (unsigned long) vq_req;
134 wr.rnic_handle = c2dev->adapter_handle;
135
136 vq_req_get(c2dev, vq_req);
137
138 err = vq_send_wr(c2dev, (union c2wr *) &wr);
139 if (err) {
140 vq_req_put(c2dev, vq_req);
141 goto bail1;
142 }
143
144 err = vq_wait_for_reply(c2dev, vq_req);
145 if (err)
146 goto bail1;
147
148 reply =
149 (struct c2wr_rnic_query_rep *) (unsigned long) (vq_req->reply_msg);
150 if (!reply)
151 err = -ENOMEM;
152
153 err = c2_errno(reply);
154 if (err)
155 goto bail2;
156
157 props->fw_ver =
158 ((u64)be32_to_cpu(reply->fw_ver_major) << 32) |
159 ((be32_to_cpu(reply->fw_ver_minor) && 0xFFFF) << 16) |
160 (be32_to_cpu(reply->fw_ver_patch) && 0xFFFF);
161 memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6);
162 props->max_mr_size = 0xFFFFFFFF;
163 props->page_size_cap = ~(C2_MIN_PAGESIZE-1);
164 props->vendor_id = be32_to_cpu(reply->vendor_id);
165 props->vendor_part_id = be32_to_cpu(reply->part_number);
166 props->hw_ver = be32_to_cpu(reply->hw_version);
167 props->max_qp = be32_to_cpu(reply->max_qps);
168 props->max_qp_wr = be32_to_cpu(reply->max_qp_depth);
169 props->device_cap_flags = c2dev->device_cap_flags;
170 props->max_sge = C2_MAX_SGES;
171 props->max_sge_rd = C2_MAX_SGE_RD;
172 props->max_cq = be32_to_cpu(reply->max_cqs);
173 props->max_cqe = be32_to_cpu(reply->max_cq_depth);
174 props->max_mr = be32_to_cpu(reply->max_mrs);
175 props->max_pd = be32_to_cpu(reply->max_pds);
176 props->max_qp_rd_atom = be32_to_cpu(reply->max_qp_ird);
177 props->max_ee_rd_atom = 0;
178 props->max_res_rd_atom = be32_to_cpu(reply->max_global_ird);
179 props->max_qp_init_rd_atom = be32_to_cpu(reply->max_qp_ord);
180 props->max_ee_init_rd_atom = 0;
181 props->atomic_cap = IB_ATOMIC_NONE;
182 props->max_ee = 0;
183 props->max_rdd = 0;
184 props->max_mw = be32_to_cpu(reply->max_mws);
185 props->max_raw_ipv6_qp = 0;
186 props->max_raw_ethy_qp = 0;
187 props->max_mcast_grp = 0;
188 props->max_mcast_qp_attach = 0;
189 props->max_total_mcast_qp_attach = 0;
190 props->max_ah = 0;
191 props->max_fmr = 0;
192 props->max_map_per_fmr = 0;
193 props->max_srq = 0;
194 props->max_srq_wr = 0;
195 props->max_srq_sge = 0;
196 props->max_pkeys = 0;
197 props->local_ca_ack_delay = 0;
198
199 bail2:
200 vq_repbuf_free(c2dev, reply);
201
202 bail1:
203 vq_req_free(c2dev, vq_req);
204 return err;
205}
206
207/*
208 * Add an IP address to the RNIC interface
209 */
210int c2_add_addr(struct c2_dev *c2dev, u32 inaddr, u32 inmask)
211{
212 struct c2_vq_req *vq_req;
213 struct c2wr_rnic_setconfig_req *wr;
214 struct c2wr_rnic_setconfig_rep *reply;
215 struct c2_netaddr netaddr;
216 int err, len;
217
218 vq_req = vq_req_alloc(c2dev);
219 if (!vq_req)
220 return -ENOMEM;
221
222 len = sizeof(struct c2_netaddr);
223 wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL);
224 if (!wr) {
225 err = -ENOMEM;
226 goto bail0;
227 }
228
229 c2_wr_set_id(wr, CCWR_RNIC_SETCONFIG);
230 wr->hdr.context = (unsigned long) vq_req;
231 wr->rnic_handle = c2dev->adapter_handle;
232 wr->option = cpu_to_be32(C2_CFG_ADD_ADDR);
233
234 netaddr.ip_addr = inaddr;
235 netaddr.netmask = inmask;
236 netaddr.mtu = 0;
237
238 memcpy(wr->data, &netaddr, len);
239
240 vq_req_get(c2dev, vq_req);
241
242 err = vq_send_wr(c2dev, (union c2wr *) wr);
243 if (err) {
244 vq_req_put(c2dev, vq_req);
245 goto bail1;
246 }
247
248 err = vq_wait_for_reply(c2dev, vq_req);
249 if (err)
250 goto bail1;
251
252 reply =
253 (struct c2wr_rnic_setconfig_rep *) (unsigned long) (vq_req->reply_msg);
254 if (!reply) {
255 err = -ENOMEM;
256 goto bail1;
257 }
258
259 err = c2_errno(reply);
260 vq_repbuf_free(c2dev, reply);
261
262 bail1:
263 kfree(wr);
264 bail0:
265 vq_req_free(c2dev, vq_req);
266 return err;
267}
268
269/*
270 * Delete an IP address from the RNIC interface
271 */
272int c2_del_addr(struct c2_dev *c2dev, u32 inaddr, u32 inmask)
273{
274 struct c2_vq_req *vq_req;
275 struct c2wr_rnic_setconfig_req *wr;
276 struct c2wr_rnic_setconfig_rep *reply;
277 struct c2_netaddr netaddr;
278 int err, len;
279
280 vq_req = vq_req_alloc(c2dev);
281 if (!vq_req)
282 return -ENOMEM;
283
284 len = sizeof(struct c2_netaddr);
285 wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL);
286 if (!wr) {
287 err = -ENOMEM;
288 goto bail0;
289 }
290
291 c2_wr_set_id(wr, CCWR_RNIC_SETCONFIG);
292 wr->hdr.context = (unsigned long) vq_req;
293 wr->rnic_handle = c2dev->adapter_handle;
294 wr->option = cpu_to_be32(C2_CFG_DEL_ADDR);
295
296 netaddr.ip_addr = inaddr;
297 netaddr.netmask = inmask;
298 netaddr.mtu = 0;
299
300 memcpy(wr->data, &netaddr, len);
301
302 vq_req_get(c2dev, vq_req);
303
304 err = vq_send_wr(c2dev, (union c2wr *) wr);
305 if (err) {
306 vq_req_put(c2dev, vq_req);
307 goto bail1;
308 }
309
310 err = vq_wait_for_reply(c2dev, vq_req);
311 if (err)
312 goto bail1;
313
314 reply =
315 (struct c2wr_rnic_setconfig_rep *) (unsigned long) (vq_req->reply_msg);
316 if (!reply) {
317 err = -ENOMEM;
318 goto bail1;
319 }
320
321 err = c2_errno(reply);
322 vq_repbuf_free(c2dev, reply);
323
324 bail1:
325 kfree(wr);
326 bail0:
327 vq_req_free(c2dev, vq_req);
328 return err;
329}
330
331/*
332 * Open a single RNIC instance to use with all
333 * low level openib calls
334 */
335static int c2_rnic_open(struct c2_dev *c2dev)
336{
337 struct c2_vq_req *vq_req;
338 union c2wr wr;
339 struct c2wr_rnic_open_rep *reply;
340 int err;
341
342 vq_req = vq_req_alloc(c2dev);
343 if (vq_req == NULL) {
344 return -ENOMEM;
345 }
346
347 memset(&wr, 0, sizeof(wr));
348 c2_wr_set_id(&wr, CCWR_RNIC_OPEN);
349 wr.rnic_open.req.hdr.context = (unsigned long) (vq_req);
350 wr.rnic_open.req.flags = cpu_to_be16(RNIC_PRIV_MODE);
351 wr.rnic_open.req.port_num = cpu_to_be16(0);
352 wr.rnic_open.req.user_context = (unsigned long) c2dev;
353
354 vq_req_get(c2dev, vq_req);
355
356 err = vq_send_wr(c2dev, &wr);
357 if (err) {
358 vq_req_put(c2dev, vq_req);
359 goto bail0;
360 }
361
362 err = vq_wait_for_reply(c2dev, vq_req);
363 if (err) {
364 goto bail0;
365 }
366
367 reply = (struct c2wr_rnic_open_rep *) (unsigned long) (vq_req->reply_msg);
368 if (!reply) {
369 err = -ENOMEM;
370 goto bail0;
371 }
372
373 if ((err = c2_errno(reply)) != 0) {
374 goto bail1;
375 }
376
377 c2dev->adapter_handle = reply->rnic_handle;
378
379 bail1:
380 vq_repbuf_free(c2dev, reply);
381 bail0:
382 vq_req_free(c2dev, vq_req);
383 return err;
384}
385
386/*
387 * Close the RNIC instance
388 */
389static int c2_rnic_close(struct c2_dev *c2dev)
390{
391 struct c2_vq_req *vq_req;
392 union c2wr wr;
393 struct c2wr_rnic_close_rep *reply;
394 int err;
395
396 vq_req = vq_req_alloc(c2dev);
397 if (vq_req == NULL) {
398 return -ENOMEM;
399 }
400
401 memset(&wr, 0, sizeof(wr));
402 c2_wr_set_id(&wr, CCWR_RNIC_CLOSE);
403 wr.rnic_close.req.hdr.context = (unsigned long) vq_req;
404 wr.rnic_close.req.rnic_handle = c2dev->adapter_handle;
405
406 vq_req_get(c2dev, vq_req);
407
408 err = vq_send_wr(c2dev, &wr);
409 if (err) {
410 vq_req_put(c2dev, vq_req);
411 goto bail0;
412 }
413
414 err = vq_wait_for_reply(c2dev, vq_req);
415 if (err) {
416 goto bail0;
417 }
418
419 reply = (struct c2wr_rnic_close_rep *) (unsigned long) (vq_req->reply_msg);
420 if (!reply) {
421 err = -ENOMEM;
422 goto bail0;
423 }
424
425 if ((err = c2_errno(reply)) != 0) {
426 goto bail1;
427 }
428
429 c2dev->adapter_handle = 0;
430
431 bail1:
432 vq_repbuf_free(c2dev, reply);
433 bail0:
434 vq_req_free(c2dev, vq_req);
435 return err;
436}
437
438/*
439 * Called by c2_probe to initialize the RNIC. This principally
440 * involves initalizing the various limits and resouce pools that
441 * comprise the RNIC instance.
442 */
443int c2_rnic_init(struct c2_dev *c2dev)
444{
445 int err;
446 u32 qsize, msgsize;
447 void *q1_pages;
448 void *q2_pages;
449 void __iomem *mmio_regs;
450
451 /* Device capabilities */
452 c2dev->device_cap_flags =
453 (IB_DEVICE_RESIZE_MAX_WR |
454 IB_DEVICE_CURR_QP_STATE_MOD |
455 IB_DEVICE_SYS_IMAGE_GUID |
456 IB_DEVICE_ZERO_STAG |
457 IB_DEVICE_SEND_W_INV | IB_DEVICE_MEM_WINDOW);
458
459 /* Allocate the qptr_array */
460 c2dev->qptr_array = vmalloc(C2_MAX_CQS * sizeof(void *));
461 if (!c2dev->qptr_array) {
462 return -ENOMEM;
463 }
464
465 /* Inialize the qptr_array */
466 memset(c2dev->qptr_array, 0, C2_MAX_CQS * sizeof(void *));
467 c2dev->qptr_array[0] = (void *) &c2dev->req_vq;
468 c2dev->qptr_array[1] = (void *) &c2dev->rep_vq;
469 c2dev->qptr_array[2] = (void *) &c2dev->aeq;
470
471 /* Initialize data structures */
472 init_waitqueue_head(&c2dev->req_vq_wo);
473 spin_lock_init(&c2dev->vqlock);
474 spin_lock_init(&c2dev->lock);
475
476 /* Allocate MQ shared pointer pool for kernel clients. User
477 * mode client pools are hung off the user context
478 */
479 err = c2_init_mqsp_pool(c2dev, GFP_KERNEL, &c2dev->kern_mqsp_pool);
480 if (err) {
481 goto bail0;
482 }
483
484 /* Allocate shared pointers for Q0, Q1, and Q2 from
485 * the shared pointer pool.
486 */
487
488 c2dev->hint_count = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
489 &c2dev->hint_count_dma,
490 GFP_KERNEL);
491 c2dev->req_vq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
492 &c2dev->req_vq.shared_dma,
493 GFP_KERNEL);
494 c2dev->rep_vq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
495 &c2dev->rep_vq.shared_dma,
496 GFP_KERNEL);
497 c2dev->aeq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
498 &c2dev->aeq.shared_dma, GFP_KERNEL);
499 if (!c2dev->hint_count || !c2dev->req_vq.shared ||
500 !c2dev->rep_vq.shared || !c2dev->aeq.shared) {
501 err = -ENOMEM;
502 goto bail1;
503 }
504
505 mmio_regs = c2dev->kva;
506 /* Initialize the Verbs Request Queue */
507 c2_mq_req_init(&c2dev->req_vq, 0,
508 be32_to_cpu(readl(mmio_regs + C2_REGS_Q0_QSIZE)),
509 be32_to_cpu(readl(mmio_regs + C2_REGS_Q0_MSGSIZE)),
510 mmio_regs +
511 be32_to_cpu(readl(mmio_regs + C2_REGS_Q0_POOLSTART)),
512 mmio_regs +
513 be32_to_cpu(readl(mmio_regs + C2_REGS_Q0_SHARED)),
514 C2_MQ_ADAPTER_TARGET);
515
516 /* Initialize the Verbs Reply Queue */
517 qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_QSIZE));
518 msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_MSGSIZE));
519 q1_pages = kmalloc(qsize * msgsize, GFP_KERNEL);
520 if (!q1_pages) {
521 err = -ENOMEM;
522 goto bail1;
523 }
524 c2dev->rep_vq.host_dma = dma_map_single(c2dev->ibdev.dma_device,
525 (void *)q1_pages, qsize * msgsize,
526 DMA_FROM_DEVICE);
527 pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma);
528 pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages,
529 (u64)c2dev->rep_vq.host_dma);
530 c2_mq_rep_init(&c2dev->rep_vq,
531 1,
532 qsize,
533 msgsize,
534 q1_pages,
535 mmio_regs +
536 be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_SHARED)),
537 C2_MQ_HOST_TARGET);
538
539 /* Initialize the Asynchronus Event Queue */
540 qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_QSIZE));
541 msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_MSGSIZE));
542 q2_pages = kmalloc(qsize * msgsize, GFP_KERNEL);
543 if (!q2_pages) {
544 err = -ENOMEM;
545 goto bail2;
546 }
547 c2dev->aeq.host_dma = dma_map_single(c2dev->ibdev.dma_device,
548 (void *)q2_pages, qsize * msgsize,
549 DMA_FROM_DEVICE);
550 pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma);
551 pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q1_pages,
552 (u64)c2dev->rep_vq.host_dma);
553 c2_mq_rep_init(&c2dev->aeq,
554 2,
555 qsize,
556 msgsize,
557 q2_pages,
558 mmio_regs +
559 be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_SHARED)),
560 C2_MQ_HOST_TARGET);
561
562 /* Initialize the verbs request allocator */
563 err = vq_init(c2dev);
564 if (err)
565 goto bail3;
566
567 /* Enable interrupts on the adapter */
568 writel(0, c2dev->regs + C2_IDIS);
569
570 /* create the WR init message */
571 err = c2_adapter_init(c2dev);
572 if (err)
573 goto bail4;
574 c2dev->init++;
575
576 /* open an adapter instance */
577 err = c2_rnic_open(c2dev);
578 if (err)
579 goto bail4;
580
581 /* Initialize cached the adapter limits */
582 if (c2_rnic_query(c2dev, &c2dev->props))
583 goto bail5;
584
585 /* Initialize the PD pool */
586 err = c2_init_pd_table(c2dev);
587 if (err)
588 goto bail5;
589
590 /* Initialize the QP pool */
591 c2_init_qp_table(c2dev);
592 return 0;
593
594 bail5:
595 c2_rnic_close(c2dev);
596 bail4:
597 vq_term(c2dev);
598 bail3:
599 dma_unmap_single(c2dev->ibdev.dma_device,
600 pci_unmap_addr(&c2dev->aeq, mapping),
601 c2dev->aeq.q_size * c2dev->aeq.msg_size,
602 DMA_FROM_DEVICE);
603 kfree(q2_pages);
604 bail2:
605 dma_unmap_single(c2dev->ibdev.dma_device,
606 pci_unmap_addr(&c2dev->rep_vq, mapping),
607 c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size,
608 DMA_FROM_DEVICE);
609 kfree(q1_pages);
610 bail1:
611 c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool);
612 bail0:
613 vfree(c2dev->qptr_array);
614
615 return err;
616}
617
618/*
619 * Called by c2_remove to cleanup the RNIC resources.
620 */
621void c2_rnic_term(struct c2_dev *c2dev)
622{
623
624 /* Close the open adapter instance */
625 c2_rnic_close(c2dev);
626
627 /* Send the TERM message to the adapter */
628 c2_adapter_term(c2dev);
629
630 /* Disable interrupts on the adapter */
631 writel(1, c2dev->regs + C2_IDIS);
632
633 /* Free the QP pool */
634 c2_cleanup_qp_table(c2dev);
635
636 /* Free the PD pool */
637 c2_cleanup_pd_table(c2dev);
638
639 /* Free the verbs request allocator */
640 vq_term(c2dev);
641
642 /* Unmap and free the asynchronus event queue */
643 dma_unmap_single(c2dev->ibdev.dma_device,
644 pci_unmap_addr(&c2dev->aeq, mapping),
645 c2dev->aeq.q_size * c2dev->aeq.msg_size,
646 DMA_FROM_DEVICE);
647 kfree(c2dev->aeq.msg_pool.host);
648
649 /* Unmap and free the verbs reply queue */
650 dma_unmap_single(c2dev->ibdev.dma_device,
651 pci_unmap_addr(&c2dev->rep_vq, mapping),
652 c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size,
653 DMA_FROM_DEVICE);
654 kfree(c2dev->rep_vq.msg_pool.host);
655
656 /* Free the MQ shared pointer pool */
657 c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool);
658
659 /* Free the qptr_array */
660 vfree(c2dev->qptr_array);
661
662 return;
663}
diff --git a/drivers/infiniband/hw/amso1100/c2_status.h b/drivers/infiniband/hw/amso1100/c2_status.h
new file mode 100644
index 000000000000..6ee4aa92d875
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_status.h
@@ -0,0 +1,158 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#ifndef _C2_STATUS_H_
34#define _C2_STATUS_H_
35
36/*
37 * Verbs Status Codes
38 */
39enum c2_status {
40 C2_OK = 0, /* This must be zero */
41 CCERR_INSUFFICIENT_RESOURCES = 1,
42 CCERR_INVALID_MODIFIER = 2,
43 CCERR_INVALID_MODE = 3,
44 CCERR_IN_USE = 4,
45 CCERR_INVALID_RNIC = 5,
46 CCERR_INTERRUPTED_OPERATION = 6,
47 CCERR_INVALID_EH = 7,
48 CCERR_INVALID_CQ = 8,
49 CCERR_CQ_EMPTY = 9,
50 CCERR_NOT_IMPLEMENTED = 10,
51 CCERR_CQ_DEPTH_TOO_SMALL = 11,
52 CCERR_PD_IN_USE = 12,
53 CCERR_INVALID_PD = 13,
54 CCERR_INVALID_SRQ = 14,
55 CCERR_INVALID_ADDRESS = 15,
56 CCERR_INVALID_NETMASK = 16,
57 CCERR_INVALID_QP = 17,
58 CCERR_INVALID_QP_STATE = 18,
59 CCERR_TOO_MANY_WRS_POSTED = 19,
60 CCERR_INVALID_WR_TYPE = 20,
61 CCERR_INVALID_SGL_LENGTH = 21,
62 CCERR_INVALID_SQ_DEPTH = 22,
63 CCERR_INVALID_RQ_DEPTH = 23,
64 CCERR_INVALID_ORD = 24,
65 CCERR_INVALID_IRD = 25,
66 CCERR_QP_ATTR_CANNOT_CHANGE = 26,
67 CCERR_INVALID_STAG = 27,
68 CCERR_QP_IN_USE = 28,
69 CCERR_OUTSTANDING_WRS = 29,
70 CCERR_STAG_IN_USE = 30,
71 CCERR_INVALID_STAG_INDEX = 31,
72 CCERR_INVALID_SGL_FORMAT = 32,
73 CCERR_ADAPTER_TIMEOUT = 33,
74 CCERR_INVALID_CQ_DEPTH = 34,
75 CCERR_INVALID_PRIVATE_DATA_LENGTH = 35,
76 CCERR_INVALID_EP = 36,
77 CCERR_MR_IN_USE = CCERR_STAG_IN_USE,
78 CCERR_FLUSHED = 38,
79 CCERR_INVALID_WQE = 39,
80 CCERR_LOCAL_QP_CATASTROPHIC_ERROR = 40,
81 CCERR_REMOTE_TERMINATION_ERROR = 41,
82 CCERR_BASE_AND_BOUNDS_VIOLATION = 42,
83 CCERR_ACCESS_VIOLATION = 43,
84 CCERR_INVALID_PD_ID = 44,
85 CCERR_WRAP_ERROR = 45,
86 CCERR_INV_STAG_ACCESS_ERROR = 46,
87 CCERR_ZERO_RDMA_READ_RESOURCES = 47,
88 CCERR_QP_NOT_PRIVILEGED = 48,
89 CCERR_STAG_STATE_NOT_INVALID = 49,
90 CCERR_INVALID_PAGE_SIZE = 50,
91 CCERR_INVALID_BUFFER_SIZE = 51,
92 CCERR_INVALID_PBE = 52,
93 CCERR_INVALID_FBO = 53,
94 CCERR_INVALID_LENGTH = 54,
95 CCERR_INVALID_ACCESS_RIGHTS = 55,
96 CCERR_PBL_TOO_BIG = 56,
97 CCERR_INVALID_VA = 57,
98 CCERR_INVALID_REGION = 58,
99 CCERR_INVALID_WINDOW = 59,
100 CCERR_TOTAL_LENGTH_TOO_BIG = 60,
101 CCERR_INVALID_QP_ID = 61,
102 CCERR_ADDR_IN_USE = 62,
103 CCERR_ADDR_NOT_AVAIL = 63,
104 CCERR_NET_DOWN = 64,
105 CCERR_NET_UNREACHABLE = 65,
106 CCERR_CONN_ABORTED = 66,
107 CCERR_CONN_RESET = 67,
108 CCERR_NO_BUFS = 68,
109 CCERR_CONN_TIMEDOUT = 69,
110 CCERR_CONN_REFUSED = 70,
111 CCERR_HOST_UNREACHABLE = 71,
112 CCERR_INVALID_SEND_SGL_DEPTH = 72,
113 CCERR_INVALID_RECV_SGL_DEPTH = 73,
114 CCERR_INVALID_RDMA_WRITE_SGL_DEPTH = 74,
115 CCERR_INSUFFICIENT_PRIVILEGES = 75,
116 CCERR_STACK_ERROR = 76,
117 CCERR_INVALID_VERSION = 77,
118 CCERR_INVALID_MTU = 78,
119 CCERR_INVALID_IMAGE = 79,
120 CCERR_PENDING = 98, /* not an error; user internally by adapter */
121 CCERR_DEFER = 99, /* not an error; used internally by adapter */
122 CCERR_FAILED_WRITE = 100,
123 CCERR_FAILED_ERASE = 101,
124 CCERR_FAILED_VERIFICATION = 102,
125 CCERR_NOT_FOUND = 103,
126
127};
128
129/*
130 * CCAE_ACTIVE_CONNECT_RESULTS status result codes.
131 */
132enum c2_connect_status {
133 C2_CONN_STATUS_SUCCESS = C2_OK,
134 C2_CONN_STATUS_NO_MEM = CCERR_INSUFFICIENT_RESOURCES,
135 C2_CONN_STATUS_TIMEDOUT = CCERR_CONN_TIMEDOUT,
136 C2_CONN_STATUS_REFUSED = CCERR_CONN_REFUSED,
137 C2_CONN_STATUS_NETUNREACH = CCERR_NET_UNREACHABLE,
138 C2_CONN_STATUS_HOSTUNREACH = CCERR_HOST_UNREACHABLE,
139 C2_CONN_STATUS_INVALID_RNIC = CCERR_INVALID_RNIC,
140 C2_CONN_STATUS_INVALID_QP = CCERR_INVALID_QP,
141 C2_CONN_STATUS_INVALID_QP_STATE = CCERR_INVALID_QP_STATE,
142 C2_CONN_STATUS_REJECTED = CCERR_CONN_RESET,
143 C2_CONN_STATUS_ADDR_NOT_AVAIL = CCERR_ADDR_NOT_AVAIL,
144};
145
146/*
147 * Flash programming status codes.
148 */
149enum c2_flash_status {
150 C2_FLASH_STATUS_SUCCESS = 0x0000,
151 C2_FLASH_STATUS_VERIFY_ERR = 0x0002,
152 C2_FLASH_STATUS_IMAGE_ERR = 0x0004,
153 C2_FLASH_STATUS_ECLBS = 0x0400,
154 C2_FLASH_STATUS_PSLBS = 0x0800,
155 C2_FLASH_STATUS_VPENS = 0x1000,
156};
157
158#endif /* _C2_STATUS_H_ */
diff --git a/drivers/infiniband/hw/amso1100/c2_user.h b/drivers/infiniband/hw/amso1100/c2_user.h
new file mode 100644
index 000000000000..7e9e7ad65467
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_user.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36#ifndef C2_USER_H
37#define C2_USER_H
38
39#include <linux/types.h>
40
41/*
42 * Make sure that all structs defined in this file remain laid out so
43 * that they pack the same way on 32-bit and 64-bit architectures (to
44 * avoid incompatibility between 32-bit userspace and 64-bit kernels).
45 * In particular do not use pointer types -- pass pointers in __u64
46 * instead.
47 */
48
49struct c2_alloc_ucontext_resp {
50 __u32 qp_tab_size;
51 __u32 uarc_size;
52};
53
54struct c2_alloc_pd_resp {
55 __u32 pdn;
56 __u32 reserved;
57};
58
59struct c2_create_cq {
60 __u32 lkey;
61 __u32 pdn;
62 __u64 arm_db_page;
63 __u64 set_db_page;
64 __u32 arm_db_index;
65 __u32 set_db_index;
66};
67
68struct c2_create_cq_resp {
69 __u32 cqn;
70 __u32 reserved;
71};
72
73struct c2_create_qp {
74 __u32 lkey;
75 __u32 reserved;
76 __u64 sq_db_page;
77 __u64 rq_db_page;
78 __u32 sq_db_index;
79 __u32 rq_db_index;
80};
81
82#endif /* C2_USER_H */
diff --git a/drivers/infiniband/hw/amso1100/c2_vq.c b/drivers/infiniband/hw/amso1100/c2_vq.c
new file mode 100644
index 000000000000..40caeb5f41b4
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_vq.c
@@ -0,0 +1,260 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#include <linux/slab.h>
34#include <linux/spinlock.h>
35
36#include "c2_vq.h"
37#include "c2_provider.h"
38
39/*
40 * Verbs Request Objects:
41 *
42 * VQ Request Objects are allocated by the kernel verbs handlers.
43 * They contain a wait object, a refcnt, an atomic bool indicating that the
44 * adapter has replied, and a copy of the verb reply work request.
45 * A pointer to the VQ Request Object is passed down in the context
46 * field of the work request message, and reflected back by the adapter
47 * in the verbs reply message. The function handle_vq() in the interrupt
48 * path will use this pointer to:
49 * 1) append a copy of the verbs reply message
50 * 2) mark that the reply is ready
51 * 3) wake up the kernel verbs handler blocked awaiting the reply.
52 *
53 *
54 * The kernel verbs handlers do a "get" to put a 2nd reference on the
55 * VQ Request object. If the kernel verbs handler exits before the adapter
56 * can respond, this extra reference will keep the VQ Request object around
57 * until the adapter's reply can be processed. The reason we need this is
58 * because a pointer to this object is stuffed into the context field of
59 * the verbs work request message, and reflected back in the reply message.
60 * It is used in the interrupt handler (handle_vq()) to wake up the appropriate
61 * kernel verb handler that is blocked awaiting the verb reply.
62 * So handle_vq() will do a "put" on the object when it's done accessing it.
63 * NOTE: If we guarantee that the kernel verb handler will never bail before
64 * getting the reply, then we don't need these refcnts.
65 *
66 *
67 * VQ Request objects are freed by the kernel verbs handlers only
68 * after the verb has been processed, or when the adapter fails and
69 * does not reply.
70 *
71 *
72 * Verbs Reply Buffers:
73 *
74 * VQ Reply bufs are local host memory copies of a
75 * outstanding Verb Request reply
76 * message. The are always allocated by the kernel verbs handlers, and _may_ be
77 * freed by either the kernel verbs handler -or- the interrupt handler. The
78 * kernel verbs handler _must_ free the repbuf, then free the vq request object
79 * in that order.
80 */
81
82int vq_init(struct c2_dev *c2dev)
83{
84 sprintf(c2dev->vq_cache_name, "c2-vq:dev%c",
85 (char) ('0' + c2dev->devnum));
86 c2dev->host_msg_cache =
87 kmem_cache_create(c2dev->vq_cache_name, c2dev->rep_vq.msg_size, 0,
88 SLAB_HWCACHE_ALIGN, NULL, NULL);
89 if (c2dev->host_msg_cache == NULL) {
90 return -ENOMEM;
91 }
92 return 0;
93}
94
95void vq_term(struct c2_dev *c2dev)
96{
97 kmem_cache_destroy(c2dev->host_msg_cache);
98}
99
100/* vq_req_alloc - allocate a VQ Request Object and initialize it.
101 * The refcnt is set to 1.
102 */
103struct c2_vq_req *vq_req_alloc(struct c2_dev *c2dev)
104{
105 struct c2_vq_req *r;
106
107 r = kmalloc(sizeof(struct c2_vq_req), GFP_KERNEL);
108 if (r) {
109 init_waitqueue_head(&r->wait_object);
110 r->reply_msg = (u64) NULL;
111 r->event = 0;
112 r->cm_id = NULL;
113 r->qp = NULL;
114 atomic_set(&r->refcnt, 1);
115 atomic_set(&r->reply_ready, 0);
116 }
117 return r;
118}
119
120
121/* vq_req_free - free the VQ Request Object. It is assumed the verbs handler
122 * has already free the VQ Reply Buffer if it existed.
123 */
124void vq_req_free(struct c2_dev *c2dev, struct c2_vq_req *r)
125{
126 r->reply_msg = (u64) NULL;
127 if (atomic_dec_and_test(&r->refcnt)) {
128 kfree(r);
129 }
130}
131
132/* vq_req_get - reference a VQ Request Object. Done
133 * only in the kernel verbs handlers.
134 */
135void vq_req_get(struct c2_dev *c2dev, struct c2_vq_req *r)
136{
137 atomic_inc(&r->refcnt);
138}
139
140
141/* vq_req_put - dereference and potentially free a VQ Request Object.
142 *
143 * This is only called by handle_vq() on the
144 * interrupt when it is done processing
145 * a verb reply message. If the associated
146 * kernel verbs handler has already bailed,
147 * then this put will actually free the VQ
148 * Request object _and_ the VQ Reply Buffer
149 * if it exists.
150 */
151void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *r)
152{
153 if (atomic_dec_and_test(&r->refcnt)) {
154 if (r->reply_msg != (u64) NULL)
155 vq_repbuf_free(c2dev,
156 (void *) (unsigned long) r->reply_msg);
157 kfree(r);
158 }
159}
160
161
162/*
163 * vq_repbuf_alloc - allocate a VQ Reply Buffer.
164 */
165void *vq_repbuf_alloc(struct c2_dev *c2dev)
166{
167 return kmem_cache_alloc(c2dev->host_msg_cache, SLAB_ATOMIC);
168}
169
170/*
171 * vq_send_wr - post a verbs request message to the Verbs Request Queue.
172 * If a message is not available in the MQ, then block until one is available.
173 * NOTE: handle_mq() on the interrupt context will wake up threads blocked here.
174 * When the adapter drains the Verbs Request Queue,
175 * it inserts MQ index 0 in to the
176 * adapter->host activity fifo and interrupts the host.
177 */
178int vq_send_wr(struct c2_dev *c2dev, union c2wr *wr)
179{
180 void *msg;
181 wait_queue_t __wait;
182
183 /*
184 * grab adapter vq lock
185 */
186 spin_lock(&c2dev->vqlock);
187
188 /*
189 * allocate msg
190 */
191 msg = c2_mq_alloc(&c2dev->req_vq);
192
193 /*
194 * If we cannot get a msg, then we'll wait
195 * When a messages are available, the int handler will wake_up()
196 * any waiters.
197 */
198 while (msg == NULL) {
199 pr_debug("%s:%d no available msg in VQ, waiting...\n",
200 __FUNCTION__, __LINE__);
201 init_waitqueue_entry(&__wait, current);
202 add_wait_queue(&c2dev->req_vq_wo, &__wait);
203 spin_unlock(&c2dev->vqlock);
204 for (;;) {
205 set_current_state(TASK_INTERRUPTIBLE);
206 if (!c2_mq_full(&c2dev->req_vq)) {
207 break;
208 }
209 if (!signal_pending(current)) {
210 schedule_timeout(1 * HZ); /* 1 second... */
211 continue;
212 }
213 set_current_state(TASK_RUNNING);
214 remove_wait_queue(&c2dev->req_vq_wo, &__wait);
215 return -EINTR;
216 }
217 set_current_state(TASK_RUNNING);
218 remove_wait_queue(&c2dev->req_vq_wo, &__wait);
219 spin_lock(&c2dev->vqlock);
220 msg = c2_mq_alloc(&c2dev->req_vq);
221 }
222
223 /*
224 * copy wr into adapter msg
225 */
226 memcpy(msg, wr, c2dev->req_vq.msg_size);
227
228 /*
229 * post msg
230 */
231 c2_mq_produce(&c2dev->req_vq);
232
233 /*
234 * release adapter vq lock
235 */
236 spin_unlock(&c2dev->vqlock);
237 return 0;
238}
239
240
241/*
242 * vq_wait_for_reply - block until the adapter posts a Verb Reply Message.
243 */
244int vq_wait_for_reply(struct c2_dev *c2dev, struct c2_vq_req *req)
245{
246 if (!wait_event_timeout(req->wait_object,
247 atomic_read(&req->reply_ready),
248 60*HZ))
249 return -ETIMEDOUT;
250
251 return 0;
252}
253
254/*
255 * vq_repbuf_free - Free a Verbs Reply Buffer.
256 */
257void vq_repbuf_free(struct c2_dev *c2dev, void *reply)
258{
259 kmem_cache_free(c2dev->host_msg_cache, reply);
260}
diff --git a/drivers/infiniband/hw/amso1100/c2_vq.h b/drivers/infiniband/hw/amso1100/c2_vq.h
new file mode 100644
index 000000000000..33805627a607
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_vq.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#ifndef _C2_VQ_H_
34#define _C2_VQ_H_
35#include <linux/sched.h>
36#include "c2.h"
37#include "c2_wr.h"
38#include "c2_provider.h"
39
40struct c2_vq_req {
41 u64 reply_msg; /* ptr to reply msg */
42 wait_queue_head_t wait_object; /* wait object for vq reqs */
43 atomic_t reply_ready; /* set when reply is ready */
44 atomic_t refcnt; /* used to cancel WRs... */
45 int event;
46 struct iw_cm_id *cm_id;
47 struct c2_qp *qp;
48};
49
50extern int vq_init(struct c2_dev *c2dev);
51extern void vq_term(struct c2_dev *c2dev);
52
53extern struct c2_vq_req *vq_req_alloc(struct c2_dev *c2dev);
54extern void vq_req_free(struct c2_dev *c2dev, struct c2_vq_req *req);
55extern void vq_req_get(struct c2_dev *c2dev, struct c2_vq_req *req);
56extern void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *req);
57extern int vq_send_wr(struct c2_dev *c2dev, union c2wr * wr);
58
59extern void *vq_repbuf_alloc(struct c2_dev *c2dev);
60extern void vq_repbuf_free(struct c2_dev *c2dev, void *reply);
61
62extern int vq_wait_for_reply(struct c2_dev *c2dev, struct c2_vq_req *req);
63#endif /* _C2_VQ_H_ */
diff --git a/drivers/infiniband/hw/amso1100/c2_wr.h b/drivers/infiniband/hw/amso1100/c2_wr.h
new file mode 100644
index 000000000000..3ec6c43bb0ef
--- /dev/null
+++ b/drivers/infiniband/hw/amso1100/c2_wr.h
@@ -0,0 +1,1520 @@
1/*
2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#ifndef _C2_WR_H_
34#define _C2_WR_H_
35
36#ifdef CCDEBUG
37#define CCWR_MAGIC 0xb07700b0
38#endif
39
40#define C2_QP_NO_ATTR_CHANGE 0xFFFFFFFF
41
42/* Maximum allowed size in bytes of private_data exchange
43 * on connect.
44 */
45#define C2_MAX_PRIVATE_DATA_SIZE 200
46
47/*
48 * These types are shared among the adapter, host, and CCIL consumer.
49 */
50enum c2_cq_notification_type {
51 C2_CQ_NOTIFICATION_TYPE_NONE = 1,
52 C2_CQ_NOTIFICATION_TYPE_NEXT,
53 C2_CQ_NOTIFICATION_TYPE_NEXT_SE
54};
55
56enum c2_setconfig_cmd {
57 C2_CFG_ADD_ADDR = 1,
58 C2_CFG_DEL_ADDR = 2,
59 C2_CFG_ADD_ROUTE = 3,
60 C2_CFG_DEL_ROUTE = 4
61};
62
63enum c2_getconfig_cmd {
64 C2_GETCONFIG_ROUTES = 1,
65 C2_GETCONFIG_ADDRS
66};
67
68/*
69 * CCIL Work Request Identifiers
70 */
71enum c2wr_ids {
72 CCWR_RNIC_OPEN = 1,
73 CCWR_RNIC_QUERY,
74 CCWR_RNIC_SETCONFIG,
75 CCWR_RNIC_GETCONFIG,
76 CCWR_RNIC_CLOSE,
77 CCWR_CQ_CREATE,
78 CCWR_CQ_QUERY,
79 CCWR_CQ_MODIFY,
80 CCWR_CQ_DESTROY,
81 CCWR_QP_CONNECT,
82 CCWR_PD_ALLOC,
83 CCWR_PD_DEALLOC,
84 CCWR_SRQ_CREATE,
85 CCWR_SRQ_QUERY,
86 CCWR_SRQ_MODIFY,
87 CCWR_SRQ_DESTROY,
88 CCWR_QP_CREATE,
89 CCWR_QP_QUERY,
90 CCWR_QP_MODIFY,
91 CCWR_QP_DESTROY,
92 CCWR_NSMR_STAG_ALLOC,
93 CCWR_NSMR_REGISTER,
94 CCWR_NSMR_PBL,
95 CCWR_STAG_DEALLOC,
96 CCWR_NSMR_REREGISTER,
97 CCWR_SMR_REGISTER,
98 CCWR_MR_QUERY,
99 CCWR_MW_ALLOC,
100 CCWR_MW_QUERY,
101 CCWR_EP_CREATE,
102 CCWR_EP_GETOPT,
103 CCWR_EP_SETOPT,
104 CCWR_EP_DESTROY,
105 CCWR_EP_BIND,
106 CCWR_EP_CONNECT,
107 CCWR_EP_LISTEN,
108 CCWR_EP_SHUTDOWN,
109 CCWR_EP_LISTEN_CREATE,
110 CCWR_EP_LISTEN_DESTROY,
111 CCWR_EP_QUERY,
112 CCWR_CR_ACCEPT,
113 CCWR_CR_REJECT,
114 CCWR_CONSOLE,
115 CCWR_TERM,
116 CCWR_FLASH_INIT,
117 CCWR_FLASH,
118 CCWR_BUF_ALLOC,
119 CCWR_BUF_FREE,
120 CCWR_FLASH_WRITE,
121 CCWR_INIT, /* WARNING: Don't move this ever again! */
122
123
124
125 /* Add new IDs here */
126
127
128
129 /*
130 * WARNING: CCWR_LAST must always be the last verbs id defined!
131 * All the preceding IDs are fixed, and must not change.
132 * You can add new IDs, but must not remove or reorder
133 * any IDs. If you do, YOU will ruin any hope of
134 * compatability between versions.
135 */
136 CCWR_LAST,
137
138 /*
139 * Start over at 1 so that arrays indexed by user wr id's
140 * begin at 1. This is OK since the verbs and user wr id's
141 * are always used on disjoint sets of queues.
142 */
143 /*
144 * The order of the CCWR_SEND_XX verbs must
145 * match the order of the RDMA_OPs
146 */
147 CCWR_SEND = 1,
148 CCWR_SEND_INV,
149 CCWR_SEND_SE,
150 CCWR_SEND_SE_INV,
151 CCWR_RDMA_WRITE,
152 CCWR_RDMA_READ,
153 CCWR_RDMA_READ_INV,
154 CCWR_MW_BIND,
155 CCWR_NSMR_FASTREG,
156 CCWR_STAG_INVALIDATE,
157 CCWR_RECV,
158 CCWR_NOP,
159 CCWR_UNIMPL,
160/* WARNING: This must always be the last user wr id defined! */
161};
162#define RDMA_SEND_OPCODE_FROM_WR_ID(x) (x+2)
163
164/*
165 * SQ/RQ Work Request Types
166 */
167enum c2_wr_type {
168 C2_WR_TYPE_SEND = CCWR_SEND,
169 C2_WR_TYPE_SEND_SE = CCWR_SEND_SE,
170 C2_WR_TYPE_SEND_INV = CCWR_SEND_INV,
171 C2_WR_TYPE_SEND_SE_INV = CCWR_SEND_SE_INV,
172 C2_WR_TYPE_RDMA_WRITE = CCWR_RDMA_WRITE,
173 C2_WR_TYPE_RDMA_READ = CCWR_RDMA_READ,
174 C2_WR_TYPE_RDMA_READ_INV_STAG = CCWR_RDMA_READ_INV,
175 C2_WR_TYPE_BIND_MW = CCWR_MW_BIND,
176 C2_WR_TYPE_FASTREG_NSMR = CCWR_NSMR_FASTREG,
177 C2_WR_TYPE_INV_STAG = CCWR_STAG_INVALIDATE,
178 C2_WR_TYPE_RECV = CCWR_RECV,
179 C2_WR_TYPE_NOP = CCWR_NOP,
180};
181
182struct c2_netaddr {
183 u32 ip_addr;
184 u32 netmask;
185 u32 mtu;
186};
187
188struct c2_route {
189 u32 ip_addr; /* 0 indicates the default route */
190 u32 netmask; /* netmask associated with dst */
191 u32 flags;
192 union {
193 u32 ipaddr; /* address of the nexthop interface */
194 u8 enaddr[6];
195 } nexthop;
196};
197
198/*
199 * A Scatter Gather Entry.
200 */
201struct c2_data_addr {
202 u32 stag;
203 u32 length;
204 u64 to;
205};
206
207/*
208 * MR and MW flags used by the consumer, RI, and RNIC.
209 */
210enum c2_mm_flags {
211 MEM_REMOTE = 0x0001, /* allow mw binds with remote access. */
212 MEM_VA_BASED = 0x0002, /* Not Zero-based */
213 MEM_PBL_COMPLETE = 0x0004, /* PBL array is complete in this msg */
214 MEM_LOCAL_READ = 0x0008, /* allow local reads */
215 MEM_LOCAL_WRITE = 0x0010, /* allow local writes */
216 MEM_REMOTE_READ = 0x0020, /* allow remote reads */
217 MEM_REMOTE_WRITE = 0x0040, /* allow remote writes */
218 MEM_WINDOW_BIND = 0x0080, /* binds allowed */
219 MEM_SHARED = 0x0100, /* set if MR is shared */
220 MEM_STAG_VALID = 0x0200 /* set if STAG is in valid state */
221};
222
223/*
224 * CCIL API ACF flags defined in terms of the low level mem flags.
225 * This minimizes translation needed in the user API
226 */
227enum c2_acf {
228 C2_ACF_LOCAL_READ = MEM_LOCAL_READ,
229 C2_ACF_LOCAL_WRITE = MEM_LOCAL_WRITE,
230 C2_ACF_REMOTE_READ = MEM_REMOTE_READ,
231 C2_ACF_REMOTE_WRITE = MEM_REMOTE_WRITE,
232 C2_ACF_WINDOW_BIND = MEM_WINDOW_BIND
233};
234
235/*
236 * Image types of objects written to flash
237 */
238#define C2_FLASH_IMG_BITFILE 1
239#define C2_FLASH_IMG_OPTION_ROM 2
240#define C2_FLASH_IMG_VPD 3
241
242/*
243 * to fix bug 1815 we define the max size allowable of the
244 * terminate message (per the IETF spec).Refer to the IETF
245 * protocal specification, section 12.1.6, page 64)
246 * The message is prefixed by 20 types of DDP info.
247 *
248 * Then the message has 6 bytes for the terminate control
249 * and DDP segment length info plus a DDP header (either
250 * 14 or 18 byts) plus 28 bytes for the RDMA header.
251 * Thus the max size in:
252 * 20 + (6 + 18 + 28) = 72
253 */
254#define C2_MAX_TERMINATE_MESSAGE_SIZE (72)
255
256/*
257 * Build String Length. It must be the same as C2_BUILD_STR_LEN in ccil_api.h
258 */
259#define WR_BUILD_STR_LEN 64
260
261/*
262 * WARNING: All of these structs need to align any 64bit types on
263 * 64 bit boundaries! 64bit types include u64 and u64.
264 */
265
266/*
267 * Clustercore Work Request Header. Be sensitive to field layout
268 * and alignment.
269 */
270struct c2wr_hdr {
271 /* wqe_count is part of the cqe. It is put here so the
272 * adapter can write to it while the wr is pending without
273 * clobbering part of the wr. This word need not be dma'd
274 * from the host to adapter by libccil, but we copy it anyway
275 * to make the memcpy to the adapter better aligned.
276 */
277 u32 wqe_count;
278
279 /* Put these fields next so that later 32- and 64-bit
280 * quantities are naturally aligned.
281 */
282 u8 id;
283 u8 result; /* adapter -> host */
284 u8 sge_count; /* host -> adapter */
285 u8 flags; /* host -> adapter */
286
287 u64 context;
288#ifdef CCMSGMAGIC
289 u32 magic;
290 u32 pad;
291#endif
292} __attribute__((packed));
293
294/*
295 *------------------------ RNIC ------------------------
296 */
297
298/*
299 * WR_RNIC_OPEN
300 */
301
302/*
303 * Flags for the RNIC WRs
304 */
305enum c2_rnic_flags {
306 RNIC_IRD_STATIC = 0x0001,
307 RNIC_ORD_STATIC = 0x0002,
308 RNIC_QP_STATIC = 0x0004,
309 RNIC_SRQ_SUPPORTED = 0x0008,
310 RNIC_PBL_BLOCK_MODE = 0x0010,
311 RNIC_SRQ_MODEL_ARRIVAL = 0x0020,
312 RNIC_CQ_OVF_DETECTED = 0x0040,
313 RNIC_PRIV_MODE = 0x0080
314};
315
316struct c2wr_rnic_open_req {
317 struct c2wr_hdr hdr;
318 u64 user_context;
319 u16 flags; /* See enum c2_rnic_flags */
320 u16 port_num;
321} __attribute__((packed));
322
323struct c2wr_rnic_open_rep {
324 struct c2wr_hdr hdr;
325 u32 rnic_handle;
326} __attribute__((packed));
327
328union c2wr_rnic_open {
329 struct c2wr_rnic_open_req req;
330 struct c2wr_rnic_open_rep rep;
331} __attribute__((packed));
332
333struct c2wr_rnic_query_req {
334 struct c2wr_hdr hdr;
335 u32 rnic_handle;
336} __attribute__((packed));
337
338/*
339 * WR_RNIC_QUERY
340 */
341struct c2wr_rnic_query_rep {
342 struct c2wr_hdr hdr;
343 u64 user_context;
344 u32 vendor_id;
345 u32 part_number;
346 u32 hw_version;
347 u32 fw_ver_major;
348 u32 fw_ver_minor;
349 u32 fw_ver_patch;
350 char fw_ver_build_str[WR_BUILD_STR_LEN];
351 u32 max_qps;
352 u32 max_qp_depth;
353 u32 max_srq_depth;
354 u32 max_send_sgl_depth;
355 u32 max_rdma_sgl_depth;
356 u32 max_cqs;
357 u32 max_cq_depth;
358 u32 max_cq_event_handlers;
359 u32 max_mrs;
360 u32 max_pbl_depth;
361 u32 max_pds;
362 u32 max_global_ird;
363 u32 max_global_ord;
364 u32 max_qp_ird;
365 u32 max_qp_ord;
366 u32 flags;
367 u32 max_mws;
368 u32 pbe_range_low;
369 u32 pbe_range_high;
370 u32 max_srqs;
371 u32 page_size;
372} __attribute__((packed));
373
374union c2wr_rnic_query {
375 struct c2wr_rnic_query_req req;
376 struct c2wr_rnic_query_rep rep;
377} __attribute__((packed));
378
379/*
380 * WR_RNIC_GETCONFIG
381 */
382
383struct c2wr_rnic_getconfig_req {
384 struct c2wr_hdr hdr;
385 u32 rnic_handle;
386 u32 option; /* see c2_getconfig_cmd_t */
387 u64 reply_buf;
388 u32 reply_buf_len;
389} __attribute__((packed)) ;
390
391struct c2wr_rnic_getconfig_rep {
392 struct c2wr_hdr hdr;
393 u32 option; /* see c2_getconfig_cmd_t */
394 u32 count_len; /* length of the number of addresses configured */
395} __attribute__((packed)) ;
396
397union c2wr_rnic_getconfig {
398 struct c2wr_rnic_getconfig_req req;
399 struct c2wr_rnic_getconfig_rep rep;
400} __attribute__((packed)) ;
401
402/*
403 * WR_RNIC_SETCONFIG
404 */
405struct c2wr_rnic_setconfig_req {
406 struct c2wr_hdr hdr;
407 u32 rnic_handle;
408 u32 option; /* See c2_setconfig_cmd_t */
409 /* variable data and pad. See c2_netaddr and c2_route */
410 u8 data[0];
411} __attribute__((packed)) ;
412
413struct c2wr_rnic_setconfig_rep {
414 struct c2wr_hdr hdr;
415} __attribute__((packed)) ;
416
417union c2wr_rnic_setconfig {
418 struct c2wr_rnic_setconfig_req req;
419 struct c2wr_rnic_setconfig_rep rep;
420} __attribute__((packed)) ;
421
422/*
423 * WR_RNIC_CLOSE
424 */
425struct c2wr_rnic_close_req {
426 struct c2wr_hdr hdr;
427 u32 rnic_handle;
428} __attribute__((packed)) ;
429
430struct c2wr_rnic_close_rep {
431 struct c2wr_hdr hdr;
432} __attribute__((packed)) ;
433
434union c2wr_rnic_close {
435 struct c2wr_rnic_close_req req;
436 struct c2wr_rnic_close_rep rep;
437} __attribute__((packed)) ;
438
439/*
440 *------------------------ CQ ------------------------
441 */
442struct c2wr_cq_create_req {
443 struct c2wr_hdr hdr;
444 u64 shared_ht;
445 u64 user_context;
446 u64 msg_pool;
447 u32 rnic_handle;
448 u32 msg_size;
449 u32 depth;
450} __attribute__((packed)) ;
451
452struct c2wr_cq_create_rep {
453 struct c2wr_hdr hdr;
454 u32 mq_index;
455 u32 adapter_shared;
456 u32 cq_handle;
457} __attribute__((packed)) ;
458
459union c2wr_cq_create {
460 struct c2wr_cq_create_req req;
461 struct c2wr_cq_create_rep rep;
462} __attribute__((packed)) ;
463
464struct c2wr_cq_modify_req {
465 struct c2wr_hdr hdr;
466 u32 rnic_handle;
467 u32 cq_handle;
468 u32 new_depth;
469 u64 new_msg_pool;
470} __attribute__((packed)) ;
471
472struct c2wr_cq_modify_rep {
473 struct c2wr_hdr hdr;
474} __attribute__((packed)) ;
475
476union c2wr_cq_modify {
477 struct c2wr_cq_modify_req req;
478 struct c2wr_cq_modify_rep rep;
479} __attribute__((packed)) ;
480
481struct c2wr_cq_destroy_req {
482 struct c2wr_hdr hdr;
483 u32 rnic_handle;
484 u32 cq_handle;
485} __attribute__((packed)) ;
486
487struct c2wr_cq_destroy_rep {
488 struct c2wr_hdr hdr;
489} __attribute__((packed)) ;
490
491union c2wr_cq_destroy {
492 struct c2wr_cq_destroy_req req;
493 struct c2wr_cq_destroy_rep rep;
494} __attribute__((packed)) ;
495
496/*
497 *------------------------ PD ------------------------
498 */
499struct c2wr_pd_alloc_req {
500 struct c2wr_hdr hdr;
501 u32 rnic_handle;
502 u32 pd_id;
503} __attribute__((packed)) ;
504
505struct c2wr_pd_alloc_rep {
506 struct c2wr_hdr hdr;
507} __attribute__((packed)) ;
508
509union c2wr_pd_alloc {
510 struct c2wr_pd_alloc_req req;
511 struct c2wr_pd_alloc_rep rep;
512} __attribute__((packed)) ;
513
514struct c2wr_pd_dealloc_req {
515 struct c2wr_hdr hdr;
516 u32 rnic_handle;
517 u32 pd_id;
518} __attribute__((packed)) ;
519
520struct c2wr_pd_dealloc_rep {
521 struct c2wr_hdr hdr;
522} __attribute__((packed)) ;
523
524union c2wr_pd_dealloc {
525 struct c2wr_pd_dealloc_req req;
526 struct c2wr_pd_dealloc_rep rep;
527} __attribute__((packed)) ;
528
529/*
530 *------------------------ SRQ ------------------------
531 */
532struct c2wr_srq_create_req {
533 struct c2wr_hdr hdr;
534 u64 shared_ht;
535 u64 user_context;
536 u32 rnic_handle;
537 u32 srq_depth;
538 u32 srq_limit;
539 u32 sgl_depth;
540 u32 pd_id;
541} __attribute__((packed)) ;
542
543struct c2wr_srq_create_rep {
544 struct c2wr_hdr hdr;
545 u32 srq_depth;
546 u32 sgl_depth;
547 u32 msg_size;
548 u32 mq_index;
549 u32 mq_start;
550 u32 srq_handle;
551} __attribute__((packed)) ;
552
553union c2wr_srq_create {
554 struct c2wr_srq_create_req req;
555 struct c2wr_srq_create_rep rep;
556} __attribute__((packed)) ;
557
558struct c2wr_srq_destroy_req {
559 struct c2wr_hdr hdr;
560 u32 rnic_handle;
561 u32 srq_handle;
562} __attribute__((packed)) ;
563
564struct c2wr_srq_destroy_rep {
565 struct c2wr_hdr hdr;
566} __attribute__((packed)) ;
567
568union c2wr_srq_destroy {
569 struct c2wr_srq_destroy_req req;
570 struct c2wr_srq_destroy_rep rep;
571} __attribute__((packed)) ;
572
573/*
574 *------------------------ QP ------------------------
575 */
576enum c2wr_qp_flags {
577 QP_RDMA_READ = 0x00000001, /* RDMA read enabled? */
578 QP_RDMA_WRITE = 0x00000002, /* RDMA write enabled? */
579 QP_MW_BIND = 0x00000004, /* MWs enabled */
580 QP_ZERO_STAG = 0x00000008, /* enabled? */
581 QP_REMOTE_TERMINATION = 0x00000010, /* remote end terminated */
582 QP_RDMA_READ_RESPONSE = 0x00000020 /* Remote RDMA read */
583 /* enabled? */
584};
585
586struct c2wr_qp_create_req {
587 struct c2wr_hdr hdr;
588 u64 shared_sq_ht;
589 u64 shared_rq_ht;
590 u64 user_context;
591 u32 rnic_handle;
592 u32 sq_cq_handle;
593 u32 rq_cq_handle;
594 u32 sq_depth;
595 u32 rq_depth;
596 u32 srq_handle;
597 u32 srq_limit;
598 u32 flags; /* see enum c2wr_qp_flags */
599 u32 send_sgl_depth;
600 u32 recv_sgl_depth;
601 u32 rdma_write_sgl_depth;
602 u32 ord;
603 u32 ird;
604 u32 pd_id;
605} __attribute__((packed)) ;
606
607struct c2wr_qp_create_rep {
608 struct c2wr_hdr hdr;
609 u32 sq_depth;
610 u32 rq_depth;
611 u32 send_sgl_depth;
612 u32 recv_sgl_depth;
613 u32 rdma_write_sgl_depth;
614 u32 ord;
615 u32 ird;
616 u32 sq_msg_size;
617 u32 sq_mq_index;
618 u32 sq_mq_start;
619 u32 rq_msg_size;
620 u32 rq_mq_index;
621 u32 rq_mq_start;
622 u32 qp_handle;
623} __attribute__((packed)) ;
624
625union c2wr_qp_create {
626 struct c2wr_qp_create_req req;
627 struct c2wr_qp_create_rep rep;
628} __attribute__((packed)) ;
629
630struct c2wr_qp_query_req {
631 struct c2wr_hdr hdr;
632 u32 rnic_handle;
633 u32 qp_handle;
634} __attribute__((packed)) ;
635
636struct c2wr_qp_query_rep {
637 struct c2wr_hdr hdr;
638 u64 user_context;
639 u32 rnic_handle;
640 u32 sq_depth;
641 u32 rq_depth;
642 u32 send_sgl_depth;
643 u32 rdma_write_sgl_depth;
644 u32 recv_sgl_depth;
645 u32 ord;
646 u32 ird;
647 u16 qp_state;
648 u16 flags; /* see c2wr_qp_flags_t */
649 u32 qp_id;
650 u32 local_addr;
651 u32 remote_addr;
652 u16 local_port;
653 u16 remote_port;
654 u32 terminate_msg_length; /* 0 if not present */
655 u8 data[0];
656 /* Terminate Message in-line here. */
657} __attribute__((packed)) ;
658
659union c2wr_qp_query {
660 struct c2wr_qp_query_req req;
661 struct c2wr_qp_query_rep rep;
662} __attribute__((packed)) ;
663
664struct c2wr_qp_modify_req {
665 struct c2wr_hdr hdr;
666 u64 stream_msg;
667 u32 stream_msg_length;
668 u32 rnic_handle;
669 u32 qp_handle;
670 u32 next_qp_state;
671 u32 ord;
672 u32 ird;
673 u32 sq_depth;
674 u32 rq_depth;
675 u32 llp_ep_handle;
676} __attribute__((packed)) ;
677
678struct c2wr_qp_modify_rep {
679 struct c2wr_hdr hdr;
680 u32 ord;
681 u32 ird;
682 u32 sq_depth;
683 u32 rq_depth;
684 u32 sq_msg_size;
685 u32 sq_mq_index;
686 u32 sq_mq_start;
687 u32 rq_msg_size;
688 u32 rq_mq_index;
689 u32 rq_mq_start;
690} __attribute__((packed)) ;
691
692union c2wr_qp_modify {
693 struct c2wr_qp_modify_req req;
694 struct c2wr_qp_modify_rep rep;
695} __attribute__((packed)) ;
696
697struct c2wr_qp_destroy_req {
698 struct c2wr_hdr hdr;
699 u32 rnic_handle;
700 u32 qp_handle;
701} __attribute__((packed)) ;
702
703struct c2wr_qp_destroy_rep {
704 struct c2wr_hdr hdr;
705} __attribute__((packed)) ;
706
707union c2wr_qp_destroy {
708 struct c2wr_qp_destroy_req req;
709 struct c2wr_qp_destroy_rep rep;
710} __attribute__((packed)) ;
711
712/*
713 * The CCWR_QP_CONNECT msg is posted on the verbs request queue. It can
714 * only be posted when a QP is in IDLE state. After the connect request is
715 * submitted to the LLP, the adapter moves the QP to CONNECT_PENDING state.
716 * No synchronous reply from adapter to this WR. The results of
717 * connection are passed back in an async event CCAE_ACTIVE_CONNECT_RESULTS
718 * See c2wr_ae_active_connect_results_t
719 */
720struct c2wr_qp_connect_req {
721 struct c2wr_hdr hdr;
722 u32 rnic_handle;
723 u32 qp_handle;
724 u32 remote_addr;
725 u16 remote_port;
726 u16 pad;
727 u32 private_data_length;
728 u8 private_data[0]; /* Private data in-line. */
729} __attribute__((packed)) ;
730
731struct c2wr_qp_connect {
732 struct c2wr_qp_connect_req req;
733 /* no synchronous reply. */
734} __attribute__((packed)) ;
735
736
737/*
738 *------------------------ MM ------------------------
739 */
740
741struct c2wr_nsmr_stag_alloc_req {
742 struct c2wr_hdr hdr;
743 u32 rnic_handle;
744 u32 pbl_depth;
745 u32 pd_id;
746 u32 flags;
747} __attribute__((packed)) ;
748
749struct c2wr_nsmr_stag_alloc_rep {
750 struct c2wr_hdr hdr;
751 u32 pbl_depth;
752 u32 stag_index;
753} __attribute__((packed)) ;
754
755union c2wr_nsmr_stag_alloc {
756 struct c2wr_nsmr_stag_alloc_req req;
757 struct c2wr_nsmr_stag_alloc_rep rep;
758} __attribute__((packed)) ;
759
760struct c2wr_nsmr_register_req {
761 struct c2wr_hdr hdr;
762 u64 va;
763 u32 rnic_handle;
764 u16 flags;
765 u8 stag_key;
766 u8 pad;
767 u32 pd_id;
768 u32 pbl_depth;
769 u32 pbe_size;
770 u32 fbo;
771 u32 length;
772 u32 addrs_length;
773 /* array of paddrs (must be aligned on a 64bit boundary) */
774 u64 paddrs[0];
775} __attribute__((packed)) ;
776
777struct c2wr_nsmr_register_rep {
778 struct c2wr_hdr hdr;
779 u32 pbl_depth;
780 u32 stag_index;
781} __attribute__((packed)) ;
782
783union c2wr_nsmr_register {
784 struct c2wr_nsmr_register_req req;
785 struct c2wr_nsmr_register_rep rep;
786} __attribute__((packed)) ;
787
788struct c2wr_nsmr_pbl_req {
789 struct c2wr_hdr hdr;
790 u32 rnic_handle;
791 u32 flags;
792 u32 stag_index;
793 u32 addrs_length;
794 /* array of paddrs (must be aligned on a 64bit boundary) */
795 u64 paddrs[0];
796} __attribute__((packed)) ;
797
798struct c2wr_nsmr_pbl_rep {
799 struct c2wr_hdr hdr;
800} __attribute__((packed)) ;
801
802union c2wr_nsmr_pbl {
803 struct c2wr_nsmr_pbl_req req;
804 struct c2wr_nsmr_pbl_rep rep;
805} __attribute__((packed)) ;
806
807struct c2wr_mr_query_req {
808 struct c2wr_hdr hdr;
809 u32 rnic_handle;
810 u32 stag_index;
811} __attribute__((packed)) ;
812
813struct c2wr_mr_query_rep {
814 struct c2wr_hdr hdr;
815 u8 stag_key;
816 u8 pad[3];
817 u32 pd_id;
818 u32 flags;
819 u32 pbl_depth;
820} __attribute__((packed)) ;
821
822union c2wr_mr_query {
823 struct c2wr_mr_query_req req;
824 struct c2wr_mr_query_rep rep;
825} __attribute__((packed)) ;
826
827struct c2wr_mw_query_req {
828 struct c2wr_hdr hdr;
829 u32 rnic_handle;
830 u32 stag_index;
831} __attribute__((packed)) ;
832
833struct c2wr_mw_query_rep {
834 struct c2wr_hdr hdr;
835 u8 stag_key;
836 u8 pad[3];
837 u32 pd_id;
838 u32 flags;
839} __attribute__((packed)) ;
840
841union c2wr_mw_query {
842 struct c2wr_mw_query_req req;
843 struct c2wr_mw_query_rep rep;
844} __attribute__((packed)) ;
845
846
847struct c2wr_stag_dealloc_req {
848 struct c2wr_hdr hdr;
849 u32 rnic_handle;
850 u32 stag_index;
851} __attribute__((packed)) ;
852
853struct c2wr_stag_dealloc_rep {
854 struct c2wr_hdr hdr;
855} __attribute__((packed)) ;
856
857union c2wr_stag_dealloc {
858 struct c2wr_stag_dealloc_req req;
859 struct c2wr_stag_dealloc_rep rep;
860} __attribute__((packed)) ;
861
862struct c2wr_nsmr_reregister_req {
863 struct c2wr_hdr hdr;
864 u64 va;
865 u32 rnic_handle;
866 u16 flags;
867 u8 stag_key;
868 u8 pad;
869 u32 stag_index;
870 u32 pd_id;
871 u32 pbl_depth;
872 u32 pbe_size;
873 u32 fbo;
874 u32 length;
875 u32 addrs_length;
876 u32 pad1;
877 /* array of paddrs (must be aligned on a 64bit boundary) */
878 u64 paddrs[0];
879} __attribute__((packed)) ;
880
881struct c2wr_nsmr_reregister_rep {
882 struct c2wr_hdr hdr;
883 u32 pbl_depth;
884 u32 stag_index;
885} __attribute__((packed)) ;
886
887union c2wr_nsmr_reregister {
888 struct c2wr_nsmr_reregister_req req;
889 struct c2wr_nsmr_reregister_rep rep;
890} __attribute__((packed)) ;
891
892struct c2wr_smr_register_req {
893 struct c2wr_hdr hdr;
894 u64 va;
895 u32 rnic_handle;
896 u16 flags;
897 u8 stag_key;
898 u8 pad;
899 u32 stag_index;
900 u32 pd_id;
901} __attribute__((packed)) ;
902
903struct c2wr_smr_register_rep {
904 struct c2wr_hdr hdr;
905 u32 stag_index;
906} __attribute__((packed)) ;
907
908union c2wr_smr_register {
909 struct c2wr_smr_register_req req;
910 struct c2wr_smr_register_rep rep;
911} __attribute__((packed)) ;
912
913struct c2wr_mw_alloc_req {
914 struct c2wr_hdr hdr;
915 u32 rnic_handle;
916 u32 pd_id;
917} __attribute__((packed)) ;
918
919struct c2wr_mw_alloc_rep {
920 struct c2wr_hdr hdr;
921 u32 stag_index;
922} __attribute__((packed)) ;
923
924union c2wr_mw_alloc {
925 struct c2wr_mw_alloc_req req;
926 struct c2wr_mw_alloc_rep rep;
927} __attribute__((packed)) ;
928
929/*
930 *------------------------ WRs -----------------------
931 */
932
933struct c2wr_user_hdr {
934 struct c2wr_hdr hdr; /* Has status and WR Type */
935} __attribute__((packed)) ;
936
937enum c2_qp_state {
938 C2_QP_STATE_IDLE = 0x01,
939 C2_QP_STATE_CONNECTING = 0x02,
940 C2_QP_STATE_RTS = 0x04,
941 C2_QP_STATE_CLOSING = 0x08,
942 C2_QP_STATE_TERMINATE = 0x10,
943 C2_QP_STATE_ERROR = 0x20,
944};
945
946/* Completion queue entry. */
947struct c2wr_ce {
948 struct c2wr_hdr hdr; /* Has status and WR Type */
949 u64 qp_user_context; /* c2_user_qp_t * */
950 u32 qp_state; /* Current QP State */
951 u32 handle; /* QPID or EP Handle */
952 u32 bytes_rcvd; /* valid for RECV WCs */
953 u32 stag;
954} __attribute__((packed)) ;
955
956
957/*
958 * Flags used for all post-sq WRs. These must fit in the flags
959 * field of the struct c2wr_hdr (eight bits).
960 */
961enum {
962 SQ_SIGNALED = 0x01,
963 SQ_READ_FENCE = 0x02,
964 SQ_FENCE = 0x04,
965};
966
967/*
968 * Common fields for all post-sq WRs. Namely the standard header and a
969 * secondary header with fields common to all post-sq WRs.
970 */
971struct c2_sq_hdr {
972 struct c2wr_user_hdr user_hdr;
973} __attribute__((packed));
974
975/*
976 * Same as above but for post-rq WRs.
977 */
978struct c2_rq_hdr {
979 struct c2wr_user_hdr user_hdr;
980} __attribute__((packed));
981
982/*
983 * use the same struct for all sends.
984 */
985struct c2wr_send_req {
986 struct c2_sq_hdr sq_hdr;
987 u32 sge_len;
988 u32 remote_stag;
989 u8 data[0]; /* SGE array */
990} __attribute__((packed));
991
992union c2wr_send {
993 struct c2wr_send_req req;
994 struct c2wr_ce rep;
995} __attribute__((packed));
996
997struct c2wr_rdma_write_req {
998 struct c2_sq_hdr sq_hdr;
999 u64 remote_to;
1000 u32 remote_stag;
1001 u32 sge_len;
1002 u8 data[0]; /* SGE array */
1003} __attribute__((packed));
1004
1005union c2wr_rdma_write {
1006 struct c2wr_rdma_write_req req;
1007 struct c2wr_ce rep;
1008} __attribute__((packed));
1009
1010struct c2wr_rdma_read_req {
1011 struct c2_sq_hdr sq_hdr;
1012 u64 local_to;
1013 u64 remote_to;
1014 u32 local_stag;
1015 u32 remote_stag;
1016 u32 length;
1017} __attribute__((packed));
1018
1019union c2wr_rdma_read {
1020 struct c2wr_rdma_read_req req;
1021 struct c2wr_ce rep;
1022} __attribute__((packed));
1023
1024struct c2wr_mw_bind_req {
1025 struct c2_sq_hdr sq_hdr;
1026 u64 va;
1027 u8 stag_key;
1028 u8 pad[3];
1029 u32 mw_stag_index;
1030 u32 mr_stag_index;
1031 u32 length;
1032 u32 flags;
1033} __attribute__((packed));
1034
1035union c2wr_mw_bind {
1036 struct c2wr_mw_bind_req req;
1037 struct c2wr_ce rep;
1038} __attribute__((packed));
1039
1040struct c2wr_nsmr_fastreg_req {
1041 struct c2_sq_hdr sq_hdr;
1042 u64 va;
1043 u8 stag_key;
1044 u8 pad[3];
1045 u32 stag_index;
1046 u32 pbe_size;
1047 u32 fbo;
1048 u32 length;
1049 u32 addrs_length;
1050 /* array of paddrs (must be aligned on a 64bit boundary) */
1051 u64 paddrs[0];
1052} __attribute__((packed));
1053
1054union c2wr_nsmr_fastreg {
1055 struct c2wr_nsmr_fastreg_req req;
1056 struct c2wr_ce rep;
1057} __attribute__((packed));
1058
1059struct c2wr_stag_invalidate_req {
1060 struct c2_sq_hdr sq_hdr;
1061 u8 stag_key;
1062 u8 pad[3];
1063 u32 stag_index;
1064} __attribute__((packed));
1065
1066union c2wr_stag_invalidate {
1067 struct c2wr_stag_invalidate_req req;
1068 struct c2wr_ce rep;
1069} __attribute__((packed));
1070
1071union c2wr_sqwr {
1072 struct c2_sq_hdr sq_hdr;
1073 struct c2wr_send_req send;
1074 struct c2wr_send_req send_se;
1075 struct c2wr_send_req send_inv;
1076 struct c2wr_send_req send_se_inv;
1077 struct c2wr_rdma_write_req rdma_write;
1078 struct c2wr_rdma_read_req rdma_read;
1079 struct c2wr_mw_bind_req mw_bind;
1080 struct c2wr_nsmr_fastreg_req nsmr_fastreg;
1081 struct c2wr_stag_invalidate_req stag_inv;
1082} __attribute__((packed));
1083
1084
1085/*
1086 * RQ WRs
1087 */
1088struct c2wr_rqwr {
1089 struct c2_rq_hdr rq_hdr;
1090 u8 data[0]; /* array of SGEs */
1091} __attribute__((packed));
1092
1093union c2wr_recv {
1094 struct c2wr_rqwr req;
1095 struct c2wr_ce rep;
1096} __attribute__((packed));
1097
1098/*
1099 * All AEs start with this header. Most AEs only need to convey the
1100 * information in the header. Some, like LLP connection events, need
1101 * more info. The union typdef c2wr_ae_t has all the possible AEs.
1102 *
1103 * hdr.context is the user_context from the rnic_open WR. NULL If this
1104 * is not affiliated with an rnic
1105 *
1106 * hdr.id is the AE identifier (eg; CCAE_REMOTE_SHUTDOWN,
1107 * CCAE_LLP_CLOSE_COMPLETE)
1108 *
1109 * resource_type is one of: C2_RES_IND_QP, C2_RES_IND_CQ, C2_RES_IND_SRQ
1110 *
1111 * user_context is the context passed down when the host created the resource.
1112 */
1113struct c2wr_ae_hdr {
1114 struct c2wr_hdr hdr;
1115 u64 user_context; /* user context for this res. */
1116 u32 resource_type; /* see enum c2_resource_indicator */
1117 u32 resource; /* handle for resource */
1118 u32 qp_state; /* current QP State */
1119} __attribute__((packed));
1120
1121/*
1122 * After submitting the CCAE_ACTIVE_CONNECT_RESULTS message on the AEQ,
1123 * the adapter moves the QP into RTS state
1124 */
1125struct c2wr_ae_active_connect_results {
1126 struct c2wr_ae_hdr ae_hdr;
1127 u32 laddr;
1128 u32 raddr;
1129 u16 lport;
1130 u16 rport;
1131 u32 private_data_length;
1132 u8 private_data[0]; /* data is in-line in the msg. */
1133} __attribute__((packed));
1134
1135/*
1136 * When connections are established by the stack (and the private data
1137 * MPA frame is received), the adapter will generate an event to the host.
1138 * The details of the connection, any private data, and the new connection
1139 * request handle is passed up via the CCAE_CONNECTION_REQUEST msg on the
1140 * AE queue:
1141 */
1142struct c2wr_ae_connection_request {
1143 struct c2wr_ae_hdr ae_hdr;
1144 u32 cr_handle; /* connreq handle (sock ptr) */
1145 u32 laddr;
1146 u32 raddr;
1147 u16 lport;
1148 u16 rport;
1149 u32 private_data_length;
1150 u8 private_data[0]; /* data is in-line in the msg. */
1151} __attribute__((packed));
1152
1153union c2wr_ae {
1154 struct c2wr_ae_hdr ae_generic;
1155 struct c2wr_ae_active_connect_results ae_active_connect_results;
1156 struct c2wr_ae_connection_request ae_connection_request;
1157} __attribute__((packed));
1158
1159struct c2wr_init_req {
1160 struct c2wr_hdr hdr;
1161 u64 hint_count;
1162 u64 q0_host_shared;
1163 u64 q1_host_shared;
1164 u64 q1_host_msg_pool;
1165 u64 q2_host_shared;
1166 u64 q2_host_msg_pool;
1167} __attribute__((packed));
1168
1169struct c2wr_init_rep {
1170 struct c2wr_hdr hdr;
1171} __attribute__((packed));
1172
1173union c2wr_init {
1174 struct c2wr_init_req req;
1175 struct c2wr_init_rep rep;
1176} __attribute__((packed));
1177
1178/*
1179 * For upgrading flash.
1180 */
1181
1182struct c2wr_flash_init_req {
1183 struct c2wr_hdr hdr;
1184 u32 rnic_handle;
1185} __attribute__((packed));
1186
1187struct c2wr_flash_init_rep {
1188 struct c2wr_hdr hdr;
1189 u32 adapter_flash_buf_offset;
1190 u32 adapter_flash_len;
1191} __attribute__((packed));
1192
1193union c2wr_flash_init {
1194 struct c2wr_flash_init_req req;
1195 struct c2wr_flash_init_rep rep;
1196} __attribute__((packed));
1197
1198struct c2wr_flash_req {
1199 struct c2wr_hdr hdr;
1200 u32 rnic_handle;
1201 u32 len;
1202} __attribute__((packed));
1203
1204struct c2wr_flash_rep {
1205 struct c2wr_hdr hdr;
1206 u32 status;
1207} __attribute__((packed));
1208
1209union c2wr_flash {
1210 struct c2wr_flash_req req;
1211 struct c2wr_flash_rep rep;
1212} __attribute__((packed));
1213
1214struct c2wr_buf_alloc_req {
1215 struct c2wr_hdr hdr;
1216 u32 rnic_handle;
1217 u32 size;
1218} __attribute__((packed));
1219
1220struct c2wr_buf_alloc_rep {
1221 struct c2wr_hdr hdr;
1222 u32 offset; /* 0 if mem not available */
1223 u32 size; /* 0 if mem not available */
1224} __attribute__((packed));
1225
1226union c2wr_buf_alloc {
1227 struct c2wr_buf_alloc_req req;
1228 struct c2wr_buf_alloc_rep rep;
1229} __attribute__((packed));
1230
1231struct c2wr_buf_free_req {
1232 struct c2wr_hdr hdr;
1233 u32 rnic_handle;
1234 u32 offset; /* Must match value from alloc */
1235 u32 size; /* Must match value from alloc */
1236} __attribute__((packed));
1237
1238struct c2wr_buf_free_rep {
1239 struct c2wr_hdr hdr;
1240} __attribute__((packed));
1241
1242union c2wr_buf_free {
1243 struct c2wr_buf_free_req req;
1244 struct c2wr_ce rep;
1245} __attribute__((packed));
1246
1247struct c2wr_flash_write_req {
1248 struct c2wr_hdr hdr;
1249 u32 rnic_handle;
1250 u32 offset;
1251 u32 size;
1252 u32 type;
1253 u32 flags;
1254} __attribute__((packed));
1255
1256struct c2wr_flash_write_rep {
1257 struct c2wr_hdr hdr;
1258 u32 status;
1259} __attribute__((packed));
1260
1261union c2wr_flash_write {
1262 struct c2wr_flash_write_req req;
1263 struct c2wr_flash_write_rep rep;
1264} __attribute__((packed));
1265
1266/*
1267 * Messages for LLP connection setup.
1268 */
1269
1270/*
1271 * Listen Request. This allocates a listening endpoint to allow passive
1272 * connection setup. Newly established LLP connections are passed up
1273 * via an AE. See c2wr_ae_connection_request_t
1274 */
1275struct c2wr_ep_listen_create_req {
1276 struct c2wr_hdr hdr;
1277 u64 user_context; /* returned in AEs. */
1278 u32 rnic_handle;
1279 u32 local_addr; /* local addr, or 0 */
1280 u16 local_port; /* 0 means "pick one" */
1281 u16 pad;
1282 u32 backlog; /* tradional tcp listen bl */
1283} __attribute__((packed));
1284
1285struct c2wr_ep_listen_create_rep {
1286 struct c2wr_hdr hdr;
1287 u32 ep_handle; /* handle to new listening ep */
1288 u16 local_port; /* resulting port... */
1289 u16 pad;
1290} __attribute__((packed));
1291
1292union c2wr_ep_listen_create {
1293 struct c2wr_ep_listen_create_req req;
1294 struct c2wr_ep_listen_create_rep rep;
1295} __attribute__((packed));
1296
1297struct c2wr_ep_listen_destroy_req {
1298 struct c2wr_hdr hdr;
1299 u32 rnic_handle;
1300 u32 ep_handle;
1301} __attribute__((packed));
1302
1303struct c2wr_ep_listen_destroy_rep {
1304 struct c2wr_hdr hdr;
1305} __attribute__((packed));
1306
1307union c2wr_ep_listen_destroy {
1308 struct c2wr_ep_listen_destroy_req req;
1309 struct c2wr_ep_listen_destroy_rep rep;
1310} __attribute__((packed));
1311
1312struct c2wr_ep_query_req {
1313 struct c2wr_hdr hdr;
1314 u32 rnic_handle;
1315 u32 ep_handle;
1316} __attribute__((packed));
1317
1318struct c2wr_ep_query_rep {
1319 struct c2wr_hdr hdr;
1320 u32 rnic_handle;
1321 u32 local_addr;
1322 u32 remote_addr;
1323 u16 local_port;
1324 u16 remote_port;
1325} __attribute__((packed));
1326
1327union c2wr_ep_query {
1328 struct c2wr_ep_query_req req;
1329 struct c2wr_ep_query_rep rep;
1330} __attribute__((packed));
1331
1332
1333/*
1334 * The host passes this down to indicate acceptance of a pending iWARP
1335 * connection. The cr_handle was obtained from the CONNECTION_REQUEST
1336 * AE passed up by the adapter. See c2wr_ae_connection_request_t.
1337 */
1338struct c2wr_cr_accept_req {
1339 struct c2wr_hdr hdr;
1340 u32 rnic_handle;
1341 u32 qp_handle; /* QP to bind to this LLP conn */
1342 u32 ep_handle; /* LLP handle to accept */
1343 u32 private_data_length;
1344 u8 private_data[0]; /* data in-line in msg. */
1345} __attribute__((packed));
1346
1347/*
1348 * adapter sends reply when private data is successfully submitted to
1349 * the LLP.
1350 */
1351struct c2wr_cr_accept_rep {
1352 struct c2wr_hdr hdr;
1353} __attribute__((packed));
1354
1355union c2wr_cr_accept {
1356 struct c2wr_cr_accept_req req;
1357 struct c2wr_cr_accept_rep rep;
1358} __attribute__((packed));
1359
1360/*
1361 * The host sends this down if a given iWARP connection request was
1362 * rejected by the consumer. The cr_handle was obtained from a
1363 * previous c2wr_ae_connection_request_t AE sent by the adapter.
1364 */
1365struct c2wr_cr_reject_req {
1366 struct c2wr_hdr hdr;
1367 u32 rnic_handle;
1368 u32 ep_handle; /* LLP handle to reject */
1369} __attribute__((packed));
1370
1371/*
1372 * Dunno if this is needed, but we'll add it for now. The adapter will
1373 * send the reject_reply after the LLP endpoint has been destroyed.
1374 */
1375struct c2wr_cr_reject_rep {
1376 struct c2wr_hdr hdr;
1377} __attribute__((packed));
1378
1379union c2wr_cr_reject {
1380 struct c2wr_cr_reject_req req;
1381 struct c2wr_cr_reject_rep rep;
1382} __attribute__((packed));
1383
1384/*
1385 * console command. Used to implement a debug console over the verbs
1386 * request and reply queues.
1387 */
1388
1389/*
1390 * Console request message. It contains:
1391 * - message hdr with id = CCWR_CONSOLE
1392 * - the physaddr/len of host memory to be used for the reply.
1393 * - the command string. eg: "netstat -s" or "zoneinfo"
1394 */
1395struct c2wr_console_req {
1396 struct c2wr_hdr hdr; /* id = CCWR_CONSOLE */
1397 u64 reply_buf; /* pinned host buf for reply */
1398 u32 reply_buf_len; /* length of reply buffer */
1399 u8 command[0]; /* NUL terminated ascii string */
1400 /* containing the command req */
1401} __attribute__((packed));
1402
1403/*
1404 * flags used in the console reply.
1405 */
1406enum c2_console_flags {
1407 CONS_REPLY_TRUNCATED = 0x00000001 /* reply was truncated */
1408} __attribute__((packed));
1409
1410/*
1411 * Console reply message.
1412 * hdr.result contains the c2_status_t error if the reply was _not_ generated,
1413 * or C2_OK if the reply was generated.
1414 */
1415struct c2wr_console_rep {
1416 struct c2wr_hdr hdr; /* id = CCWR_CONSOLE */
1417 u32 flags;
1418} __attribute__((packed));
1419
1420union c2wr_console {
1421 struct c2wr_console_req req;
1422 struct c2wr_console_rep rep;
1423} __attribute__((packed));
1424
1425
1426/*
1427 * Giant union with all WRs. Makes life easier...
1428 */
1429union c2wr {
1430 struct c2wr_hdr hdr;
1431 struct c2wr_user_hdr user_hdr;
1432 union c2wr_rnic_open rnic_open;
1433 union c2wr_rnic_query rnic_query;
1434 union c2wr_rnic_getconfig rnic_getconfig;
1435 union c2wr_rnic_setconfig rnic_setconfig;
1436 union c2wr_rnic_close rnic_close;
1437 union c2wr_cq_create cq_create;
1438 union c2wr_cq_modify cq_modify;
1439 union c2wr_cq_destroy cq_destroy;
1440 union c2wr_pd_alloc pd_alloc;
1441 union c2wr_pd_dealloc pd_dealloc;
1442 union c2wr_srq_create srq_create;
1443 union c2wr_srq_destroy srq_destroy;
1444 union c2wr_qp_create qp_create;
1445 union c2wr_qp_query qp_query;
1446 union c2wr_qp_modify qp_modify;
1447 union c2wr_qp_destroy qp_destroy;
1448 struct c2wr_qp_connect qp_connect;
1449 union c2wr_nsmr_stag_alloc nsmr_stag_alloc;
1450 union c2wr_nsmr_register nsmr_register;
1451 union c2wr_nsmr_pbl nsmr_pbl;
1452 union c2wr_mr_query mr_query;
1453 union c2wr_mw_query mw_query;
1454 union c2wr_stag_dealloc stag_dealloc;
1455 union c2wr_sqwr sqwr;
1456 struct c2wr_rqwr rqwr;
1457 struct c2wr_ce ce;
1458 union c2wr_ae ae;
1459 union c2wr_init init;
1460 union c2wr_ep_listen_create ep_listen_create;
1461 union c2wr_ep_listen_destroy ep_listen_destroy;
1462 union c2wr_cr_accept cr_accept;
1463 union c2wr_cr_reject cr_reject;
1464 union c2wr_console console;
1465 union c2wr_flash_init flash_init;
1466 union c2wr_flash flash;
1467 union c2wr_buf_alloc buf_alloc;
1468 union c2wr_buf_free buf_free;
1469 union c2wr_flash_write flash_write;
1470} __attribute__((packed));
1471
1472
1473/*
1474 * Accessors for the wr fields that are packed together tightly to
1475 * reduce the wr message size. The wr arguments are void* so that
1476 * either a struct c2wr*, a struct c2wr_hdr*, or a pointer to any of the types
1477 * in the struct c2wr union can be passed in.
1478 */
1479static __inline__ u8 c2_wr_get_id(void *wr)
1480{
1481 return ((struct c2wr_hdr *) wr)->id;
1482}
1483static __inline__ void c2_wr_set_id(void *wr, u8 id)
1484{
1485 ((struct c2wr_hdr *) wr)->id = id;
1486}
1487static __inline__ u8 c2_wr_get_result(void *wr)
1488{
1489 return ((struct c2wr_hdr *) wr)->result;
1490}
1491static __inline__ void c2_wr_set_result(void *wr, u8 result)
1492{
1493 ((struct c2wr_hdr *) wr)->result = result;
1494}
1495static __inline__ u8 c2_wr_get_flags(void *wr)
1496{
1497 return ((struct c2wr_hdr *) wr)->flags;
1498}
1499static __inline__ void c2_wr_set_flags(void *wr, u8 flags)
1500{
1501 ((struct c2wr_hdr *) wr)->flags = flags;
1502}
1503static __inline__ u8 c2_wr_get_sge_count(void *wr)
1504{
1505 return ((struct c2wr_hdr *) wr)->sge_count;
1506}
1507static __inline__ void c2_wr_set_sge_count(void *wr, u8 sge_count)
1508{
1509 ((struct c2wr_hdr *) wr)->sge_count = sge_count;
1510}
1511static __inline__ u32 c2_wr_get_wqe_count(void *wr)
1512{
1513 return ((struct c2wr_hdr *) wr)->wqe_count;
1514}
1515static __inline__ void c2_wr_set_wqe_count(void *wr, u32 wqe_count)
1516{
1517 ((struct c2wr_hdr *) wr)->wqe_count = wqe_count;
1518}
1519
1520#endif /* _C2_WR_H_ */
diff --git a/drivers/infiniband/hw/ehca/Kconfig b/drivers/infiniband/hw/ehca/Kconfig
new file mode 100644
index 000000000000..922389b64394
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/Kconfig
@@ -0,0 +1,16 @@
1config INFINIBAND_EHCA
2 tristate "eHCA support"
3 depends on IBMEBUS && INFINIBAND
4 ---help---
5 This driver supports the IBM pSeries eHCA InfiniBand adapter.
6
7 To compile the driver as a module, choose M here. The module
8 will be called ib_ehca.
9
10config INFINIBAND_EHCA_SCALING
11 bool "Scaling support (EXPERIMENTAL)"
12 depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL
13 ---help---
14 eHCA scaling support schedules the CQ callbacks to different CPUs.
15
16 To enable this feature choose Y here.
diff --git a/drivers/infiniband/hw/ehca/Makefile b/drivers/infiniband/hw/ehca/Makefile
new file mode 100644
index 000000000000..74d284e46a40
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/Makefile
@@ -0,0 +1,16 @@
1# Authors: Heiko J Schick <schickhj@de.ibm.com>
2# Christoph Raisch <raisch@de.ibm.com>
3# Joachim Fenkes <fenkes@de.ibm.com>
4#
5# Copyright (c) 2005 IBM Corporation
6#
7# All rights reserved.
8#
9# This source code is distributed under a dual license of GPL v2.0 and OpenIB BSD.
10
11obj-$(CONFIG_INFINIBAND_EHCA) += ib_ehca.o
12
13ib_ehca-objs = ehca_main.o ehca_hca.o ehca_mcast.o ehca_pd.o ehca_av.o ehca_eq.o \
14 ehca_cq.o ehca_qp.o ehca_sqp.o ehca_mrmw.o ehca_reqs.o ehca_irq.o \
15 ehca_uverbs.o ipz_pt_fn.o hcp_if.o hcp_phyp.o
16
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
new file mode 100644
index 000000000000..3bac197f9014
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_av.c
@@ -0,0 +1,271 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * adress vector functions
5 *
6 * Authors: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
7 * Khadija Souissi <souissik@de.ibm.com>
8 * Reinhard Ernst <rernst@de.ibm.com>
9 * Christoph Raisch <raisch@de.ibm.com>
10 *
11 * Copyright (c) 2005 IBM Corporation
12 *
13 * All rights reserved.
14 *
15 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
16 * BSD.
17 *
18 * OpenIB BSD License
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *
23 * Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
25 *
26 * Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials
29 * provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44
45#include <asm/current.h>
46
47#include "ehca_tools.h"
48#include "ehca_iverbs.h"
49#include "hcp_if.h"
50
51static struct kmem_cache *av_cache;
52
53struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
54{
55 int ret;
56 struct ehca_av *av;
57 struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
58 ib_device);
59
60 av = kmem_cache_alloc(av_cache, SLAB_KERNEL);
61 if (!av) {
62 ehca_err(pd->device, "Out of memory pd=%p ah_attr=%p",
63 pd, ah_attr);
64 return ERR_PTR(-ENOMEM);
65 }
66
67 av->av.sl = ah_attr->sl;
68 av->av.dlid = ah_attr->dlid;
69 av->av.slid_path_bits = ah_attr->src_path_bits;
70
71 if (ehca_static_rate < 0) {
72 int ah_mult = ib_rate_to_mult(ah_attr->static_rate);
73 int ehca_mult =
74 ib_rate_to_mult(shca->sport[ah_attr->port_num].rate );
75
76 if (ah_mult >= ehca_mult)
77 av->av.ipd = 0;
78 else
79 av->av.ipd = (ah_mult > 0) ?
80 ((ehca_mult - 1) / ah_mult) : 0;
81 } else
82 av->av.ipd = ehca_static_rate;
83
84 av->av.lnh = ah_attr->ah_flags;
85 av->av.grh.word_0 = EHCA_BMASK_SET(GRH_IPVERSION_MASK, 6);
86 av->av.grh.word_0 |= EHCA_BMASK_SET(GRH_TCLASS_MASK,
87 ah_attr->grh.traffic_class);
88 av->av.grh.word_0 |= EHCA_BMASK_SET(GRH_FLOWLABEL_MASK,
89 ah_attr->grh.flow_label);
90 av->av.grh.word_0 |= EHCA_BMASK_SET(GRH_HOPLIMIT_MASK,
91 ah_attr->grh.hop_limit);
92 av->av.grh.word_0 |= EHCA_BMASK_SET(GRH_NEXTHEADER_MASK, 0x1B);
93 /* set sgid in grh.word_1 */
94 if (ah_attr->ah_flags & IB_AH_GRH) {
95 int rc;
96 struct ib_port_attr port_attr;
97 union ib_gid gid;
98 memset(&port_attr, 0, sizeof(port_attr));
99 rc = ehca_query_port(pd->device, ah_attr->port_num,
100 &port_attr);
101 if (rc) { /* invalid port number */
102 ret = -EINVAL;
103 ehca_err(pd->device, "Invalid port number "
104 "ehca_query_port() returned %x "
105 "pd=%p ah_attr=%p", rc, pd, ah_attr);
106 goto create_ah_exit1;
107 }
108 memset(&gid, 0, sizeof(gid));
109 rc = ehca_query_gid(pd->device,
110 ah_attr->port_num,
111 ah_attr->grh.sgid_index, &gid);
112 if (rc) {
113 ret = -EINVAL;
114 ehca_err(pd->device, "Failed to retrieve sgid "
115 "ehca_query_gid() returned %x "
116 "pd=%p ah_attr=%p", rc, pd, ah_attr);
117 goto create_ah_exit1;
118 }
119 memcpy(&av->av.grh.word_1, &gid, sizeof(gid));
120 }
121 /* for the time being we use a hard coded PMTU of 2048 Bytes */
122 av->av.pmtu = 4;
123
124 /* dgid comes in grh.word_3 */
125 memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid,
126 sizeof(ah_attr->grh.dgid));
127
128 return &av->ib_ah;
129
130create_ah_exit1:
131 kmem_cache_free(av_cache, av);
132
133 return ERR_PTR(ret);
134}
135
136int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
137{
138 struct ehca_av *av;
139 struct ehca_ud_av new_ehca_av;
140 struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd);
141 u32 cur_pid = current->tgid;
142
143 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
144 my_pd->ownpid != cur_pid) {
145 ehca_err(ah->device, "Invalid caller pid=%x ownpid=%x",
146 cur_pid, my_pd->ownpid);
147 return -EINVAL;
148 }
149
150 memset(&new_ehca_av, 0, sizeof(new_ehca_av));
151 new_ehca_av.sl = ah_attr->sl;
152 new_ehca_av.dlid = ah_attr->dlid;
153 new_ehca_av.slid_path_bits = ah_attr->src_path_bits;
154 new_ehca_av.ipd = ah_attr->static_rate;
155 new_ehca_av.lnh = EHCA_BMASK_SET(GRH_FLAG_MASK,
156 (ah_attr->ah_flags & IB_AH_GRH) > 0);
157 new_ehca_av.grh.word_0 = EHCA_BMASK_SET(GRH_TCLASS_MASK,
158 ah_attr->grh.traffic_class);
159 new_ehca_av.grh.word_0 |= EHCA_BMASK_SET(GRH_FLOWLABEL_MASK,
160 ah_attr->grh.flow_label);
161 new_ehca_av.grh.word_0 |= EHCA_BMASK_SET(GRH_HOPLIMIT_MASK,
162 ah_attr->grh.hop_limit);
163 new_ehca_av.grh.word_0 |= EHCA_BMASK_SET(GRH_NEXTHEADER_MASK, 0x1b);
164
165 /* set sgid in grh.word_1 */
166 if (ah_attr->ah_flags & IB_AH_GRH) {
167 int rc;
168 struct ib_port_attr port_attr;
169 union ib_gid gid;
170 memset(&port_attr, 0, sizeof(port_attr));
171 rc = ehca_query_port(ah->device, ah_attr->port_num,
172 &port_attr);
173 if (rc) { /* invalid port number */
174 ehca_err(ah->device, "Invalid port number "
175 "ehca_query_port() returned %x "
176 "ah=%p ah_attr=%p port_num=%x",
177 rc, ah, ah_attr, ah_attr->port_num);
178 return -EINVAL;
179 }
180 memset(&gid, 0, sizeof(gid));
181 rc = ehca_query_gid(ah->device,
182 ah_attr->port_num,
183 ah_attr->grh.sgid_index, &gid);
184 if (rc) {
185 ehca_err(ah->device, "Failed to retrieve sgid "
186 "ehca_query_gid() returned %x "
187 "ah=%p ah_attr=%p port_num=%x "
188 "sgid_index=%x",
189 rc, ah, ah_attr, ah_attr->port_num,
190 ah_attr->grh.sgid_index);
191 return -EINVAL;
192 }
193 memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid));
194 }
195
196 new_ehca_av.pmtu = 4; /* see also comment in create_ah() */
197
198 memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid,
199 sizeof(ah_attr->grh.dgid));
200
201 av = container_of(ah, struct ehca_av, ib_ah);
202 av->av = new_ehca_av;
203
204 return 0;
205}
206
207int ehca_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
208{
209 struct ehca_av *av = container_of(ah, struct ehca_av, ib_ah);
210 struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd);
211 u32 cur_pid = current->tgid;
212
213 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
214 my_pd->ownpid != cur_pid) {
215 ehca_err(ah->device, "Invalid caller pid=%x ownpid=%x",
216 cur_pid, my_pd->ownpid);
217 return -EINVAL;
218 }
219
220 memcpy(&ah_attr->grh.dgid, &av->av.grh.word_3,
221 sizeof(ah_attr->grh.dgid));
222 ah_attr->sl = av->av.sl;
223
224 ah_attr->dlid = av->av.dlid;
225
226 ah_attr->src_path_bits = av->av.slid_path_bits;
227 ah_attr->static_rate = av->av.ipd;
228 ah_attr->ah_flags = EHCA_BMASK_GET(GRH_FLAG_MASK, av->av.lnh);
229 ah_attr->grh.traffic_class = EHCA_BMASK_GET(GRH_TCLASS_MASK,
230 av->av.grh.word_0);
231 ah_attr->grh.hop_limit = EHCA_BMASK_GET(GRH_HOPLIMIT_MASK,
232 av->av.grh.word_0);
233 ah_attr->grh.flow_label = EHCA_BMASK_GET(GRH_FLOWLABEL_MASK,
234 av->av.grh.word_0);
235
236 return 0;
237}
238
239int ehca_destroy_ah(struct ib_ah *ah)
240{
241 struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd);
242 u32 cur_pid = current->tgid;
243
244 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
245 my_pd->ownpid != cur_pid) {
246 ehca_err(ah->device, "Invalid caller pid=%x ownpid=%x",
247 cur_pid, my_pd->ownpid);
248 return -EINVAL;
249 }
250
251 kmem_cache_free(av_cache, container_of(ah, struct ehca_av, ib_ah));
252
253 return 0;
254}
255
256int ehca_init_av_cache(void)
257{
258 av_cache = kmem_cache_create("ehca_cache_av",
259 sizeof(struct ehca_av), 0,
260 SLAB_HWCACHE_ALIGN,
261 NULL, NULL);
262 if (!av_cache)
263 return -ENOMEM;
264 return 0;
265}
266
267void ehca_cleanup_av_cache(void)
268{
269 if (av_cache)
270 kmem_cache_destroy(av_cache);
271}
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
new file mode 100644
index 000000000000..1c722032319c
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -0,0 +1,346 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Struct definition for eHCA internal structures
5 *
6 * Authors: Heiko J Schick <schickhj@de.ibm.com>
7 * Christoph Raisch <raisch@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#ifndef __EHCA_CLASSES_H__
43#define __EHCA_CLASSES_H__
44
45#include "ehca_classes.h"
46#include "ipz_pt_fn.h"
47
48struct ehca_module;
49struct ehca_qp;
50struct ehca_cq;
51struct ehca_eq;
52struct ehca_mr;
53struct ehca_mw;
54struct ehca_pd;
55struct ehca_av;
56
57#ifdef CONFIG_PPC64
58#include "ehca_classes_pSeries.h"
59#endif
60
61#include <rdma/ib_verbs.h>
62#include <rdma/ib_user_verbs.h>
63
64#include "ehca_irq.h"
65
66struct ehca_eq {
67 u32 length;
68 struct ipz_queue ipz_queue;
69 struct ipz_eq_handle ipz_eq_handle;
70 struct work_struct work;
71 struct h_galpas galpas;
72 int is_initialized;
73 struct ehca_pfeq pf;
74 spinlock_t spinlock;
75 struct tasklet_struct interrupt_task;
76 u32 ist;
77};
78
79struct ehca_sport {
80 struct ib_cq *ibcq_aqp1;
81 struct ib_qp *ibqp_aqp1;
82 enum ib_rate rate;
83 enum ib_port_state port_state;
84};
85
86struct ehca_shca {
87 struct ib_device ib_device;
88 struct ibmebus_dev *ibmebus_dev;
89 u8 num_ports;
90 int hw_level;
91 struct list_head shca_list;
92 struct ipz_adapter_handle ipz_hca_handle;
93 struct ehca_sport sport[2];
94 struct ehca_eq eq;
95 struct ehca_eq neq;
96 struct ehca_mr *maxmr;
97 struct ehca_pd *pd;
98 struct h_galpas galpas;
99};
100
101struct ehca_pd {
102 struct ib_pd ib_pd;
103 struct ipz_pd fw_pd;
104 u32 ownpid;
105};
106
107struct ehca_qp {
108 struct ib_qp ib_qp;
109 u32 qp_type;
110 struct ipz_queue ipz_squeue;
111 struct ipz_queue ipz_rqueue;
112 struct h_galpas galpas;
113 u32 qkey;
114 u32 real_qp_num;
115 u32 token;
116 spinlock_t spinlock_s;
117 spinlock_t spinlock_r;
118 u32 sq_max_inline_data_size;
119 struct ipz_qp_handle ipz_qp_handle;
120 struct ehca_pfqp pf;
121 struct ib_qp_init_attr init_attr;
122 u64 uspace_squeue;
123 u64 uspace_rqueue;
124 u64 uspace_fwh;
125 struct ehca_cq *send_cq;
126 struct ehca_cq *recv_cq;
127 unsigned int sqerr_purgeflag;
128 struct hlist_node list_entries;
129};
130
131/* must be power of 2 */
132#define QP_HASHTAB_LEN 8
133
134struct ehca_cq {
135 struct ib_cq ib_cq;
136 struct ipz_queue ipz_queue;
137 struct h_galpas galpas;
138 spinlock_t spinlock;
139 u32 cq_number;
140 u32 token;
141 u32 nr_of_entries;
142 struct ipz_cq_handle ipz_cq_handle;
143 struct ehca_pfcq pf;
144 spinlock_t cb_lock;
145 u64 uspace_queue;
146 u64 uspace_fwh;
147 struct hlist_head qp_hashtab[QP_HASHTAB_LEN];
148 struct list_head entry;
149 u32 nr_callbacks;
150 spinlock_t task_lock;
151 u32 ownpid;
152};
153
154enum ehca_mr_flag {
155 EHCA_MR_FLAG_FMR = 0x80000000, /* FMR, created with ehca_alloc_fmr */
156 EHCA_MR_FLAG_MAXMR = 0x40000000, /* max-MR */
157};
158
159struct ehca_mr {
160 union {
161 struct ib_mr ib_mr; /* must always be first in ehca_mr */
162 struct ib_fmr ib_fmr; /* must always be first in ehca_mr */
163 } ib;
164 spinlock_t mrlock;
165
166 enum ehca_mr_flag flags;
167 u32 num_pages; /* number of MR pages */
168 u32 num_4k; /* number of 4k "page" portions to form MR */
169 int acl; /* ACL (stored here for usage in reregister) */
170 u64 *start; /* virtual start address (stored here for */
171 /* usage in reregister) */
172 u64 size; /* size (stored here for usage in reregister) */
173 u32 fmr_page_size; /* page size for FMR */
174 u32 fmr_max_pages; /* max pages for FMR */
175 u32 fmr_max_maps; /* max outstanding maps for FMR */
176 u32 fmr_map_cnt; /* map counter for FMR */
177 /* fw specific data */
178 struct ipz_mrmw_handle ipz_mr_handle; /* MR handle for h-calls */
179 struct h_galpas galpas;
180 /* data for userspace bridge */
181 u32 nr_of_pages;
182 void *pagearray;
183};
184
185struct ehca_mw {
186 struct ib_mw ib_mw; /* gen2 mw, must always be first in ehca_mw */
187 spinlock_t mwlock;
188
189 u8 never_bound; /* indication MW was never bound */
190 struct ipz_mrmw_handle ipz_mw_handle; /* MW handle for h-calls */
191 struct h_galpas galpas;
192};
193
194enum ehca_mr_pgi_type {
195 EHCA_MR_PGI_PHYS = 1, /* type of ehca_reg_phys_mr,
196 * ehca_rereg_phys_mr,
197 * ehca_reg_internal_maxmr */
198 EHCA_MR_PGI_USER = 2, /* type of ehca_reg_user_mr */
199 EHCA_MR_PGI_FMR = 3 /* type of ehca_map_phys_fmr */
200};
201
202struct ehca_mr_pginfo {
203 enum ehca_mr_pgi_type type;
204 u64 num_pages;
205 u64 page_cnt;
206 u64 num_4k; /* number of 4k "page" portions */
207 u64 page_4k_cnt; /* counter for 4k "page" portions */
208 u64 next_4k; /* next 4k "page" portion in buffer/chunk/listelem */
209
210 /* type EHCA_MR_PGI_PHYS section */
211 int num_phys_buf;
212 struct ib_phys_buf *phys_buf_array;
213 u64 next_buf;
214
215 /* type EHCA_MR_PGI_USER section */
216 struct ib_umem *region;
217 struct ib_umem_chunk *next_chunk;
218 u64 next_nmap;
219
220 /* type EHCA_MR_PGI_FMR section */
221 u64 *page_list;
222 u64 next_listelem;
223 /* next_4k also used within EHCA_MR_PGI_FMR */
224};
225
226/* output parameters for MR/FMR hipz calls */
227struct ehca_mr_hipzout_parms {
228 struct ipz_mrmw_handle handle;
229 u32 lkey;
230 u32 rkey;
231 u64 len;
232 u64 vaddr;
233 u32 acl;
234};
235
236/* output parameters for MW hipz calls */
237struct ehca_mw_hipzout_parms {
238 struct ipz_mrmw_handle handle;
239 u32 rkey;
240};
241
242struct ehca_av {
243 struct ib_ah ib_ah;
244 struct ehca_ud_av av;
245};
246
247struct ehca_ucontext {
248 struct ib_ucontext ib_ucontext;
249};
250
251struct ehca_module *ehca_module_new(void);
252
253int ehca_module_delete(struct ehca_module *me);
254
255int ehca_eq_ctor(struct ehca_eq *eq);
256
257int ehca_eq_dtor(struct ehca_eq *eq);
258
259struct ehca_shca *ehca_shca_new(void);
260
261int ehca_shca_delete(struct ehca_shca *me);
262
263struct ehca_sport *ehca_sport_new(struct ehca_shca *anchor);
264
265int ehca_init_pd_cache(void);
266void ehca_cleanup_pd_cache(void);
267int ehca_init_cq_cache(void);
268void ehca_cleanup_cq_cache(void);
269int ehca_init_qp_cache(void);
270void ehca_cleanup_qp_cache(void);
271int ehca_init_av_cache(void);
272void ehca_cleanup_av_cache(void);
273int ehca_init_mrmw_cache(void);
274void ehca_cleanup_mrmw_cache(void);
275
276extern spinlock_t ehca_qp_idr_lock;
277extern spinlock_t ehca_cq_idr_lock;
278extern struct idr ehca_qp_idr;
279extern struct idr ehca_cq_idr;
280
281extern int ehca_static_rate;
282extern int ehca_port_act_time;
283extern int ehca_use_hp_mr;
284
285struct ipzu_queue_resp {
286 u64 queue; /* points to first queue entry */
287 u32 qe_size; /* queue entry size */
288 u32 act_nr_of_sg;
289 u32 queue_length; /* queue length allocated in bytes */
290 u32 pagesize;
291 u32 toggle_state;
292 u32 dummy; /* padding for 8 byte alignment */
293};
294
295struct ehca_create_cq_resp {
296 u32 cq_number;
297 u32 token;
298 struct ipzu_queue_resp ipz_queue;
299 struct h_galpas galpas;
300};
301
302struct ehca_create_qp_resp {
303 u32 qp_num;
304 u32 token;
305 u32 qp_type;
306 u32 qkey;
307 /* qp_num assigned by ehca: sqp0/1 may have got different numbers */
308 u32 real_qp_num;
309 u32 dummy; /* padding for 8 byte alignment */
310 struct ipzu_queue_resp ipz_squeue;
311 struct ipzu_queue_resp ipz_rqueue;
312 struct h_galpas galpas;
313};
314
315struct ehca_alloc_cq_parms {
316 u32 nr_cqe;
317 u32 act_nr_of_entries;
318 u32 act_pages;
319 struct ipz_eq_handle eq_handle;
320};
321
322struct ehca_alloc_qp_parms {
323 int servicetype;
324 int sigtype;
325 int daqp_ctrl;
326 int max_send_sge;
327 int max_recv_sge;
328 int ud_av_l_key_ctl;
329
330 u16 act_nr_send_wqes;
331 u16 act_nr_recv_wqes;
332 u8 act_nr_recv_sges;
333 u8 act_nr_send_sges;
334
335 u32 nr_rq_pages;
336 u32 nr_sq_pages;
337
338 struct ipz_eq_handle ipz_eq_handle;
339 struct ipz_pd pd;
340};
341
342int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp);
343int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int qp_num);
344struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int qp_num);
345
346#endif
diff --git a/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h b/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
new file mode 100644
index 000000000000..5665f213b81a
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
@@ -0,0 +1,236 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * pSeries interface definitions
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Christoph Raisch <raisch@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#ifndef __EHCA_CLASSES_PSERIES_H__
43#define __EHCA_CLASSES_PSERIES_H__
44
45#include "hcp_phyp.h"
46#include "ipz_pt_fn.h"
47
48
49struct ehca_pfqp {
50 struct ipz_qpt sqpt;
51 struct ipz_qpt rqpt;
52};
53
54struct ehca_pfcq {
55 struct ipz_qpt qpt;
56 u32 cqnr;
57};
58
59struct ehca_pfeq {
60 struct ipz_qpt qpt;
61 struct h_galpa galpa;
62 u32 eqnr;
63};
64
65struct ipz_adapter_handle {
66 u64 handle;
67};
68
69struct ipz_cq_handle {
70 u64 handle;
71};
72
73struct ipz_eq_handle {
74 u64 handle;
75};
76
77struct ipz_qp_handle {
78 u64 handle;
79};
80struct ipz_mrmw_handle {
81 u64 handle;
82};
83
84struct ipz_pd {
85 u32 value;
86};
87
88struct hcp_modify_qp_control_block {
89 u32 qkey; /* 00 */
90 u32 rdd; /* reliable datagram domain */
91 u32 send_psn; /* 02 */
92 u32 receive_psn; /* 03 */
93 u32 prim_phys_port; /* 04 */
94 u32 alt_phys_port; /* 05 */
95 u32 prim_p_key_idx; /* 06 */
96 u32 alt_p_key_idx; /* 07 */
97 u32 rdma_atomic_ctrl; /* 08 */
98 u32 qp_state; /* 09 */
99 u32 reserved_10; /* 10 */
100 u32 rdma_nr_atomic_resp_res; /* 11 */
101 u32 path_migration_state; /* 12 */
102 u32 rdma_atomic_outst_dest_qp; /* 13 */
103 u32 dest_qp_nr; /* 14 */
104 u32 min_rnr_nak_timer_field; /* 15 */
105 u32 service_level; /* 16 */
106 u32 send_grh_flag; /* 17 */
107 u32 retry_count; /* 18 */
108 u32 timeout; /* 19 */
109 u32 path_mtu; /* 20 */
110 u32 max_static_rate; /* 21 */
111 u32 dlid; /* 22 */
112 u32 rnr_retry_count; /* 23 */
113 u32 source_path_bits; /* 24 */
114 u32 traffic_class; /* 25 */
115 u32 hop_limit; /* 26 */
116 u32 source_gid_idx; /* 27 */
117 u32 flow_label; /* 28 */
118 u32 reserved_29; /* 29 */
119 union { /* 30 */
120 u64 dw[2];
121 u8 byte[16];
122 } dest_gid;
123 u32 service_level_al; /* 34 */
124 u32 send_grh_flag_al; /* 35 */
125 u32 retry_count_al; /* 36 */
126 u32 timeout_al; /* 37 */
127 u32 max_static_rate_al; /* 38 */
128 u32 dlid_al; /* 39 */
129 u32 rnr_retry_count_al; /* 40 */
130 u32 source_path_bits_al; /* 41 */
131 u32 traffic_class_al; /* 42 */
132 u32 hop_limit_al; /* 43 */
133 u32 source_gid_idx_al; /* 44 */
134 u32 flow_label_al; /* 45 */
135 u32 reserved_46; /* 46 */
136 u32 reserved_47; /* 47 */
137 union { /* 48 */
138 u64 dw[2];
139 u8 byte[16];
140 } dest_gid_al;
141 u32 max_nr_outst_send_wr; /* 52 */
142 u32 max_nr_outst_recv_wr; /* 53 */
143 u32 disable_ete_credit_check; /* 54 */
144 u32 qp_number; /* 55 */
145 u64 send_queue_handle; /* 56 */
146 u64 recv_queue_handle; /* 58 */
147 u32 actual_nr_sges_in_sq_wqe; /* 60 */
148 u32 actual_nr_sges_in_rq_wqe; /* 61 */
149 u32 qp_enable; /* 62 */
150 u32 curr_srq_limit; /* 63 */
151 u64 qp_aff_asyn_ev_log_reg; /* 64 */
152 u64 shared_rq_hndl; /* 66 */
153 u64 trigg_doorbell_qp_hndl; /* 68 */
154 u32 reserved_70_127[58]; /* 70 */
155};
156
157#define MQPCB_MASK_QKEY EHCA_BMASK_IBM(0,0)
158#define MQPCB_MASK_SEND_PSN EHCA_BMASK_IBM(2,2)
159#define MQPCB_MASK_RECEIVE_PSN EHCA_BMASK_IBM(3,3)
160#define MQPCB_MASK_PRIM_PHYS_PORT EHCA_BMASK_IBM(4,4)
161#define MQPCB_PRIM_PHYS_PORT EHCA_BMASK_IBM(24,31)
162#define MQPCB_MASK_ALT_PHYS_PORT EHCA_BMASK_IBM(5,5)
163#define MQPCB_MASK_PRIM_P_KEY_IDX EHCA_BMASK_IBM(6,6)
164#define MQPCB_PRIM_P_KEY_IDX EHCA_BMASK_IBM(24,31)
165#define MQPCB_MASK_ALT_P_KEY_IDX EHCA_BMASK_IBM(7,7)
166#define MQPCB_MASK_RDMA_ATOMIC_CTRL EHCA_BMASK_IBM(8,8)
167#define MQPCB_MASK_QP_STATE EHCA_BMASK_IBM(9,9)
168#define MQPCB_QP_STATE EHCA_BMASK_IBM(24,31)
169#define MQPCB_MASK_RDMA_NR_ATOMIC_RESP_RES EHCA_BMASK_IBM(11,11)
170#define MQPCB_MASK_PATH_MIGRATION_STATE EHCA_BMASK_IBM(12,12)
171#define MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP EHCA_BMASK_IBM(13,13)
172#define MQPCB_MASK_DEST_QP_NR EHCA_BMASK_IBM(14,14)
173#define MQPCB_MASK_MIN_RNR_NAK_TIMER_FIELD EHCA_BMASK_IBM(15,15)
174#define MQPCB_MASK_SERVICE_LEVEL EHCA_BMASK_IBM(16,16)
175#define MQPCB_MASK_SEND_GRH_FLAG EHCA_BMASK_IBM(17,17)
176#define MQPCB_MASK_RETRY_COUNT EHCA_BMASK_IBM(18,18)
177#define MQPCB_MASK_TIMEOUT EHCA_BMASK_IBM(19,19)
178#define MQPCB_MASK_PATH_MTU EHCA_BMASK_IBM(20,20)
179#define MQPCB_PATH_MTU EHCA_BMASK_IBM(24,31)
180#define MQPCB_MASK_MAX_STATIC_RATE EHCA_BMASK_IBM(21,21)
181#define MQPCB_MAX_STATIC_RATE EHCA_BMASK_IBM(24,31)
182#define MQPCB_MASK_DLID EHCA_BMASK_IBM(22,22)
183#define MQPCB_DLID EHCA_BMASK_IBM(16,31)
184#define MQPCB_MASK_RNR_RETRY_COUNT EHCA_BMASK_IBM(23,23)
185#define MQPCB_RNR_RETRY_COUNT EHCA_BMASK_IBM(29,31)
186#define MQPCB_MASK_SOURCE_PATH_BITS EHCA_BMASK_IBM(24,24)
187#define MQPCB_SOURCE_PATH_BITS EHCA_BMASK_IBM(25,31)
188#define MQPCB_MASK_TRAFFIC_CLASS EHCA_BMASK_IBM(25,25)
189#define MQPCB_TRAFFIC_CLASS EHCA_BMASK_IBM(24,31)
190#define MQPCB_MASK_HOP_LIMIT EHCA_BMASK_IBM(26,26)
191#define MQPCB_HOP_LIMIT EHCA_BMASK_IBM(24,31)
192#define MQPCB_MASK_SOURCE_GID_IDX EHCA_BMASK_IBM(27,27)
193#define MQPCB_SOURCE_GID_IDX EHCA_BMASK_IBM(24,31)
194#define MQPCB_MASK_FLOW_LABEL EHCA_BMASK_IBM(28,28)
195#define MQPCB_FLOW_LABEL EHCA_BMASK_IBM(12,31)
196#define MQPCB_MASK_DEST_GID EHCA_BMASK_IBM(30,30)
197#define MQPCB_MASK_SERVICE_LEVEL_AL EHCA_BMASK_IBM(31,31)
198#define MQPCB_SERVICE_LEVEL_AL EHCA_BMASK_IBM(28,31)
199#define MQPCB_MASK_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(32,32)
200#define MQPCB_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(31,31)
201#define MQPCB_MASK_RETRY_COUNT_AL EHCA_BMASK_IBM(33,33)
202#define MQPCB_RETRY_COUNT_AL EHCA_BMASK_IBM(29,31)
203#define MQPCB_MASK_TIMEOUT_AL EHCA_BMASK_IBM(34,34)
204#define MQPCB_TIMEOUT_AL EHCA_BMASK_IBM(27,31)
205#define MQPCB_MASK_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(35,35)
206#define MQPCB_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(24,31)
207#define MQPCB_MASK_DLID_AL EHCA_BMASK_IBM(36,36)
208#define MQPCB_DLID_AL EHCA_BMASK_IBM(16,31)
209#define MQPCB_MASK_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(37,37)
210#define MQPCB_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(29,31)
211#define MQPCB_MASK_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(38,38)
212#define MQPCB_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(25,31)
213#define MQPCB_MASK_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(39,39)
214#define MQPCB_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(24,31)
215#define MQPCB_MASK_HOP_LIMIT_AL EHCA_BMASK_IBM(40,40)
216#define MQPCB_HOP_LIMIT_AL EHCA_BMASK_IBM(24,31)
217#define MQPCB_MASK_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(41,41)
218#define MQPCB_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(24,31)
219#define MQPCB_MASK_FLOW_LABEL_AL EHCA_BMASK_IBM(42,42)
220#define MQPCB_FLOW_LABEL_AL EHCA_BMASK_IBM(12,31)
221#define MQPCB_MASK_DEST_GID_AL EHCA_BMASK_IBM(44,44)
222#define MQPCB_MASK_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(45,45)
223#define MQPCB_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(16,31)
224#define MQPCB_MASK_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(46,46)
225#define MQPCB_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(16,31)
226#define MQPCB_MASK_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(47,47)
227#define MQPCB_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(31,31)
228#define MQPCB_QP_NUMBER EHCA_BMASK_IBM(8,31)
229#define MQPCB_MASK_QP_ENABLE EHCA_BMASK_IBM(48,48)
230#define MQPCB_QP_ENABLE EHCA_BMASK_IBM(31,31)
231#define MQPCB_MASK_CURR_SQR_LIMIT EHCA_BMASK_IBM(49,49)
232#define MQPCB_CURR_SQR_LIMIT EHCA_BMASK_IBM(15,31)
233#define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG EHCA_BMASK_IBM(50,50)
234#define MQPCB_MASK_SHARED_RQ_HNDL EHCA_BMASK_IBM(51,51)
235
236#endif /* __EHCA_CLASSES_PSERIES_H__ */
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
new file mode 100644
index 000000000000..458fe19648a1
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -0,0 +1,427 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Completion queue handling
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Khadija Souissi <souissi@de.ibm.com>
8 * Reinhard Ernst <rernst@de.ibm.com>
9 * Heiko J Schick <schickhj@de.ibm.com>
10 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
11 *
12 *
13 * Copyright (c) 2005 IBM Corporation
14 *
15 * All rights reserved.
16 *
17 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
18 * BSD.
19 *
20 * OpenIB BSD License
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 *
25 * Redistributions of source code must retain the above copyright notice, this
26 * list of conditions and the following disclaimer.
27 *
28 * Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials
31 * provided with the distribution.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
37 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
40 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
41 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGE.
44 */
45
46#include <asm/current.h>
47
48#include "ehca_iverbs.h"
49#include "ehca_classes.h"
50#include "ehca_irq.h"
51#include "hcp_if.h"
52
53static struct kmem_cache *cq_cache;
54
55int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp)
56{
57 unsigned int qp_num = qp->real_qp_num;
58 unsigned int key = qp_num & (QP_HASHTAB_LEN-1);
59 unsigned long spl_flags;
60
61 spin_lock_irqsave(&cq->spinlock, spl_flags);
62 hlist_add_head(&qp->list_entries, &cq->qp_hashtab[key]);
63 spin_unlock_irqrestore(&cq->spinlock, spl_flags);
64
65 ehca_dbg(cq->ib_cq.device, "cq_num=%x real_qp_num=%x",
66 cq->cq_number, qp_num);
67
68 return 0;
69}
70
71int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
72{
73 int ret = -EINVAL;
74 unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
75 struct hlist_node *iter;
76 struct ehca_qp *qp;
77 unsigned long spl_flags;
78
79 spin_lock_irqsave(&cq->spinlock, spl_flags);
80 hlist_for_each(iter, &cq->qp_hashtab[key]) {
81 qp = hlist_entry(iter, struct ehca_qp, list_entries);
82 if (qp->real_qp_num == real_qp_num) {
83 hlist_del(iter);
84 ehca_dbg(cq->ib_cq.device,
85 "removed qp from cq .cq_num=%x real_qp_num=%x",
86 cq->cq_number, real_qp_num);
87 ret = 0;
88 break;
89 }
90 }
91 spin_unlock_irqrestore(&cq->spinlock, spl_flags);
92 if (ret)
93 ehca_err(cq->ib_cq.device,
94 "qp not found cq_num=%x real_qp_num=%x",
95 cq->cq_number, real_qp_num);
96
97 return ret;
98}
99
100struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num)
101{
102 struct ehca_qp *ret = NULL;
103 unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
104 struct hlist_node *iter;
105 struct ehca_qp *qp;
106 hlist_for_each(iter, &cq->qp_hashtab[key]) {
107 qp = hlist_entry(iter, struct ehca_qp, list_entries);
108 if (qp->real_qp_num == real_qp_num) {
109 ret = qp;
110 break;
111 }
112 }
113 return ret;
114}
115
116struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
117 struct ib_ucontext *context,
118 struct ib_udata *udata)
119{
120 static const u32 additional_cqe = 20;
121 struct ib_cq *cq;
122 struct ehca_cq *my_cq;
123 struct ehca_shca *shca =
124 container_of(device, struct ehca_shca, ib_device);
125 struct ipz_adapter_handle adapter_handle;
126 struct ehca_alloc_cq_parms param; /* h_call's out parameters */
127 struct h_galpa gal;
128 void *vpage;
129 u32 counter;
130 u64 rpage, cqx_fec, h_ret;
131 int ipz_rc, ret, i;
132 unsigned long flags;
133
134 if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
135 return ERR_PTR(-EINVAL);
136
137 my_cq = kmem_cache_alloc(cq_cache, SLAB_KERNEL);
138 if (!my_cq) {
139 ehca_err(device, "Out of memory for ehca_cq struct device=%p",
140 device);
141 return ERR_PTR(-ENOMEM);
142 }
143
144 memset(my_cq, 0, sizeof(struct ehca_cq));
145 memset(&param, 0, sizeof(struct ehca_alloc_cq_parms));
146
147 spin_lock_init(&my_cq->spinlock);
148 spin_lock_init(&my_cq->cb_lock);
149 spin_lock_init(&my_cq->task_lock);
150 my_cq->ownpid = current->tgid;
151
152 cq = &my_cq->ib_cq;
153
154 adapter_handle = shca->ipz_hca_handle;
155 param.eq_handle = shca->eq.ipz_eq_handle;
156
157 do {
158 if (!idr_pre_get(&ehca_cq_idr, GFP_KERNEL)) {
159 cq = ERR_PTR(-ENOMEM);
160 ehca_err(device, "Can't reserve idr nr. device=%p",
161 device);
162 goto create_cq_exit1;
163 }
164
165 spin_lock_irqsave(&ehca_cq_idr_lock, flags);
166 ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token);
167 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
168
169 } while (ret == -EAGAIN);
170
171 if (ret) {
172 cq = ERR_PTR(-ENOMEM);
173 ehca_err(device, "Can't allocate new idr entry. device=%p",
174 device);
175 goto create_cq_exit1;
176 }
177
178 /*
179 * CQs maximum depth is 4GB-64, but we need additional 20 as buffer
180 * for receiving errors CQEs.
181 */
182 param.nr_cqe = cqe + additional_cqe;
183 h_ret = hipz_h_alloc_resource_cq(adapter_handle, my_cq, &param);
184
185 if (h_ret != H_SUCCESS) {
186 ehca_err(device, "hipz_h_alloc_resource_cq() failed "
187 "h_ret=%lx device=%p", h_ret, device);
188 cq = ERR_PTR(ehca2ib_return_code(h_ret));
189 goto create_cq_exit2;
190 }
191
192 ipz_rc = ipz_queue_ctor(&my_cq->ipz_queue, param.act_pages,
193 EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0);
194 if (!ipz_rc) {
195 ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%x device=%p",
196 ipz_rc, device);
197 cq = ERR_PTR(-EINVAL);
198 goto create_cq_exit3;
199 }
200
201 for (counter = 0; counter < param.act_pages; counter++) {
202 vpage = ipz_qpageit_get_inc(&my_cq->ipz_queue);
203 if (!vpage) {
204 ehca_err(device, "ipz_qpageit_get_inc() "
205 "returns NULL device=%p", device);
206 cq = ERR_PTR(-EAGAIN);
207 goto create_cq_exit4;
208 }
209 rpage = virt_to_abs(vpage);
210
211 h_ret = hipz_h_register_rpage_cq(adapter_handle,
212 my_cq->ipz_cq_handle,
213 &my_cq->pf,
214 0,
215 0,
216 rpage,
217 1,
218 my_cq->galpas.
219 kernel);
220
221 if (h_ret < H_SUCCESS) {
222 ehca_err(device, "hipz_h_register_rpage_cq() failed "
223 "ehca_cq=%p cq_num=%x h_ret=%lx counter=%i "
224 "act_pages=%i", my_cq, my_cq->cq_number,
225 h_ret, counter, param.act_pages);
226 cq = ERR_PTR(-EINVAL);
227 goto create_cq_exit4;
228 }
229
230 if (counter == (param.act_pages - 1)) {
231 vpage = ipz_qpageit_get_inc(&my_cq->ipz_queue);
232 if ((h_ret != H_SUCCESS) || vpage) {
233 ehca_err(device, "Registration of pages not "
234 "complete ehca_cq=%p cq_num=%x "
235 "h_ret=%lx", my_cq, my_cq->cq_number,
236 h_ret);
237 cq = ERR_PTR(-EAGAIN);
238 goto create_cq_exit4;
239 }
240 } else {
241 if (h_ret != H_PAGE_REGISTERED) {
242 ehca_err(device, "Registration of page failed "
243 "ehca_cq=%p cq_num=%x h_ret=%lx"
244 "counter=%i act_pages=%i",
245 my_cq, my_cq->cq_number,
246 h_ret, counter, param.act_pages);
247 cq = ERR_PTR(-ENOMEM);
248 goto create_cq_exit4;
249 }
250 }
251 }
252
253 ipz_qeit_reset(&my_cq->ipz_queue);
254
255 gal = my_cq->galpas.kernel;
256 cqx_fec = hipz_galpa_load(gal, CQTEMM_OFFSET(cqx_fec));
257 ehca_dbg(device, "ehca_cq=%p cq_num=%x CQX_FEC=%lx",
258 my_cq, my_cq->cq_number, cqx_fec);
259
260 my_cq->ib_cq.cqe = my_cq->nr_of_entries =
261 param.act_nr_of_entries - additional_cqe;
262 my_cq->cq_number = (my_cq->ipz_cq_handle.handle) & 0xffff;
263
264 for (i = 0; i < QP_HASHTAB_LEN; i++)
265 INIT_HLIST_HEAD(&my_cq->qp_hashtab[i]);
266
267 if (context) {
268 struct ipz_queue *ipz_queue = &my_cq->ipz_queue;
269 struct ehca_create_cq_resp resp;
270 struct vm_area_struct *vma;
271 memset(&resp, 0, sizeof(resp));
272 resp.cq_number = my_cq->cq_number;
273 resp.token = my_cq->token;
274 resp.ipz_queue.qe_size = ipz_queue->qe_size;
275 resp.ipz_queue.act_nr_of_sg = ipz_queue->act_nr_of_sg;
276 resp.ipz_queue.queue_length = ipz_queue->queue_length;
277 resp.ipz_queue.pagesize = ipz_queue->pagesize;
278 resp.ipz_queue.toggle_state = ipz_queue->toggle_state;
279 ret = ehca_mmap_nopage(((u64)(my_cq->token) << 32) | 0x12000000,
280 ipz_queue->queue_length,
281 (void**)&resp.ipz_queue.queue,
282 &vma);
283 if (ret) {
284 ehca_err(device, "Could not mmap queue pages");
285 cq = ERR_PTR(ret);
286 goto create_cq_exit4;
287 }
288 my_cq->uspace_queue = resp.ipz_queue.queue;
289 resp.galpas = my_cq->galpas;
290 ret = ehca_mmap_register(my_cq->galpas.user.fw_handle,
291 (void**)&resp.galpas.kernel.fw_handle,
292 &vma);
293 if (ret) {
294 ehca_err(device, "Could not mmap fw_handle");
295 cq = ERR_PTR(ret);
296 goto create_cq_exit5;
297 }
298 my_cq->uspace_fwh = (u64)resp.galpas.kernel.fw_handle;
299 if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
300 ehca_err(device, "Copy to udata failed.");
301 goto create_cq_exit6;
302 }
303 }
304
305 return cq;
306
307create_cq_exit6:
308 ehca_munmap(my_cq->uspace_fwh, EHCA_PAGESIZE);
309
310create_cq_exit5:
311 ehca_munmap(my_cq->uspace_queue, my_cq->ipz_queue.queue_length);
312
313create_cq_exit4:
314 ipz_queue_dtor(&my_cq->ipz_queue);
315
316create_cq_exit3:
317 h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1);
318 if (h_ret != H_SUCCESS)
319 ehca_err(device, "hipz_h_destroy_cq() failed ehca_cq=%p "
320 "cq_num=%x h_ret=%lx", my_cq, my_cq->cq_number, h_ret);
321
322create_cq_exit2:
323 spin_lock_irqsave(&ehca_cq_idr_lock, flags);
324 idr_remove(&ehca_cq_idr, my_cq->token);
325 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
326
327create_cq_exit1:
328 kmem_cache_free(cq_cache, my_cq);
329
330 return cq;
331}
332
333int ehca_destroy_cq(struct ib_cq *cq)
334{
335 u64 h_ret;
336 int ret;
337 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
338 int cq_num = my_cq->cq_number;
339 struct ib_device *device = cq->device;
340 struct ehca_shca *shca = container_of(device, struct ehca_shca,
341 ib_device);
342 struct ipz_adapter_handle adapter_handle = shca->ipz_hca_handle;
343 u32 cur_pid = current->tgid;
344 unsigned long flags;
345
346 spin_lock_irqsave(&ehca_cq_idr_lock, flags);
347 while (my_cq->nr_callbacks)
348 yield();
349
350 idr_remove(&ehca_cq_idr, my_cq->token);
351 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
352
353 if (my_cq->uspace_queue && my_cq->ownpid != cur_pid) {
354 ehca_err(device, "Invalid caller pid=%x ownpid=%x",
355 cur_pid, my_cq->ownpid);
356 return -EINVAL;
357 }
358
359 /* un-mmap if vma alloc */
360 if (my_cq->uspace_queue ) {
361 ret = ehca_munmap(my_cq->uspace_queue,
362 my_cq->ipz_queue.queue_length);
363 if (ret)
364 ehca_err(device, "Could not munmap queue ehca_cq=%p "
365 "cq_num=%x", my_cq, cq_num);
366 ret = ehca_munmap(my_cq->uspace_fwh, EHCA_PAGESIZE);
367 if (ret)
368 ehca_err(device, "Could not munmap fwh ehca_cq=%p "
369 "cq_num=%x", my_cq, cq_num);
370 }
371
372 h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0);
373 if (h_ret == H_R_STATE) {
374 /* cq in err: read err data and destroy it forcibly */
375 ehca_dbg(device, "ehca_cq=%p cq_num=%x ressource=%lx in err "
376 "state. Try to delete it forcibly.",
377 my_cq, cq_num, my_cq->ipz_cq_handle.handle);
378 ehca_error_data(shca, my_cq, my_cq->ipz_cq_handle.handle);
379 h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1);
380 if (h_ret == H_SUCCESS)
381 ehca_dbg(device, "cq_num=%x deleted successfully.",
382 cq_num);
383 }
384 if (h_ret != H_SUCCESS) {
385 ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%lx "
386 "ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num);
387 return ehca2ib_return_code(h_ret);
388 }
389 ipz_queue_dtor(&my_cq->ipz_queue);
390 kmem_cache_free(cq_cache, my_cq);
391
392 return 0;
393}
394
395int ehca_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata)
396{
397 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
398 u32 cur_pid = current->tgid;
399
400 if (my_cq->uspace_queue && my_cq->ownpid != cur_pid) {
401 ehca_err(cq->device, "Invalid caller pid=%x ownpid=%x",
402 cur_pid, my_cq->ownpid);
403 return -EINVAL;
404 }
405
406 /* TODO: proper resize needs to be done */
407 ehca_err(cq->device, "not implemented yet");
408
409 return -EFAULT;
410}
411
412int ehca_init_cq_cache(void)
413{
414 cq_cache = kmem_cache_create("ehca_cache_cq",
415 sizeof(struct ehca_cq), 0,
416 SLAB_HWCACHE_ALIGN,
417 NULL, NULL);
418 if (!cq_cache)
419 return -ENOMEM;
420 return 0;
421}
422
423void ehca_cleanup_cq_cache(void)
424{
425 if (cq_cache)
426 kmem_cache_destroy(cq_cache);
427}
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
new file mode 100644
index 000000000000..5281dec66f12
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -0,0 +1,185 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Event queue handling
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Khadija Souissi <souissi@de.ibm.com>
8 * Reinhard Ernst <rernst@de.ibm.com>
9 * Heiko J Schick <schickhj@de.ibm.com>
10 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
11 *
12 *
13 * Copyright (c) 2005 IBM Corporation
14 *
15 * All rights reserved.
16 *
17 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
18 * BSD.
19 *
20 * OpenIB BSD License
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 *
25 * Redistributions of source code must retain the above copyright notice, this
26 * list of conditions and the following disclaimer.
27 *
28 * Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials
31 * provided with the distribution.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
37 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
40 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
41 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGE.
44 */
45
46#include "ehca_classes.h"
47#include "ehca_irq.h"
48#include "ehca_iverbs.h"
49#include "ehca_qes.h"
50#include "hcp_if.h"
51#include "ipz_pt_fn.h"
52
53int ehca_create_eq(struct ehca_shca *shca,
54 struct ehca_eq *eq,
55 const enum ehca_eq_type type, const u32 length)
56{
57 u64 ret;
58 u32 nr_pages;
59 u32 i;
60 void *vpage;
61 struct ib_device *ib_dev = &shca->ib_device;
62
63 spin_lock_init(&eq->spinlock);
64 eq->is_initialized = 0;
65
66 if (type != EHCA_EQ && type != EHCA_NEQ) {
67 ehca_err(ib_dev, "Invalid EQ type %x. eq=%p", type, eq);
68 return -EINVAL;
69 }
70 if (!length) {
71 ehca_err(ib_dev, "EQ length must not be zero. eq=%p", eq);
72 return -EINVAL;
73 }
74
75 ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle,
76 &eq->pf,
77 type,
78 length,
79 &eq->ipz_eq_handle,
80 &eq->length,
81 &nr_pages, &eq->ist);
82
83 if (ret != H_SUCCESS) {
84 ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq);
85 return -EINVAL;
86 }
87
88 ret = ipz_queue_ctor(&eq->ipz_queue, nr_pages,
89 EHCA_PAGESIZE, sizeof(struct ehca_eqe), 0);
90 if (!ret) {
91 ehca_err(ib_dev, "Can't allocate EQ pages eq=%p", eq);
92 goto create_eq_exit1;
93 }
94
95 for (i = 0; i < nr_pages; i++) {
96 u64 rpage;
97
98 if (!(vpage = ipz_qpageit_get_inc(&eq->ipz_queue))) {
99 ret = H_RESOURCE;
100 goto create_eq_exit2;
101 }
102
103 rpage = virt_to_abs(vpage);
104 ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle,
105 eq->ipz_eq_handle,
106 &eq->pf,
107 0, 0, rpage, 1);
108
109 if (i == (nr_pages - 1)) {
110 /* last page */
111 vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
112 if (ret != H_SUCCESS || vpage)
113 goto create_eq_exit2;
114 } else {
115 if (ret != H_PAGE_REGISTERED || !vpage)
116 goto create_eq_exit2;
117 }
118 }
119
120 ipz_qeit_reset(&eq->ipz_queue);
121
122 /* register interrupt handlers and initialize work queues */
123 if (type == EHCA_EQ) {
124 ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_eq,
125 SA_INTERRUPT, "ehca_eq",
126 (void *)shca);
127 if (ret < 0)
128 ehca_err(ib_dev, "Can't map interrupt handler.");
129
130 tasklet_init(&eq->interrupt_task, ehca_tasklet_eq, (long)shca);
131 } else if (type == EHCA_NEQ) {
132 ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_neq,
133 SA_INTERRUPT, "ehca_neq",
134 (void *)shca);
135 if (ret < 0)
136 ehca_err(ib_dev, "Can't map interrupt handler.");
137
138 tasklet_init(&eq->interrupt_task, ehca_tasklet_neq, (long)shca);
139 }
140
141 eq->is_initialized = 1;
142
143 return 0;
144
145create_eq_exit2:
146 ipz_queue_dtor(&eq->ipz_queue);
147
148create_eq_exit1:
149 hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
150
151 return -EINVAL;
152}
153
154void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq)
155{
156 unsigned long flags;
157 void *eqe;
158
159 spin_lock_irqsave(&eq->spinlock, flags);
160 eqe = ipz_eqit_eq_get_inc_valid(&eq->ipz_queue);
161 spin_unlock_irqrestore(&eq->spinlock, flags);
162
163 return eqe;
164}
165
166int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq)
167{
168 unsigned long flags;
169 u64 h_ret;
170
171 spin_lock_irqsave(&eq->spinlock, flags);
172 ibmebus_free_irq(NULL, eq->ist, (void *)shca);
173
174 h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
175
176 spin_unlock_irqrestore(&eq->spinlock, flags);
177
178 if (h_ret != H_SUCCESS) {
179 ehca_err(&shca->ib_device, "Can't free EQ resources.");
180 return -EINVAL;
181 }
182 ipz_queue_dtor(&eq->ipz_queue);
183
184 return 0;
185}
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
new file mode 100644
index 000000000000..5eae6ac48425
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -0,0 +1,241 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * HCA query functions
5 *
6 * Authors: Heiko J Schick <schickhj@de.ibm.com>
7 * Christoph Raisch <raisch@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#include "ehca_tools.h"
43#include "hcp_if.h"
44
45int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
46{
47 int ret = 0;
48 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
49 ib_device);
50 struct hipz_query_hca *rblock;
51
52 rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
53 if (!rblock) {
54 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
55 return -ENOMEM;
56 }
57
58 if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) {
59 ehca_err(&shca->ib_device, "Can't query device properties");
60 ret = -EINVAL;
61 goto query_device1;
62 }
63
64 memset(props, 0, sizeof(struct ib_device_attr));
65 props->fw_ver = rblock->hw_ver;
66 props->max_mr_size = rblock->max_mr_size;
67 props->vendor_id = rblock->vendor_id >> 8;
68 props->vendor_part_id = rblock->vendor_part_id >> 16;
69 props->hw_ver = rblock->hw_ver;
70 props->max_qp = min_t(int, rblock->max_qp, INT_MAX);
71 props->max_qp_wr = min_t(int, rblock->max_wqes_wq, INT_MAX);
72 props->max_sge = min_t(int, rblock->max_sge, INT_MAX);
73 props->max_sge_rd = min_t(int, rblock->max_sge_rd, INT_MAX);
74 props->max_cq = min_t(int, rblock->max_cq, INT_MAX);
75 props->max_cqe = min_t(int, rblock->max_cqe, INT_MAX);
76 props->max_mr = min_t(int, rblock->max_mr, INT_MAX);
77 props->max_mw = min_t(int, rblock->max_mw, INT_MAX);
78 props->max_pd = min_t(int, rblock->max_pd, INT_MAX);
79 props->max_ah = min_t(int, rblock->max_ah, INT_MAX);
80 props->max_fmr = min_t(int, rblock->max_mr, INT_MAX);
81 props->max_srq = 0;
82 props->max_srq_wr = 0;
83 props->max_srq_sge = 0;
84 props->max_pkeys = 16;
85 props->local_ca_ack_delay
86 = rblock->local_ca_ack_delay;
87 props->max_raw_ipv6_qp
88 = min_t(int, rblock->max_raw_ipv6_qp, INT_MAX);
89 props->max_raw_ethy_qp
90 = min_t(int, rblock->max_raw_ethy_qp, INT_MAX);
91 props->max_mcast_grp
92 = min_t(int, rblock->max_mcast_grp, INT_MAX);
93 props->max_mcast_qp_attach
94 = min_t(int, rblock->max_mcast_qp_attach, INT_MAX);
95 props->max_total_mcast_qp_attach
96 = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
97
98query_device1:
99 kfree(rblock);
100
101 return ret;
102}
103
104int ehca_query_port(struct ib_device *ibdev,
105 u8 port, struct ib_port_attr *props)
106{
107 int ret = 0;
108 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
109 ib_device);
110 struct hipz_query_port *rblock;
111
112 rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
113 if (!rblock) {
114 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
115 return -ENOMEM;
116 }
117
118 if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
119 ehca_err(&shca->ib_device, "Can't query port properties");
120 ret = -EINVAL;
121 goto query_port1;
122 }
123
124 memset(props, 0, sizeof(struct ib_port_attr));
125 props->state = rblock->state;
126
127 switch (rblock->max_mtu) {
128 case 0x1:
129 props->active_mtu = props->max_mtu = IB_MTU_256;
130 break;
131 case 0x2:
132 props->active_mtu = props->max_mtu = IB_MTU_512;
133 break;
134 case 0x3:
135 props->active_mtu = props->max_mtu = IB_MTU_1024;
136 break;
137 case 0x4:
138 props->active_mtu = props->max_mtu = IB_MTU_2048;
139 break;
140 case 0x5:
141 props->active_mtu = props->max_mtu = IB_MTU_4096;
142 break;
143 default:
144 ehca_err(&shca->ib_device, "Unknown MTU size: %x.",
145 rblock->max_mtu);
146 break;
147 }
148
149 props->gid_tbl_len = rblock->gid_tbl_len;
150 props->max_msg_sz = rblock->max_msg_sz;
151 props->bad_pkey_cntr = rblock->bad_pkey_cntr;
152 props->qkey_viol_cntr = rblock->qkey_viol_cntr;
153 props->pkey_tbl_len = rblock->pkey_tbl_len;
154 props->lid = rblock->lid;
155 props->sm_lid = rblock->sm_lid;
156 props->lmc = rblock->lmc;
157 props->sm_sl = rblock->sm_sl;
158 props->subnet_timeout = rblock->subnet_timeout;
159 props->init_type_reply = rblock->init_type_reply;
160
161 props->active_width = IB_WIDTH_12X;
162 props->active_speed = 0x1;
163
164query_port1:
165 kfree(rblock);
166
167 return ret;
168}
169
170int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
171{
172 int ret = 0;
173 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device);
174 struct hipz_query_port *rblock;
175
176 if (index > 16) {
177 ehca_err(&shca->ib_device, "Invalid index: %x.", index);
178 return -EINVAL;
179 }
180
181 rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
182 if (!rblock) {
183 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
184 return -ENOMEM;
185 }
186
187 if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
188 ehca_err(&shca->ib_device, "Can't query port properties");
189 ret = -EINVAL;
190 goto query_pkey1;
191 }
192
193 memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16));
194
195query_pkey1:
196 kfree(rblock);
197
198 return ret;
199}
200
201int ehca_query_gid(struct ib_device *ibdev, u8 port,
202 int index, union ib_gid *gid)
203{
204 int ret = 0;
205 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
206 ib_device);
207 struct hipz_query_port *rblock;
208
209 if (index > 255) {
210 ehca_err(&shca->ib_device, "Invalid index: %x.", index);
211 return -EINVAL;
212 }
213
214 rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
215 if (!rblock) {
216 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
217 return -ENOMEM;
218 }
219
220 if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
221 ehca_err(&shca->ib_device, "Can't query port properties");
222 ret = -EINVAL;
223 goto query_gid1;
224 }
225
226 memcpy(&gid->raw[0], &rblock->gid_prefix, sizeof(u64));
227 memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64));
228
229query_gid1:
230 kfree(rblock);
231
232 return ret;
233}
234
235int ehca_modify_port(struct ib_device *ibdev,
236 u8 port, int port_modify_mask,
237 struct ib_port_modify *props)
238{
239 /* Not implemented yet */
240 return -EFAULT;
241}
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
new file mode 100644
index 000000000000..2a65b5be1979
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -0,0 +1,762 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Functions for EQs, NEQs and interrupts
5 *
6 * Authors: Heiko J Schick <schickhj@de.ibm.com>
7 * Khadija Souissi <souissi@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#include "ehca_classes.h"
43#include "ehca_irq.h"
44#include "ehca_iverbs.h"
45#include "ehca_tools.h"
46#include "hcp_if.h"
47#include "hipz_fns.h"
48
49#define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1)
50#define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31)
51#define EQE_EE_IDENTIFIER EHCA_BMASK_IBM(2,7)
52#define EQE_CQ_NUMBER EHCA_BMASK_IBM(8,31)
53#define EQE_QP_NUMBER EHCA_BMASK_IBM(8,31)
54#define EQE_QP_TOKEN EHCA_BMASK_IBM(32,63)
55#define EQE_CQ_TOKEN EHCA_BMASK_IBM(32,63)
56
57#define NEQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1)
58#define NEQE_EVENT_CODE EHCA_BMASK_IBM(2,7)
59#define NEQE_PORT_NUMBER EHCA_BMASK_IBM(8,15)
60#define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16,16)
61
62#define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52,63)
63#define ERROR_DATA_TYPE EHCA_BMASK_IBM(0,7)
64
65#ifdef CONFIG_INFINIBAND_EHCA_SCALING
66
67static void queue_comp_task(struct ehca_cq *__cq);
68
69static struct ehca_comp_pool* pool;
70static struct notifier_block comp_pool_callback_nb;
71
72#endif
73
74static inline void comp_event_callback(struct ehca_cq *cq)
75{
76 if (!cq->ib_cq.comp_handler)
77 return;
78
79 spin_lock(&cq->cb_lock);
80 cq->ib_cq.comp_handler(&cq->ib_cq, cq->ib_cq.cq_context);
81 spin_unlock(&cq->cb_lock);
82
83 return;
84}
85
86static void print_error_data(struct ehca_shca * shca, void* data,
87 u64* rblock, int length)
88{
89 u64 type = EHCA_BMASK_GET(ERROR_DATA_TYPE, rblock[2]);
90 u64 resource = rblock[1];
91
92 switch (type) {
93 case 0x1: /* Queue Pair */
94 {
95 struct ehca_qp *qp = (struct ehca_qp*)data;
96
97 /* only print error data if AER is set */
98 if (rblock[6] == 0)
99 return;
100
101 ehca_err(&shca->ib_device,
102 "QP 0x%x (resource=%lx) has errors.",
103 qp->ib_qp.qp_num, resource);
104 break;
105 }
106 case 0x4: /* Completion Queue */
107 {
108 struct ehca_cq *cq = (struct ehca_cq*)data;
109
110 ehca_err(&shca->ib_device,
111 "CQ 0x%x (resource=%lx) has errors.",
112 cq->cq_number, resource);
113 break;
114 }
115 default:
116 ehca_err(&shca->ib_device,
117 "Unknown errror type: %lx on %s.",
118 type, shca->ib_device.name);
119 break;
120 }
121
122 ehca_err(&shca->ib_device, "Error data is available: %lx.", resource);
123 ehca_err(&shca->ib_device, "EHCA ----- error data begin "
124 "---------------------------------------------------");
125 ehca_dmp(rblock, length, "resource=%lx", resource);
126 ehca_err(&shca->ib_device, "EHCA ----- error data end "
127 "----------------------------------------------------");
128
129 return;
130}
131
132int ehca_error_data(struct ehca_shca *shca, void *data,
133 u64 resource)
134{
135
136 unsigned long ret;
137 u64 *rblock;
138 unsigned long block_count;
139
140 rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
141 if (!rblock) {
142 ehca_err(&shca->ib_device, "Cannot allocate rblock memory.");
143 ret = -ENOMEM;
144 goto error_data1;
145 }
146
147 ret = hipz_h_error_data(shca->ipz_hca_handle,
148 resource,
149 rblock,
150 &block_count);
151
152 if (ret == H_R_STATE) {
153 ehca_err(&shca->ib_device,
154 "No error data is available: %lx.", resource);
155 }
156 else if (ret == H_SUCCESS) {
157 int length;
158
159 length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]);
160
161 if (length > PAGE_SIZE)
162 length = PAGE_SIZE;
163
164 print_error_data(shca, data, rblock, length);
165 }
166 else {
167 ehca_err(&shca->ib_device,
168 "Error data could not be fetched: %lx", resource);
169 }
170
171 kfree(rblock);
172
173error_data1:
174 return ret;
175
176}
177
178static void qp_event_callback(struct ehca_shca *shca,
179 u64 eqe,
180 enum ib_event_type event_type)
181{
182 struct ib_event event;
183 struct ehca_qp *qp;
184 unsigned long flags;
185 u32 token = EHCA_BMASK_GET(EQE_QP_TOKEN, eqe);
186
187 spin_lock_irqsave(&ehca_qp_idr_lock, flags);
188 qp = idr_find(&ehca_qp_idr, token);
189 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
190
191
192 if (!qp)
193 return;
194
195 ehca_error_data(shca, qp, qp->ipz_qp_handle.handle);
196
197 if (!qp->ib_qp.event_handler)
198 return;
199
200 event.device = &shca->ib_device;
201 event.event = event_type;
202 event.element.qp = &qp->ib_qp;
203
204 qp->ib_qp.event_handler(&event, qp->ib_qp.qp_context);
205
206 return;
207}
208
209static void cq_event_callback(struct ehca_shca *shca,
210 u64 eqe)
211{
212 struct ehca_cq *cq;
213 unsigned long flags;
214 u32 token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe);
215
216 spin_lock_irqsave(&ehca_cq_idr_lock, flags);
217 cq = idr_find(&ehca_cq_idr, token);
218 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
219
220 if (!cq)
221 return;
222
223 ehca_error_data(shca, cq, cq->ipz_cq_handle.handle);
224
225 return;
226}
227
228static void parse_identifier(struct ehca_shca *shca, u64 eqe)
229{
230 u8 identifier = EHCA_BMASK_GET(EQE_EE_IDENTIFIER, eqe);
231
232 switch (identifier) {
233 case 0x02: /* path migrated */
234 qp_event_callback(shca, eqe, IB_EVENT_PATH_MIG);
235 break;
236 case 0x03: /* communication established */
237 qp_event_callback(shca, eqe, IB_EVENT_COMM_EST);
238 break;
239 case 0x04: /* send queue drained */
240 qp_event_callback(shca, eqe, IB_EVENT_SQ_DRAINED);
241 break;
242 case 0x05: /* QP error */
243 case 0x06: /* QP error */
244 qp_event_callback(shca, eqe, IB_EVENT_QP_FATAL);
245 break;
246 case 0x07: /* CQ error */
247 case 0x08: /* CQ error */
248 cq_event_callback(shca, eqe);
249 break;
250 case 0x09: /* MRMWPTE error */
251 ehca_err(&shca->ib_device, "MRMWPTE error.");
252 break;
253 case 0x0A: /* port event */
254 ehca_err(&shca->ib_device, "Port event.");
255 break;
256 case 0x0B: /* MR access error */
257 ehca_err(&shca->ib_device, "MR access error.");
258 break;
259 case 0x0C: /* EQ error */
260 ehca_err(&shca->ib_device, "EQ error.");
261 break;
262 case 0x0D: /* P/Q_Key mismatch */
263 ehca_err(&shca->ib_device, "P/Q_Key mismatch.");
264 break;
265 case 0x10: /* sampling complete */
266 ehca_err(&shca->ib_device, "Sampling complete.");
267 break;
268 case 0x11: /* unaffiliated access error */
269 ehca_err(&shca->ib_device, "Unaffiliated access error.");
270 break;
271 case 0x12: /* path migrating error */
272 ehca_err(&shca->ib_device, "Path migration error.");
273 break;
274 case 0x13: /* interface trace stopped */
275 ehca_err(&shca->ib_device, "Interface trace stopped.");
276 break;
277 case 0x14: /* first error capture info available */
278 default:
279 ehca_err(&shca->ib_device, "Unknown identifier: %x on %s.",
280 identifier, shca->ib_device.name);
281 break;
282 }
283
284 return;
285}
286
287static void parse_ec(struct ehca_shca *shca, u64 eqe)
288{
289 struct ib_event event;
290 u8 ec = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe);
291 u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe);
292
293 switch (ec) {
294 case 0x30: /* port availability change */
295 if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) {
296 ehca_info(&shca->ib_device,
297 "port %x is active.", port);
298 event.device = &shca->ib_device;
299 event.event = IB_EVENT_PORT_ACTIVE;
300 event.element.port_num = port;
301 shca->sport[port - 1].port_state = IB_PORT_ACTIVE;
302 ib_dispatch_event(&event);
303 } else {
304 ehca_info(&shca->ib_device,
305 "port %x is inactive.", port);
306 event.device = &shca->ib_device;
307 event.event = IB_EVENT_PORT_ERR;
308 event.element.port_num = port;
309 shca->sport[port - 1].port_state = IB_PORT_DOWN;
310 ib_dispatch_event(&event);
311 }
312 break;
313 case 0x31:
314 /* port configuration change
315 * disruptive change is caused by
316 * LID, PKEY or SM change
317 */
318 ehca_warn(&shca->ib_device,
319 "disruptive port %x configuration change", port);
320
321 ehca_info(&shca->ib_device,
322 "port %x is inactive.", port);
323 event.device = &shca->ib_device;
324 event.event = IB_EVENT_PORT_ERR;
325 event.element.port_num = port;
326 shca->sport[port - 1].port_state = IB_PORT_DOWN;
327 ib_dispatch_event(&event);
328
329 ehca_info(&shca->ib_device,
330 "port %x is active.", port);
331 event.device = &shca->ib_device;
332 event.event = IB_EVENT_PORT_ACTIVE;
333 event.element.port_num = port;
334 shca->sport[port - 1].port_state = IB_PORT_ACTIVE;
335 ib_dispatch_event(&event);
336 break;
337 case 0x32: /* adapter malfunction */
338 ehca_err(&shca->ib_device, "Adapter malfunction.");
339 break;
340 case 0x33: /* trace stopped */
341 ehca_err(&shca->ib_device, "Traced stopped.");
342 break;
343 default:
344 ehca_err(&shca->ib_device, "Unknown event code: %x on %s.",
345 ec, shca->ib_device.name);
346 break;
347 }
348
349 return;
350}
351
352static inline void reset_eq_pending(struct ehca_cq *cq)
353{
354 u64 CQx_EP;
355 struct h_galpa gal = cq->galpas.kernel;
356
357 hipz_galpa_store_cq(gal, cqx_ep, 0x0);
358 CQx_EP = hipz_galpa_load(gal, CQTEMM_OFFSET(cqx_ep));
359
360 return;
361}
362
363irqreturn_t ehca_interrupt_neq(int irq, void *dev_id, struct pt_regs *regs)
364{
365 struct ehca_shca *shca = (struct ehca_shca*)dev_id;
366
367 tasklet_hi_schedule(&shca->neq.interrupt_task);
368
369 return IRQ_HANDLED;
370}
371
372void ehca_tasklet_neq(unsigned long data)
373{
374 struct ehca_shca *shca = (struct ehca_shca*)data;
375 struct ehca_eqe *eqe;
376 u64 ret;
377
378 eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->neq);
379
380 while (eqe) {
381 if (!EHCA_BMASK_GET(NEQE_COMPLETION_EVENT, eqe->entry))
382 parse_ec(shca, eqe->entry);
383
384 eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->neq);
385 }
386
387 ret = hipz_h_reset_event(shca->ipz_hca_handle,
388 shca->neq.ipz_eq_handle, 0xFFFFFFFFFFFFFFFFL);
389
390 if (ret != H_SUCCESS)
391 ehca_err(&shca->ib_device, "Can't clear notification events.");
392
393 return;
394}
395
396irqreturn_t ehca_interrupt_eq(int irq, void *dev_id, struct pt_regs *regs)
397{
398 struct ehca_shca *shca = (struct ehca_shca*)dev_id;
399
400 tasklet_hi_schedule(&shca->eq.interrupt_task);
401
402 return IRQ_HANDLED;
403}
404
405void ehca_tasklet_eq(unsigned long data)
406{
407 struct ehca_shca *shca = (struct ehca_shca*)data;
408 struct ehca_eqe *eqe;
409 int int_state;
410 int query_cnt = 0;
411
412 do {
413 eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq);
414
415 if ((shca->hw_level >= 2) && eqe)
416 int_state = 1;
417 else
418 int_state = 0;
419
420 while ((int_state == 1) || eqe) {
421 while (eqe) {
422 u64 eqe_value = eqe->entry;
423
424 ehca_dbg(&shca->ib_device,
425 "eqe_value=%lx", eqe_value);
426
427 /* TODO: better structure */
428 if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT,
429 eqe_value)) {
430 unsigned long flags;
431 u32 token;
432 struct ehca_cq *cq;
433
434 ehca_dbg(&shca->ib_device,
435 "... completion event");
436 token =
437 EHCA_BMASK_GET(EQE_CQ_TOKEN,
438 eqe_value);
439 spin_lock_irqsave(&ehca_cq_idr_lock,
440 flags);
441 cq = idr_find(&ehca_cq_idr, token);
442
443 if (cq == NULL) {
444 spin_unlock(&ehca_cq_idr_lock);
445 break;
446 }
447
448 reset_eq_pending(cq);
449#ifdef CONFIG_INFINIBAND_EHCA_SCALING
450 queue_comp_task(cq);
451 spin_unlock_irqrestore(&ehca_cq_idr_lock,
452 flags);
453#else
454 spin_unlock_irqrestore(&ehca_cq_idr_lock,
455 flags);
456 comp_event_callback(cq);
457#endif
458 } else {
459 ehca_dbg(&shca->ib_device,
460 "... non completion event");
461 parse_identifier(shca, eqe_value);
462 }
463 eqe =
464 (struct ehca_eqe *)ehca_poll_eq(shca,
465 &shca->eq);
466 }
467
468 if (shca->hw_level >= 2) {
469 int_state =
470 hipz_h_query_int_state(shca->ipz_hca_handle,
471 shca->eq.ist);
472 query_cnt++;
473 iosync();
474 if (query_cnt >= 100) {
475 query_cnt = 0;
476 int_state = 0;
477 }
478 }
479 eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq);
480
481 }
482 } while (int_state != 0);
483
484 return;
485}
486
487#ifdef CONFIG_INFINIBAND_EHCA_SCALING
488
489static inline int find_next_online_cpu(struct ehca_comp_pool* pool)
490{
491 unsigned long flags_last_cpu;
492
493 if (ehca_debug_level)
494 ehca_dmp(&cpu_online_map, sizeof(cpumask_t), "");
495
496 spin_lock_irqsave(&pool->last_cpu_lock, flags_last_cpu);
497 pool->last_cpu = next_cpu(pool->last_cpu, cpu_online_map);
498 if (pool->last_cpu == NR_CPUS)
499 pool->last_cpu = first_cpu(cpu_online_map);
500 spin_unlock_irqrestore(&pool->last_cpu_lock, flags_last_cpu);
501
502 return pool->last_cpu;
503}
504
505static void __queue_comp_task(struct ehca_cq *__cq,
506 struct ehca_cpu_comp_task *cct)
507{
508 unsigned long flags_cct;
509 unsigned long flags_cq;
510
511 spin_lock_irqsave(&cct->task_lock, flags_cct);
512 spin_lock_irqsave(&__cq->task_lock, flags_cq);
513
514 if (__cq->nr_callbacks == 0) {
515 __cq->nr_callbacks++;
516 list_add_tail(&__cq->entry, &cct->cq_list);
517 cct->cq_jobs++;
518 wake_up(&cct->wait_queue);
519 }
520 else
521 __cq->nr_callbacks++;
522
523 spin_unlock_irqrestore(&__cq->task_lock, flags_cq);
524 spin_unlock_irqrestore(&cct->task_lock, flags_cct);
525}
526
527static void queue_comp_task(struct ehca_cq *__cq)
528{
529 int cpu;
530 int cpu_id;
531 struct ehca_cpu_comp_task *cct;
532
533 cpu = get_cpu();
534 cpu_id = find_next_online_cpu(pool);
535
536 BUG_ON(!cpu_online(cpu_id));
537
538 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
539
540 if (cct->cq_jobs > 0) {
541 cpu_id = find_next_online_cpu(pool);
542 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
543 }
544
545 __queue_comp_task(__cq, cct);
546
547 put_cpu();
548
549 return;
550}
551
552static void run_comp_task(struct ehca_cpu_comp_task* cct)
553{
554 struct ehca_cq *cq;
555 unsigned long flags_cct;
556 unsigned long flags_cq;
557
558 spin_lock_irqsave(&cct->task_lock, flags_cct);
559
560 while (!list_empty(&cct->cq_list)) {
561 cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
562 spin_unlock_irqrestore(&cct->task_lock, flags_cct);
563 comp_event_callback(cq);
564 spin_lock_irqsave(&cct->task_lock, flags_cct);
565
566 spin_lock_irqsave(&cq->task_lock, flags_cq);
567 cq->nr_callbacks--;
568 if (cq->nr_callbacks == 0) {
569 list_del_init(cct->cq_list.next);
570 cct->cq_jobs--;
571 }
572 spin_unlock_irqrestore(&cq->task_lock, flags_cq);
573
574 }
575
576 spin_unlock_irqrestore(&cct->task_lock, flags_cct);
577
578 return;
579}
580
581static int comp_task(void *__cct)
582{
583 struct ehca_cpu_comp_task* cct = __cct;
584 DECLARE_WAITQUEUE(wait, current);
585
586 set_current_state(TASK_INTERRUPTIBLE);
587 while(!kthread_should_stop()) {
588 add_wait_queue(&cct->wait_queue, &wait);
589
590 if (list_empty(&cct->cq_list))
591 schedule();
592 else
593 __set_current_state(TASK_RUNNING);
594
595 remove_wait_queue(&cct->wait_queue, &wait);
596
597 if (!list_empty(&cct->cq_list))
598 run_comp_task(__cct);
599
600 set_current_state(TASK_INTERRUPTIBLE);
601 }
602 __set_current_state(TASK_RUNNING);
603
604 return 0;
605}
606
607static struct task_struct *create_comp_task(struct ehca_comp_pool *pool,
608 int cpu)
609{
610 struct ehca_cpu_comp_task *cct;
611
612 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu);
613 spin_lock_init(&cct->task_lock);
614 INIT_LIST_HEAD(&cct->cq_list);
615 init_waitqueue_head(&cct->wait_queue);
616 cct->task = kthread_create(comp_task, cct, "ehca_comp/%d", cpu);
617
618 return cct->task;
619}
620
621static void destroy_comp_task(struct ehca_comp_pool *pool,
622 int cpu)
623{
624 struct ehca_cpu_comp_task *cct;
625 struct task_struct *task;
626 unsigned long flags_cct;
627
628 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu);
629
630 spin_lock_irqsave(&cct->task_lock, flags_cct);
631
632 task = cct->task;
633 cct->task = NULL;
634 cct->cq_jobs = 0;
635
636 spin_unlock_irqrestore(&cct->task_lock, flags_cct);
637
638 if (task)
639 kthread_stop(task);
640
641 return;
642}
643
644static void take_over_work(struct ehca_comp_pool *pool,
645 int cpu)
646{
647 struct ehca_cpu_comp_task *cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu);
648 LIST_HEAD(list);
649 struct ehca_cq *cq;
650 unsigned long flags_cct;
651
652 spin_lock_irqsave(&cct->task_lock, flags_cct);
653
654 list_splice_init(&cct->cq_list, &list);
655
656 while(!list_empty(&list)) {
657 cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
658
659 list_del(&cq->entry);
660 __queue_comp_task(cq, per_cpu_ptr(pool->cpu_comp_tasks,
661 smp_processor_id()));
662 }
663
664 spin_unlock_irqrestore(&cct->task_lock, flags_cct);
665
666}
667
668static int comp_pool_callback(struct notifier_block *nfb,
669 unsigned long action,
670 void *hcpu)
671{
672 unsigned int cpu = (unsigned long)hcpu;
673 struct ehca_cpu_comp_task *cct;
674
675 switch (action) {
676 case CPU_UP_PREPARE:
677 ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu);
678 if(!create_comp_task(pool, cpu)) {
679 ehca_gen_err("Can't create comp_task for cpu: %x", cpu);
680 return NOTIFY_BAD;
681 }
682 break;
683 case CPU_UP_CANCELED:
684 ehca_gen_dbg("CPU: %x (CPU_CANCELED)", cpu);
685 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu);
686 kthread_bind(cct->task, any_online_cpu(cpu_online_map));
687 destroy_comp_task(pool, cpu);
688 break;
689 case CPU_ONLINE:
690 ehca_gen_dbg("CPU: %x (CPU_ONLINE)", cpu);
691 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu);
692 kthread_bind(cct->task, cpu);
693 wake_up_process(cct->task);
694 break;
695 case CPU_DOWN_PREPARE:
696 ehca_gen_dbg("CPU: %x (CPU_DOWN_PREPARE)", cpu);
697 break;
698 case CPU_DOWN_FAILED:
699 ehca_gen_dbg("CPU: %x (CPU_DOWN_FAILED)", cpu);
700 break;
701 case CPU_DEAD:
702 ehca_gen_dbg("CPU: %x (CPU_DEAD)", cpu);
703 destroy_comp_task(pool, cpu);
704 take_over_work(pool, cpu);
705 break;
706 }
707
708 return NOTIFY_OK;
709}
710
711#endif
712
713int ehca_create_comp_pool(void)
714{
715#ifdef CONFIG_INFINIBAND_EHCA_SCALING
716 int cpu;
717 struct task_struct *task;
718
719 pool = kzalloc(sizeof(struct ehca_comp_pool), GFP_KERNEL);
720 if (pool == NULL)
721 return -ENOMEM;
722
723 spin_lock_init(&pool->last_cpu_lock);
724 pool->last_cpu = any_online_cpu(cpu_online_map);
725
726 pool->cpu_comp_tasks = alloc_percpu(struct ehca_cpu_comp_task);
727 if (pool->cpu_comp_tasks == NULL) {
728 kfree(pool);
729 return -EINVAL;
730 }
731
732 for_each_online_cpu(cpu) {
733 task = create_comp_task(pool, cpu);
734 if (task) {
735 kthread_bind(task, cpu);
736 wake_up_process(task);
737 }
738 }
739
740 comp_pool_callback_nb.notifier_call = comp_pool_callback;
741 comp_pool_callback_nb.priority =0;
742 register_cpu_notifier(&comp_pool_callback_nb);
743#endif
744
745 return 0;
746}
747
748void ehca_destroy_comp_pool(void)
749{
750#ifdef CONFIG_INFINIBAND_EHCA_SCALING
751 int i;
752
753 unregister_cpu_notifier(&comp_pool_callback_nb);
754
755 for (i = 0; i < NR_CPUS; i++) {
756 if (cpu_online(i))
757 destroy_comp_task(pool, i);
758 }
759#endif
760
761 return;
762}
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.h b/drivers/infiniband/hw/ehca/ehca_irq.h
new file mode 100644
index 000000000000..85bf1fe16fe4
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_irq.h
@@ -0,0 +1,77 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Function definitions and structs for EQs, NEQs and interrupts
5 *
6 * Authors: Heiko J Schick <schickhj@de.ibm.com>
7 * Khadija Souissi <souissi@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#ifndef __EHCA_IRQ_H
43#define __EHCA_IRQ_H
44
45
46struct ehca_shca;
47
48#include <linux/interrupt.h>
49#include <linux/types.h>
50#include <asm/atomic.h>
51
52int ehca_error_data(struct ehca_shca *shca, void *data, u64 resource);
53
54irqreturn_t ehca_interrupt_neq(int irq, void *dev_id, struct pt_regs *regs);
55void ehca_tasklet_neq(unsigned long data);
56
57irqreturn_t ehca_interrupt_eq(int irq, void *dev_id, struct pt_regs *regs);
58void ehca_tasklet_eq(unsigned long data);
59
60struct ehca_cpu_comp_task {
61 wait_queue_head_t wait_queue;
62 struct list_head cq_list;
63 struct task_struct *task;
64 spinlock_t task_lock;
65 int cq_jobs;
66};
67
68struct ehca_comp_pool {
69 struct ehca_cpu_comp_task *cpu_comp_tasks;
70 int last_cpu;
71 spinlock_t last_cpu_lock;
72};
73
74int ehca_create_comp_pool(void);
75void ehca_destroy_comp_pool(void);
76
77#endif
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
new file mode 100644
index 000000000000..319c39d47f3a
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -0,0 +1,182 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Function definitions for internal functions
5 *
6 * Authors: Heiko J Schick <schickhj@de.ibm.com>
7 * Dietmar Decker <ddecker@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#ifndef __EHCA_IVERBS_H__
43#define __EHCA_IVERBS_H__
44
45#include "ehca_classes.h"
46
47int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props);
48
49int ehca_query_port(struct ib_device *ibdev, u8 port,
50 struct ib_port_attr *props);
51
52int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 * pkey);
53
54int ehca_query_gid(struct ib_device *ibdev, u8 port, int index,
55 union ib_gid *gid);
56
57int ehca_modify_port(struct ib_device *ibdev, u8 port, int port_modify_mask,
58 struct ib_port_modify *props);
59
60struct ib_pd *ehca_alloc_pd(struct ib_device *device,
61 struct ib_ucontext *context,
62 struct ib_udata *udata);
63
64int ehca_dealloc_pd(struct ib_pd *pd);
65
66struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
67
68int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr);
69
70int ehca_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr);
71
72int ehca_destroy_ah(struct ib_ah *ah);
73
74struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
75
76struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
77 struct ib_phys_buf *phys_buf_array,
78 int num_phys_buf,
79 int mr_access_flags, u64 *iova_start);
80
81struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd,
82 struct ib_umem *region,
83 int mr_access_flags, struct ib_udata *udata);
84
85int ehca_rereg_phys_mr(struct ib_mr *mr,
86 int mr_rereg_mask,
87 struct ib_pd *pd,
88 struct ib_phys_buf *phys_buf_array,
89 int num_phys_buf, int mr_access_flags, u64 *iova_start);
90
91int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr);
92
93int ehca_dereg_mr(struct ib_mr *mr);
94
95struct ib_mw *ehca_alloc_mw(struct ib_pd *pd);
96
97int ehca_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
98 struct ib_mw_bind *mw_bind);
99
100int ehca_dealloc_mw(struct ib_mw *mw);
101
102struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
103 int mr_access_flags,
104 struct ib_fmr_attr *fmr_attr);
105
106int ehca_map_phys_fmr(struct ib_fmr *fmr,
107 u64 *page_list, int list_len, u64 iova);
108
109int ehca_unmap_fmr(struct list_head *fmr_list);
110
111int ehca_dealloc_fmr(struct ib_fmr *fmr);
112
113enum ehca_eq_type {
114 EHCA_EQ = 0, /* Event Queue */
115 EHCA_NEQ /* Notification Event Queue */
116};
117
118int ehca_create_eq(struct ehca_shca *shca, struct ehca_eq *eq,
119 enum ehca_eq_type type, const u32 length);
120
121int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq);
122
123void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq);
124
125
126struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
127 struct ib_ucontext *context,
128 struct ib_udata *udata);
129
130int ehca_destroy_cq(struct ib_cq *cq);
131
132int ehca_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata);
133
134int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc);
135
136int ehca_peek_cq(struct ib_cq *cq, int wc_cnt);
137
138int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify cq_notify);
139
140struct ib_qp *ehca_create_qp(struct ib_pd *pd,
141 struct ib_qp_init_attr *init_attr,
142 struct ib_udata *udata);
143
144int ehca_destroy_qp(struct ib_qp *qp);
145
146int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
147 struct ib_udata *udata);
148
149int ehca_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr,
150 int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr);
151
152int ehca_post_send(struct ib_qp *qp, struct ib_send_wr *send_wr,
153 struct ib_send_wr **bad_send_wr);
154
155int ehca_post_recv(struct ib_qp *qp, struct ib_recv_wr *recv_wr,
156 struct ib_recv_wr **bad_recv_wr);
157
158u64 ehca_define_sqp(struct ehca_shca *shca, struct ehca_qp *ibqp,
159 struct ib_qp_init_attr *qp_init_attr);
160
161int ehca_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid);
162
163int ehca_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid);
164
165struct ib_ucontext *ehca_alloc_ucontext(struct ib_device *device,
166 struct ib_udata *udata);
167
168int ehca_dealloc_ucontext(struct ib_ucontext *context);
169
170int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
171
172void ehca_poll_eqs(unsigned long data);
173
174int ehca_mmap_nopage(u64 foffset,u64 length,void **mapped,
175 struct vm_area_struct **vma);
176
177int ehca_mmap_register(u64 physical,void **mapped,
178 struct vm_area_struct **vma);
179
180int ehca_munmap(unsigned long addr, size_t len);
181
182#endif
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
new file mode 100644
index 000000000000..2380994418a5
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -0,0 +1,818 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * module start stop, hca detection
5 *
6 * Authors: Heiko J Schick <schickhj@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Joachim Fenkes <fenkes@de.ibm.com>
9 *
10 * Copyright (c) 2005 IBM Corporation
11 *
12 * All rights reserved.
13 *
14 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
15 * BSD.
16 *
17 * OpenIB BSD License
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * Redistributions of source code must retain the above copyright notice, this
23 * list of conditions and the following disclaimer.
24 *
25 * Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials
28 * provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42
43#include "ehca_classes.h"
44#include "ehca_iverbs.h"
45#include "ehca_mrmw.h"
46#include "ehca_tools.h"
47#include "hcp_if.h"
48
49MODULE_LICENSE("Dual BSD/GPL");
50MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
51MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
52MODULE_VERSION("SVNEHCA_0016");
53
54int ehca_open_aqp1 = 0;
55int ehca_debug_level = 0;
56int ehca_hw_level = 0;
57int ehca_nr_ports = 2;
58int ehca_use_hp_mr = 0;
59int ehca_port_act_time = 30;
60int ehca_poll_all_eqs = 1;
61int ehca_static_rate = -1;
62
63module_param_named(open_aqp1, ehca_open_aqp1, int, 0);
64module_param_named(debug_level, ehca_debug_level, int, 0);
65module_param_named(hw_level, ehca_hw_level, int, 0);
66module_param_named(nr_ports, ehca_nr_ports, int, 0);
67module_param_named(use_hp_mr, ehca_use_hp_mr, int, 0);
68module_param_named(port_act_time, ehca_port_act_time, int, 0);
69module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0);
70module_param_named(static_rate, ehca_static_rate, int, 0);
71
72MODULE_PARM_DESC(open_aqp1,
73 "AQP1 on startup (0: no (default), 1: yes)");
74MODULE_PARM_DESC(debug_level,
75 "debug level"
76 " (0: no debug traces (default), 1: with debug traces)");
77MODULE_PARM_DESC(hw_level,
78 "hardware level"
79 " (0: autosensing (default), 1: v. 0.20, 2: v. 0.21)");
80MODULE_PARM_DESC(nr_ports,
81 "number of connected ports (default: 2)");
82MODULE_PARM_DESC(use_hp_mr,
83 "high performance MRs (0: no (default), 1: yes)");
84MODULE_PARM_DESC(port_act_time,
85 "time to wait for port activation (default: 30 sec)");
86MODULE_PARM_DESC(poll_all_eqs,
87 "polls all event queues periodically"
88 " (0: no, 1: yes (default))");
89MODULE_PARM_DESC(static_rate,
90 "set permanent static rate (default: disabled)");
91
92spinlock_t ehca_qp_idr_lock;
93spinlock_t ehca_cq_idr_lock;
94DEFINE_IDR(ehca_qp_idr);
95DEFINE_IDR(ehca_cq_idr);
96
97static struct list_head shca_list; /* list of all registered ehcas */
98static spinlock_t shca_list_lock;
99
100static struct timer_list poll_eqs_timer;
101
102static int ehca_create_slab_caches(void)
103{
104 int ret;
105
106 ret = ehca_init_pd_cache();
107 if (ret) {
108 ehca_gen_err("Cannot create PD SLAB cache.");
109 return ret;
110 }
111
112 ret = ehca_init_cq_cache();
113 if (ret) {
114 ehca_gen_err("Cannot create CQ SLAB cache.");
115 goto create_slab_caches2;
116 }
117
118 ret = ehca_init_qp_cache();
119 if (ret) {
120 ehca_gen_err("Cannot create QP SLAB cache.");
121 goto create_slab_caches3;
122 }
123
124 ret = ehca_init_av_cache();
125 if (ret) {
126 ehca_gen_err("Cannot create AV SLAB cache.");
127 goto create_slab_caches4;
128 }
129
130 ret = ehca_init_mrmw_cache();
131 if (ret) {
132 ehca_gen_err("Cannot create MR&MW SLAB cache.");
133 goto create_slab_caches5;
134 }
135
136 return 0;
137
138create_slab_caches5:
139 ehca_cleanup_av_cache();
140
141create_slab_caches4:
142 ehca_cleanup_qp_cache();
143
144create_slab_caches3:
145 ehca_cleanup_cq_cache();
146
147create_slab_caches2:
148 ehca_cleanup_pd_cache();
149
150 return ret;
151}
152
153static void ehca_destroy_slab_caches(void)
154{
155 ehca_cleanup_mrmw_cache();
156 ehca_cleanup_av_cache();
157 ehca_cleanup_qp_cache();
158 ehca_cleanup_cq_cache();
159 ehca_cleanup_pd_cache();
160}
161
162#define EHCA_HCAAVER EHCA_BMASK_IBM(32,39)
163#define EHCA_REVID EHCA_BMASK_IBM(40,63)
164
165int ehca_sense_attributes(struct ehca_shca *shca)
166{
167 int ret = 0;
168 u64 h_ret;
169 struct hipz_query_hca *rblock;
170
171 rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
172 if (!rblock) {
173 ehca_gen_err("Cannot allocate rblock memory.");
174 return -ENOMEM;
175 }
176
177 h_ret = hipz_h_query_hca(shca->ipz_hca_handle, rblock);
178 if (h_ret != H_SUCCESS) {
179 ehca_gen_err("Cannot query device properties. h_ret=%lx",
180 h_ret);
181 ret = -EPERM;
182 goto num_ports1;
183 }
184
185 if (ehca_nr_ports == 1)
186 shca->num_ports = 1;
187 else
188 shca->num_ports = (u8)rblock->num_ports;
189
190 ehca_gen_dbg(" ... found %x ports", rblock->num_ports);
191
192 if (ehca_hw_level == 0) {
193 u32 hcaaver;
194 u32 revid;
195
196 hcaaver = EHCA_BMASK_GET(EHCA_HCAAVER, rblock->hw_ver);
197 revid = EHCA_BMASK_GET(EHCA_REVID, rblock->hw_ver);
198
199 ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid);
200
201 if ((hcaaver == 1) && (revid == 0))
202 shca->hw_level = 0;
203 else if ((hcaaver == 1) && (revid == 1))
204 shca->hw_level = 1;
205 else if ((hcaaver == 1) && (revid == 2))
206 shca->hw_level = 2;
207 }
208 ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
209
210 shca->sport[0].rate = IB_RATE_30_GBPS;
211 shca->sport[1].rate = IB_RATE_30_GBPS;
212
213num_ports1:
214 kfree(rblock);
215 return ret;
216}
217
218static int init_node_guid(struct ehca_shca *shca)
219{
220 int ret = 0;
221 struct hipz_query_hca *rblock;
222
223 rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
224 if (!rblock) {
225 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
226 return -ENOMEM;
227 }
228
229 if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) {
230 ehca_err(&shca->ib_device, "Can't query device properties");
231 ret = -EINVAL;
232 goto init_node_guid1;
233 }
234
235 memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64));
236
237init_node_guid1:
238 kfree(rblock);
239 return ret;
240}
241
242int ehca_register_device(struct ehca_shca *shca)
243{
244 int ret;
245
246 ret = init_node_guid(shca);
247 if (ret)
248 return ret;
249
250 strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX);
251 shca->ib_device.owner = THIS_MODULE;
252
253 shca->ib_device.uverbs_abi_ver = 5;
254 shca->ib_device.uverbs_cmd_mask =
255 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
256 (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
257 (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
258 (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
259 (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
260 (1ull << IB_USER_VERBS_CMD_REG_MR) |
261 (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
262 (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
263 (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
264 (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
265 (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
266 (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
267 (1ull << IB_USER_VERBS_CMD_QUERY_QP) |
268 (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
269 (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) |
270 (1ull << IB_USER_VERBS_CMD_DETACH_MCAST);
271
272 shca->ib_device.node_type = RDMA_NODE_IB_CA;
273 shca->ib_device.phys_port_cnt = shca->num_ports;
274 shca->ib_device.dma_device = &shca->ibmebus_dev->ofdev.dev;
275 shca->ib_device.query_device = ehca_query_device;
276 shca->ib_device.query_port = ehca_query_port;
277 shca->ib_device.query_gid = ehca_query_gid;
278 shca->ib_device.query_pkey = ehca_query_pkey;
279 /* shca->in_device.modify_device = ehca_modify_device */
280 shca->ib_device.modify_port = ehca_modify_port;
281 shca->ib_device.alloc_ucontext = ehca_alloc_ucontext;
282 shca->ib_device.dealloc_ucontext = ehca_dealloc_ucontext;
283 shca->ib_device.alloc_pd = ehca_alloc_pd;
284 shca->ib_device.dealloc_pd = ehca_dealloc_pd;
285 shca->ib_device.create_ah = ehca_create_ah;
286 /* shca->ib_device.modify_ah = ehca_modify_ah; */
287 shca->ib_device.query_ah = ehca_query_ah;
288 shca->ib_device.destroy_ah = ehca_destroy_ah;
289 shca->ib_device.create_qp = ehca_create_qp;
290 shca->ib_device.modify_qp = ehca_modify_qp;
291 shca->ib_device.query_qp = ehca_query_qp;
292 shca->ib_device.destroy_qp = ehca_destroy_qp;
293 shca->ib_device.post_send = ehca_post_send;
294 shca->ib_device.post_recv = ehca_post_recv;
295 shca->ib_device.create_cq = ehca_create_cq;
296 shca->ib_device.destroy_cq = ehca_destroy_cq;
297 shca->ib_device.resize_cq = ehca_resize_cq;
298 shca->ib_device.poll_cq = ehca_poll_cq;
299 /* shca->ib_device.peek_cq = ehca_peek_cq; */
300 shca->ib_device.req_notify_cq = ehca_req_notify_cq;
301 /* shca->ib_device.req_ncomp_notif = ehca_req_ncomp_notif; */
302 shca->ib_device.get_dma_mr = ehca_get_dma_mr;
303 shca->ib_device.reg_phys_mr = ehca_reg_phys_mr;
304 shca->ib_device.reg_user_mr = ehca_reg_user_mr;
305 shca->ib_device.query_mr = ehca_query_mr;
306 shca->ib_device.dereg_mr = ehca_dereg_mr;
307 shca->ib_device.rereg_phys_mr = ehca_rereg_phys_mr;
308 shca->ib_device.alloc_mw = ehca_alloc_mw;
309 shca->ib_device.bind_mw = ehca_bind_mw;
310 shca->ib_device.dealloc_mw = ehca_dealloc_mw;
311 shca->ib_device.alloc_fmr = ehca_alloc_fmr;
312 shca->ib_device.map_phys_fmr = ehca_map_phys_fmr;
313 shca->ib_device.unmap_fmr = ehca_unmap_fmr;
314 shca->ib_device.dealloc_fmr = ehca_dealloc_fmr;
315 shca->ib_device.attach_mcast = ehca_attach_mcast;
316 shca->ib_device.detach_mcast = ehca_detach_mcast;
317 /* shca->ib_device.process_mad = ehca_process_mad; */
318 shca->ib_device.mmap = ehca_mmap;
319
320 ret = ib_register_device(&shca->ib_device);
321 if (ret)
322 ehca_err(&shca->ib_device,
323 "ib_register_device() failed ret=%x", ret);
324
325 return ret;
326}
327
328static int ehca_create_aqp1(struct ehca_shca *shca, u32 port)
329{
330 struct ehca_sport *sport = &shca->sport[port - 1];
331 struct ib_cq *ibcq;
332 struct ib_qp *ibqp;
333 struct ib_qp_init_attr qp_init_attr;
334 int ret;
335
336 if (sport->ibcq_aqp1) {
337 ehca_err(&shca->ib_device, "AQP1 CQ is already created.");
338 return -EPERM;
339 }
340
341 ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10);
342 if (IS_ERR(ibcq)) {
343 ehca_err(&shca->ib_device, "Cannot create AQP1 CQ.");
344 return PTR_ERR(ibcq);
345 }
346 sport->ibcq_aqp1 = ibcq;
347
348 if (sport->ibqp_aqp1) {
349 ehca_err(&shca->ib_device, "AQP1 QP is already created.");
350 ret = -EPERM;
351 goto create_aqp1;
352 }
353
354 memset(&qp_init_attr, 0, sizeof(struct ib_qp_init_attr));
355 qp_init_attr.send_cq = ibcq;
356 qp_init_attr.recv_cq = ibcq;
357 qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR;
358 qp_init_attr.cap.max_send_wr = 100;
359 qp_init_attr.cap.max_recv_wr = 100;
360 qp_init_attr.cap.max_send_sge = 2;
361 qp_init_attr.cap.max_recv_sge = 1;
362 qp_init_attr.qp_type = IB_QPT_GSI;
363 qp_init_attr.port_num = port;
364 qp_init_attr.qp_context = NULL;
365 qp_init_attr.event_handler = NULL;
366 qp_init_attr.srq = NULL;
367
368 ibqp = ib_create_qp(&shca->pd->ib_pd, &qp_init_attr);
369 if (IS_ERR(ibqp)) {
370 ehca_err(&shca->ib_device, "Cannot create AQP1 QP.");
371 ret = PTR_ERR(ibqp);
372 goto create_aqp1;
373 }
374 sport->ibqp_aqp1 = ibqp;
375
376 return 0;
377
378create_aqp1:
379 ib_destroy_cq(sport->ibcq_aqp1);
380 return ret;
381}
382
383static int ehca_destroy_aqp1(struct ehca_sport *sport)
384{
385 int ret;
386
387 ret = ib_destroy_qp(sport->ibqp_aqp1);
388 if (ret) {
389 ehca_gen_err("Cannot destroy AQP1 QP. ret=%x", ret);
390 return ret;
391 }
392
393 ret = ib_destroy_cq(sport->ibcq_aqp1);
394 if (ret)
395 ehca_gen_err("Cannot destroy AQP1 CQ. ret=%x", ret);
396
397 return ret;
398}
399
400static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf)
401{
402 return snprintf(buf, PAGE_SIZE, "%d\n",
403 ehca_debug_level);
404}
405
406static ssize_t ehca_store_debug_level(struct device_driver *ddp,
407 const char *buf, size_t count)
408{
409 int value = (*buf) - '0';
410 if (value >= 0 && value <= 9)
411 ehca_debug_level = value;
412 return 1;
413}
414
415DRIVER_ATTR(debug_level, S_IRUSR | S_IWUSR,
416 ehca_show_debug_level, ehca_store_debug_level);
417
418void ehca_create_driver_sysfs(struct ibmebus_driver *drv)
419{
420 driver_create_file(&drv->driver, &driver_attr_debug_level);
421}
422
423void ehca_remove_driver_sysfs(struct ibmebus_driver *drv)
424{
425 driver_remove_file(&drv->driver, &driver_attr_debug_level);
426}
427
428#define EHCA_RESOURCE_ATTR(name) \
429static ssize_t ehca_show_##name(struct device *dev, \
430 struct device_attribute *attr, \
431 char *buf) \
432{ \
433 struct ehca_shca *shca; \
434 struct hipz_query_hca *rblock; \
435 int data; \
436 \
437 shca = dev->driver_data; \
438 \
439 rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); \
440 if (!rblock) { \
441 dev_err(dev, "Can't allocate rblock memory."); \
442 return 0; \
443 } \
444 \
445 if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \
446 dev_err(dev, "Can't query device properties"); \
447 kfree(rblock); \
448 return 0; \
449 } \
450 \
451 data = rblock->name; \
452 kfree(rblock); \
453 \
454 if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1)) \
455 return snprintf(buf, 256, "1\n"); \
456 else \
457 return snprintf(buf, 256, "%d\n", data); \
458 \
459} \
460static DEVICE_ATTR(name, S_IRUGO, ehca_show_##name, NULL);
461
462EHCA_RESOURCE_ATTR(num_ports);
463EHCA_RESOURCE_ATTR(hw_ver);
464EHCA_RESOURCE_ATTR(max_eq);
465EHCA_RESOURCE_ATTR(cur_eq);
466EHCA_RESOURCE_ATTR(max_cq);
467EHCA_RESOURCE_ATTR(cur_cq);
468EHCA_RESOURCE_ATTR(max_qp);
469EHCA_RESOURCE_ATTR(cur_qp);
470EHCA_RESOURCE_ATTR(max_mr);
471EHCA_RESOURCE_ATTR(cur_mr);
472EHCA_RESOURCE_ATTR(max_mw);
473EHCA_RESOURCE_ATTR(cur_mw);
474EHCA_RESOURCE_ATTR(max_pd);
475EHCA_RESOURCE_ATTR(max_ah);
476
477static ssize_t ehca_show_adapter_handle(struct device *dev,
478 struct device_attribute *attr,
479 char *buf)
480{
481 struct ehca_shca *shca = dev->driver_data;
482
483 return sprintf(buf, "%lx\n", shca->ipz_hca_handle.handle);
484
485}
486static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);
487
488
489void ehca_create_device_sysfs(struct ibmebus_dev *dev)
490{
491 device_create_file(&dev->ofdev.dev, &dev_attr_adapter_handle);
492 device_create_file(&dev->ofdev.dev, &dev_attr_num_ports);
493 device_create_file(&dev->ofdev.dev, &dev_attr_hw_ver);
494 device_create_file(&dev->ofdev.dev, &dev_attr_max_eq);
495 device_create_file(&dev->ofdev.dev, &dev_attr_cur_eq);
496 device_create_file(&dev->ofdev.dev, &dev_attr_max_cq);
497 device_create_file(&dev->ofdev.dev, &dev_attr_cur_cq);
498 device_create_file(&dev->ofdev.dev, &dev_attr_max_qp);
499 device_create_file(&dev->ofdev.dev, &dev_attr_cur_qp);
500 device_create_file(&dev->ofdev.dev, &dev_attr_max_mr);
501 device_create_file(&dev->ofdev.dev, &dev_attr_cur_mr);
502 device_create_file(&dev->ofdev.dev, &dev_attr_max_mw);
503 device_create_file(&dev->ofdev.dev, &dev_attr_cur_mw);
504 device_create_file(&dev->ofdev.dev, &dev_attr_max_pd);
505 device_create_file(&dev->ofdev.dev, &dev_attr_max_ah);
506}
507
508void ehca_remove_device_sysfs(struct ibmebus_dev *dev)
509{
510 device_remove_file(&dev->ofdev.dev, &dev_attr_adapter_handle);
511 device_remove_file(&dev->ofdev.dev, &dev_attr_num_ports);
512 device_remove_file(&dev->ofdev.dev, &dev_attr_hw_ver);
513 device_remove_file(&dev->ofdev.dev, &dev_attr_max_eq);
514 device_remove_file(&dev->ofdev.dev, &dev_attr_cur_eq);
515 device_remove_file(&dev->ofdev.dev, &dev_attr_max_cq);
516 device_remove_file(&dev->ofdev.dev, &dev_attr_cur_cq);
517 device_remove_file(&dev->ofdev.dev, &dev_attr_max_qp);
518 device_remove_file(&dev->ofdev.dev, &dev_attr_cur_qp);
519 device_remove_file(&dev->ofdev.dev, &dev_attr_max_mr);
520 device_remove_file(&dev->ofdev.dev, &dev_attr_cur_mr);
521 device_remove_file(&dev->ofdev.dev, &dev_attr_max_mw);
522 device_remove_file(&dev->ofdev.dev, &dev_attr_cur_mw);
523 device_remove_file(&dev->ofdev.dev, &dev_attr_max_pd);
524 device_remove_file(&dev->ofdev.dev, &dev_attr_max_ah);
525}
526
527static int __devinit ehca_probe(struct ibmebus_dev *dev,
528 const struct of_device_id *id)
529{
530 struct ehca_shca *shca;
531 u64 *handle;
532 struct ib_pd *ibpd;
533 int ret;
534
535 handle = (u64 *)get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
536 if (!handle) {
537 ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
538 dev->ofdev.node->full_name);
539 return -ENODEV;
540 }
541
542 if (!(*handle)) {
543 ehca_gen_err("Wrong eHCA handle for adapter: %s.",
544 dev->ofdev.node->full_name);
545 return -ENODEV;
546 }
547
548 shca = (struct ehca_shca *)ib_alloc_device(sizeof(*shca));
549 if (!shca) {
550 ehca_gen_err("Cannot allocate shca memory.");
551 return -ENOMEM;
552 }
553
554 shca->ibmebus_dev = dev;
555 shca->ipz_hca_handle.handle = *handle;
556 dev->ofdev.dev.driver_data = shca;
557
558 ret = ehca_sense_attributes(shca);
559 if (ret < 0) {
560 ehca_gen_err("Cannot sense eHCA attributes.");
561 goto probe1;
562 }
563
564 ret = ehca_register_device(shca);
565 if (ret) {
566 ehca_gen_err("Cannot register Infiniband device");
567 goto probe1;
568 }
569
570 /* create event queues */
571 ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
572 if (ret) {
573 ehca_err(&shca->ib_device, "Cannot create EQ.");
574 goto probe2;
575 }
576
577 ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
578 if (ret) {
579 ehca_err(&shca->ib_device, "Cannot create NEQ.");
580 goto probe3;
581 }
582
583 /* create internal protection domain */
584 ibpd = ehca_alloc_pd(&shca->ib_device, (void*)(-1), NULL);
585 if (IS_ERR(ibpd)) {
586 ehca_err(&shca->ib_device, "Cannot create internal PD.");
587 ret = PTR_ERR(ibpd);
588 goto probe4;
589 }
590
591 shca->pd = container_of(ibpd, struct ehca_pd, ib_pd);
592 shca->pd->ib_pd.device = &shca->ib_device;
593
594 /* create internal max MR */
595 ret = ehca_reg_internal_maxmr(shca, shca->pd, &shca->maxmr);
596
597 if (ret) {
598 ehca_err(&shca->ib_device, "Cannot create internal MR ret=%x",
599 ret);
600 goto probe5;
601 }
602
603 /* create AQP1 for port 1 */
604 if (ehca_open_aqp1 == 1) {
605 shca->sport[0].port_state = IB_PORT_DOWN;
606 ret = ehca_create_aqp1(shca, 1);
607 if (ret) {
608 ehca_err(&shca->ib_device,
609 "Cannot create AQP1 for port 1.");
610 goto probe6;
611 }
612 }
613
614 /* create AQP1 for port 2 */
615 if ((ehca_open_aqp1 == 1) && (shca->num_ports == 2)) {
616 shca->sport[1].port_state = IB_PORT_DOWN;
617 ret = ehca_create_aqp1(shca, 2);
618 if (ret) {
619 ehca_err(&shca->ib_device,
620 "Cannot create AQP1 for port 2.");
621 goto probe7;
622 }
623 }
624
625 ehca_create_device_sysfs(dev);
626
627 spin_lock(&shca_list_lock);
628 list_add(&shca->shca_list, &shca_list);
629 spin_unlock(&shca_list_lock);
630
631 return 0;
632
633probe7:
634 ret = ehca_destroy_aqp1(&shca->sport[0]);
635 if (ret)
636 ehca_err(&shca->ib_device,
637 "Cannot destroy AQP1 for port 1. ret=%x", ret);
638
639probe6:
640 ret = ehca_dereg_internal_maxmr(shca);
641 if (ret)
642 ehca_err(&shca->ib_device,
643 "Cannot destroy internal MR. ret=%x", ret);
644
645probe5:
646 ret = ehca_dealloc_pd(&shca->pd->ib_pd);
647 if (ret)
648 ehca_err(&shca->ib_device,
649 "Cannot destroy internal PD. ret=%x", ret);
650
651probe4:
652 ret = ehca_destroy_eq(shca, &shca->neq);
653 if (ret)
654 ehca_err(&shca->ib_device,
655 "Cannot destroy NEQ. ret=%x", ret);
656
657probe3:
658 ret = ehca_destroy_eq(shca, &shca->eq);
659 if (ret)
660 ehca_err(&shca->ib_device,
661 "Cannot destroy EQ. ret=%x", ret);
662
663probe2:
664 ib_unregister_device(&shca->ib_device);
665
666probe1:
667 ib_dealloc_device(&shca->ib_device);
668
669 return -EINVAL;
670}
671
672static int __devexit ehca_remove(struct ibmebus_dev *dev)
673{
674 struct ehca_shca *shca = dev->ofdev.dev.driver_data;
675 int ret;
676
677 ehca_remove_device_sysfs(dev);
678
679 if (ehca_open_aqp1 == 1) {
680 int i;
681 for (i = 0; i < shca->num_ports; i++) {
682 ret = ehca_destroy_aqp1(&shca->sport[i]);
683 if (ret)
684 ehca_err(&shca->ib_device,
685 "Cannot destroy AQP1 for port %x "
686 "ret=%x", ret, i);
687 }
688 }
689
690 ib_unregister_device(&shca->ib_device);
691
692 ret = ehca_dereg_internal_maxmr(shca);
693 if (ret)
694 ehca_err(&shca->ib_device,
695 "Cannot destroy internal MR. ret=%x", ret);
696
697 ret = ehca_dealloc_pd(&shca->pd->ib_pd);
698 if (ret)
699 ehca_err(&shca->ib_device,
700 "Cannot destroy internal PD. ret=%x", ret);
701
702 ret = ehca_destroy_eq(shca, &shca->eq);
703 if (ret)
704 ehca_err(&shca->ib_device, "Cannot destroy EQ. ret=%x", ret);
705
706 ret = ehca_destroy_eq(shca, &shca->neq);
707 if (ret)
708 ehca_err(&shca->ib_device, "Canot destroy NEQ. ret=%x", ret);
709
710 ib_dealloc_device(&shca->ib_device);
711
712 spin_lock(&shca_list_lock);
713 list_del(&shca->shca_list);
714 spin_unlock(&shca_list_lock);
715
716 return ret;
717}
718
719static struct of_device_id ehca_device_table[] =
720{
721 {
722 .name = "lhca",
723 .compatible = "IBM,lhca",
724 },
725 {},
726};
727
728static struct ibmebus_driver ehca_driver = {
729 .name = "ehca",
730 .id_table = ehca_device_table,
731 .probe = ehca_probe,
732 .remove = ehca_remove,
733};
734
735void ehca_poll_eqs(unsigned long data)
736{
737 struct ehca_shca *shca;
738
739 spin_lock(&shca_list_lock);
740 list_for_each_entry(shca, &shca_list, shca_list) {
741 if (shca->eq.is_initialized)
742 ehca_tasklet_eq((unsigned long)(void*)shca);
743 }
744 mod_timer(&poll_eqs_timer, jiffies + HZ);
745 spin_unlock(&shca_list_lock);
746}
747
748int __init ehca_module_init(void)
749{
750 int ret;
751
752 printk(KERN_INFO "eHCA Infiniband Device Driver "
753 "(Rel.: SVNEHCA_0016)\n");
754 idr_init(&ehca_qp_idr);
755 idr_init(&ehca_cq_idr);
756 spin_lock_init(&ehca_qp_idr_lock);
757 spin_lock_init(&ehca_cq_idr_lock);
758
759 INIT_LIST_HEAD(&shca_list);
760 spin_lock_init(&shca_list_lock);
761
762 if ((ret = ehca_create_comp_pool())) {
763 ehca_gen_err("Cannot create comp pool.");
764 return ret;
765 }
766
767 if ((ret = ehca_create_slab_caches())) {
768 ehca_gen_err("Cannot create SLAB caches");
769 ret = -ENOMEM;
770 goto module_init1;
771 }
772
773 if ((ret = ibmebus_register_driver(&ehca_driver))) {
774 ehca_gen_err("Cannot register eHCA device driver");
775 ret = -EINVAL;
776 goto module_init2;
777 }
778
779 ehca_create_driver_sysfs(&ehca_driver);
780
781 if (ehca_poll_all_eqs != 1) {
782 ehca_gen_err("WARNING!!!");
783 ehca_gen_err("It is possible to lose interrupts.");
784 } else {
785 init_timer(&poll_eqs_timer);
786 poll_eqs_timer.function = ehca_poll_eqs;
787 poll_eqs_timer.expires = jiffies + HZ;
788 add_timer(&poll_eqs_timer);
789 }
790
791 return 0;
792
793module_init2:
794 ehca_destroy_slab_caches();
795
796module_init1:
797 ehca_destroy_comp_pool();
798 return ret;
799};
800
801void __exit ehca_module_exit(void)
802{
803 if (ehca_poll_all_eqs == 1)
804 del_timer_sync(&poll_eqs_timer);
805
806 ehca_remove_driver_sysfs(&ehca_driver);
807 ibmebus_unregister_driver(&ehca_driver);
808
809 ehca_destroy_slab_caches();
810
811 ehca_destroy_comp_pool();
812
813 idr_destroy(&ehca_cq_idr);
814 idr_destroy(&ehca_qp_idr);
815};
816
817module_init(ehca_module_init);
818module_exit(ehca_module_exit);
diff --git a/drivers/infiniband/hw/ehca/ehca_mcast.c b/drivers/infiniband/hw/ehca/ehca_mcast.c
new file mode 100644
index 000000000000..32a870660bfe
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_mcast.c
@@ -0,0 +1,131 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * mcast functions
5 *
6 * Authors: Khadija Souissi <souissik@de.ibm.com>
7 * Waleri Fomin <fomin@de.ibm.com>
8 * Reinhard Ernst <rernst@de.ibm.com>
9 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
10 * Heiko J Schick <schickhj@de.ibm.com>
11 *
12 * Copyright (c) 2005 IBM Corporation
13 *
14 * All rights reserved.
15 *
16 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
17 * BSD.
18 *
19 * OpenIB BSD License
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 *
24 * Redistributions of source code must retain the above copyright notice, this
25 * list of conditions and the following disclaimer.
26 *
27 * Redistributions in binary form must reproduce the above copyright notice,
28 * this list of conditions and the following disclaimer in the documentation
29 * and/or other materials
30 * provided with the distribution.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
36 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
40 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGE.
43 */
44
45#include <linux/module.h>
46#include <linux/err.h>
47#include "ehca_classes.h"
48#include "ehca_tools.h"
49#include "ehca_qes.h"
50#include "ehca_iverbs.h"
51#include "hcp_if.h"
52
53#define MAX_MC_LID 0xFFFE
54#define MIN_MC_LID 0xC000 /* Multicast limits */
55#define EHCA_VALID_MULTICAST_GID(gid) ((gid)[0] == 0xFF)
56#define EHCA_VALID_MULTICAST_LID(lid) \
57 (((lid) >= MIN_MC_LID) && ((lid) <= MAX_MC_LID))
58
59int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
60{
61 struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
62 struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
63 ib_device);
64 union ib_gid my_gid;
65 u64 subnet_prefix, interface_id, h_ret;
66
67 if (ibqp->qp_type != IB_QPT_UD) {
68 ehca_err(ibqp->device, "invalid qp_type=%x", ibqp->qp_type);
69 return -EINVAL;
70 }
71
72 if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
73 ehca_err(ibqp->device, "invalid mulitcast gid");
74 return -EINVAL;
75 } else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
76 ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
77 return -EINVAL;
78 }
79
80 memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
81
82 subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
83 interface_id = be64_to_cpu(my_gid.global.interface_id);
84 h_ret = hipz_h_attach_mcqp(shca->ipz_hca_handle,
85 my_qp->ipz_qp_handle,
86 my_qp->galpas.kernel,
87 lid, subnet_prefix, interface_id);
88 if (h_ret != H_SUCCESS)
89 ehca_err(ibqp->device,
90 "ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed "
91 "h_ret=%lx", my_qp, ibqp->qp_num, h_ret);
92
93 return ehca2ib_return_code(h_ret);
94}
95
96int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
97{
98 struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
99 struct ehca_shca *shca = container_of(ibqp->pd->device,
100 struct ehca_shca, ib_device);
101 union ib_gid my_gid;
102 u64 subnet_prefix, interface_id, h_ret;
103
104 if (ibqp->qp_type != IB_QPT_UD) {
105 ehca_err(ibqp->device, "invalid qp_type %x", ibqp->qp_type);
106 return -EINVAL;
107 }
108
109 if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
110 ehca_err(ibqp->device, "invalid mulitcast gid");
111 return -EINVAL;
112 } else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
113 ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
114 return -EINVAL;
115 }
116
117 memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
118
119 subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
120 interface_id = be64_to_cpu(my_gid.global.interface_id);
121 h_ret = hipz_h_detach_mcqp(shca->ipz_hca_handle,
122 my_qp->ipz_qp_handle,
123 my_qp->galpas.kernel,
124 lid, subnet_prefix, interface_id);
125 if (h_ret != H_SUCCESS)
126 ehca_err(ibqp->device,
127 "ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed "
128 "h_ret=%lx", my_qp, ibqp->qp_num, h_ret);
129
130 return ehca2ib_return_code(h_ret);
131}
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
new file mode 100644
index 000000000000..5ca65441e1da
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -0,0 +1,2261 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * MR/MW functions
5 *
6 * Authors: Dietmar Decker <ddecker@de.ibm.com>
7 * Christoph Raisch <raisch@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#include <asm/current.h>
43
44#include "ehca_iverbs.h"
45#include "ehca_mrmw.h"
46#include "hcp_if.h"
47#include "hipz_hw.h"
48
49static struct kmem_cache *mr_cache;
50static struct kmem_cache *mw_cache;
51
52static struct ehca_mr *ehca_mr_new(void)
53{
54 struct ehca_mr *me;
55
56 me = kmem_cache_alloc(mr_cache, SLAB_KERNEL);
57 if (me) {
58 memset(me, 0, sizeof(struct ehca_mr));
59 spin_lock_init(&me->mrlock);
60 } else
61 ehca_gen_err("alloc failed");
62
63 return me;
64}
65
66static void ehca_mr_delete(struct ehca_mr *me)
67{
68 kmem_cache_free(mr_cache, me);
69}
70
71static struct ehca_mw *ehca_mw_new(void)
72{
73 struct ehca_mw *me;
74
75 me = kmem_cache_alloc(mw_cache, SLAB_KERNEL);
76 if (me) {
77 memset(me, 0, sizeof(struct ehca_mw));
78 spin_lock_init(&me->mwlock);
79 } else
80 ehca_gen_err("alloc failed");
81
82 return me;
83}
84
85static void ehca_mw_delete(struct ehca_mw *me)
86{
87 kmem_cache_free(mw_cache, me);
88}
89
90/*----------------------------------------------------------------------*/
91
92struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
93{
94 struct ib_mr *ib_mr;
95 int ret;
96 struct ehca_mr *e_maxmr;
97 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
98 struct ehca_shca *shca =
99 container_of(pd->device, struct ehca_shca, ib_device);
100
101 if (shca->maxmr) {
102 e_maxmr = ehca_mr_new();
103 if (!e_maxmr) {
104 ehca_err(&shca->ib_device, "out of memory");
105 ib_mr = ERR_PTR(-ENOMEM);
106 goto get_dma_mr_exit0;
107 }
108
109 ret = ehca_reg_maxmr(shca, e_maxmr, (u64*)KERNELBASE,
110 mr_access_flags, e_pd,
111 &e_maxmr->ib.ib_mr.lkey,
112 &e_maxmr->ib.ib_mr.rkey);
113 if (ret) {
114 ib_mr = ERR_PTR(ret);
115 goto get_dma_mr_exit0;
116 }
117 ib_mr = &e_maxmr->ib.ib_mr;
118 } else {
119 ehca_err(&shca->ib_device, "no internal max-MR exist!");
120 ib_mr = ERR_PTR(-EINVAL);
121 goto get_dma_mr_exit0;
122 }
123
124get_dma_mr_exit0:
125 if (IS_ERR(ib_mr))
126 ehca_err(&shca->ib_device, "rc=%lx pd=%p mr_access_flags=%x ",
127 PTR_ERR(ib_mr), pd, mr_access_flags);
128 return ib_mr;
129} /* end ehca_get_dma_mr() */
130
131/*----------------------------------------------------------------------*/
132
133struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
134 struct ib_phys_buf *phys_buf_array,
135 int num_phys_buf,
136 int mr_access_flags,
137 u64 *iova_start)
138{
139 struct ib_mr *ib_mr;
140 int ret;
141 struct ehca_mr *e_mr;
142 struct ehca_shca *shca =
143 container_of(pd->device, struct ehca_shca, ib_device);
144 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
145
146 u64 size;
147 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
148 u32 num_pages_mr;
149 u32 num_pages_4k; /* 4k portion "pages" */
150
151 if ((num_phys_buf <= 0) || !phys_buf_array) {
152 ehca_err(pd->device, "bad input values: num_phys_buf=%x "
153 "phys_buf_array=%p", num_phys_buf, phys_buf_array);
154 ib_mr = ERR_PTR(-EINVAL);
155 goto reg_phys_mr_exit0;
156 }
157 if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
158 !(mr_access_flags & IB_ACCESS_LOCAL_WRITE)) ||
159 ((mr_access_flags & IB_ACCESS_REMOTE_ATOMIC) &&
160 !(mr_access_flags & IB_ACCESS_LOCAL_WRITE))) {
161 /*
162 * Remote Write Access requires Local Write Access
163 * Remote Atomic Access requires Local Write Access
164 */
165 ehca_err(pd->device, "bad input values: mr_access_flags=%x",
166 mr_access_flags);
167 ib_mr = ERR_PTR(-EINVAL);
168 goto reg_phys_mr_exit0;
169 }
170
171 /* check physical buffer list and calculate size */
172 ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array, num_phys_buf,
173 iova_start, &size);
174 if (ret) {
175 ib_mr = ERR_PTR(ret);
176 goto reg_phys_mr_exit0;
177 }
178 if ((size == 0) ||
179 (((u64)iova_start + size) < (u64)iova_start)) {
180 ehca_err(pd->device, "bad input values: size=%lx iova_start=%p",
181 size, iova_start);
182 ib_mr = ERR_PTR(-EINVAL);
183 goto reg_phys_mr_exit0;
184 }
185
186 e_mr = ehca_mr_new();
187 if (!e_mr) {
188 ehca_err(pd->device, "out of memory");
189 ib_mr = ERR_PTR(-ENOMEM);
190 goto reg_phys_mr_exit0;
191 }
192
193 /* determine number of MR pages */
194 num_pages_mr = ((((u64)iova_start % PAGE_SIZE) + size +
195 PAGE_SIZE - 1) / PAGE_SIZE);
196 num_pages_4k = ((((u64)iova_start % EHCA_PAGESIZE) + size +
197 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE);
198
199 /* register MR on HCA */
200 if (ehca_mr_is_maxmr(size, iova_start)) {
201 e_mr->flags |= EHCA_MR_FLAG_MAXMR;
202 ret = ehca_reg_maxmr(shca, e_mr, iova_start, mr_access_flags,
203 e_pd, &e_mr->ib.ib_mr.lkey,
204 &e_mr->ib.ib_mr.rkey);
205 if (ret) {
206 ib_mr = ERR_PTR(ret);
207 goto reg_phys_mr_exit1;
208 }
209 } else {
210 pginfo.type = EHCA_MR_PGI_PHYS;
211 pginfo.num_pages = num_pages_mr;
212 pginfo.num_4k = num_pages_4k;
213 pginfo.num_phys_buf = num_phys_buf;
214 pginfo.phys_buf_array = phys_buf_array;
215 pginfo.next_4k = (((u64)iova_start & ~PAGE_MASK) /
216 EHCA_PAGESIZE);
217
218 ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
219 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
220 &e_mr->ib.ib_mr.rkey);
221 if (ret) {
222 ib_mr = ERR_PTR(ret);
223 goto reg_phys_mr_exit1;
224 }
225 }
226
227 /* successful registration of all pages */
228 return &e_mr->ib.ib_mr;
229
230reg_phys_mr_exit1:
231 ehca_mr_delete(e_mr);
232reg_phys_mr_exit0:
233 if (IS_ERR(ib_mr))
234 ehca_err(pd->device, "rc=%lx pd=%p phys_buf_array=%p "
235 "num_phys_buf=%x mr_access_flags=%x iova_start=%p",
236 PTR_ERR(ib_mr), pd, phys_buf_array,
237 num_phys_buf, mr_access_flags, iova_start);
238 return ib_mr;
239} /* end ehca_reg_phys_mr() */
240
241/*----------------------------------------------------------------------*/
242
243struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd,
244 struct ib_umem *region,
245 int mr_access_flags,
246 struct ib_udata *udata)
247{
248 struct ib_mr *ib_mr;
249 struct ehca_mr *e_mr;
250 struct ehca_shca *shca =
251 container_of(pd->device, struct ehca_shca, ib_device);
252 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
253 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
254 int ret;
255 u32 num_pages_mr;
256 u32 num_pages_4k; /* 4k portion "pages" */
257
258 if (!pd) {
259 ehca_gen_err("bad pd=%p", pd);
260 return ERR_PTR(-EFAULT);
261 }
262 if (!region) {
263 ehca_err(pd->device, "bad input values: region=%p", region);
264 ib_mr = ERR_PTR(-EINVAL);
265 goto reg_user_mr_exit0;
266 }
267 if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
268 !(mr_access_flags & IB_ACCESS_LOCAL_WRITE)) ||
269 ((mr_access_flags & IB_ACCESS_REMOTE_ATOMIC) &&
270 !(mr_access_flags & IB_ACCESS_LOCAL_WRITE))) {
271 /*
272 * Remote Write Access requires Local Write Access
273 * Remote Atomic Access requires Local Write Access
274 */
275 ehca_err(pd->device, "bad input values: mr_access_flags=%x",
276 mr_access_flags);
277 ib_mr = ERR_PTR(-EINVAL);
278 goto reg_user_mr_exit0;
279 }
280 if (region->page_size != PAGE_SIZE) {
281 ehca_err(pd->device, "page size not supported, "
282 "region->page_size=%x", region->page_size);
283 ib_mr = ERR_PTR(-EINVAL);
284 goto reg_user_mr_exit0;
285 }
286
287 if ((region->length == 0) ||
288 ((region->virt_base + region->length) < region->virt_base)) {
289 ehca_err(pd->device, "bad input values: length=%lx "
290 "virt_base=%lx", region->length, region->virt_base);
291 ib_mr = ERR_PTR(-EINVAL);
292 goto reg_user_mr_exit0;
293 }
294
295 e_mr = ehca_mr_new();
296 if (!e_mr) {
297 ehca_err(pd->device, "out of memory");
298 ib_mr = ERR_PTR(-ENOMEM);
299 goto reg_user_mr_exit0;
300 }
301
302 /* determine number of MR pages */
303 num_pages_mr = (((region->virt_base % PAGE_SIZE) + region->length +
304 PAGE_SIZE - 1) / PAGE_SIZE);
305 num_pages_4k = (((region->virt_base % EHCA_PAGESIZE) + region->length +
306 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE);
307
308 /* register MR on HCA */
309 pginfo.type = EHCA_MR_PGI_USER;
310 pginfo.num_pages = num_pages_mr;
311 pginfo.num_4k = num_pages_4k;
312 pginfo.region = region;
313 pginfo.next_4k = region->offset / EHCA_PAGESIZE;
314 pginfo.next_chunk = list_prepare_entry(pginfo.next_chunk,
315 (&region->chunk_list),
316 list);
317
318 ret = ehca_reg_mr(shca, e_mr, (u64*)region->virt_base,
319 region->length, mr_access_flags, e_pd, &pginfo,
320 &e_mr->ib.ib_mr.lkey, &e_mr->ib.ib_mr.rkey);
321 if (ret) {
322 ib_mr = ERR_PTR(ret);
323 goto reg_user_mr_exit1;
324 }
325
326 /* successful registration of all pages */
327 return &e_mr->ib.ib_mr;
328
329reg_user_mr_exit1:
330 ehca_mr_delete(e_mr);
331reg_user_mr_exit0:
332 if (IS_ERR(ib_mr))
333 ehca_err(pd->device, "rc=%lx pd=%p region=%p mr_access_flags=%x"
334 " udata=%p",
335 PTR_ERR(ib_mr), pd, region, mr_access_flags, udata);
336 return ib_mr;
337} /* end ehca_reg_user_mr() */
338
339/*----------------------------------------------------------------------*/
340
341int ehca_rereg_phys_mr(struct ib_mr *mr,
342 int mr_rereg_mask,
343 struct ib_pd *pd,
344 struct ib_phys_buf *phys_buf_array,
345 int num_phys_buf,
346 int mr_access_flags,
347 u64 *iova_start)
348{
349 int ret;
350
351 struct ehca_shca *shca =
352 container_of(mr->device, struct ehca_shca, ib_device);
353 struct ehca_mr *e_mr = container_of(mr, struct ehca_mr, ib.ib_mr);
354 struct ehca_pd *my_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
355 u64 new_size;
356 u64 *new_start;
357 u32 new_acl;
358 struct ehca_pd *new_pd;
359 u32 tmp_lkey, tmp_rkey;
360 unsigned long sl_flags;
361 u32 num_pages_mr = 0;
362 u32 num_pages_4k = 0; /* 4k portion "pages" */
363 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
364 u32 cur_pid = current->tgid;
365
366 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
367 (my_pd->ownpid != cur_pid)) {
368 ehca_err(mr->device, "Invalid caller pid=%x ownpid=%x",
369 cur_pid, my_pd->ownpid);
370 ret = -EINVAL;
371 goto rereg_phys_mr_exit0;
372 }
373
374 if (!(mr_rereg_mask & IB_MR_REREG_TRANS)) {
375 /* TODO not supported, because PHYP rereg hCall needs pages */
376 ehca_err(mr->device, "rereg without IB_MR_REREG_TRANS not "
377 "supported yet, mr_rereg_mask=%x", mr_rereg_mask);
378 ret = -EINVAL;
379 goto rereg_phys_mr_exit0;
380 }
381
382 if (mr_rereg_mask & IB_MR_REREG_PD) {
383 if (!pd) {
384 ehca_err(mr->device, "rereg with bad pd, pd=%p "
385 "mr_rereg_mask=%x", pd, mr_rereg_mask);
386 ret = -EINVAL;
387 goto rereg_phys_mr_exit0;
388 }
389 }
390
391 if ((mr_rereg_mask &
392 ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS)) ||
393 (mr_rereg_mask == 0)) {
394 ret = -EINVAL;
395 goto rereg_phys_mr_exit0;
396 }
397
398 /* check other parameters */
399 if (e_mr == shca->maxmr) {
400 /* should be impossible, however reject to be sure */
401 ehca_err(mr->device, "rereg internal max-MR impossible, mr=%p "
402 "shca->maxmr=%p mr->lkey=%x",
403 mr, shca->maxmr, mr->lkey);
404 ret = -EINVAL;
405 goto rereg_phys_mr_exit0;
406 }
407 if (mr_rereg_mask & IB_MR_REREG_TRANS) { /* transl., i.e. addr/size */
408 if (e_mr->flags & EHCA_MR_FLAG_FMR) {
409 ehca_err(mr->device, "not supported for FMR, mr=%p "
410 "flags=%x", mr, e_mr->flags);
411 ret = -EINVAL;
412 goto rereg_phys_mr_exit0;
413 }
414 if (!phys_buf_array || num_phys_buf <= 0) {
415 ehca_err(mr->device, "bad input values: mr_rereg_mask=%x"
416 " phys_buf_array=%p num_phys_buf=%x",
417 mr_rereg_mask, phys_buf_array, num_phys_buf);
418 ret = -EINVAL;
419 goto rereg_phys_mr_exit0;
420 }
421 }
422 if ((mr_rereg_mask & IB_MR_REREG_ACCESS) && /* change ACL */
423 (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
424 !(mr_access_flags & IB_ACCESS_LOCAL_WRITE)) ||
425 ((mr_access_flags & IB_ACCESS_REMOTE_ATOMIC) &&
426 !(mr_access_flags & IB_ACCESS_LOCAL_WRITE)))) {
427 /*
428 * Remote Write Access requires Local Write Access
429 * Remote Atomic Access requires Local Write Access
430 */
431 ehca_err(mr->device, "bad input values: mr_rereg_mask=%x "
432 "mr_access_flags=%x", mr_rereg_mask, mr_access_flags);
433 ret = -EINVAL;
434 goto rereg_phys_mr_exit0;
435 }
436
437 /* set requested values dependent on rereg request */
438 spin_lock_irqsave(&e_mr->mrlock, sl_flags);
439 new_start = e_mr->start; /* new == old address */
440 new_size = e_mr->size; /* new == old length */
441 new_acl = e_mr->acl; /* new == old access control */
442 new_pd = container_of(mr->pd,struct ehca_pd,ib_pd); /*new == old PD*/
443
444 if (mr_rereg_mask & IB_MR_REREG_TRANS) {
445 new_start = iova_start; /* change address */
446 /* check physical buffer list and calculate size */
447 ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array,
448 num_phys_buf, iova_start,
449 &new_size);
450 if (ret)
451 goto rereg_phys_mr_exit1;
452 if ((new_size == 0) ||
453 (((u64)iova_start + new_size) < (u64)iova_start)) {
454 ehca_err(mr->device, "bad input values: new_size=%lx "
455 "iova_start=%p", new_size, iova_start);
456 ret = -EINVAL;
457 goto rereg_phys_mr_exit1;
458 }
459 num_pages_mr = ((((u64)new_start % PAGE_SIZE) + new_size +
460 PAGE_SIZE - 1) / PAGE_SIZE);
461 num_pages_4k = ((((u64)new_start % EHCA_PAGESIZE) + new_size +
462 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE);
463 pginfo.type = EHCA_MR_PGI_PHYS;
464 pginfo.num_pages = num_pages_mr;
465 pginfo.num_4k = num_pages_4k;
466 pginfo.num_phys_buf = num_phys_buf;
467 pginfo.phys_buf_array = phys_buf_array;
468 pginfo.next_4k = (((u64)iova_start & ~PAGE_MASK) /
469 EHCA_PAGESIZE);
470 }
471 if (mr_rereg_mask & IB_MR_REREG_ACCESS)
472 new_acl = mr_access_flags;
473 if (mr_rereg_mask & IB_MR_REREG_PD)
474 new_pd = container_of(pd, struct ehca_pd, ib_pd);
475
476 ret = ehca_rereg_mr(shca, e_mr, new_start, new_size, new_acl,
477 new_pd, &pginfo, &tmp_lkey, &tmp_rkey);
478 if (ret)
479 goto rereg_phys_mr_exit1;
480
481 /* successful reregistration */
482 if (mr_rereg_mask & IB_MR_REREG_PD)
483 mr->pd = pd;
484 mr->lkey = tmp_lkey;
485 mr->rkey = tmp_rkey;
486
487rereg_phys_mr_exit1:
488 spin_unlock_irqrestore(&e_mr->mrlock, sl_flags);
489rereg_phys_mr_exit0:
490 if (ret)
491 ehca_err(mr->device, "ret=%x mr=%p mr_rereg_mask=%x pd=%p "
492 "phys_buf_array=%p num_phys_buf=%x mr_access_flags=%x "
493 "iova_start=%p",
494 ret, mr, mr_rereg_mask, pd, phys_buf_array,
495 num_phys_buf, mr_access_flags, iova_start);
496 return ret;
497} /* end ehca_rereg_phys_mr() */
498
499/*----------------------------------------------------------------------*/
500
501int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
502{
503 int ret = 0;
504 u64 h_ret;
505 struct ehca_shca *shca =
506 container_of(mr->device, struct ehca_shca, ib_device);
507 struct ehca_mr *e_mr = container_of(mr, struct ehca_mr, ib.ib_mr);
508 struct ehca_pd *my_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
509 u32 cur_pid = current->tgid;
510 unsigned long sl_flags;
511 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
512
513 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
514 (my_pd->ownpid != cur_pid)) {
515 ehca_err(mr->device, "Invalid caller pid=%x ownpid=%x",
516 cur_pid, my_pd->ownpid);
517 ret = -EINVAL;
518 goto query_mr_exit0;
519 }
520
521 if ((e_mr->flags & EHCA_MR_FLAG_FMR)) {
522 ehca_err(mr->device, "not supported for FMR, mr=%p e_mr=%p "
523 "e_mr->flags=%x", mr, e_mr, e_mr->flags);
524 ret = -EINVAL;
525 goto query_mr_exit0;
526 }
527
528 memset(mr_attr, 0, sizeof(struct ib_mr_attr));
529 spin_lock_irqsave(&e_mr->mrlock, sl_flags);
530
531 h_ret = hipz_h_query_mr(shca->ipz_hca_handle, e_mr, &hipzout);
532 if (h_ret != H_SUCCESS) {
533 ehca_err(mr->device, "hipz_mr_query failed, h_ret=%lx mr=%p "
534 "hca_hndl=%lx mr_hndl=%lx lkey=%x",
535 h_ret, mr, shca->ipz_hca_handle.handle,
536 e_mr->ipz_mr_handle.handle, mr->lkey);
537 ret = ehca_mrmw_map_hrc_query_mr(h_ret);
538 goto query_mr_exit1;
539 }
540 mr_attr->pd = mr->pd;
541 mr_attr->device_virt_addr = hipzout.vaddr;
542 mr_attr->size = hipzout.len;
543 mr_attr->lkey = hipzout.lkey;
544 mr_attr->rkey = hipzout.rkey;
545 ehca_mrmw_reverse_map_acl(&hipzout.acl, &mr_attr->mr_access_flags);
546
547query_mr_exit1:
548 spin_unlock_irqrestore(&e_mr->mrlock, sl_flags);
549query_mr_exit0:
550 if (ret)
551 ehca_err(mr->device, "ret=%x mr=%p mr_attr=%p",
552 ret, mr, mr_attr);
553 return ret;
554} /* end ehca_query_mr() */
555
556/*----------------------------------------------------------------------*/
557
558int ehca_dereg_mr(struct ib_mr *mr)
559{
560 int ret = 0;
561 u64 h_ret;
562 struct ehca_shca *shca =
563 container_of(mr->device, struct ehca_shca, ib_device);
564 struct ehca_mr *e_mr = container_of(mr, struct ehca_mr, ib.ib_mr);
565 struct ehca_pd *my_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
566 u32 cur_pid = current->tgid;
567
568 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
569 (my_pd->ownpid != cur_pid)) {
570 ehca_err(mr->device, "Invalid caller pid=%x ownpid=%x",
571 cur_pid, my_pd->ownpid);
572 ret = -EINVAL;
573 goto dereg_mr_exit0;
574 }
575
576 if ((e_mr->flags & EHCA_MR_FLAG_FMR)) {
577 ehca_err(mr->device, "not supported for FMR, mr=%p e_mr=%p "
578 "e_mr->flags=%x", mr, e_mr, e_mr->flags);
579 ret = -EINVAL;
580 goto dereg_mr_exit0;
581 } else if (e_mr == shca->maxmr) {
582 /* should be impossible, however reject to be sure */
583 ehca_err(mr->device, "dereg internal max-MR impossible, mr=%p "
584 "shca->maxmr=%p mr->lkey=%x",
585 mr, shca->maxmr, mr->lkey);
586 ret = -EINVAL;
587 goto dereg_mr_exit0;
588 }
589
590 /* TODO: BUSY: MR still has bound window(s) */
591 h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr);
592 if (h_ret != H_SUCCESS) {
593 ehca_err(mr->device, "hipz_free_mr failed, h_ret=%lx shca=%p "
594 "e_mr=%p hca_hndl=%lx mr_hndl=%lx mr->lkey=%x",
595 h_ret, shca, e_mr, shca->ipz_hca_handle.handle,
596 e_mr->ipz_mr_handle.handle, mr->lkey);
597 ret = ehca_mrmw_map_hrc_free_mr(h_ret);
598 goto dereg_mr_exit0;
599 }
600
601 /* successful deregistration */
602 ehca_mr_delete(e_mr);
603
604dereg_mr_exit0:
605 if (ret)
606 ehca_err(mr->device, "ret=%x mr=%p", ret, mr);
607 return ret;
608} /* end ehca_dereg_mr() */
609
610/*----------------------------------------------------------------------*/
611
612struct ib_mw *ehca_alloc_mw(struct ib_pd *pd)
613{
614 struct ib_mw *ib_mw;
615 u64 h_ret;
616 struct ehca_mw *e_mw;
617 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
618 struct ehca_shca *shca =
619 container_of(pd->device, struct ehca_shca, ib_device);
620 struct ehca_mw_hipzout_parms hipzout = {{0},0};
621
622 e_mw = ehca_mw_new();
623 if (!e_mw) {
624 ib_mw = ERR_PTR(-ENOMEM);
625 goto alloc_mw_exit0;
626 }
627
628 h_ret = hipz_h_alloc_resource_mw(shca->ipz_hca_handle, e_mw,
629 e_pd->fw_pd, &hipzout);
630 if (h_ret != H_SUCCESS) {
631 ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%lx "
632 "shca=%p hca_hndl=%lx mw=%p",
633 h_ret, shca, shca->ipz_hca_handle.handle, e_mw);
634 ib_mw = ERR_PTR(ehca_mrmw_map_hrc_alloc(h_ret));
635 goto alloc_mw_exit1;
636 }
637 /* successful MW allocation */
638 e_mw->ipz_mw_handle = hipzout.handle;
639 e_mw->ib_mw.rkey = hipzout.rkey;
640 return &e_mw->ib_mw;
641
642alloc_mw_exit1:
643 ehca_mw_delete(e_mw);
644alloc_mw_exit0:
645 if (IS_ERR(ib_mw))
646 ehca_err(pd->device, "rc=%lx pd=%p", PTR_ERR(ib_mw), pd);
647 return ib_mw;
648} /* end ehca_alloc_mw() */
649
650/*----------------------------------------------------------------------*/
651
652int ehca_bind_mw(struct ib_qp *qp,
653 struct ib_mw *mw,
654 struct ib_mw_bind *mw_bind)
655{
656 /* TODO: not supported up to now */
657 ehca_gen_err("bind MW currently not supported by HCAD");
658
659 return -EPERM;
660} /* end ehca_bind_mw() */
661
662/*----------------------------------------------------------------------*/
663
664int ehca_dealloc_mw(struct ib_mw *mw)
665{
666 u64 h_ret;
667 struct ehca_shca *shca =
668 container_of(mw->device, struct ehca_shca, ib_device);
669 struct ehca_mw *e_mw = container_of(mw, struct ehca_mw, ib_mw);
670
671 h_ret = hipz_h_free_resource_mw(shca->ipz_hca_handle, e_mw);
672 if (h_ret != H_SUCCESS) {
673 ehca_err(mw->device, "hipz_free_mw failed, h_ret=%lx shca=%p "
674 "mw=%p rkey=%x hca_hndl=%lx mw_hndl=%lx",
675 h_ret, shca, mw, mw->rkey, shca->ipz_hca_handle.handle,
676 e_mw->ipz_mw_handle.handle);
677 return ehca_mrmw_map_hrc_free_mw(h_ret);
678 }
679 /* successful deallocation */
680 ehca_mw_delete(e_mw);
681 return 0;
682} /* end ehca_dealloc_mw() */
683
684/*----------------------------------------------------------------------*/
685
686struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
687 int mr_access_flags,
688 struct ib_fmr_attr *fmr_attr)
689{
690 struct ib_fmr *ib_fmr;
691 struct ehca_shca *shca =
692 container_of(pd->device, struct ehca_shca, ib_device);
693 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
694 struct ehca_mr *e_fmr;
695 int ret;
696 u32 tmp_lkey, tmp_rkey;
697 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
698
699 /* check other parameters */
700 if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
701 !(mr_access_flags & IB_ACCESS_LOCAL_WRITE)) ||
702 ((mr_access_flags & IB_ACCESS_REMOTE_ATOMIC) &&
703 !(mr_access_flags & IB_ACCESS_LOCAL_WRITE))) {
704 /*
705 * Remote Write Access requires Local Write Access
706 * Remote Atomic Access requires Local Write Access
707 */
708 ehca_err(pd->device, "bad input values: mr_access_flags=%x",
709 mr_access_flags);
710 ib_fmr = ERR_PTR(-EINVAL);
711 goto alloc_fmr_exit0;
712 }
713 if (mr_access_flags & IB_ACCESS_MW_BIND) {
714 ehca_err(pd->device, "bad input values: mr_access_flags=%x",
715 mr_access_flags);
716 ib_fmr = ERR_PTR(-EINVAL);
717 goto alloc_fmr_exit0;
718 }
719 if ((fmr_attr->max_pages == 0) || (fmr_attr->max_maps == 0)) {
720 ehca_err(pd->device, "bad input values: fmr_attr->max_pages=%x "
721 "fmr_attr->max_maps=%x fmr_attr->page_shift=%x",
722 fmr_attr->max_pages, fmr_attr->max_maps,
723 fmr_attr->page_shift);
724 ib_fmr = ERR_PTR(-EINVAL);
725 goto alloc_fmr_exit0;
726 }
727 if (((1 << fmr_attr->page_shift) != EHCA_PAGESIZE) &&
728 ((1 << fmr_attr->page_shift) != PAGE_SIZE)) {
729 ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x",
730 fmr_attr->page_shift);
731 ib_fmr = ERR_PTR(-EINVAL);
732 goto alloc_fmr_exit0;
733 }
734
735 e_fmr = ehca_mr_new();
736 if (!e_fmr) {
737 ib_fmr = ERR_PTR(-ENOMEM);
738 goto alloc_fmr_exit0;
739 }
740 e_fmr->flags |= EHCA_MR_FLAG_FMR;
741
742 /* register MR on HCA */
743 ret = ehca_reg_mr(shca, e_fmr, NULL,
744 fmr_attr->max_pages * (1 << fmr_attr->page_shift),
745 mr_access_flags, e_pd, &pginfo,
746 &tmp_lkey, &tmp_rkey);
747 if (ret) {
748 ib_fmr = ERR_PTR(ret);
749 goto alloc_fmr_exit1;
750 }
751
752 /* successful */
753 e_fmr->fmr_page_size = 1 << fmr_attr->page_shift;
754 e_fmr->fmr_max_pages = fmr_attr->max_pages;
755 e_fmr->fmr_max_maps = fmr_attr->max_maps;
756 e_fmr->fmr_map_cnt = 0;
757 return &e_fmr->ib.ib_fmr;
758
759alloc_fmr_exit1:
760 ehca_mr_delete(e_fmr);
761alloc_fmr_exit0:
762 if (IS_ERR(ib_fmr))
763 ehca_err(pd->device, "rc=%lx pd=%p mr_access_flags=%x "
764 "fmr_attr=%p", PTR_ERR(ib_fmr), pd,
765 mr_access_flags, fmr_attr);
766 return ib_fmr;
767} /* end ehca_alloc_fmr() */
768
769/*----------------------------------------------------------------------*/
770
771int ehca_map_phys_fmr(struct ib_fmr *fmr,
772 u64 *page_list,
773 int list_len,
774 u64 iova)
775{
776 int ret;
777 struct ehca_shca *shca =
778 container_of(fmr->device, struct ehca_shca, ib_device);
779 struct ehca_mr *e_fmr = container_of(fmr, struct ehca_mr, ib.ib_fmr);
780 struct ehca_pd *e_pd = container_of(fmr->pd, struct ehca_pd, ib_pd);
781 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
782 u32 tmp_lkey, tmp_rkey;
783
784 if (!(e_fmr->flags & EHCA_MR_FLAG_FMR)) {
785 ehca_err(fmr->device, "not a FMR, e_fmr=%p e_fmr->flags=%x",
786 e_fmr, e_fmr->flags);
787 ret = -EINVAL;
788 goto map_phys_fmr_exit0;
789 }
790 ret = ehca_fmr_check_page_list(e_fmr, page_list, list_len);
791 if (ret)
792 goto map_phys_fmr_exit0;
793 if (iova % e_fmr->fmr_page_size) {
794 /* only whole-numbered pages */
795 ehca_err(fmr->device, "bad iova, iova=%lx fmr_page_size=%x",
796 iova, e_fmr->fmr_page_size);
797 ret = -EINVAL;
798 goto map_phys_fmr_exit0;
799 }
800 if (e_fmr->fmr_map_cnt >= e_fmr->fmr_max_maps) {
801 /* HCAD does not limit the maps, however trace this anyway */
802 ehca_info(fmr->device, "map limit exceeded, fmr=%p "
803 "e_fmr->fmr_map_cnt=%x e_fmr->fmr_max_maps=%x",
804 fmr, e_fmr->fmr_map_cnt, e_fmr->fmr_max_maps);
805 }
806
807 pginfo.type = EHCA_MR_PGI_FMR;
808 pginfo.num_pages = list_len;
809 pginfo.num_4k = list_len * (e_fmr->fmr_page_size / EHCA_PAGESIZE);
810 pginfo.page_list = page_list;
811 pginfo.next_4k = ((iova & (e_fmr->fmr_page_size-1)) /
812 EHCA_PAGESIZE);
813
814 ret = ehca_rereg_mr(shca, e_fmr, (u64*)iova,
815 list_len * e_fmr->fmr_page_size,
816 e_fmr->acl, e_pd, &pginfo, &tmp_lkey, &tmp_rkey);
817 if (ret)
818 goto map_phys_fmr_exit0;
819
820 /* successful reregistration */
821 e_fmr->fmr_map_cnt++;
822 e_fmr->ib.ib_fmr.lkey = tmp_lkey;
823 e_fmr->ib.ib_fmr.rkey = tmp_rkey;
824 return 0;
825
826map_phys_fmr_exit0:
827 if (ret)
828 ehca_err(fmr->device, "ret=%x fmr=%p page_list=%p list_len=%x "
829 "iova=%lx",
830 ret, fmr, page_list, list_len, iova);
831 return ret;
832} /* end ehca_map_phys_fmr() */
833
834/*----------------------------------------------------------------------*/
835
836int ehca_unmap_fmr(struct list_head *fmr_list)
837{
838 int ret = 0;
839 struct ib_fmr *ib_fmr;
840 struct ehca_shca *shca = NULL;
841 struct ehca_shca *prev_shca;
842 struct ehca_mr *e_fmr;
843 u32 num_fmr = 0;
844 u32 unmap_fmr_cnt = 0;
845
846 /* check all FMR belong to same SHCA, and check internal flag */
847 list_for_each_entry(ib_fmr, fmr_list, list) {
848 prev_shca = shca;
849 if (!ib_fmr) {
850 ehca_gen_err("bad fmr=%p in list", ib_fmr);
851 ret = -EINVAL;
852 goto unmap_fmr_exit0;
853 }
854 shca = container_of(ib_fmr->device, struct ehca_shca,
855 ib_device);
856 e_fmr = container_of(ib_fmr, struct ehca_mr, ib.ib_fmr);
857 if ((shca != prev_shca) && prev_shca) {
858 ehca_err(&shca->ib_device, "SHCA mismatch, shca=%p "
859 "prev_shca=%p e_fmr=%p",
860 shca, prev_shca, e_fmr);
861 ret = -EINVAL;
862 goto unmap_fmr_exit0;
863 }
864 if (!(e_fmr->flags & EHCA_MR_FLAG_FMR)) {
865 ehca_err(&shca->ib_device, "not a FMR, e_fmr=%p "
866 "e_fmr->flags=%x", e_fmr, e_fmr->flags);
867 ret = -EINVAL;
868 goto unmap_fmr_exit0;
869 }
870 num_fmr++;
871 }
872
873 /* loop over all FMRs to unmap */
874 list_for_each_entry(ib_fmr, fmr_list, list) {
875 unmap_fmr_cnt++;
876 e_fmr = container_of(ib_fmr, struct ehca_mr, ib.ib_fmr);
877 shca = container_of(ib_fmr->device, struct ehca_shca,
878 ib_device);
879 ret = ehca_unmap_one_fmr(shca, e_fmr);
880 if (ret) {
881 /* unmap failed, stop unmapping of rest of FMRs */
882 ehca_err(&shca->ib_device, "unmap of one FMR failed, "
883 "stop rest, e_fmr=%p num_fmr=%x "
884 "unmap_fmr_cnt=%x lkey=%x", e_fmr, num_fmr,
885 unmap_fmr_cnt, e_fmr->ib.ib_fmr.lkey);
886 goto unmap_fmr_exit0;
887 }
888 }
889
890unmap_fmr_exit0:
891 if (ret)
892 ehca_gen_err("ret=%x fmr_list=%p num_fmr=%x unmap_fmr_cnt=%x",
893 ret, fmr_list, num_fmr, unmap_fmr_cnt);
894 return ret;
895} /* end ehca_unmap_fmr() */
896
897/*----------------------------------------------------------------------*/
898
899int ehca_dealloc_fmr(struct ib_fmr *fmr)
900{
901 int ret;
902 u64 h_ret;
903 struct ehca_shca *shca =
904 container_of(fmr->device, struct ehca_shca, ib_device);
905 struct ehca_mr *e_fmr = container_of(fmr, struct ehca_mr, ib.ib_fmr);
906
907 if (!(e_fmr->flags & EHCA_MR_FLAG_FMR)) {
908 ehca_err(fmr->device, "not a FMR, e_fmr=%p e_fmr->flags=%x",
909 e_fmr, e_fmr->flags);
910 ret = -EINVAL;
911 goto free_fmr_exit0;
912 }
913
914 h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr);
915 if (h_ret != H_SUCCESS) {
916 ehca_err(fmr->device, "hipz_free_mr failed, h_ret=%lx e_fmr=%p "
917 "hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x",
918 h_ret, e_fmr, shca->ipz_hca_handle.handle,
919 e_fmr->ipz_mr_handle.handle, fmr->lkey);
920 ret = ehca_mrmw_map_hrc_free_mr(h_ret);
921 goto free_fmr_exit0;
922 }
923 /* successful deregistration */
924 ehca_mr_delete(e_fmr);
925 return 0;
926
927free_fmr_exit0:
928 if (ret)
929 ehca_err(&shca->ib_device, "ret=%x fmr=%p", ret, fmr);
930 return ret;
931} /* end ehca_dealloc_fmr() */
932
933/*----------------------------------------------------------------------*/
934
935int ehca_reg_mr(struct ehca_shca *shca,
936 struct ehca_mr *e_mr,
937 u64 *iova_start,
938 u64 size,
939 int acl,
940 struct ehca_pd *e_pd,
941 struct ehca_mr_pginfo *pginfo,
942 u32 *lkey, /*OUT*/
943 u32 *rkey) /*OUT*/
944{
945 int ret;
946 u64 h_ret;
947 u32 hipz_acl;
948 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
949
950 ehca_mrmw_map_acl(acl, &hipz_acl);
951 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
952 if (ehca_use_hp_mr == 1)
953 hipz_acl |= 0x00000001;
954
955 h_ret = hipz_h_alloc_resource_mr(shca->ipz_hca_handle, e_mr,
956 (u64)iova_start, size, hipz_acl,
957 e_pd->fw_pd, &hipzout);
958 if (h_ret != H_SUCCESS) {
959 ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%lx "
960 "hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle);
961 ret = ehca_mrmw_map_hrc_alloc(h_ret);
962 goto ehca_reg_mr_exit0;
963 }
964
965 e_mr->ipz_mr_handle = hipzout.handle;
966
967 ret = ehca_reg_mr_rpages(shca, e_mr, pginfo);
968 if (ret)
969 goto ehca_reg_mr_exit1;
970
971 /* successful registration */
972 e_mr->num_pages = pginfo->num_pages;
973 e_mr->num_4k = pginfo->num_4k;
974 e_mr->start = iova_start;
975 e_mr->size = size;
976 e_mr->acl = acl;
977 *lkey = hipzout.lkey;
978 *rkey = hipzout.rkey;
979 return 0;
980
981ehca_reg_mr_exit1:
982 h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr);
983 if (h_ret != H_SUCCESS) {
984 ehca_err(&shca->ib_device, "h_ret=%lx shca=%p e_mr=%p "
985 "iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x "
986 "pginfo=%p num_pages=%lx num_4k=%lx ret=%x",
987 h_ret, shca, e_mr, iova_start, size, acl, e_pd,
988 hipzout.lkey, pginfo, pginfo->num_pages,
989 pginfo->num_4k, ret);
990 ehca_err(&shca->ib_device, "internal error in ehca_reg_mr, "
991 "not recoverable");
992 }
993ehca_reg_mr_exit0:
994 if (ret)
995 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p "
996 "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "
997 "num_pages=%lx num_4k=%lx",
998 ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo,
999 pginfo->num_pages, pginfo->num_4k);
1000 return ret;
1001} /* end ehca_reg_mr() */
1002
1003/*----------------------------------------------------------------------*/
1004
1005int ehca_reg_mr_rpages(struct ehca_shca *shca,
1006 struct ehca_mr *e_mr,
1007 struct ehca_mr_pginfo *pginfo)
1008{
1009 int ret = 0;
1010 u64 h_ret;
1011 u32 rnum;
1012 u64 rpage;
1013 u32 i;
1014 u64 *kpage;
1015
1016 kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
1017 if (!kpage) {
1018 ehca_err(&shca->ib_device, "kpage alloc failed");
1019 ret = -ENOMEM;
1020 goto ehca_reg_mr_rpages_exit0;
1021 }
1022
1023 /* max 512 pages per shot */
1024 for (i = 0; i < ((pginfo->num_4k + 512 - 1) / 512); i++) {
1025
1026 if (i == ((pginfo->num_4k + 512 - 1) / 512) - 1) {
1027 rnum = pginfo->num_4k % 512; /* last shot */
1028 if (rnum == 0)
1029 rnum = 512; /* last shot is full */
1030 } else
1031 rnum = 512;
1032
1033 if (rnum > 1) {
1034 ret = ehca_set_pagebuf(e_mr, pginfo, rnum, kpage);
1035 if (ret) {
1036 ehca_err(&shca->ib_device, "ehca_set_pagebuf "
1037 "bad rc, ret=%x rnum=%x kpage=%p",
1038 ret, rnum, kpage);
1039 ret = -EFAULT;
1040 goto ehca_reg_mr_rpages_exit1;
1041 }
1042 rpage = virt_to_abs(kpage);
1043 if (!rpage) {
1044 ehca_err(&shca->ib_device, "kpage=%p i=%x",
1045 kpage, i);
1046 ret = -EFAULT;
1047 goto ehca_reg_mr_rpages_exit1;
1048 }
1049 } else { /* rnum==1 */
1050 ret = ehca_set_pagebuf_1(e_mr, pginfo, &rpage);
1051 if (ret) {
1052 ehca_err(&shca->ib_device, "ehca_set_pagebuf_1 "
1053 "bad rc, ret=%x i=%x", ret, i);
1054 ret = -EFAULT;
1055 goto ehca_reg_mr_rpages_exit1;
1056 }
1057 }
1058
1059 h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, e_mr,
1060 0, /* pagesize 4k */
1061 0, rpage, rnum);
1062
1063 if (i == ((pginfo->num_4k + 512 - 1) / 512) - 1) {
1064 /*
1065 * check for 'registration complete'==H_SUCCESS
1066 * and for 'page registered'==H_PAGE_REGISTERED
1067 */
1068 if (h_ret != H_SUCCESS) {
1069 ehca_err(&shca->ib_device, "last "
1070 "hipz_reg_rpage_mr failed, h_ret=%lx "
1071 "e_mr=%p i=%x hca_hndl=%lx mr_hndl=%lx"
1072 " lkey=%x", h_ret, e_mr, i,
1073 shca->ipz_hca_handle.handle,
1074 e_mr->ipz_mr_handle.handle,
1075 e_mr->ib.ib_mr.lkey);
1076 ret = ehca_mrmw_map_hrc_rrpg_last(h_ret);
1077 break;
1078 } else
1079 ret = 0;
1080 } else if (h_ret != H_PAGE_REGISTERED) {
1081 ehca_err(&shca->ib_device, "hipz_reg_rpage_mr failed, "
1082 "h_ret=%lx e_mr=%p i=%x lkey=%x hca_hndl=%lx "
1083 "mr_hndl=%lx", h_ret, e_mr, i,
1084 e_mr->ib.ib_mr.lkey,
1085 shca->ipz_hca_handle.handle,
1086 e_mr->ipz_mr_handle.handle);
1087 ret = ehca_mrmw_map_hrc_rrpg_notlast(h_ret);
1088 break;
1089 } else
1090 ret = 0;
1091 } /* end for(i) */
1092
1093
1094ehca_reg_mr_rpages_exit1:
1095 kfree(kpage);
1096ehca_reg_mr_rpages_exit0:
1097 if (ret)
1098 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p "
1099 "num_pages=%lx num_4k=%lx", ret, shca, e_mr, pginfo,
1100 pginfo->num_pages, pginfo->num_4k);
1101 return ret;
1102} /* end ehca_reg_mr_rpages() */
1103
1104/*----------------------------------------------------------------------*/
1105
1106inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
1107 struct ehca_mr *e_mr,
1108 u64 *iova_start,
1109 u64 size,
1110 u32 acl,
1111 struct ehca_pd *e_pd,
1112 struct ehca_mr_pginfo *pginfo,
1113 u32 *lkey, /*OUT*/
1114 u32 *rkey) /*OUT*/
1115{
1116 int ret;
1117 u64 h_ret;
1118 u32 hipz_acl;
1119 u64 *kpage;
1120 u64 rpage;
1121 struct ehca_mr_pginfo pginfo_save;
1122 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
1123
1124 ehca_mrmw_map_acl(acl, &hipz_acl);
1125 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
1126
1127 kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
1128 if (!kpage) {
1129 ehca_err(&shca->ib_device, "kpage alloc failed");
1130 ret = -ENOMEM;
1131 goto ehca_rereg_mr_rereg1_exit0;
1132 }
1133
1134 pginfo_save = *pginfo;
1135 ret = ehca_set_pagebuf(e_mr, pginfo, pginfo->num_4k, kpage);
1136 if (ret) {
1137 ehca_err(&shca->ib_device, "set pagebuf failed, e_mr=%p "
1138 "pginfo=%p type=%x num_pages=%lx num_4k=%lx kpage=%p",
1139 e_mr, pginfo, pginfo->type, pginfo->num_pages,
1140 pginfo->num_4k,kpage);
1141 goto ehca_rereg_mr_rereg1_exit1;
1142 }
1143 rpage = virt_to_abs(kpage);
1144 if (!rpage) {
1145 ehca_err(&shca->ib_device, "kpage=%p", kpage);
1146 ret = -EFAULT;
1147 goto ehca_rereg_mr_rereg1_exit1;
1148 }
1149 h_ret = hipz_h_reregister_pmr(shca->ipz_hca_handle, e_mr,
1150 (u64)iova_start, size, hipz_acl,
1151 e_pd->fw_pd, rpage, &hipzout);
1152 if (h_ret != H_SUCCESS) {
1153 /*
1154 * reregistration unsuccessful, try it again with the 3 hCalls,
1155 * e.g. this is required in case H_MR_CONDITION
1156 * (MW bound or MR is shared)
1157 */
1158 ehca_warn(&shca->ib_device, "hipz_h_reregister_pmr failed "
1159 "(Rereg1), h_ret=%lx e_mr=%p", h_ret, e_mr);
1160 *pginfo = pginfo_save;
1161 ret = -EAGAIN;
1162 } else if ((u64*)hipzout.vaddr != iova_start) {
1163 ehca_err(&shca->ib_device, "PHYP changed iova_start in "
1164 "rereg_pmr, iova_start=%p iova_start_out=%lx e_mr=%p "
1165 "mr_handle=%lx lkey=%x lkey_out=%x", iova_start,
1166 hipzout.vaddr, e_mr, e_mr->ipz_mr_handle.handle,
1167 e_mr->ib.ib_mr.lkey, hipzout.lkey);
1168 ret = -EFAULT;
1169 } else {
1170 /*
1171 * successful reregistration
1172 * note: start and start_out are identical for eServer HCAs
1173 */
1174 e_mr->num_pages = pginfo->num_pages;
1175 e_mr->num_4k = pginfo->num_4k;
1176 e_mr->start = iova_start;
1177 e_mr->size = size;
1178 e_mr->acl = acl;
1179 *lkey = hipzout.lkey;
1180 *rkey = hipzout.rkey;
1181 }
1182
1183ehca_rereg_mr_rereg1_exit1:
1184 kfree(kpage);
1185ehca_rereg_mr_rereg1_exit0:
1186 if ( ret && (ret != -EAGAIN) )
1187 ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x "
1188 "pginfo=%p num_pages=%lx num_4k=%lx",
1189 ret, *lkey, *rkey, pginfo, pginfo->num_pages,
1190 pginfo->num_4k);
1191 return ret;
1192} /* end ehca_rereg_mr_rereg1() */
1193
1194/*----------------------------------------------------------------------*/
1195
1196int ehca_rereg_mr(struct ehca_shca *shca,
1197 struct ehca_mr *e_mr,
1198 u64 *iova_start,
1199 u64 size,
1200 int acl,
1201 struct ehca_pd *e_pd,
1202 struct ehca_mr_pginfo *pginfo,
1203 u32 *lkey,
1204 u32 *rkey)
1205{
1206 int ret = 0;
1207 u64 h_ret;
1208 int rereg_1_hcall = 1; /* 1: use hipz_h_reregister_pmr directly */
1209 int rereg_3_hcall = 0; /* 1: use 3 hipz calls for reregistration */
1210
1211 /* first determine reregistration hCall(s) */
1212 if ((pginfo->num_4k > 512) || (e_mr->num_4k > 512) ||
1213 (pginfo->num_4k > e_mr->num_4k)) {
1214 ehca_dbg(&shca->ib_device, "Rereg3 case, pginfo->num_4k=%lx "
1215 "e_mr->num_4k=%x", pginfo->num_4k, e_mr->num_4k);
1216 rereg_1_hcall = 0;
1217 rereg_3_hcall = 1;
1218 }
1219
1220 if (e_mr->flags & EHCA_MR_FLAG_MAXMR) { /* check for max-MR */
1221 rereg_1_hcall = 0;
1222 rereg_3_hcall = 1;
1223 e_mr->flags &= ~EHCA_MR_FLAG_MAXMR;
1224 ehca_err(&shca->ib_device, "Rereg MR for max-MR! e_mr=%p",
1225 e_mr);
1226 }
1227
1228 if (rereg_1_hcall) {
1229 ret = ehca_rereg_mr_rereg1(shca, e_mr, iova_start, size,
1230 acl, e_pd, pginfo, lkey, rkey);
1231 if (ret) {
1232 if (ret == -EAGAIN)
1233 rereg_3_hcall = 1;
1234 else
1235 goto ehca_rereg_mr_exit0;
1236 }
1237 }
1238
1239 if (rereg_3_hcall) {
1240 struct ehca_mr save_mr;
1241
1242 /* first deregister old MR */
1243 h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr);
1244 if (h_ret != H_SUCCESS) {
1245 ehca_err(&shca->ib_device, "hipz_free_mr failed, "
1246 "h_ret=%lx e_mr=%p hca_hndl=%lx mr_hndl=%lx "
1247 "mr->lkey=%x",
1248 h_ret, e_mr, shca->ipz_hca_handle.handle,
1249 e_mr->ipz_mr_handle.handle,
1250 e_mr->ib.ib_mr.lkey);
1251 ret = ehca_mrmw_map_hrc_free_mr(h_ret);
1252 goto ehca_rereg_mr_exit0;
1253 }
1254 /* clean ehca_mr_t, without changing struct ib_mr and lock */
1255 save_mr = *e_mr;
1256 ehca_mr_deletenew(e_mr);
1257
1258 /* set some MR values */
1259 e_mr->flags = save_mr.flags;
1260 e_mr->fmr_page_size = save_mr.fmr_page_size;
1261 e_mr->fmr_max_pages = save_mr.fmr_max_pages;
1262 e_mr->fmr_max_maps = save_mr.fmr_max_maps;
1263 e_mr->fmr_map_cnt = save_mr.fmr_map_cnt;
1264
1265 ret = ehca_reg_mr(shca, e_mr, iova_start, size, acl,
1266 e_pd, pginfo, lkey, rkey);
1267 if (ret) {
1268 u32 offset = (u64)(&e_mr->flags) - (u64)e_mr;
1269 memcpy(&e_mr->flags, &(save_mr.flags),
1270 sizeof(struct ehca_mr) - offset);
1271 goto ehca_rereg_mr_exit0;
1272 }
1273 }
1274
1275ehca_rereg_mr_exit0:
1276 if (ret)
1277 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p "
1278 "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "
1279 "num_pages=%lx lkey=%x rkey=%x rereg_1_hcall=%x "
1280 "rereg_3_hcall=%x", ret, shca, e_mr, iova_start, size,
1281 acl, e_pd, pginfo, pginfo->num_pages, *lkey, *rkey,
1282 rereg_1_hcall, rereg_3_hcall);
1283 return ret;
1284} /* end ehca_rereg_mr() */
1285
1286/*----------------------------------------------------------------------*/
1287
1288int ehca_unmap_one_fmr(struct ehca_shca *shca,
1289 struct ehca_mr *e_fmr)
1290{
1291 int ret = 0;
1292 u64 h_ret;
1293 int rereg_1_hcall = 1; /* 1: use hipz_mr_reregister directly */
1294 int rereg_3_hcall = 0; /* 1: use 3 hipz calls for unmapping */
1295 struct ehca_pd *e_pd =
1296 container_of(e_fmr->ib.ib_fmr.pd, struct ehca_pd, ib_pd);
1297 struct ehca_mr save_fmr;
1298 u32 tmp_lkey, tmp_rkey;
1299 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
1300 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
1301
1302 /* first check if reregistration hCall can be used for unmap */
1303 if (e_fmr->fmr_max_pages > 512) {
1304 rereg_1_hcall = 0;
1305 rereg_3_hcall = 1;
1306 }
1307
1308 if (rereg_1_hcall) {
1309 /*
1310 * note: after using rereg hcall with len=0,
1311 * rereg hcall must be used again for registering pages
1312 */
1313 h_ret = hipz_h_reregister_pmr(shca->ipz_hca_handle, e_fmr, 0,
1314 0, 0, e_pd->fw_pd, 0, &hipzout);
1315 if (h_ret != H_SUCCESS) {
1316 /*
1317 * should not happen, because length checked above,
1318 * FMRs are not shared and no MW bound to FMRs
1319 */
1320 ehca_err(&shca->ib_device, "hipz_reregister_pmr failed "
1321 "(Rereg1), h_ret=%lx e_fmr=%p hca_hndl=%lx "
1322 "mr_hndl=%lx lkey=%x lkey_out=%x",
1323 h_ret, e_fmr, shca->ipz_hca_handle.handle,
1324 e_fmr->ipz_mr_handle.handle,
1325 e_fmr->ib.ib_fmr.lkey, hipzout.lkey);
1326 rereg_3_hcall = 1;
1327 } else {
1328 /* successful reregistration */
1329 e_fmr->start = NULL;
1330 e_fmr->size = 0;
1331 tmp_lkey = hipzout.lkey;
1332 tmp_rkey = hipzout.rkey;
1333 }
1334 }
1335
1336 if (rereg_3_hcall) {
1337 struct ehca_mr save_mr;
1338
1339 /* first free old FMR */
1340 h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr);
1341 if (h_ret != H_SUCCESS) {
1342 ehca_err(&shca->ib_device, "hipz_free_mr failed, "
1343 "h_ret=%lx e_fmr=%p hca_hndl=%lx mr_hndl=%lx "
1344 "lkey=%x",
1345 h_ret, e_fmr, shca->ipz_hca_handle.handle,
1346 e_fmr->ipz_mr_handle.handle,
1347 e_fmr->ib.ib_fmr.lkey);
1348 ret = ehca_mrmw_map_hrc_free_mr(h_ret);
1349 goto ehca_unmap_one_fmr_exit0;
1350 }
1351 /* clean ehca_mr_t, without changing lock */
1352 save_fmr = *e_fmr;
1353 ehca_mr_deletenew(e_fmr);
1354
1355 /* set some MR values */
1356 e_fmr->flags = save_fmr.flags;
1357 e_fmr->fmr_page_size = save_fmr.fmr_page_size;
1358 e_fmr->fmr_max_pages = save_fmr.fmr_max_pages;
1359 e_fmr->fmr_max_maps = save_fmr.fmr_max_maps;
1360 e_fmr->fmr_map_cnt = save_fmr.fmr_map_cnt;
1361 e_fmr->acl = save_fmr.acl;
1362
1363 pginfo.type = EHCA_MR_PGI_FMR;
1364 pginfo.num_pages = 0;
1365 pginfo.num_4k = 0;
1366 ret = ehca_reg_mr(shca, e_fmr, NULL,
1367 (e_fmr->fmr_max_pages * e_fmr->fmr_page_size),
1368 e_fmr->acl, e_pd, &pginfo, &tmp_lkey,
1369 &tmp_rkey);
1370 if (ret) {
1371 u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr;
1372 memcpy(&e_fmr->flags, &(save_mr.flags),
1373 sizeof(struct ehca_mr) - offset);
1374 goto ehca_unmap_one_fmr_exit0;
1375 }
1376 }
1377
1378ehca_unmap_one_fmr_exit0:
1379 if (ret)
1380 ehca_err(&shca->ib_device, "ret=%x tmp_lkey=%x tmp_rkey=%x "
1381 "fmr_max_pages=%x rereg_1_hcall=%x rereg_3_hcall=%x",
1382 ret, tmp_lkey, tmp_rkey, e_fmr->fmr_max_pages,
1383 rereg_1_hcall, rereg_3_hcall);
1384 return ret;
1385} /* end ehca_unmap_one_fmr() */
1386
1387/*----------------------------------------------------------------------*/
1388
1389int ehca_reg_smr(struct ehca_shca *shca,
1390 struct ehca_mr *e_origmr,
1391 struct ehca_mr *e_newmr,
1392 u64 *iova_start,
1393 int acl,
1394 struct ehca_pd *e_pd,
1395 u32 *lkey, /*OUT*/
1396 u32 *rkey) /*OUT*/
1397{
1398 int ret = 0;
1399 u64 h_ret;
1400 u32 hipz_acl;
1401 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
1402
1403 ehca_mrmw_map_acl(acl, &hipz_acl);
1404 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
1405
1406 h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr,
1407 (u64)iova_start, hipz_acl, e_pd->fw_pd,
1408 &hipzout);
1409 if (h_ret != H_SUCCESS) {
1410 ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%lx "
1411 "shca=%p e_origmr=%p e_newmr=%p iova_start=%p acl=%x "
1412 "e_pd=%p hca_hndl=%lx mr_hndl=%lx lkey=%x",
1413 h_ret, shca, e_origmr, e_newmr, iova_start, acl, e_pd,
1414 shca->ipz_hca_handle.handle,
1415 e_origmr->ipz_mr_handle.handle,
1416 e_origmr->ib.ib_mr.lkey);
1417 ret = ehca_mrmw_map_hrc_reg_smr(h_ret);
1418 goto ehca_reg_smr_exit0;
1419 }
1420 /* successful registration */
1421 e_newmr->num_pages = e_origmr->num_pages;
1422 e_newmr->num_4k = e_origmr->num_4k;
1423 e_newmr->start = iova_start;
1424 e_newmr->size = e_origmr->size;
1425 e_newmr->acl = acl;
1426 e_newmr->ipz_mr_handle = hipzout.handle;
1427 *lkey = hipzout.lkey;
1428 *rkey = hipzout.rkey;
1429 return 0;
1430
1431ehca_reg_smr_exit0:
1432 if (ret)
1433 ehca_err(&shca->ib_device, "ret=%x shca=%p e_origmr=%p "
1434 "e_newmr=%p iova_start=%p acl=%x e_pd=%p",
1435 ret, shca, e_origmr, e_newmr, iova_start, acl, e_pd);
1436 return ret;
1437} /* end ehca_reg_smr() */
1438
1439/*----------------------------------------------------------------------*/
1440
1441/* register internal max-MR to internal SHCA */
1442int ehca_reg_internal_maxmr(
1443 struct ehca_shca *shca,
1444 struct ehca_pd *e_pd,
1445 struct ehca_mr **e_maxmr) /*OUT*/
1446{
1447 int ret;
1448 struct ehca_mr *e_mr;
1449 u64 *iova_start;
1450 u64 size_maxmr;
1451 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
1452 struct ib_phys_buf ib_pbuf;
1453 u32 num_pages_mr;
1454 u32 num_pages_4k; /* 4k portion "pages" */
1455
1456 e_mr = ehca_mr_new();
1457 if (!e_mr) {
1458 ehca_err(&shca->ib_device, "out of memory");
1459 ret = -ENOMEM;
1460 goto ehca_reg_internal_maxmr_exit0;
1461 }
1462 e_mr->flags |= EHCA_MR_FLAG_MAXMR;
1463
1464 /* register internal max-MR on HCA */
1465 size_maxmr = (u64)high_memory - PAGE_OFFSET;
1466 iova_start = (u64*)KERNELBASE;
1467 ib_pbuf.addr = 0;
1468 ib_pbuf.size = size_maxmr;
1469 num_pages_mr = ((((u64)iova_start % PAGE_SIZE) + size_maxmr +
1470 PAGE_SIZE - 1) / PAGE_SIZE);
1471 num_pages_4k = ((((u64)iova_start % EHCA_PAGESIZE) + size_maxmr +
1472 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE);
1473
1474 pginfo.type = EHCA_MR_PGI_PHYS;
1475 pginfo.num_pages = num_pages_mr;
1476 pginfo.num_4k = num_pages_4k;
1477 pginfo.num_phys_buf = 1;
1478 pginfo.phys_buf_array = &ib_pbuf;
1479
1480 ret = ehca_reg_mr(shca, e_mr, iova_start, size_maxmr, 0, e_pd,
1481 &pginfo, &e_mr->ib.ib_mr.lkey,
1482 &e_mr->ib.ib_mr.rkey);
1483 if (ret) {
1484 ehca_err(&shca->ib_device, "reg of internal max MR failed, "
1485 "e_mr=%p iova_start=%p size_maxmr=%lx num_pages_mr=%x "
1486 "num_pages_4k=%x", e_mr, iova_start, size_maxmr,
1487 num_pages_mr, num_pages_4k);
1488 goto ehca_reg_internal_maxmr_exit1;
1489 }
1490
1491 /* successful registration of all pages */
1492 e_mr->ib.ib_mr.device = e_pd->ib_pd.device;
1493 e_mr->ib.ib_mr.pd = &e_pd->ib_pd;
1494 e_mr->ib.ib_mr.uobject = NULL;
1495 atomic_inc(&(e_pd->ib_pd.usecnt));
1496 atomic_set(&(e_mr->ib.ib_mr.usecnt), 0);
1497 *e_maxmr = e_mr;
1498 return 0;
1499
1500ehca_reg_internal_maxmr_exit1:
1501 ehca_mr_delete(e_mr);
1502ehca_reg_internal_maxmr_exit0:
1503 if (ret)
1504 ehca_err(&shca->ib_device, "ret=%x shca=%p e_pd=%p e_maxmr=%p",
1505 ret, shca, e_pd, e_maxmr);
1506 return ret;
1507} /* end ehca_reg_internal_maxmr() */
1508
1509/*----------------------------------------------------------------------*/
1510
1511int ehca_reg_maxmr(struct ehca_shca *shca,
1512 struct ehca_mr *e_newmr,
1513 u64 *iova_start,
1514 int acl,
1515 struct ehca_pd *e_pd,
1516 u32 *lkey,
1517 u32 *rkey)
1518{
1519 u64 h_ret;
1520 struct ehca_mr *e_origmr = shca->maxmr;
1521 u32 hipz_acl;
1522 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
1523
1524 ehca_mrmw_map_acl(acl, &hipz_acl);
1525 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
1526
1527 h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr,
1528 (u64)iova_start, hipz_acl, e_pd->fw_pd,
1529 &hipzout);
1530 if (h_ret != H_SUCCESS) {
1531 ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%lx "
1532 "e_origmr=%p hca_hndl=%lx mr_hndl=%lx lkey=%x",
1533 h_ret, e_origmr, shca->ipz_hca_handle.handle,
1534 e_origmr->ipz_mr_handle.handle,
1535 e_origmr->ib.ib_mr.lkey);
1536 return ehca_mrmw_map_hrc_reg_smr(h_ret);
1537 }
1538 /* successful registration */
1539 e_newmr->num_pages = e_origmr->num_pages;
1540 e_newmr->num_4k = e_origmr->num_4k;
1541 e_newmr->start = iova_start;
1542 e_newmr->size = e_origmr->size;
1543 e_newmr->acl = acl;
1544 e_newmr->ipz_mr_handle = hipzout.handle;
1545 *lkey = hipzout.lkey;
1546 *rkey = hipzout.rkey;
1547 return 0;
1548} /* end ehca_reg_maxmr() */
1549
1550/*----------------------------------------------------------------------*/
1551
1552int ehca_dereg_internal_maxmr(struct ehca_shca *shca)
1553{
1554 int ret;
1555 struct ehca_mr *e_maxmr;
1556 struct ib_pd *ib_pd;
1557
1558 if (!shca->maxmr) {
1559 ehca_err(&shca->ib_device, "bad call, shca=%p", shca);
1560 ret = -EINVAL;
1561 goto ehca_dereg_internal_maxmr_exit0;
1562 }
1563
1564 e_maxmr = shca->maxmr;
1565 ib_pd = e_maxmr->ib.ib_mr.pd;
1566 shca->maxmr = NULL; /* remove internal max-MR indication from SHCA */
1567
1568 ret = ehca_dereg_mr(&e_maxmr->ib.ib_mr);
1569 if (ret) {
1570 ehca_err(&shca->ib_device, "dereg internal max-MR failed, "
1571 "ret=%x e_maxmr=%p shca=%p lkey=%x",
1572 ret, e_maxmr, shca, e_maxmr->ib.ib_mr.lkey);
1573 shca->maxmr = e_maxmr;
1574 goto ehca_dereg_internal_maxmr_exit0;
1575 }
1576
1577 atomic_dec(&ib_pd->usecnt);
1578
1579ehca_dereg_internal_maxmr_exit0:
1580 if (ret)
1581 ehca_err(&shca->ib_device, "ret=%x shca=%p shca->maxmr=%p",
1582 ret, shca, shca->maxmr);
1583 return ret;
1584} /* end ehca_dereg_internal_maxmr() */
1585
1586/*----------------------------------------------------------------------*/
1587
1588/*
1589 * check physical buffer array of MR verbs for validness and
1590 * calculates MR size
1591 */
1592int ehca_mr_chk_buf_and_calc_size(struct ib_phys_buf *phys_buf_array,
1593 int num_phys_buf,
1594 u64 *iova_start,
1595 u64 *size)
1596{
1597 struct ib_phys_buf *pbuf = phys_buf_array;
1598 u64 size_count = 0;
1599 u32 i;
1600
1601 if (num_phys_buf == 0) {
1602 ehca_gen_err("bad phys buf array len, num_phys_buf=0");
1603 return -EINVAL;
1604 }
1605 /* check first buffer */
1606 if (((u64)iova_start & ~PAGE_MASK) != (pbuf->addr & ~PAGE_MASK)) {
1607 ehca_gen_err("iova_start/addr mismatch, iova_start=%p "
1608 "pbuf->addr=%lx pbuf->size=%lx",
1609 iova_start, pbuf->addr, pbuf->size);
1610 return -EINVAL;
1611 }
1612 if (((pbuf->addr + pbuf->size) % PAGE_SIZE) &&
1613 (num_phys_buf > 1)) {
1614 ehca_gen_err("addr/size mismatch in 1st buf, pbuf->addr=%lx "
1615 "pbuf->size=%lx", pbuf->addr, pbuf->size);
1616 return -EINVAL;
1617 }
1618
1619 for (i = 0; i < num_phys_buf; i++) {
1620 if ((i > 0) && (pbuf->addr % PAGE_SIZE)) {
1621 ehca_gen_err("bad address, i=%x pbuf->addr=%lx "
1622 "pbuf->size=%lx",
1623 i, pbuf->addr, pbuf->size);
1624 return -EINVAL;
1625 }
1626 if (((i > 0) && /* not 1st */
1627 (i < (num_phys_buf - 1)) && /* not last */
1628 (pbuf->size % PAGE_SIZE)) || (pbuf->size == 0)) {
1629 ehca_gen_err("bad size, i=%x pbuf->size=%lx",
1630 i, pbuf->size);
1631 return -EINVAL;
1632 }
1633 size_count += pbuf->size;
1634 pbuf++;
1635 }
1636
1637 *size = size_count;
1638 return 0;
1639} /* end ehca_mr_chk_buf_and_calc_size() */
1640
1641/*----------------------------------------------------------------------*/
1642
1643/* check page list of map FMR verb for validness */
1644int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
1645 u64 *page_list,
1646 int list_len)
1647{
1648 u32 i;
1649 u64 *page;
1650
1651 if ((list_len == 0) || (list_len > e_fmr->fmr_max_pages)) {
1652 ehca_gen_err("bad list_len, list_len=%x "
1653 "e_fmr->fmr_max_pages=%x fmr=%p",
1654 list_len, e_fmr->fmr_max_pages, e_fmr);
1655 return -EINVAL;
1656 }
1657
1658 /* each page must be aligned */
1659 page = page_list;
1660 for (i = 0; i < list_len; i++) {
1661 if (*page % e_fmr->fmr_page_size) {
1662 ehca_gen_err("bad page, i=%x *page=%lx page=%p fmr=%p "
1663 "fmr_page_size=%x", i, *page, page, e_fmr,
1664 e_fmr->fmr_page_size);
1665 return -EINVAL;
1666 }
1667 page++;
1668 }
1669
1670 return 0;
1671} /* end ehca_fmr_check_page_list() */
1672
1673/*----------------------------------------------------------------------*/
1674
1675/* setup page buffer from page info */
1676int ehca_set_pagebuf(struct ehca_mr *e_mr,
1677 struct ehca_mr_pginfo *pginfo,
1678 u32 number,
1679 u64 *kpage)
1680{
1681 int ret = 0;
1682 struct ib_umem_chunk *prev_chunk;
1683 struct ib_umem_chunk *chunk;
1684 struct ib_phys_buf *pbuf;
1685 u64 *fmrlist;
1686 u64 num4k, pgaddr, offs4k;
1687 u32 i = 0;
1688 u32 j = 0;
1689
1690 if (pginfo->type == EHCA_MR_PGI_PHYS) {
1691 /* loop over desired phys_buf_array entries */
1692 while (i < number) {
1693 pbuf = pginfo->phys_buf_array + pginfo->next_buf;
1694 num4k = ((pbuf->addr % EHCA_PAGESIZE) + pbuf->size +
1695 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE;
1696 offs4k = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
1697 while (pginfo->next_4k < offs4k + num4k) {
1698 /* sanity check */
1699 if ((pginfo->page_cnt >= pginfo->num_pages) ||
1700 (pginfo->page_4k_cnt >= pginfo->num_4k)) {
1701 ehca_gen_err("page_cnt >= num_pages, "
1702 "page_cnt=%lx "
1703 "num_pages=%lx "
1704 "page_4k_cnt=%lx "
1705 "num_4k=%lx i=%x",
1706 pginfo->page_cnt,
1707 pginfo->num_pages,
1708 pginfo->page_4k_cnt,
1709 pginfo->num_4k, i);
1710 ret = -EFAULT;
1711 goto ehca_set_pagebuf_exit0;
1712 }
1713 *kpage = phys_to_abs(
1714 (pbuf->addr & EHCA_PAGEMASK)
1715 + (pginfo->next_4k * EHCA_PAGESIZE));
1716 if ( !(*kpage) && pbuf->addr ) {
1717 ehca_gen_err("pbuf->addr=%lx "
1718 "pbuf->size=%lx "
1719 "next_4k=%lx", pbuf->addr,
1720 pbuf->size,
1721 pginfo->next_4k);
1722 ret = -EFAULT;
1723 goto ehca_set_pagebuf_exit0;
1724 }
1725 (pginfo->page_4k_cnt)++;
1726 (pginfo->next_4k)++;
1727 if (pginfo->next_4k %
1728 (PAGE_SIZE / EHCA_PAGESIZE) == 0)
1729 (pginfo->page_cnt)++;
1730 kpage++;
1731 i++;
1732 if (i >= number) break;
1733 }
1734 if (pginfo->next_4k >= offs4k + num4k) {
1735 (pginfo->next_buf)++;
1736 pginfo->next_4k = 0;
1737 }
1738 }
1739 } else if (pginfo->type == EHCA_MR_PGI_USER) {
1740 /* loop over desired chunk entries */
1741 chunk = pginfo->next_chunk;
1742 prev_chunk = pginfo->next_chunk;
1743 list_for_each_entry_continue(chunk,
1744 (&(pginfo->region->chunk_list)),
1745 list) {
1746 for (i = pginfo->next_nmap; i < chunk->nmap; ) {
1747 pgaddr = ( page_to_pfn(chunk->page_list[i].page)
1748 << PAGE_SHIFT );
1749 *kpage = phys_to_abs(pgaddr +
1750 (pginfo->next_4k *
1751 EHCA_PAGESIZE));
1752 if ( !(*kpage) ) {
1753 ehca_gen_err("pgaddr=%lx "
1754 "chunk->page_list[i]=%lx "
1755 "i=%x next_4k=%lx mr=%p",
1756 pgaddr,
1757 (u64)sg_dma_address(
1758 &chunk->
1759 page_list[i]),
1760 i, pginfo->next_4k, e_mr);
1761 ret = -EFAULT;
1762 goto ehca_set_pagebuf_exit0;
1763 }
1764 (pginfo->page_4k_cnt)++;
1765 (pginfo->next_4k)++;
1766 kpage++;
1767 if (pginfo->next_4k %
1768 (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
1769 (pginfo->page_cnt)++;
1770 (pginfo->next_nmap)++;
1771 pginfo->next_4k = 0;
1772 i++;
1773 }
1774 j++;
1775 if (j >= number) break;
1776 }
1777 if ((pginfo->next_nmap >= chunk->nmap) &&
1778 (j >= number)) {
1779 pginfo->next_nmap = 0;
1780 prev_chunk = chunk;
1781 break;
1782 } else if (pginfo->next_nmap >= chunk->nmap) {
1783 pginfo->next_nmap = 0;
1784 prev_chunk = chunk;
1785 } else if (j >= number)
1786 break;
1787 else
1788 prev_chunk = chunk;
1789 }
1790 pginfo->next_chunk =
1791 list_prepare_entry(prev_chunk,
1792 (&(pginfo->region->chunk_list)),
1793 list);
1794 } else if (pginfo->type == EHCA_MR_PGI_FMR) {
1795 /* loop over desired page_list entries */
1796 fmrlist = pginfo->page_list + pginfo->next_listelem;
1797 for (i = 0; i < number; i++) {
1798 *kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
1799 pginfo->next_4k * EHCA_PAGESIZE);
1800 if ( !(*kpage) ) {
1801 ehca_gen_err("*fmrlist=%lx fmrlist=%p "
1802 "next_listelem=%lx next_4k=%lx",
1803 *fmrlist, fmrlist,
1804 pginfo->next_listelem,
1805 pginfo->next_4k);
1806 ret = -EFAULT;
1807 goto ehca_set_pagebuf_exit0;
1808 }
1809 (pginfo->page_4k_cnt)++;
1810 (pginfo->next_4k)++;
1811 kpage++;
1812 if (pginfo->next_4k %
1813 (e_mr->fmr_page_size / EHCA_PAGESIZE) == 0) {
1814 (pginfo->page_cnt)++;
1815 (pginfo->next_listelem)++;
1816 fmrlist++;
1817 pginfo->next_4k = 0;
1818 }
1819 }
1820 } else {
1821 ehca_gen_err("bad pginfo->type=%x", pginfo->type);
1822 ret = -EFAULT;
1823 goto ehca_set_pagebuf_exit0;
1824 }
1825
1826ehca_set_pagebuf_exit0:
1827 if (ret)
1828 ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_pages=%lx "
1829 "num_4k=%lx next_buf=%lx next_4k=%lx number=%x "
1830 "kpage=%p page_cnt=%lx page_4k_cnt=%lx i=%x "
1831 "next_listelem=%lx region=%p next_chunk=%p "
1832 "next_nmap=%lx", ret, e_mr, pginfo, pginfo->type,
1833 pginfo->num_pages, pginfo->num_4k,
1834 pginfo->next_buf, pginfo->next_4k, number, kpage,
1835 pginfo->page_cnt, pginfo->page_4k_cnt, i,
1836 pginfo->next_listelem, pginfo->region,
1837 pginfo->next_chunk, pginfo->next_nmap);
1838 return ret;
1839} /* end ehca_set_pagebuf() */
1840
1841/*----------------------------------------------------------------------*/
1842
1843/* setup 1 page from page info page buffer */
1844int ehca_set_pagebuf_1(struct ehca_mr *e_mr,
1845 struct ehca_mr_pginfo *pginfo,
1846 u64 *rpage)
1847{
1848 int ret = 0;
1849 struct ib_phys_buf *tmp_pbuf;
1850 u64 *fmrlist;
1851 struct ib_umem_chunk *chunk;
1852 struct ib_umem_chunk *prev_chunk;
1853 u64 pgaddr, num4k, offs4k;
1854
1855 if (pginfo->type == EHCA_MR_PGI_PHYS) {
1856 /* sanity check */
1857 if ((pginfo->page_cnt >= pginfo->num_pages) ||
1858 (pginfo->page_4k_cnt >= pginfo->num_4k)) {
1859 ehca_gen_err("page_cnt >= num_pages, page_cnt=%lx "
1860 "num_pages=%lx page_4k_cnt=%lx num_4k=%lx",
1861 pginfo->page_cnt, pginfo->num_pages,
1862 pginfo->page_4k_cnt, pginfo->num_4k);
1863 ret = -EFAULT;
1864 goto ehca_set_pagebuf_1_exit0;
1865 }
1866 tmp_pbuf = pginfo->phys_buf_array + pginfo->next_buf;
1867 num4k = ((tmp_pbuf->addr % EHCA_PAGESIZE) + tmp_pbuf->size +
1868 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE;
1869 offs4k = (tmp_pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
1870 *rpage = phys_to_abs((tmp_pbuf->addr & EHCA_PAGEMASK) +
1871 (pginfo->next_4k * EHCA_PAGESIZE));
1872 if ( !(*rpage) && tmp_pbuf->addr ) {
1873 ehca_gen_err("tmp_pbuf->addr=%lx"
1874 " tmp_pbuf->size=%lx next_4k=%lx",
1875 tmp_pbuf->addr, tmp_pbuf->size,
1876 pginfo->next_4k);
1877 ret = -EFAULT;
1878 goto ehca_set_pagebuf_1_exit0;
1879 }
1880 (pginfo->page_4k_cnt)++;
1881 (pginfo->next_4k)++;
1882 if (pginfo->next_4k % (PAGE_SIZE / EHCA_PAGESIZE) == 0)
1883 (pginfo->page_cnt)++;
1884 if (pginfo->next_4k >= offs4k + num4k) {
1885 (pginfo->next_buf)++;
1886 pginfo->next_4k = 0;
1887 }
1888 } else if (pginfo->type == EHCA_MR_PGI_USER) {
1889 chunk = pginfo->next_chunk;
1890 prev_chunk = pginfo->next_chunk;
1891 list_for_each_entry_continue(chunk,
1892 (&(pginfo->region->chunk_list)),
1893 list) {
1894 pgaddr = ( page_to_pfn(chunk->page_list[
1895 pginfo->next_nmap].page)
1896 << PAGE_SHIFT);
1897 *rpage = phys_to_abs(pgaddr +
1898 (pginfo->next_4k * EHCA_PAGESIZE));
1899 if ( !(*rpage) ) {
1900 ehca_gen_err("pgaddr=%lx chunk->page_list[]=%lx"
1901 " next_nmap=%lx next_4k=%lx mr=%p",
1902 pgaddr, (u64)sg_dma_address(
1903 &chunk->page_list[
1904 pginfo->
1905 next_nmap]),
1906 pginfo->next_nmap, pginfo->next_4k,
1907 e_mr);
1908 ret = -EFAULT;
1909 goto ehca_set_pagebuf_1_exit0;
1910 }
1911 (pginfo->page_4k_cnt)++;
1912 (pginfo->next_4k)++;
1913 if (pginfo->next_4k %
1914 (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
1915 (pginfo->page_cnt)++;
1916 (pginfo->next_nmap)++;
1917 pginfo->next_4k = 0;
1918 }
1919 if (pginfo->next_nmap >= chunk->nmap) {
1920 pginfo->next_nmap = 0;
1921 prev_chunk = chunk;
1922 }
1923 break;
1924 }
1925 pginfo->next_chunk =
1926 list_prepare_entry(prev_chunk,
1927 (&(pginfo->region->chunk_list)),
1928 list);
1929 } else if (pginfo->type == EHCA_MR_PGI_FMR) {
1930 fmrlist = pginfo->page_list + pginfo->next_listelem;
1931 *rpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
1932 pginfo->next_4k * EHCA_PAGESIZE);
1933 if ( !(*rpage) ) {
1934 ehca_gen_err("*fmrlist=%lx fmrlist=%p "
1935 "next_listelem=%lx next_4k=%lx",
1936 *fmrlist, fmrlist, pginfo->next_listelem,
1937 pginfo->next_4k);
1938 ret = -EFAULT;
1939 goto ehca_set_pagebuf_1_exit0;
1940 }
1941 (pginfo->page_4k_cnt)++;
1942 (pginfo->next_4k)++;
1943 if (pginfo->next_4k %
1944 (e_mr->fmr_page_size / EHCA_PAGESIZE) == 0) {
1945 (pginfo->page_cnt)++;
1946 (pginfo->next_listelem)++;
1947 pginfo->next_4k = 0;
1948 }
1949 } else {
1950 ehca_gen_err("bad pginfo->type=%x", pginfo->type);
1951 ret = -EFAULT;
1952 goto ehca_set_pagebuf_1_exit0;
1953 }
1954
1955ehca_set_pagebuf_1_exit0:
1956 if (ret)
1957 ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_pages=%lx "
1958 "num_4k=%lx next_buf=%lx next_4k=%lx rpage=%p "
1959 "page_cnt=%lx page_4k_cnt=%lx next_listelem=%lx "
1960 "region=%p next_chunk=%p next_nmap=%lx", ret, e_mr,
1961 pginfo, pginfo->type, pginfo->num_pages,
1962 pginfo->num_4k, pginfo->next_buf, pginfo->next_4k,
1963 rpage, pginfo->page_cnt, pginfo->page_4k_cnt,
1964 pginfo->next_listelem, pginfo->region,
1965 pginfo->next_chunk, pginfo->next_nmap);
1966 return ret;
1967} /* end ehca_set_pagebuf_1() */
1968
1969/*----------------------------------------------------------------------*/
1970
1971/*
1972 * check MR if it is a max-MR, i.e. uses whole memory
1973 * in case it's a max-MR 1 is returned, else 0
1974 */
1975int ehca_mr_is_maxmr(u64 size,
1976 u64 *iova_start)
1977{
1978 /* a MR is treated as max-MR only if it fits following: */
1979 if ((size == ((u64)high_memory - PAGE_OFFSET)) &&
1980 (iova_start == (void*)KERNELBASE)) {
1981 ehca_gen_dbg("this is a max-MR");
1982 return 1;
1983 } else
1984 return 0;
1985} /* end ehca_mr_is_maxmr() */
1986
1987/*----------------------------------------------------------------------*/
1988
1989/* map access control for MR/MW. This routine is used for MR and MW. */
1990void ehca_mrmw_map_acl(int ib_acl,
1991 u32 *hipz_acl)
1992{
1993 *hipz_acl = 0;
1994 if (ib_acl & IB_ACCESS_REMOTE_READ)
1995 *hipz_acl |= HIPZ_ACCESSCTRL_R_READ;
1996 if (ib_acl & IB_ACCESS_REMOTE_WRITE)
1997 *hipz_acl |= HIPZ_ACCESSCTRL_R_WRITE;
1998 if (ib_acl & IB_ACCESS_REMOTE_ATOMIC)
1999 *hipz_acl |= HIPZ_ACCESSCTRL_R_ATOMIC;
2000 if (ib_acl & IB_ACCESS_LOCAL_WRITE)
2001 *hipz_acl |= HIPZ_ACCESSCTRL_L_WRITE;
2002 if (ib_acl & IB_ACCESS_MW_BIND)
2003 *hipz_acl |= HIPZ_ACCESSCTRL_MW_BIND;
2004} /* end ehca_mrmw_map_acl() */
2005
2006/*----------------------------------------------------------------------*/
2007
2008/* sets page size in hipz access control for MR/MW. */
2009void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl) /*INOUT*/
2010{
2011 return; /* HCA supports only 4k */
2012} /* end ehca_mrmw_set_pgsize_hipz_acl() */
2013
2014/*----------------------------------------------------------------------*/
2015
2016/*
2017 * reverse map access control for MR/MW.
2018 * This routine is used for MR and MW.
2019 */
2020void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
2021 int *ib_acl) /*OUT*/
2022{
2023 *ib_acl = 0;
2024 if (*hipz_acl & HIPZ_ACCESSCTRL_R_READ)
2025 *ib_acl |= IB_ACCESS_REMOTE_READ;
2026 if (*hipz_acl & HIPZ_ACCESSCTRL_R_WRITE)
2027 *ib_acl |= IB_ACCESS_REMOTE_WRITE;
2028 if (*hipz_acl & HIPZ_ACCESSCTRL_R_ATOMIC)
2029 *ib_acl |= IB_ACCESS_REMOTE_ATOMIC;
2030 if (*hipz_acl & HIPZ_ACCESSCTRL_L_WRITE)
2031 *ib_acl |= IB_ACCESS_LOCAL_WRITE;
2032 if (*hipz_acl & HIPZ_ACCESSCTRL_MW_BIND)
2033 *ib_acl |= IB_ACCESS_MW_BIND;
2034} /* end ehca_mrmw_reverse_map_acl() */
2035
2036
2037/*----------------------------------------------------------------------*/
2038
2039/*
2040 * map HIPZ rc to IB retcodes for MR/MW allocations
2041 * Used for hipz_mr_reg_alloc and hipz_mw_alloc.
2042 */
2043int ehca_mrmw_map_hrc_alloc(const u64 hipz_rc)
2044{
2045 switch (hipz_rc) {
2046 case H_SUCCESS: /* successful completion */
2047 return 0;
2048 case H_ADAPTER_PARM: /* invalid adapter handle */
2049 case H_RT_PARM: /* invalid resource type */
2050 case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
2051 case H_MLENGTH_PARM: /* invalid memory length */
2052 case H_MEM_ACCESS_PARM: /* invalid access controls */
2053 case H_CONSTRAINED: /* resource constraint */
2054 return -EINVAL;
2055 case H_BUSY: /* long busy */
2056 return -EBUSY;
2057 default:
2058 return -EINVAL;
2059 }
2060} /* end ehca_mrmw_map_hrc_alloc() */
2061
2062/*----------------------------------------------------------------------*/
2063
2064/*
2065 * map HIPZ rc to IB retcodes for MR register rpage
2066 * Used for hipz_h_register_rpage_mr at registering last page
2067 */
2068int ehca_mrmw_map_hrc_rrpg_last(const u64 hipz_rc)
2069{
2070 switch (hipz_rc) {
2071 case H_SUCCESS: /* registration complete */
2072 return 0;
2073 case H_PAGE_REGISTERED: /* page registered */
2074 case H_ADAPTER_PARM: /* invalid adapter handle */
2075 case H_RH_PARM: /* invalid resource handle */
2076/* case H_QT_PARM: invalid queue type */
2077 case H_PARAMETER: /*
2078 * invalid logical address,
2079 * or count zero or greater 512
2080 */
2081 case H_TABLE_FULL: /* page table full */
2082 case H_HARDWARE: /* HCA not operational */
2083 return -EINVAL;
2084 case H_BUSY: /* long busy */
2085 return -EBUSY;
2086 default:
2087 return -EINVAL;
2088 }
2089} /* end ehca_mrmw_map_hrc_rrpg_last() */
2090
2091/*----------------------------------------------------------------------*/
2092
2093/*
2094 * map HIPZ rc to IB retcodes for MR register rpage
2095 * Used for hipz_h_register_rpage_mr at registering one page, but not last page
2096 */
2097int ehca_mrmw_map_hrc_rrpg_notlast(const u64 hipz_rc)
2098{
2099 switch (hipz_rc) {
2100 case H_PAGE_REGISTERED: /* page registered */
2101 return 0;
2102 case H_SUCCESS: /* registration complete */
2103 case H_ADAPTER_PARM: /* invalid adapter handle */
2104 case H_RH_PARM: /* invalid resource handle */
2105/* case H_QT_PARM: invalid queue type */
2106 case H_PARAMETER: /*
2107 * invalid logical address,
2108 * or count zero or greater 512
2109 */
2110 case H_TABLE_FULL: /* page table full */
2111 case H_HARDWARE: /* HCA not operational */
2112 return -EINVAL;
2113 case H_BUSY: /* long busy */
2114 return -EBUSY;
2115 default:
2116 return -EINVAL;
2117 }
2118} /* end ehca_mrmw_map_hrc_rrpg_notlast() */
2119
2120/*----------------------------------------------------------------------*/
2121
2122/* map HIPZ rc to IB retcodes for MR query. Used for hipz_mr_query. */
2123int ehca_mrmw_map_hrc_query_mr(const u64 hipz_rc)
2124{
2125 switch (hipz_rc) {
2126 case H_SUCCESS: /* successful completion */
2127 return 0;
2128 case H_ADAPTER_PARM: /* invalid adapter handle */
2129 case H_RH_PARM: /* invalid resource handle */
2130 return -EINVAL;
2131 case H_BUSY: /* long busy */
2132 return -EBUSY;
2133 default:
2134 return -EINVAL;
2135 }
2136} /* end ehca_mrmw_map_hrc_query_mr() */
2137
2138/*----------------------------------------------------------------------*/
2139/*----------------------------------------------------------------------*/
2140
2141/*
2142 * map HIPZ rc to IB retcodes for freeing MR resource
2143 * Used for hipz_h_free_resource_mr
2144 */
2145int ehca_mrmw_map_hrc_free_mr(const u64 hipz_rc)
2146{
2147 switch (hipz_rc) {
2148 case H_SUCCESS: /* resource freed */
2149 return 0;
2150 case H_ADAPTER_PARM: /* invalid adapter handle */
2151 case H_RH_PARM: /* invalid resource handle */
2152 case H_R_STATE: /* invalid resource state */
2153 case H_HARDWARE: /* HCA not operational */
2154 return -EINVAL;
2155 case H_RESOURCE: /* Resource in use */
2156 case H_BUSY: /* long busy */
2157 return -EBUSY;
2158 default:
2159 return -EINVAL;
2160 }
2161} /* end ehca_mrmw_map_hrc_free_mr() */
2162
2163/*----------------------------------------------------------------------*/
2164
2165/*
2166 * map HIPZ rc to IB retcodes for freeing MW resource
2167 * Used for hipz_h_free_resource_mw
2168 */
2169int ehca_mrmw_map_hrc_free_mw(const u64 hipz_rc)
2170{
2171 switch (hipz_rc) {
2172 case H_SUCCESS: /* resource freed */
2173 return 0;
2174 case H_ADAPTER_PARM: /* invalid adapter handle */
2175 case H_RH_PARM: /* invalid resource handle */
2176 case H_R_STATE: /* invalid resource state */
2177 case H_HARDWARE: /* HCA not operational */
2178 return -EINVAL;
2179 case H_RESOURCE: /* Resource in use */
2180 case H_BUSY: /* long busy */
2181 return -EBUSY;
2182 default:
2183 return -EINVAL;
2184 }
2185} /* end ehca_mrmw_map_hrc_free_mw() */
2186
2187/*----------------------------------------------------------------------*/
2188
2189/*
2190 * map HIPZ rc to IB retcodes for SMR registrations
2191 * Used for hipz_h_register_smr.
2192 */
2193int ehca_mrmw_map_hrc_reg_smr(const u64 hipz_rc)
2194{
2195 switch (hipz_rc) {
2196 case H_SUCCESS: /* successful completion */
2197 return 0;
2198 case H_ADAPTER_PARM: /* invalid adapter handle */
2199 case H_RH_PARM: /* invalid resource handle */
2200 case H_MEM_PARM: /* invalid MR virtual address */
2201 case H_MEM_ACCESS_PARM: /* invalid access controls */
2202 case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
2203 return -EINVAL;
2204 case H_BUSY: /* long busy */
2205 return -EBUSY;
2206 default:
2207 return -EINVAL;
2208 }
2209} /* end ehca_mrmw_map_hrc_reg_smr() */
2210
2211/*----------------------------------------------------------------------*/
2212
2213/*
2214 * MR destructor and constructor
2215 * used in Reregister MR verb, sets all fields in ehca_mr_t to 0,
2216 * except struct ib_mr and spinlock
2217 */
2218void ehca_mr_deletenew(struct ehca_mr *mr)
2219{
2220 mr->flags = 0;
2221 mr->num_pages = 0;
2222 mr->num_4k = 0;
2223 mr->acl = 0;
2224 mr->start = NULL;
2225 mr->fmr_page_size = 0;
2226 mr->fmr_max_pages = 0;
2227 mr->fmr_max_maps = 0;
2228 mr->fmr_map_cnt = 0;
2229 memset(&mr->ipz_mr_handle, 0, sizeof(mr->ipz_mr_handle));
2230 memset(&mr->galpas, 0, sizeof(mr->galpas));
2231 mr->nr_of_pages = 0;
2232 mr->pagearray = NULL;
2233} /* end ehca_mr_deletenew() */
2234
2235int ehca_init_mrmw_cache(void)
2236{
2237 mr_cache = kmem_cache_create("ehca_cache_mr",
2238 sizeof(struct ehca_mr), 0,
2239 SLAB_HWCACHE_ALIGN,
2240 NULL, NULL);
2241 if (!mr_cache)
2242 return -ENOMEM;
2243 mw_cache = kmem_cache_create("ehca_cache_mw",
2244 sizeof(struct ehca_mw), 0,
2245 SLAB_HWCACHE_ALIGN,
2246 NULL, NULL);
2247 if (!mw_cache) {
2248 kmem_cache_destroy(mr_cache);
2249 mr_cache = NULL;
2250 return -ENOMEM;
2251 }
2252 return 0;
2253}
2254
2255void ehca_cleanup_mrmw_cache(void)
2256{
2257 if (mr_cache)
2258 kmem_cache_destroy(mr_cache);
2259 if (mw_cache)
2260 kmem_cache_destroy(mw_cache);
2261}
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.h b/drivers/infiniband/hw/ehca/ehca_mrmw.h
new file mode 100644
index 000000000000..d936e40a5748
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.h
@@ -0,0 +1,140 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * MR/MW declarations and inline functions
5 *
6 * Authors: Dietmar Decker <ddecker@de.ibm.com>
7 * Christoph Raisch <raisch@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#ifndef _EHCA_MRMW_H_
43#define _EHCA_MRMW_H_
44
45int ehca_reg_mr(struct ehca_shca *shca,
46 struct ehca_mr *e_mr,
47 u64 *iova_start,
48 u64 size,
49 int acl,
50 struct ehca_pd *e_pd,
51 struct ehca_mr_pginfo *pginfo,
52 u32 *lkey,
53 u32 *rkey);
54
55int ehca_reg_mr_rpages(struct ehca_shca *shca,
56 struct ehca_mr *e_mr,
57 struct ehca_mr_pginfo *pginfo);
58
59int ehca_rereg_mr(struct ehca_shca *shca,
60 struct ehca_mr *e_mr,
61 u64 *iova_start,
62 u64 size,
63 int mr_access_flags,
64 struct ehca_pd *e_pd,
65 struct ehca_mr_pginfo *pginfo,
66 u32 *lkey,
67 u32 *rkey);
68
69int ehca_unmap_one_fmr(struct ehca_shca *shca,
70 struct ehca_mr *e_fmr);
71
72int ehca_reg_smr(struct ehca_shca *shca,
73 struct ehca_mr *e_origmr,
74 struct ehca_mr *e_newmr,
75 u64 *iova_start,
76 int acl,
77 struct ehca_pd *e_pd,
78 u32 *lkey,
79 u32 *rkey);
80
81int ehca_reg_internal_maxmr(struct ehca_shca *shca,
82 struct ehca_pd *e_pd,
83 struct ehca_mr **maxmr);
84
85int ehca_reg_maxmr(struct ehca_shca *shca,
86 struct ehca_mr *e_newmr,
87 u64 *iova_start,
88 int acl,
89 struct ehca_pd *e_pd,
90 u32 *lkey,
91 u32 *rkey);
92
93int ehca_dereg_internal_maxmr(struct ehca_shca *shca);
94
95int ehca_mr_chk_buf_and_calc_size(struct ib_phys_buf *phys_buf_array,
96 int num_phys_buf,
97 u64 *iova_start,
98 u64 *size);
99
100int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
101 u64 *page_list,
102 int list_len);
103
104int ehca_set_pagebuf(struct ehca_mr *e_mr,
105 struct ehca_mr_pginfo *pginfo,
106 u32 number,
107 u64 *kpage);
108
109int ehca_set_pagebuf_1(struct ehca_mr *e_mr,
110 struct ehca_mr_pginfo *pginfo,
111 u64 *rpage);
112
113int ehca_mr_is_maxmr(u64 size,
114 u64 *iova_start);
115
116void ehca_mrmw_map_acl(int ib_acl,
117 u32 *hipz_acl);
118
119void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl);
120
121void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
122 int *ib_acl);
123
124int ehca_mrmw_map_hrc_alloc(const u64 hipz_rc);
125
126int ehca_mrmw_map_hrc_rrpg_last(const u64 hipz_rc);
127
128int ehca_mrmw_map_hrc_rrpg_notlast(const u64 hipz_rc);
129
130int ehca_mrmw_map_hrc_query_mr(const u64 hipz_rc);
131
132int ehca_mrmw_map_hrc_free_mr(const u64 hipz_rc);
133
134int ehca_mrmw_map_hrc_free_mw(const u64 hipz_rc);
135
136int ehca_mrmw_map_hrc_reg_smr(const u64 hipz_rc);
137
138void ehca_mr_deletenew(struct ehca_mr *mr);
139
140#endif /*_EHCA_MRMW_H_*/
diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c
new file mode 100644
index 000000000000..2c3cdc6f7b39
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_pd.c
@@ -0,0 +1,114 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * PD functions
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 *
8 * Copyright (c) 2005 IBM Corporation
9 *
10 * All rights reserved.
11 *
12 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
13 * BSD.
14 *
15 * OpenIB BSD License
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are met:
19 *
20 * Redistributions of source code must retain the above copyright notice, this
21 * list of conditions and the following disclaimer.
22 *
23 * Redistributions in binary form must reproduce the above copyright notice,
24 * this list of conditions and the following disclaimer in the documentation
25 * and/or other materials
26 * provided with the distribution.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#include <asm/current.h>
42
43#include "ehca_tools.h"
44#include "ehca_iverbs.h"
45
46static struct kmem_cache *pd_cache;
47
48struct ib_pd *ehca_alloc_pd(struct ib_device *device,
49 struct ib_ucontext *context, struct ib_udata *udata)
50{
51 struct ehca_pd *pd;
52
53 pd = kmem_cache_alloc(pd_cache, SLAB_KERNEL);
54 if (!pd) {
55 ehca_err(device, "device=%p context=%p out of memory",
56 device, context);
57 return ERR_PTR(-ENOMEM);
58 }
59
60 memset(pd, 0, sizeof(struct ehca_pd));
61 pd->ownpid = current->tgid;
62
63 /*
64 * Kernel PD: when device = -1, 0
65 * User PD: when context != -1
66 */
67 if (!context) {
68 /*
69 * Kernel PDs after init reuses always
70 * the one created in ehca_shca_reopen()
71 */
72 struct ehca_shca *shca = container_of(device, struct ehca_shca,
73 ib_device);
74 pd->fw_pd.value = shca->pd->fw_pd.value;
75 } else
76 pd->fw_pd.value = (u64)pd;
77
78 return &pd->ib_pd;
79}
80
81int ehca_dealloc_pd(struct ib_pd *pd)
82{
83 u32 cur_pid = current->tgid;
84 struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
85
86 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
87 my_pd->ownpid != cur_pid) {
88 ehca_err(pd->device, "Invalid caller pid=%x ownpid=%x",
89 cur_pid, my_pd->ownpid);
90 return -EINVAL;
91 }
92
93 kmem_cache_free(pd_cache,
94 container_of(pd, struct ehca_pd, ib_pd));
95
96 return 0;
97}
98
99int ehca_init_pd_cache(void)
100{
101 pd_cache = kmem_cache_create("ehca_cache_pd",
102 sizeof(struct ehca_pd), 0,
103 SLAB_HWCACHE_ALIGN,
104 NULL, NULL);
105 if (!pd_cache)
106 return -ENOMEM;
107 return 0;
108}
109
110void ehca_cleanup_pd_cache(void)
111{
112 if (pd_cache)
113 kmem_cache_destroy(pd_cache);
114}
diff --git a/drivers/infiniband/hw/ehca/ehca_qes.h b/drivers/infiniband/hw/ehca/ehca_qes.h
new file mode 100644
index 000000000000..8707d297ce4c
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_qes.h
@@ -0,0 +1,259 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Hardware request structures
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Reinhard Ernst <rernst@de.ibm.com>
8 * Christoph Raisch <raisch@de.ibm.com>
9 *
10 * Copyright (c) 2005 IBM Corporation
11 *
12 * All rights reserved.
13 *
14 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
15 * BSD.
16 *
17 * OpenIB BSD License
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * Redistributions of source code must retain the above copyright notice, this
23 * list of conditions and the following disclaimer.
24 *
25 * Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials
28 * provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42
43
44#ifndef _EHCA_QES_H_
45#define _EHCA_QES_H_
46
47#include "ehca_tools.h"
48
49/* virtual scatter gather entry to specify remote adresses with length */
50struct ehca_vsgentry {
51 u64 vaddr;
52 u32 lkey;
53 u32 length;
54};
55
56#define GRH_FLAG_MASK EHCA_BMASK_IBM(7,7)
57#define GRH_IPVERSION_MASK EHCA_BMASK_IBM(0,3)
58#define GRH_TCLASS_MASK EHCA_BMASK_IBM(4,12)
59#define GRH_FLOWLABEL_MASK EHCA_BMASK_IBM(13,31)
60#define GRH_PAYLEN_MASK EHCA_BMASK_IBM(32,47)
61#define GRH_NEXTHEADER_MASK EHCA_BMASK_IBM(48,55)
62#define GRH_HOPLIMIT_MASK EHCA_BMASK_IBM(56,63)
63
64/*
65 * Unreliable Datagram Address Vector Format
66 * see IBTA Vol1 chapter 8.3 Global Routing Header
67 */
68struct ehca_ud_av {
69 u8 sl;
70 u8 lnh;
71 u16 dlid;
72 u8 reserved1;
73 u8 reserved2;
74 u8 reserved3;
75 u8 slid_path_bits;
76 u8 reserved4;
77 u8 ipd;
78 u8 reserved5;
79 u8 pmtu;
80 u32 reserved6;
81 u64 reserved7;
82 union {
83 struct {
84 u64 word_0; /* always set to 6 */
85 /*should be 0x1B for IB transport */
86 u64 word_1;
87 u64 word_2;
88 u64 word_3;
89 u64 word_4;
90 } grh;
91 struct {
92 u32 wd_0;
93 u32 wd_1;
94 /* DWord_1 --> SGID */
95
96 u32 sgid_wd3;
97 u32 sgid_wd2;
98
99 u32 sgid_wd1;
100 u32 sgid_wd0;
101 /* DWord_3 --> DGID */
102
103 u32 dgid_wd3;
104 u32 dgid_wd2;
105
106 u32 dgid_wd1;
107 u32 dgid_wd0;
108 } grh_l;
109 };
110};
111
112/* maximum number of sg entries allowed in a WQE */
113#define MAX_WQE_SG_ENTRIES 252
114
115#define WQE_OPTYPE_SEND 0x80
116#define WQE_OPTYPE_RDMAREAD 0x40
117#define WQE_OPTYPE_RDMAWRITE 0x20
118#define WQE_OPTYPE_CMPSWAP 0x10
119#define WQE_OPTYPE_FETCHADD 0x08
120#define WQE_OPTYPE_BIND 0x04
121
122#define WQE_WRFLAG_REQ_SIGNAL_COM 0x80
123#define WQE_WRFLAG_FENCE 0x40
124#define WQE_WRFLAG_IMM_DATA_PRESENT 0x20
125#define WQE_WRFLAG_SOLIC_EVENT 0x10
126
127#define WQEF_CACHE_HINT 0x80
128#define WQEF_CACHE_HINT_RD_WR 0x40
129#define WQEF_TIMED_WQE 0x20
130#define WQEF_PURGE 0x08
131#define WQEF_HIGH_NIBBLE 0xF0
132
133#define MW_BIND_ACCESSCTRL_R_WRITE 0x40
134#define MW_BIND_ACCESSCTRL_R_READ 0x20
135#define MW_BIND_ACCESSCTRL_R_ATOMIC 0x10
136
137struct ehca_wqe {
138 u64 work_request_id;
139 u8 optype;
140 u8 wr_flag;
141 u16 pkeyi;
142 u8 wqef;
143 u8 nr_of_data_seg;
144 u16 wqe_provided_slid;
145 u32 destination_qp_number;
146 u32 resync_psn_sqp;
147 u32 local_ee_context_qkey;
148 u32 immediate_data;
149 union {
150 struct {
151 u64 remote_virtual_adress;
152 u32 rkey;
153 u32 reserved;
154 u64 atomic_1st_op_dma_len;
155 u64 atomic_2nd_op;
156 struct ehca_vsgentry sg_list[MAX_WQE_SG_ENTRIES];
157
158 } nud;
159 struct {
160 u64 ehca_ud_av_ptr;
161 u64 reserved1;
162 u64 reserved2;
163 u64 reserved3;
164 struct ehca_vsgentry sg_list[MAX_WQE_SG_ENTRIES];
165 } ud_avp;
166 struct {
167 struct ehca_ud_av ud_av;
168 struct ehca_vsgentry sg_list[MAX_WQE_SG_ENTRIES -
169 2];
170 } ud_av;
171 struct {
172 u64 reserved0;
173 u64 reserved1;
174 u64 reserved2;
175 u64 reserved3;
176 struct ehca_vsgentry sg_list[MAX_WQE_SG_ENTRIES];
177 } all_rcv;
178
179 struct {
180 u64 reserved;
181 u32 rkey;
182 u32 old_rkey;
183 u64 reserved1;
184 u64 reserved2;
185 u64 virtual_address;
186 u32 reserved3;
187 u32 length;
188 u32 reserved4;
189 u16 reserved5;
190 u8 reserved6;
191 u8 lr_ctl;
192 u32 lkey;
193 u32 reserved7;
194 u64 reserved8;
195 u64 reserved9;
196 u64 reserved10;
197 u64 reserved11;
198 } bind;
199 struct {
200 u64 reserved12;
201 u64 reserved13;
202 u32 size;
203 u32 start;
204 } inline_data;
205 } u;
206
207};
208
209#define WC_SEND_RECEIVE EHCA_BMASK_IBM(0,0)
210#define WC_IMM_DATA EHCA_BMASK_IBM(1,1)
211#define WC_GRH_PRESENT EHCA_BMASK_IBM(2,2)
212#define WC_SE_BIT EHCA_BMASK_IBM(3,3)
213#define WC_STATUS_ERROR_BIT 0x80000000
214#define WC_STATUS_REMOTE_ERROR_FLAGS 0x0000F800
215#define WC_STATUS_PURGE_BIT 0x10
216
217struct ehca_cqe {
218 u64 work_request_id;
219 u8 optype;
220 u8 w_completion_flags;
221 u16 reserved1;
222 u32 nr_bytes_transferred;
223 u32 immediate_data;
224 u32 local_qp_number;
225 u8 freed_resource_count;
226 u8 service_level;
227 u16 wqe_count;
228 u32 qp_token;
229 u32 qkey_ee_token;
230 u32 remote_qp_number;
231 u16 dlid;
232 u16 rlid;
233 u16 reserved2;
234 u16 pkey_index;
235 u32 cqe_timestamp;
236 u32 wqe_timestamp;
237 u8 wqe_timestamp_valid;
238 u8 reserved3;
239 u8 reserved4;
240 u8 cqe_flags;
241 u32 status;
242};
243
244struct ehca_eqe {
245 u64 entry;
246};
247
248struct ehca_mrte {
249 u64 starting_va;
250 u64 length; /* length of memory region in bytes*/
251 u32 pd;
252 u8 key_instance;
253 u8 pagesize;
254 u8 mr_control;
255 u8 local_remote_access_ctrl;
256 u8 reserved[0x20 - 0x18];
257 u64 at_pointer[4];
258};
259#endif /*_EHCA_QES_H_*/
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
new file mode 100644
index 000000000000..4394123cdbd7
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -0,0 +1,1507 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * QP functions
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Reinhard Ernst <rernst@de.ibm.com>
9 * Heiko J Schick <schickhj@de.ibm.com>
10 *
11 * Copyright (c) 2005 IBM Corporation
12 *
13 * All rights reserved.
14 *
15 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
16 * BSD.
17 *
18 * OpenIB BSD License
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *
23 * Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
25 *
26 * Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials
29 * provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44
45#include <asm/current.h>
46
47#include "ehca_classes.h"
48#include "ehca_tools.h"
49#include "ehca_qes.h"
50#include "ehca_iverbs.h"
51#include "hcp_if.h"
52#include "hipz_fns.h"
53
54static struct kmem_cache *qp_cache;
55
56/*
57 * attributes not supported by query qp
58 */
59#define QP_ATTR_QUERY_NOT_SUPPORTED (IB_QP_MAX_DEST_RD_ATOMIC | \
60 IB_QP_MAX_QP_RD_ATOMIC | \
61 IB_QP_ACCESS_FLAGS | \
62 IB_QP_EN_SQD_ASYNC_NOTIFY)
63
64/*
65 * ehca (internal) qp state values
66 */
67enum ehca_qp_state {
68 EHCA_QPS_RESET = 1,
69 EHCA_QPS_INIT = 2,
70 EHCA_QPS_RTR = 3,
71 EHCA_QPS_RTS = 5,
72 EHCA_QPS_SQD = 6,
73 EHCA_QPS_SQE = 8,
74 EHCA_QPS_ERR = 128
75};
76
77/*
78 * qp state transitions as defined by IB Arch Rel 1.1 page 431
79 */
80enum ib_qp_statetrans {
81 IB_QPST_ANY2RESET,
82 IB_QPST_ANY2ERR,
83 IB_QPST_RESET2INIT,
84 IB_QPST_INIT2RTR,
85 IB_QPST_INIT2INIT,
86 IB_QPST_RTR2RTS,
87 IB_QPST_RTS2SQD,
88 IB_QPST_RTS2RTS,
89 IB_QPST_SQD2RTS,
90 IB_QPST_SQE2RTS,
91 IB_QPST_SQD2SQD,
92 IB_QPST_MAX /* nr of transitions, this must be last!!! */
93};
94
95/*
96 * ib2ehca_qp_state maps IB to ehca qp_state
97 * returns ehca qp state corresponding to given ib qp state
98 */
99static inline enum ehca_qp_state ib2ehca_qp_state(enum ib_qp_state ib_qp_state)
100{
101 switch (ib_qp_state) {
102 case IB_QPS_RESET:
103 return EHCA_QPS_RESET;
104 case IB_QPS_INIT:
105 return EHCA_QPS_INIT;
106 case IB_QPS_RTR:
107 return EHCA_QPS_RTR;
108 case IB_QPS_RTS:
109 return EHCA_QPS_RTS;
110 case IB_QPS_SQD:
111 return EHCA_QPS_SQD;
112 case IB_QPS_SQE:
113 return EHCA_QPS_SQE;
114 case IB_QPS_ERR:
115 return EHCA_QPS_ERR;
116 default:
117 ehca_gen_err("invalid ib_qp_state=%x", ib_qp_state);
118 return -EINVAL;
119 }
120}
121
122/*
123 * ehca2ib_qp_state maps ehca to IB qp_state
124 * returns ib qp state corresponding to given ehca qp state
125 */
126static inline enum ib_qp_state ehca2ib_qp_state(enum ehca_qp_state
127 ehca_qp_state)
128{
129 switch (ehca_qp_state) {
130 case EHCA_QPS_RESET:
131 return IB_QPS_RESET;
132 case EHCA_QPS_INIT:
133 return IB_QPS_INIT;
134 case EHCA_QPS_RTR:
135 return IB_QPS_RTR;
136 case EHCA_QPS_RTS:
137 return IB_QPS_RTS;
138 case EHCA_QPS_SQD:
139 return IB_QPS_SQD;
140 case EHCA_QPS_SQE:
141 return IB_QPS_SQE;
142 case EHCA_QPS_ERR:
143 return IB_QPS_ERR;
144 default:
145 ehca_gen_err("invalid ehca_qp_state=%x", ehca_qp_state);
146 return -EINVAL;
147 }
148}
149
150/*
151 * ehca_qp_type used as index for req_attr and opt_attr of
152 * struct ehca_modqp_statetrans
153 */
154enum ehca_qp_type {
155 QPT_RC = 0,
156 QPT_UC = 1,
157 QPT_UD = 2,
158 QPT_SQP = 3,
159 QPT_MAX
160};
161
162/*
163 * ib2ehcaqptype maps Ib to ehca qp_type
164 * returns ehca qp type corresponding to ib qp type
165 */
166static inline enum ehca_qp_type ib2ehcaqptype(enum ib_qp_type ibqptype)
167{
168 switch (ibqptype) {
169 case IB_QPT_SMI:
170 case IB_QPT_GSI:
171 return QPT_SQP;
172 case IB_QPT_RC:
173 return QPT_RC;
174 case IB_QPT_UC:
175 return QPT_UC;
176 case IB_QPT_UD:
177 return QPT_UD;
178 default:
179 ehca_gen_err("Invalid ibqptype=%x", ibqptype);
180 return -EINVAL;
181 }
182}
183
184static inline enum ib_qp_statetrans get_modqp_statetrans(int ib_fromstate,
185 int ib_tostate)
186{
187 int index = -EINVAL;
188 switch (ib_tostate) {
189 case IB_QPS_RESET:
190 index = IB_QPST_ANY2RESET;
191 break;
192 case IB_QPS_INIT:
193 switch (ib_fromstate) {
194 case IB_QPS_RESET:
195 index = IB_QPST_RESET2INIT;
196 break;
197 case IB_QPS_INIT:
198 index = IB_QPST_INIT2INIT;
199 break;
200 }
201 break;
202 case IB_QPS_RTR:
203 if (ib_fromstate == IB_QPS_INIT)
204 index = IB_QPST_INIT2RTR;
205 break;
206 case IB_QPS_RTS:
207 switch (ib_fromstate) {
208 case IB_QPS_RTR:
209 index = IB_QPST_RTR2RTS;
210 break;
211 case IB_QPS_RTS:
212 index = IB_QPST_RTS2RTS;
213 break;
214 case IB_QPS_SQD:
215 index = IB_QPST_SQD2RTS;
216 break;
217 case IB_QPS_SQE:
218 index = IB_QPST_SQE2RTS;
219 break;
220 }
221 break;
222 case IB_QPS_SQD:
223 if (ib_fromstate == IB_QPS_RTS)
224 index = IB_QPST_RTS2SQD;
225 break;
226 case IB_QPS_SQE:
227 break;
228 case IB_QPS_ERR:
229 index = IB_QPST_ANY2ERR;
230 break;
231 default:
232 break;
233 }
234 return index;
235}
236
237enum ehca_service_type {
238 ST_RC = 0,
239 ST_UC = 1,
240 ST_RD = 2,
241 ST_UD = 3
242};
243
244/*
245 * ibqptype2servicetype returns hcp service type corresponding to given
246 * ib qp type used by create_qp()
247 */
248static inline int ibqptype2servicetype(enum ib_qp_type ibqptype)
249{
250 switch (ibqptype) {
251 case IB_QPT_SMI:
252 case IB_QPT_GSI:
253 return ST_UD;
254 case IB_QPT_RC:
255 return ST_RC;
256 case IB_QPT_UC:
257 return ST_UC;
258 case IB_QPT_UD:
259 return ST_UD;
260 case IB_QPT_RAW_IPV6:
261 return -EINVAL;
262 case IB_QPT_RAW_ETY:
263 return -EINVAL;
264 default:
265 ehca_gen_err("Invalid ibqptype=%x", ibqptype);
266 return -EINVAL;
267 }
268}
269
270/*
271 * init_qp_queues initializes/constructs r/squeue and registers queue pages.
272 */
273static inline int init_qp_queues(struct ehca_shca *shca,
274 struct ehca_qp *my_qp,
275 int nr_sq_pages,
276 int nr_rq_pages,
277 int swqe_size,
278 int rwqe_size,
279 int nr_send_sges, int nr_receive_sges)
280{
281 int ret, cnt, ipz_rc;
282 void *vpage;
283 u64 rpage, h_ret;
284 struct ib_device *ib_dev = &shca->ib_device;
285 struct ipz_adapter_handle ipz_hca_handle = shca->ipz_hca_handle;
286
287 ipz_rc = ipz_queue_ctor(&my_qp->ipz_squeue,
288 nr_sq_pages,
289 EHCA_PAGESIZE, swqe_size, nr_send_sges);
290 if (!ipz_rc) {
291 ehca_err(ib_dev,"Cannot allocate page for squeue. ipz_rc=%x",
292 ipz_rc);
293 return -EBUSY;
294 }
295
296 ipz_rc = ipz_queue_ctor(&my_qp->ipz_rqueue,
297 nr_rq_pages,
298 EHCA_PAGESIZE, rwqe_size, nr_receive_sges);
299 if (!ipz_rc) {
300 ehca_err(ib_dev, "Cannot allocate page for rqueue. ipz_rc=%x",
301 ipz_rc);
302 ret = -EBUSY;
303 goto init_qp_queues0;
304 }
305 /* register SQ pages */
306 for (cnt = 0; cnt < nr_sq_pages; cnt++) {
307 vpage = ipz_qpageit_get_inc(&my_qp->ipz_squeue);
308 if (!vpage) {
309 ehca_err(ib_dev, "SQ ipz_qpageit_get_inc() "
310 "failed p_vpage= %p", vpage);
311 ret = -EINVAL;
312 goto init_qp_queues1;
313 }
314 rpage = virt_to_abs(vpage);
315
316 h_ret = hipz_h_register_rpage_qp(ipz_hca_handle,
317 my_qp->ipz_qp_handle,
318 &my_qp->pf, 0, 0,
319 rpage, 1,
320 my_qp->galpas.kernel);
321 if (h_ret < H_SUCCESS) {
322 ehca_err(ib_dev, "SQ hipz_qp_register_rpage()"
323 " failed rc=%lx", h_ret);
324 ret = ehca2ib_return_code(h_ret);
325 goto init_qp_queues1;
326 }
327 }
328
329 ipz_qeit_reset(&my_qp->ipz_squeue);
330
331 /* register RQ pages */
332 for (cnt = 0; cnt < nr_rq_pages; cnt++) {
333 vpage = ipz_qpageit_get_inc(&my_qp->ipz_rqueue);
334 if (!vpage) {
335 ehca_err(ib_dev, "RQ ipz_qpageit_get_inc() "
336 "failed p_vpage = %p", vpage);
337 ret = -EINVAL;
338 goto init_qp_queues1;
339 }
340
341 rpage = virt_to_abs(vpage);
342
343 h_ret = hipz_h_register_rpage_qp(ipz_hca_handle,
344 my_qp->ipz_qp_handle,
345 &my_qp->pf, 0, 1,
346 rpage, 1,my_qp->galpas.kernel);
347 if (h_ret < H_SUCCESS) {
348 ehca_err(ib_dev, "RQ hipz_qp_register_rpage() failed "
349 "rc=%lx", h_ret);
350 ret = ehca2ib_return_code(h_ret);
351 goto init_qp_queues1;
352 }
353 if (cnt == (nr_rq_pages - 1)) { /* last page! */
354 if (h_ret != H_SUCCESS) {
355 ehca_err(ib_dev, "RQ hipz_qp_register_rpage() "
356 "h_ret= %lx ", h_ret);
357 ret = ehca2ib_return_code(h_ret);
358 goto init_qp_queues1;
359 }
360 vpage = ipz_qpageit_get_inc(&my_qp->ipz_rqueue);
361 if (vpage) {
362 ehca_err(ib_dev, "ipz_qpageit_get_inc() "
363 "should not succeed vpage=%p", vpage);
364 ret = -EINVAL;
365 goto init_qp_queues1;
366 }
367 } else {
368 if (h_ret != H_PAGE_REGISTERED) {
369 ehca_err(ib_dev, "RQ hipz_qp_register_rpage() "
370 "h_ret= %lx ", h_ret);
371 ret = ehca2ib_return_code(h_ret);
372 goto init_qp_queues1;
373 }
374 }
375 }
376
377 ipz_qeit_reset(&my_qp->ipz_rqueue);
378
379 return 0;
380
381init_qp_queues1:
382 ipz_queue_dtor(&my_qp->ipz_rqueue);
383init_qp_queues0:
384 ipz_queue_dtor(&my_qp->ipz_squeue);
385 return ret;
386}
387
388struct ib_qp *ehca_create_qp(struct ib_pd *pd,
389 struct ib_qp_init_attr *init_attr,
390 struct ib_udata *udata)
391{
392 static int da_rc_msg_size[]={ 128, 256, 512, 1024, 2048, 4096 };
393 static int da_ud_sq_msg_size[]={ 128, 384, 896, 1920, 3968 };
394 struct ehca_qp *my_qp;
395 struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
396 struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
397 ib_device);
398 struct ib_ucontext *context = NULL;
399 u64 h_ret;
400 int max_send_sge, max_recv_sge, ret;
401
402 /* h_call's out parameters */
403 struct ehca_alloc_qp_parms parms;
404 u32 swqe_size = 0, rwqe_size = 0;
405 u8 daqp_completion, isdaqp;
406 unsigned long flags;
407
408 if (init_attr->sq_sig_type != IB_SIGNAL_REQ_WR &&
409 init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) {
410 ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed",
411 init_attr->sq_sig_type);
412 return ERR_PTR(-EINVAL);
413 }
414
415 /* save daqp completion bits */
416 daqp_completion = init_attr->qp_type & 0x60;
417 /* save daqp bit */
418 isdaqp = (init_attr->qp_type & 0x80) ? 1 : 0;
419 init_attr->qp_type = init_attr->qp_type & 0x1F;
420
421 if (init_attr->qp_type != IB_QPT_UD &&
422 init_attr->qp_type != IB_QPT_SMI &&
423 init_attr->qp_type != IB_QPT_GSI &&
424 init_attr->qp_type != IB_QPT_UC &&
425 init_attr->qp_type != IB_QPT_RC) {
426 ehca_err(pd->device, "wrong QP Type=%x", init_attr->qp_type);
427 return ERR_PTR(-EINVAL);
428 }
429 if ((init_attr->qp_type != IB_QPT_RC && init_attr->qp_type != IB_QPT_UD)
430 && isdaqp) {
431 ehca_err(pd->device, "unsupported LL QP Type=%x",
432 init_attr->qp_type);
433 return ERR_PTR(-EINVAL);
434 } else if (init_attr->qp_type == IB_QPT_RC && isdaqp &&
435 (init_attr->cap.max_send_wr > 255 ||
436 init_attr->cap.max_recv_wr > 255 )) {
437 ehca_err(pd->device, "Invalid Number of max_sq_wr =%x "
438 "or max_rq_wr=%x for QP Type=%x",
439 init_attr->cap.max_send_wr,
440 init_attr->cap.max_recv_wr,init_attr->qp_type);
441 return ERR_PTR(-EINVAL);
442 } else if (init_attr->qp_type == IB_QPT_UD && isdaqp &&
443 init_attr->cap.max_send_wr > 255) {
444 ehca_err(pd->device,
445 "Invalid Number of max_send_wr=%x for UD QP_TYPE=%x",
446 init_attr->cap.max_send_wr, init_attr->qp_type);
447 return ERR_PTR(-EINVAL);
448 }
449
450 if (pd->uobject && udata)
451 context = pd->uobject->context;
452
453 my_qp = kmem_cache_alloc(qp_cache, SLAB_KERNEL);
454 if (!my_qp) {
455 ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd);
456 return ERR_PTR(-ENOMEM);
457 }
458
459 memset(my_qp, 0, sizeof(struct ehca_qp));
460 memset (&parms, 0, sizeof(struct ehca_alloc_qp_parms));
461 spin_lock_init(&my_qp->spinlock_s);
462 spin_lock_init(&my_qp->spinlock_r);
463
464 my_qp->recv_cq =
465 container_of(init_attr->recv_cq, struct ehca_cq, ib_cq);
466 my_qp->send_cq =
467 container_of(init_attr->send_cq, struct ehca_cq, ib_cq);
468
469 my_qp->init_attr = *init_attr;
470
471 do {
472 if (!idr_pre_get(&ehca_qp_idr, GFP_KERNEL)) {
473 ret = -ENOMEM;
474 ehca_err(pd->device, "Can't reserve idr resources.");
475 goto create_qp_exit0;
476 }
477
478 spin_lock_irqsave(&ehca_qp_idr_lock, flags);
479 ret = idr_get_new(&ehca_qp_idr, my_qp, &my_qp->token);
480 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
481
482 } while (ret == -EAGAIN);
483
484 if (ret) {
485 ret = -ENOMEM;
486 ehca_err(pd->device, "Can't allocate new idr entry.");
487 goto create_qp_exit0;
488 }
489
490 parms.servicetype = ibqptype2servicetype(init_attr->qp_type);
491 if (parms.servicetype < 0) {
492 ret = -EINVAL;
493 ehca_err(pd->device, "Invalid qp_type=%x", init_attr->qp_type);
494 goto create_qp_exit0;
495 }
496
497 if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
498 parms.sigtype = HCALL_SIGT_EVERY;
499 else
500 parms.sigtype = HCALL_SIGT_BY_WQE;
501
502 /* UD_AV CIRCUMVENTION */
503 max_send_sge = init_attr->cap.max_send_sge;
504 max_recv_sge = init_attr->cap.max_recv_sge;
505 if (IB_QPT_UD == init_attr->qp_type ||
506 IB_QPT_GSI == init_attr->qp_type ||
507 IB_QPT_SMI == init_attr->qp_type) {
508 max_send_sge += 2;
509 max_recv_sge += 2;
510 }
511
512 parms.ipz_eq_handle = shca->eq.ipz_eq_handle;
513 parms.daqp_ctrl = isdaqp | daqp_completion;
514 parms.pd = my_pd->fw_pd;
515 parms.max_recv_sge = max_recv_sge;
516 parms.max_send_sge = max_send_sge;
517
518 h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, my_qp, &parms);
519
520 if (h_ret != H_SUCCESS) {
521 ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%lx",
522 h_ret);
523 ret = ehca2ib_return_code(h_ret);
524 goto create_qp_exit1;
525 }
526
527 switch (init_attr->qp_type) {
528 case IB_QPT_RC:
529 if (isdaqp == 0) {
530 swqe_size = offsetof(struct ehca_wqe, u.nud.sg_list[
531 (parms.act_nr_send_sges)]);
532 rwqe_size = offsetof(struct ehca_wqe, u.nud.sg_list[
533 (parms.act_nr_recv_sges)]);
534 } else { /* for daqp we need to use msg size, not wqe size */
535 swqe_size = da_rc_msg_size[max_send_sge];
536 rwqe_size = da_rc_msg_size[max_recv_sge];
537 parms.act_nr_send_sges = 1;
538 parms.act_nr_recv_sges = 1;
539 }
540 break;
541 case IB_QPT_UC:
542 swqe_size = offsetof(struct ehca_wqe,
543 u.nud.sg_list[parms.act_nr_send_sges]);
544 rwqe_size = offsetof(struct ehca_wqe,
545 u.nud.sg_list[parms.act_nr_recv_sges]);
546 break;
547
548 case IB_QPT_UD:
549 case IB_QPT_GSI:
550 case IB_QPT_SMI:
551 /* UD circumvention */
552 parms.act_nr_recv_sges -= 2;
553 parms.act_nr_send_sges -= 2;
554 if (isdaqp) {
555 swqe_size = da_ud_sq_msg_size[max_send_sge];
556 rwqe_size = da_rc_msg_size[max_recv_sge];
557 parms.act_nr_send_sges = 1;
558 parms.act_nr_recv_sges = 1;
559 } else {
560 swqe_size = offsetof(struct ehca_wqe,
561 u.ud_av.sg_list[parms.act_nr_send_sges]);
562 rwqe_size = offsetof(struct ehca_wqe,
563 u.ud_av.sg_list[parms.act_nr_recv_sges]);
564 }
565
566 if (IB_QPT_GSI == init_attr->qp_type ||
567 IB_QPT_SMI == init_attr->qp_type) {
568 parms.act_nr_send_wqes = init_attr->cap.max_send_wr;
569 parms.act_nr_recv_wqes = init_attr->cap.max_recv_wr;
570 parms.act_nr_send_sges = init_attr->cap.max_send_sge;
571 parms.act_nr_recv_sges = init_attr->cap.max_recv_sge;
572 my_qp->real_qp_num =
573 (init_attr->qp_type == IB_QPT_SMI) ? 0 : 1;
574 }
575
576 break;
577
578 default:
579 break;
580 }
581
582 /* initializes r/squeue and registers queue pages */
583 ret = init_qp_queues(shca, my_qp,
584 parms.nr_sq_pages, parms.nr_rq_pages,
585 swqe_size, rwqe_size,
586 parms.act_nr_send_sges, parms.act_nr_recv_sges);
587 if (ret) {
588 ehca_err(pd->device,
589 "Couldn't initialize r/squeue and pages ret=%x", ret);
590 goto create_qp_exit2;
591 }
592
593 my_qp->ib_qp.pd = &my_pd->ib_pd;
594 my_qp->ib_qp.device = my_pd->ib_pd.device;
595
596 my_qp->ib_qp.recv_cq = init_attr->recv_cq;
597 my_qp->ib_qp.send_cq = init_attr->send_cq;
598
599 my_qp->ib_qp.qp_num = my_qp->real_qp_num;
600 my_qp->ib_qp.qp_type = init_attr->qp_type;
601
602 my_qp->qp_type = init_attr->qp_type;
603 my_qp->ib_qp.srq = init_attr->srq;
604
605 my_qp->ib_qp.qp_context = init_attr->qp_context;
606 my_qp->ib_qp.event_handler = init_attr->event_handler;
607
608 init_attr->cap.max_inline_data = 0; /* not supported yet */
609 init_attr->cap.max_recv_sge = parms.act_nr_recv_sges;
610 init_attr->cap.max_recv_wr = parms.act_nr_recv_wqes;
611 init_attr->cap.max_send_sge = parms.act_nr_send_sges;
612 init_attr->cap.max_send_wr = parms.act_nr_send_wqes;
613
614 /* NOTE: define_apq0() not supported yet */
615 if (init_attr->qp_type == IB_QPT_GSI) {
616 h_ret = ehca_define_sqp(shca, my_qp, init_attr);
617 if (h_ret != H_SUCCESS) {
618 ehca_err(pd->device, "ehca_define_sqp() failed rc=%lx",
619 h_ret);
620 ret = ehca2ib_return_code(h_ret);
621 goto create_qp_exit3;
622 }
623 }
624 if (init_attr->send_cq) {
625 struct ehca_cq *cq = container_of(init_attr->send_cq,
626 struct ehca_cq, ib_cq);
627 ret = ehca_cq_assign_qp(cq, my_qp);
628 if (ret) {
629 ehca_err(pd->device, "Couldn't assign qp to send_cq ret=%x",
630 ret);
631 goto create_qp_exit3;
632 }
633 my_qp->send_cq = cq;
634 }
635 /* copy queues, galpa data to user space */
636 if (context && udata) {
637 struct ipz_queue *ipz_rqueue = &my_qp->ipz_rqueue;
638 struct ipz_queue *ipz_squeue = &my_qp->ipz_squeue;
639 struct ehca_create_qp_resp resp;
640 struct vm_area_struct * vma;
641 memset(&resp, 0, sizeof(resp));
642
643 resp.qp_num = my_qp->real_qp_num;
644 resp.token = my_qp->token;
645 resp.qp_type = my_qp->qp_type;
646 resp.qkey = my_qp->qkey;
647 resp.real_qp_num = my_qp->real_qp_num;
648 /* rqueue properties */
649 resp.ipz_rqueue.qe_size = ipz_rqueue->qe_size;
650 resp.ipz_rqueue.act_nr_of_sg = ipz_rqueue->act_nr_of_sg;
651 resp.ipz_rqueue.queue_length = ipz_rqueue->queue_length;
652 resp.ipz_rqueue.pagesize = ipz_rqueue->pagesize;
653 resp.ipz_rqueue.toggle_state = ipz_rqueue->toggle_state;
654 ret = ehca_mmap_nopage(((u64)(my_qp->token) << 32) | 0x22000000,
655 ipz_rqueue->queue_length,
656 (void**)&resp.ipz_rqueue.queue,
657 &vma);
658 if (ret) {
659 ehca_err(pd->device, "Could not mmap rqueue pages");
660 goto create_qp_exit3;
661 }
662 my_qp->uspace_rqueue = resp.ipz_rqueue.queue;
663 /* squeue properties */
664 resp.ipz_squeue.qe_size = ipz_squeue->qe_size;
665 resp.ipz_squeue.act_nr_of_sg = ipz_squeue->act_nr_of_sg;
666 resp.ipz_squeue.queue_length = ipz_squeue->queue_length;
667 resp.ipz_squeue.pagesize = ipz_squeue->pagesize;
668 resp.ipz_squeue.toggle_state = ipz_squeue->toggle_state;
669 ret = ehca_mmap_nopage(((u64)(my_qp->token) << 32) | 0x23000000,
670 ipz_squeue->queue_length,
671 (void**)&resp.ipz_squeue.queue,
672 &vma);
673 if (ret) {
674 ehca_err(pd->device, "Could not mmap squeue pages");
675 goto create_qp_exit4;
676 }
677 my_qp->uspace_squeue = resp.ipz_squeue.queue;
678 /* fw_handle */
679 resp.galpas = my_qp->galpas;
680 ret = ehca_mmap_register(my_qp->galpas.user.fw_handle,
681 (void**)&resp.galpas.kernel.fw_handle,
682 &vma);
683 if (ret) {
684 ehca_err(pd->device, "Could not mmap fw_handle");
685 goto create_qp_exit5;
686 }
687 my_qp->uspace_fwh = (u64)resp.galpas.kernel.fw_handle;
688
689 if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
690 ehca_err(pd->device, "Copy to udata failed");
691 ret = -EINVAL;
692 goto create_qp_exit6;
693 }
694 }
695
696 return &my_qp->ib_qp;
697
698create_qp_exit6:
699 ehca_munmap(my_qp->uspace_fwh, EHCA_PAGESIZE);
700
701create_qp_exit5:
702 ehca_munmap(my_qp->uspace_squeue, my_qp->ipz_squeue.queue_length);
703
704create_qp_exit4:
705 ehca_munmap(my_qp->uspace_rqueue, my_qp->ipz_rqueue.queue_length);
706
707create_qp_exit3:
708 ipz_queue_dtor(&my_qp->ipz_rqueue);
709 ipz_queue_dtor(&my_qp->ipz_squeue);
710
711create_qp_exit2:
712 hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
713
714create_qp_exit1:
715 spin_lock_irqsave(&ehca_qp_idr_lock, flags);
716 idr_remove(&ehca_qp_idr, my_qp->token);
717 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
718
719create_qp_exit0:
720 kmem_cache_free(qp_cache, my_qp);
721 return ERR_PTR(ret);
722}
723
724/*
725 * prepare_sqe_rts called by internal_modify_qp() at trans sqe -> rts
726 * set purge bit of bad wqe and subsequent wqes to avoid reentering sqe
727 * returns total number of bad wqes in bad_wqe_cnt
728 */
729static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
730 int *bad_wqe_cnt)
731{
732 u64 h_ret;
733 struct ipz_queue *squeue;
734 void *bad_send_wqe_p, *bad_send_wqe_v;
735 void *squeue_start_p, *squeue_end_p;
736 void *squeue_start_v, *squeue_end_v;
737 struct ehca_wqe *wqe;
738 int qp_num = my_qp->ib_qp.qp_num;
739
740 /* get send wqe pointer */
741 h_ret = hipz_h_disable_and_get_wqe(shca->ipz_hca_handle,
742 my_qp->ipz_qp_handle, &my_qp->pf,
743 &bad_send_wqe_p, NULL, 2);
744 if (h_ret != H_SUCCESS) {
745 ehca_err(&shca->ib_device, "hipz_h_disable_and_get_wqe() failed"
746 " ehca_qp=%p qp_num=%x h_ret=%lx",
747 my_qp, qp_num, h_ret);
748 return ehca2ib_return_code(h_ret);
749 }
750 bad_send_wqe_p = (void*)((u64)bad_send_wqe_p & (~(1L<<63)));
751 ehca_dbg(&shca->ib_device, "qp_num=%x bad_send_wqe_p=%p",
752 qp_num, bad_send_wqe_p);
753 /* convert wqe pointer to vadr */
754 bad_send_wqe_v = abs_to_virt((u64)bad_send_wqe_p);
755 if (ehca_debug_level)
756 ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num);
757 squeue = &my_qp->ipz_squeue;
758 squeue_start_p = (void*)virt_to_abs(ipz_qeit_calc(squeue, 0L));
759 squeue_end_p = squeue_start_p+squeue->queue_length;
760 squeue_start_v = abs_to_virt((u64)squeue_start_p);
761 squeue_end_v = abs_to_virt((u64)squeue_end_p);
762 ehca_dbg(&shca->ib_device, "qp_num=%x squeue_start_v=%p squeue_end_v=%p",
763 qp_num, squeue_start_v, squeue_end_v);
764
765 /* loop sets wqe's purge bit */
766 wqe = (struct ehca_wqe*)bad_send_wqe_v;
767 *bad_wqe_cnt = 0;
768 while (wqe->optype != 0xff && wqe->wqef != 0xff) {
769 if (ehca_debug_level)
770 ehca_dmp(wqe, 32, "qp_num=%x wqe", qp_num);
771 wqe->nr_of_data_seg = 0; /* suppress data access */
772 wqe->wqef = WQEF_PURGE; /* WQE to be purged */
773 wqe = (struct ehca_wqe*)((u8*)wqe+squeue->qe_size);
774 *bad_wqe_cnt = (*bad_wqe_cnt)+1;
775 if ((void*)wqe >= squeue_end_v) {
776 wqe = squeue_start_v;
777 }
778 }
779 /*
780 * bad wqe will be reprocessed and ignored when pol_cq() is called,
781 * i.e. nr of wqes with flush error status is one less
782 */
783 ehca_dbg(&shca->ib_device, "qp_num=%x flusherr_wqe_cnt=%x",
784 qp_num, (*bad_wqe_cnt)-1);
785 wqe->wqef = 0;
786
787 return 0;
788}
789
790/*
791 * internal_modify_qp with circumvention to handle aqp0 properly
792 * smi_reset2init indicates if this is an internal reset-to-init-call for
793 * smi. This flag must always be zero if called from ehca_modify_qp()!
794 * This internal func was intorduced to avoid recursion of ehca_modify_qp()!
795 */
796static int internal_modify_qp(struct ib_qp *ibqp,
797 struct ib_qp_attr *attr,
798 int attr_mask, int smi_reset2init)
799{
800 enum ib_qp_state qp_cur_state, qp_new_state;
801 int cnt, qp_attr_idx, ret = 0;
802 enum ib_qp_statetrans statetrans;
803 struct hcp_modify_qp_control_block *mqpcb;
804 struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
805 struct ehca_shca *shca =
806 container_of(ibqp->pd->device, struct ehca_shca, ib_device);
807 u64 update_mask;
808 u64 h_ret;
809 int bad_wqe_cnt = 0;
810 int squeue_locked = 0;
811 unsigned long spl_flags = 0;
812
813 /* do query_qp to obtain current attr values */
814 mqpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
815 if (mqpcb == NULL) {
816 ehca_err(ibqp->device, "Could not get zeroed page for mqpcb "
817 "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num);
818 return -ENOMEM;
819 }
820
821 h_ret = hipz_h_query_qp(shca->ipz_hca_handle,
822 my_qp->ipz_qp_handle,
823 &my_qp->pf,
824 mqpcb, my_qp->galpas.kernel);
825 if (h_ret != H_SUCCESS) {
826 ehca_err(ibqp->device, "hipz_h_query_qp() failed "
827 "ehca_qp=%p qp_num=%x h_ret=%lx",
828 my_qp, ibqp->qp_num, h_ret);
829 ret = ehca2ib_return_code(h_ret);
830 goto modify_qp_exit1;
831 }
832
833 qp_cur_state = ehca2ib_qp_state(mqpcb->qp_state);
834
835 if (qp_cur_state == -EINVAL) { /* invalid qp state */
836 ret = -EINVAL;
837 ehca_err(ibqp->device, "Invalid current ehca_qp_state=%x "
838 "ehca_qp=%p qp_num=%x",
839 mqpcb->qp_state, my_qp, ibqp->qp_num);
840 goto modify_qp_exit1;
841 }
842 /*
843 * circumvention to set aqp0 initial state to init
844 * as expected by IB spec
845 */
846 if (smi_reset2init == 0 &&
847 ibqp->qp_type == IB_QPT_SMI &&
848 qp_cur_state == IB_QPS_RESET &&
849 (attr_mask & IB_QP_STATE) &&
850 attr->qp_state == IB_QPS_INIT) { /* RESET -> INIT */
851 struct ib_qp_attr smiqp_attr = {
852 .qp_state = IB_QPS_INIT,
853 .port_num = my_qp->init_attr.port_num,
854 .pkey_index = 0,
855 .qkey = 0
856 };
857 int smiqp_attr_mask = IB_QP_STATE | IB_QP_PORT |
858 IB_QP_PKEY_INDEX | IB_QP_QKEY;
859 int smirc = internal_modify_qp(
860 ibqp, &smiqp_attr, smiqp_attr_mask, 1);
861 if (smirc) {
862 ehca_err(ibqp->device, "SMI RESET -> INIT failed. "
863 "ehca_modify_qp() rc=%x", smirc);
864 ret = H_PARAMETER;
865 goto modify_qp_exit1;
866 }
867 qp_cur_state = IB_QPS_INIT;
868 ehca_dbg(ibqp->device, "SMI RESET -> INIT succeeded");
869 }
870 /* is transmitted current state equal to "real" current state */
871 if ((attr_mask & IB_QP_CUR_STATE) &&
872 qp_cur_state != attr->cur_qp_state) {
873 ret = -EINVAL;
874 ehca_err(ibqp->device,
875 "Invalid IB_QP_CUR_STATE attr->curr_qp_state=%x <>"
876 " actual cur_qp_state=%x. ehca_qp=%p qp_num=%x",
877 attr->cur_qp_state, qp_cur_state, my_qp, ibqp->qp_num);
878 goto modify_qp_exit1;
879 }
880
881 ehca_dbg(ibqp->device,"ehca_qp=%p qp_num=%x current qp_state=%x "
882 "new qp_state=%x attribute_mask=%x",
883 my_qp, ibqp->qp_num, qp_cur_state, attr->qp_state, attr_mask);
884
885 qp_new_state = attr_mask & IB_QP_STATE ? attr->qp_state : qp_cur_state;
886 if (!smi_reset2init &&
887 !ib_modify_qp_is_ok(qp_cur_state, qp_new_state, ibqp->qp_type,
888 attr_mask)) {
889 ret = -EINVAL;
890 ehca_err(ibqp->device,
891 "Invalid qp transition new_state=%x cur_state=%x "
892 "ehca_qp=%p qp_num=%x attr_mask=%x", qp_new_state,
893 qp_cur_state, my_qp, ibqp->qp_num, attr_mask);
894 goto modify_qp_exit1;
895 }
896
897 if ((mqpcb->qp_state = ib2ehca_qp_state(qp_new_state)))
898 update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_STATE, 1);
899 else {
900 ret = -EINVAL;
901 ehca_err(ibqp->device, "Invalid new qp state=%x "
902 "ehca_qp=%p qp_num=%x",
903 qp_new_state, my_qp, ibqp->qp_num);
904 goto modify_qp_exit1;
905 }
906
907 /* retrieve state transition struct to get req and opt attrs */
908 statetrans = get_modqp_statetrans(qp_cur_state, qp_new_state);
909 if (statetrans < 0) {
910 ret = -EINVAL;
911 ehca_err(ibqp->device, "<INVALID STATE CHANGE> qp_cur_state=%x "
912 "new_qp_state=%x State_xsition=%x ehca_qp=%p "
913 "qp_num=%x", qp_cur_state, qp_new_state,
914 statetrans, my_qp, ibqp->qp_num);
915 goto modify_qp_exit1;
916 }
917
918 qp_attr_idx = ib2ehcaqptype(ibqp->qp_type);
919
920 if (qp_attr_idx < 0) {
921 ret = qp_attr_idx;
922 ehca_err(ibqp->device,
923 "Invalid QP type=%x ehca_qp=%p qp_num=%x",
924 ibqp->qp_type, my_qp, ibqp->qp_num);
925 goto modify_qp_exit1;
926 }
927
928 ehca_dbg(ibqp->device,
929 "ehca_qp=%p qp_num=%x <VALID STATE CHANGE> qp_state_xsit=%x",
930 my_qp, ibqp->qp_num, statetrans);
931
932 /* sqe -> rts: set purge bit of bad wqe before actual trans */
933 if ((my_qp->qp_type == IB_QPT_UD ||
934 my_qp->qp_type == IB_QPT_GSI ||
935 my_qp->qp_type == IB_QPT_SMI) &&
936 statetrans == IB_QPST_SQE2RTS) {
937 /* mark next free wqe if kernel */
938 if (my_qp->uspace_squeue == 0) {
939 struct ehca_wqe *wqe;
940 /* lock send queue */
941 spin_lock_irqsave(&my_qp->spinlock_s, spl_flags);
942 squeue_locked = 1;
943 /* mark next free wqe */
944 wqe = (struct ehca_wqe*)
945 ipz_qeit_get(&my_qp->ipz_squeue);
946 wqe->optype = wqe->wqef = 0xff;
947 ehca_dbg(ibqp->device, "qp_num=%x next_free_wqe=%p",
948 ibqp->qp_num, wqe);
949 }
950 ret = prepare_sqe_rts(my_qp, shca, &bad_wqe_cnt);
951 if (ret) {
952 ehca_err(ibqp->device, "prepare_sqe_rts() failed "
953 "ehca_qp=%p qp_num=%x ret=%x",
954 my_qp, ibqp->qp_num, ret);
955 goto modify_qp_exit2;
956 }
957 }
958
959 /*
960 * enable RDMA_Atomic_Control if reset->init und reliable con
961 * this is necessary since gen2 does not provide that flag,
962 * but pHyp requires it
963 */
964 if (statetrans == IB_QPST_RESET2INIT &&
965 (ibqp->qp_type == IB_QPT_RC || ibqp->qp_type == IB_QPT_UC)) {
966 mqpcb->rdma_atomic_ctrl = 3;
967 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_RDMA_ATOMIC_CTRL, 1);
968 }
969 /* circ. pHyp requires #RDMA/Atomic Resp Res for UC INIT -> RTR */
970 if (statetrans == IB_QPST_INIT2RTR &&
971 (ibqp->qp_type == IB_QPT_UC) &&
972 !(attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)) {
973 mqpcb->rdma_nr_atomic_resp_res = 1; /* default to 1 */
974 update_mask |=
975 EHCA_BMASK_SET(MQPCB_MASK_RDMA_NR_ATOMIC_RESP_RES, 1);
976 }
977
978 if (attr_mask & IB_QP_PKEY_INDEX) {
979 mqpcb->prim_p_key_idx = attr->pkey_index;
980 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_P_KEY_IDX, 1);
981 }
982 if (attr_mask & IB_QP_PORT) {
983 if (attr->port_num < 1 || attr->port_num > shca->num_ports) {
984 ret = -EINVAL;
985 ehca_err(ibqp->device, "Invalid port=%x. "
986 "ehca_qp=%p qp_num=%x num_ports=%x",
987 attr->port_num, my_qp, ibqp->qp_num,
988 shca->num_ports);
989 goto modify_qp_exit2;
990 }
991 mqpcb->prim_phys_port = attr->port_num;
992 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_PHYS_PORT, 1);
993 }
994 if (attr_mask & IB_QP_QKEY) {
995 mqpcb->qkey = attr->qkey;
996 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_QKEY, 1);
997 }
998 if (attr_mask & IB_QP_AV) {
999 int ah_mult = ib_rate_to_mult(attr->ah_attr.static_rate);
1000 int ehca_mult = ib_rate_to_mult(shca->sport[my_qp->
1001 init_attr.port_num].rate);
1002
1003 mqpcb->dlid = attr->ah_attr.dlid;
1004 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DLID, 1);
1005 mqpcb->source_path_bits = attr->ah_attr.src_path_bits;
1006 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SOURCE_PATH_BITS, 1);
1007 mqpcb->service_level = attr->ah_attr.sl;
1008 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL, 1);
1009
1010 if (ah_mult < ehca_mult)
1011 mqpcb->max_static_rate = (ah_mult > 0) ?
1012 ((ehca_mult - 1) / ah_mult) : 0;
1013 else
1014 mqpcb->max_static_rate = 0;
1015
1016 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE, 1);
1017
1018 /*
1019 * only if GRH is TRUE we might consider SOURCE_GID_IDX
1020 * and DEST_GID otherwise phype will return H_ATTR_PARM!!!
1021 */
1022 if (attr->ah_attr.ah_flags == IB_AH_GRH) {
1023 mqpcb->send_grh_flag = 1 << 31;
1024 update_mask |=
1025 EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG, 1);
1026 mqpcb->source_gid_idx = attr->ah_attr.grh.sgid_index;
1027 update_mask |=
1028 EHCA_BMASK_SET(MQPCB_MASK_SOURCE_GID_IDX, 1);
1029
1030 for (cnt = 0; cnt < 16; cnt++)
1031 mqpcb->dest_gid.byte[cnt] =
1032 attr->ah_attr.grh.dgid.raw[cnt];
1033
1034 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DEST_GID, 1);
1035 mqpcb->flow_label = attr->ah_attr.grh.flow_label;
1036 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_FLOW_LABEL, 1);
1037 mqpcb->hop_limit = attr->ah_attr.grh.hop_limit;
1038 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_HOP_LIMIT, 1);
1039 mqpcb->traffic_class = attr->ah_attr.grh.traffic_class;
1040 update_mask |=
1041 EHCA_BMASK_SET(MQPCB_MASK_TRAFFIC_CLASS, 1);
1042 }
1043 }
1044
1045 if (attr_mask & IB_QP_PATH_MTU) {
1046 mqpcb->path_mtu = attr->path_mtu;
1047 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PATH_MTU, 1);
1048 }
1049 if (attr_mask & IB_QP_TIMEOUT) {
1050 mqpcb->timeout = attr->timeout;
1051 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_TIMEOUT, 1);
1052 }
1053 if (attr_mask & IB_QP_RETRY_CNT) {
1054 mqpcb->retry_count = attr->retry_cnt;
1055 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_RETRY_COUNT, 1);
1056 }
1057 if (attr_mask & IB_QP_RNR_RETRY) {
1058 mqpcb->rnr_retry_count = attr->rnr_retry;
1059 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_RNR_RETRY_COUNT, 1);
1060 }
1061 if (attr_mask & IB_QP_RQ_PSN) {
1062 mqpcb->receive_psn = attr->rq_psn;
1063 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_RECEIVE_PSN, 1);
1064 }
1065 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
1066 mqpcb->rdma_nr_atomic_resp_res = attr->max_dest_rd_atomic < 3 ?
1067 attr->max_dest_rd_atomic : 2;
1068 update_mask |=
1069 EHCA_BMASK_SET(MQPCB_MASK_RDMA_NR_ATOMIC_RESP_RES, 1);
1070 }
1071 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
1072 mqpcb->rdma_atomic_outst_dest_qp = attr->max_rd_atomic < 3 ?
1073 attr->max_rd_atomic : 2;
1074 update_mask |=
1075 EHCA_BMASK_SET
1076 (MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP, 1);
1077 }
1078 if (attr_mask & IB_QP_ALT_PATH) {
1079 int ah_mult = ib_rate_to_mult(attr->alt_ah_attr.static_rate);
1080 int ehca_mult = ib_rate_to_mult(
1081 shca->sport[my_qp->init_attr.port_num].rate);
1082
1083 mqpcb->dlid_al = attr->alt_ah_attr.dlid;
1084 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DLID_AL, 1);
1085 mqpcb->source_path_bits_al = attr->alt_ah_attr.src_path_bits;
1086 update_mask |=
1087 EHCA_BMASK_SET(MQPCB_MASK_SOURCE_PATH_BITS_AL, 1);
1088 mqpcb->service_level_al = attr->alt_ah_attr.sl;
1089 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL_AL, 1);
1090
1091 if (ah_mult < ehca_mult)
1092 mqpcb->max_static_rate = (ah_mult > 0) ?
1093 ((ehca_mult - 1) / ah_mult) : 0;
1094 else
1095 mqpcb->max_static_rate_al = 0;
1096
1097 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE_AL, 1);
1098
1099 /*
1100 * only if GRH is TRUE we might consider SOURCE_GID_IDX
1101 * and DEST_GID otherwise phype will return H_ATTR_PARM!!!
1102 */
1103 if (attr->alt_ah_attr.ah_flags == IB_AH_GRH) {
1104 mqpcb->send_grh_flag_al = 1 << 31;
1105 update_mask |=
1106 EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG_AL, 1);
1107 mqpcb->source_gid_idx_al =
1108 attr->alt_ah_attr.grh.sgid_index;
1109 update_mask |=
1110 EHCA_BMASK_SET(MQPCB_MASK_SOURCE_GID_IDX_AL, 1);
1111
1112 for (cnt = 0; cnt < 16; cnt++)
1113 mqpcb->dest_gid_al.byte[cnt] =
1114 attr->alt_ah_attr.grh.dgid.raw[cnt];
1115
1116 update_mask |=
1117 EHCA_BMASK_SET(MQPCB_MASK_DEST_GID_AL, 1);
1118 mqpcb->flow_label_al = attr->alt_ah_attr.grh.flow_label;
1119 update_mask |=
1120 EHCA_BMASK_SET(MQPCB_MASK_FLOW_LABEL_AL, 1);
1121 mqpcb->hop_limit_al = attr->alt_ah_attr.grh.hop_limit;
1122 update_mask |=
1123 EHCA_BMASK_SET(MQPCB_MASK_HOP_LIMIT_AL, 1);
1124 mqpcb->traffic_class_al =
1125 attr->alt_ah_attr.grh.traffic_class;
1126 update_mask |=
1127 EHCA_BMASK_SET(MQPCB_MASK_TRAFFIC_CLASS_AL, 1);
1128 }
1129 }
1130
1131 if (attr_mask & IB_QP_MIN_RNR_TIMER) {
1132 mqpcb->min_rnr_nak_timer_field = attr->min_rnr_timer;
1133 update_mask |=
1134 EHCA_BMASK_SET(MQPCB_MASK_MIN_RNR_NAK_TIMER_FIELD, 1);
1135 }
1136
1137 if (attr_mask & IB_QP_SQ_PSN) {
1138 mqpcb->send_psn = attr->sq_psn;
1139 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SEND_PSN, 1);
1140 }
1141
1142 if (attr_mask & IB_QP_DEST_QPN) {
1143 mqpcb->dest_qp_nr = attr->dest_qp_num;
1144 update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DEST_QP_NR, 1);
1145 }
1146
1147 if (attr_mask & IB_QP_PATH_MIG_STATE) {
1148 mqpcb->path_migration_state = attr->path_mig_state;
1149 update_mask |=
1150 EHCA_BMASK_SET(MQPCB_MASK_PATH_MIGRATION_STATE, 1);
1151 }
1152
1153 if (attr_mask & IB_QP_CAP) {
1154 mqpcb->max_nr_outst_send_wr = attr->cap.max_send_wr+1;
1155 update_mask |=
1156 EHCA_BMASK_SET(MQPCB_MASK_MAX_NR_OUTST_SEND_WR, 1);
1157 mqpcb->max_nr_outst_recv_wr = attr->cap.max_recv_wr+1;
1158 update_mask |=
1159 EHCA_BMASK_SET(MQPCB_MASK_MAX_NR_OUTST_RECV_WR, 1);
1160 /* no support for max_send/recv_sge yet */
1161 }
1162
1163 if (ehca_debug_level)
1164 ehca_dmp(mqpcb, 4*70, "qp_num=%x", ibqp->qp_num);
1165
1166 h_ret = hipz_h_modify_qp(shca->ipz_hca_handle,
1167 my_qp->ipz_qp_handle,
1168 &my_qp->pf,
1169 update_mask,
1170 mqpcb, my_qp->galpas.kernel);
1171
1172 if (h_ret != H_SUCCESS) {
1173 ret = ehca2ib_return_code(h_ret);
1174 ehca_err(ibqp->device, "hipz_h_modify_qp() failed rc=%lx "
1175 "ehca_qp=%p qp_num=%x",h_ret, my_qp, ibqp->qp_num);
1176 goto modify_qp_exit2;
1177 }
1178
1179 if ((my_qp->qp_type == IB_QPT_UD ||
1180 my_qp->qp_type == IB_QPT_GSI ||
1181 my_qp->qp_type == IB_QPT_SMI) &&
1182 statetrans == IB_QPST_SQE2RTS) {
1183 /* doorbell to reprocessing wqes */
1184 iosync(); /* serialize GAL register access */
1185 hipz_update_sqa(my_qp, bad_wqe_cnt-1);
1186 ehca_gen_dbg("doorbell for %x wqes", bad_wqe_cnt);
1187 }
1188
1189 if (statetrans == IB_QPST_RESET2INIT ||
1190 statetrans == IB_QPST_INIT2INIT) {
1191 mqpcb->qp_enable = 1;
1192 mqpcb->qp_state = EHCA_QPS_INIT;
1193 update_mask = 0;
1194 update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_ENABLE, 1);
1195
1196 h_ret = hipz_h_modify_qp(shca->ipz_hca_handle,
1197 my_qp->ipz_qp_handle,
1198 &my_qp->pf,
1199 update_mask,
1200 mqpcb,
1201 my_qp->galpas.kernel);
1202
1203 if (h_ret != H_SUCCESS) {
1204 ret = ehca2ib_return_code(h_ret);
1205 ehca_err(ibqp->device, "ENABLE in context of "
1206 "RESET_2_INIT failed! Maybe you didn't get "
1207 "a LID h_ret=%lx ehca_qp=%p qp_num=%x",
1208 h_ret, my_qp, ibqp->qp_num);
1209 goto modify_qp_exit2;
1210 }
1211 }
1212
1213 if (statetrans == IB_QPST_ANY2RESET) {
1214 ipz_qeit_reset(&my_qp->ipz_rqueue);
1215 ipz_qeit_reset(&my_qp->ipz_squeue);
1216 }
1217
1218 if (attr_mask & IB_QP_QKEY)
1219 my_qp->qkey = attr->qkey;
1220
1221modify_qp_exit2:
1222 if (squeue_locked) { /* this means: sqe -> rts */
1223 spin_unlock_irqrestore(&my_qp->spinlock_s, spl_flags);
1224 my_qp->sqerr_purgeflag = 1;
1225 }
1226
1227modify_qp_exit1:
1228 kfree(mqpcb);
1229
1230 return ret;
1231}
1232
1233int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
1234 struct ib_udata *udata)
1235{
1236 struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
1237 struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd,
1238 ib_pd);
1239 u32 cur_pid = current->tgid;
1240
1241 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
1242 my_pd->ownpid != cur_pid) {
1243 ehca_err(ibqp->pd->device, "Invalid caller pid=%x ownpid=%x",
1244 cur_pid, my_pd->ownpid);
1245 return -EINVAL;
1246 }
1247
1248 return internal_modify_qp(ibqp, attr, attr_mask, 0);
1249}
1250
1251int ehca_query_qp(struct ib_qp *qp,
1252 struct ib_qp_attr *qp_attr,
1253 int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
1254{
1255 struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp);
1256 struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd,
1257 ib_pd);
1258 struct ehca_shca *shca = container_of(qp->device, struct ehca_shca,
1259 ib_device);
1260 struct ipz_adapter_handle adapter_handle = shca->ipz_hca_handle;
1261 struct hcp_modify_qp_control_block *qpcb;
1262 u32 cur_pid = current->tgid;
1263 int cnt, ret = 0;
1264 u64 h_ret;
1265
1266 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
1267 my_pd->ownpid != cur_pid) {
1268 ehca_err(qp->device, "Invalid caller pid=%x ownpid=%x",
1269 cur_pid, my_pd->ownpid);
1270 return -EINVAL;
1271 }
1272
1273 if (qp_attr_mask & QP_ATTR_QUERY_NOT_SUPPORTED) {
1274 ehca_err(qp->device,"Invalid attribute mask "
1275 "ehca_qp=%p qp_num=%x qp_attr_mask=%x ",
1276 my_qp, qp->qp_num, qp_attr_mask);
1277 return -EINVAL;
1278 }
1279
1280 qpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL );
1281 if (!qpcb) {
1282 ehca_err(qp->device,"Out of memory for qpcb "
1283 "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num);
1284 return -ENOMEM;
1285 }
1286
1287 h_ret = hipz_h_query_qp(adapter_handle,
1288 my_qp->ipz_qp_handle,
1289 &my_qp->pf,
1290 qpcb, my_qp->galpas.kernel);
1291
1292 if (h_ret != H_SUCCESS) {
1293 ret = ehca2ib_return_code(h_ret);
1294 ehca_err(qp->device,"hipz_h_query_qp() failed "
1295 "ehca_qp=%p qp_num=%x h_ret=%lx",
1296 my_qp, qp->qp_num, h_ret);
1297 goto query_qp_exit1;
1298 }
1299
1300 qp_attr->cur_qp_state = ehca2ib_qp_state(qpcb->qp_state);
1301 qp_attr->qp_state = qp_attr->cur_qp_state;
1302
1303 if (qp_attr->cur_qp_state == -EINVAL) {
1304 ret = -EINVAL;
1305 ehca_err(qp->device,"Got invalid ehca_qp_state=%x "
1306 "ehca_qp=%p qp_num=%x",
1307 qpcb->qp_state, my_qp, qp->qp_num);
1308 goto query_qp_exit1;
1309 }
1310
1311 if (qp_attr->qp_state == IB_QPS_SQD)
1312 qp_attr->sq_draining = 1;
1313
1314 qp_attr->qkey = qpcb->qkey;
1315 qp_attr->path_mtu = qpcb->path_mtu;
1316 qp_attr->path_mig_state = qpcb->path_migration_state;
1317 qp_attr->rq_psn = qpcb->receive_psn;
1318 qp_attr->sq_psn = qpcb->send_psn;
1319 qp_attr->min_rnr_timer = qpcb->min_rnr_nak_timer_field;
1320 qp_attr->cap.max_send_wr = qpcb->max_nr_outst_send_wr-1;
1321 qp_attr->cap.max_recv_wr = qpcb->max_nr_outst_recv_wr-1;
1322 /* UD_AV CIRCUMVENTION */
1323 if (my_qp->qp_type == IB_QPT_UD) {
1324 qp_attr->cap.max_send_sge =
1325 qpcb->actual_nr_sges_in_sq_wqe - 2;
1326 qp_attr->cap.max_recv_sge =
1327 qpcb->actual_nr_sges_in_rq_wqe - 2;
1328 } else {
1329 qp_attr->cap.max_send_sge =
1330 qpcb->actual_nr_sges_in_sq_wqe;
1331 qp_attr->cap.max_recv_sge =
1332 qpcb->actual_nr_sges_in_rq_wqe;
1333 }
1334
1335 qp_attr->cap.max_inline_data = my_qp->sq_max_inline_data_size;
1336 qp_attr->dest_qp_num = qpcb->dest_qp_nr;
1337
1338 qp_attr->pkey_index =
1339 EHCA_BMASK_GET(MQPCB_PRIM_P_KEY_IDX, qpcb->prim_p_key_idx);
1340
1341 qp_attr->port_num =
1342 EHCA_BMASK_GET(MQPCB_PRIM_PHYS_PORT, qpcb->prim_phys_port);
1343
1344 qp_attr->timeout = qpcb->timeout;
1345 qp_attr->retry_cnt = qpcb->retry_count;
1346 qp_attr->rnr_retry = qpcb->rnr_retry_count;
1347
1348 qp_attr->alt_pkey_index =
1349 EHCA_BMASK_GET(MQPCB_PRIM_P_KEY_IDX, qpcb->alt_p_key_idx);
1350
1351 qp_attr->alt_port_num = qpcb->alt_phys_port;
1352 qp_attr->alt_timeout = qpcb->timeout_al;
1353
1354 /* primary av */
1355 qp_attr->ah_attr.sl = qpcb->service_level;
1356
1357 if (qpcb->send_grh_flag) {
1358 qp_attr->ah_attr.ah_flags = IB_AH_GRH;
1359 }
1360
1361 qp_attr->ah_attr.static_rate = qpcb->max_static_rate;
1362 qp_attr->ah_attr.dlid = qpcb->dlid;
1363 qp_attr->ah_attr.src_path_bits = qpcb->source_path_bits;
1364 qp_attr->ah_attr.port_num = qp_attr->port_num;
1365
1366 /* primary GRH */
1367 qp_attr->ah_attr.grh.traffic_class = qpcb->traffic_class;
1368 qp_attr->ah_attr.grh.hop_limit = qpcb->hop_limit;
1369 qp_attr->ah_attr.grh.sgid_index = qpcb->source_gid_idx;
1370 qp_attr->ah_attr.grh.flow_label = qpcb->flow_label;
1371
1372 for (cnt = 0; cnt < 16; cnt++)
1373 qp_attr->ah_attr.grh.dgid.raw[cnt] =
1374 qpcb->dest_gid.byte[cnt];
1375
1376 /* alternate AV */
1377 qp_attr->alt_ah_attr.sl = qpcb->service_level_al;
1378 if (qpcb->send_grh_flag_al) {
1379 qp_attr->alt_ah_attr.ah_flags = IB_AH_GRH;
1380 }
1381
1382 qp_attr->alt_ah_attr.static_rate = qpcb->max_static_rate_al;
1383 qp_attr->alt_ah_attr.dlid = qpcb->dlid_al;
1384 qp_attr->alt_ah_attr.src_path_bits = qpcb->source_path_bits_al;
1385
1386 /* alternate GRH */
1387 qp_attr->alt_ah_attr.grh.traffic_class = qpcb->traffic_class_al;
1388 qp_attr->alt_ah_attr.grh.hop_limit = qpcb->hop_limit_al;
1389 qp_attr->alt_ah_attr.grh.sgid_index = qpcb->source_gid_idx_al;
1390 qp_attr->alt_ah_attr.grh.flow_label = qpcb->flow_label_al;
1391
1392 for (cnt = 0; cnt < 16; cnt++)
1393 qp_attr->alt_ah_attr.grh.dgid.raw[cnt] =
1394 qpcb->dest_gid_al.byte[cnt];
1395
1396 /* return init attributes given in ehca_create_qp */
1397 if (qp_init_attr)
1398 *qp_init_attr = my_qp->init_attr;
1399
1400 if (ehca_debug_level)
1401 ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num);
1402
1403query_qp_exit1:
1404 kfree(qpcb);
1405
1406 return ret;
1407}
1408
1409int ehca_destroy_qp(struct ib_qp *ibqp)
1410{
1411 struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
1412 struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
1413 ib_device);
1414 struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd,
1415 ib_pd);
1416 u32 cur_pid = current->tgid;
1417 u32 qp_num = ibqp->qp_num;
1418 int ret;
1419 u64 h_ret;
1420 u8 port_num;
1421 enum ib_qp_type qp_type;
1422 unsigned long flags;
1423
1424 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
1425 my_pd->ownpid != cur_pid) {
1426 ehca_err(ibqp->device, "Invalid caller pid=%x ownpid=%x",
1427 cur_pid, my_pd->ownpid);
1428 return -EINVAL;
1429 }
1430
1431 if (my_qp->send_cq) {
1432 ret = ehca_cq_unassign_qp(my_qp->send_cq,
1433 my_qp->real_qp_num);
1434 if (ret) {
1435 ehca_err(ibqp->device, "Couldn't unassign qp from "
1436 "send_cq ret=%x qp_num=%x cq_num=%x", ret,
1437 my_qp->ib_qp.qp_num, my_qp->send_cq->cq_number);
1438 return ret;
1439 }
1440 }
1441
1442 spin_lock_irqsave(&ehca_qp_idr_lock, flags);
1443 idr_remove(&ehca_qp_idr, my_qp->token);
1444 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
1445
1446 /* un-mmap if vma alloc */
1447 if (my_qp->uspace_rqueue) {
1448 ret = ehca_munmap(my_qp->uspace_rqueue,
1449 my_qp->ipz_rqueue.queue_length);
1450 if (ret)
1451 ehca_err(ibqp->device, "Could not munmap rqueue "
1452 "qp_num=%x", qp_num);
1453 ret = ehca_munmap(my_qp->uspace_squeue,
1454 my_qp->ipz_squeue.queue_length);
1455 if (ret)
1456 ehca_err(ibqp->device, "Could not munmap squeue "
1457 "qp_num=%x", qp_num);
1458 ret = ehca_munmap(my_qp->uspace_fwh, EHCA_PAGESIZE);
1459 if (ret)
1460 ehca_err(ibqp->device, "Could not munmap fwh qp_num=%x",
1461 qp_num);
1462 }
1463
1464 h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
1465 if (h_ret != H_SUCCESS) {
1466 ehca_err(ibqp->device, "hipz_h_destroy_qp() failed rc=%lx "
1467 "ehca_qp=%p qp_num=%x", h_ret, my_qp, qp_num);
1468 return ehca2ib_return_code(h_ret);
1469 }
1470
1471 port_num = my_qp->init_attr.port_num;
1472 qp_type = my_qp->init_attr.qp_type;
1473
1474 /* no support for IB_QPT_SMI yet */
1475 if (qp_type == IB_QPT_GSI) {
1476 struct ib_event event;
1477 ehca_info(ibqp->device, "device %s: port %x is inactive.",
1478 shca->ib_device.name, port_num);
1479 event.device = &shca->ib_device;
1480 event.event = IB_EVENT_PORT_ERR;
1481 event.element.port_num = port_num;
1482 shca->sport[port_num - 1].port_state = IB_PORT_DOWN;
1483 ib_dispatch_event(&event);
1484 }
1485
1486 ipz_queue_dtor(&my_qp->ipz_rqueue);
1487 ipz_queue_dtor(&my_qp->ipz_squeue);
1488 kmem_cache_free(qp_cache, my_qp);
1489 return 0;
1490}
1491
1492int ehca_init_qp_cache(void)
1493{
1494 qp_cache = kmem_cache_create("ehca_cache_qp",
1495 sizeof(struct ehca_qp), 0,
1496 SLAB_HWCACHE_ALIGN,
1497 NULL, NULL);
1498 if (!qp_cache)
1499 return -ENOMEM;
1500 return 0;
1501}
1502
1503void ehca_cleanup_qp_cache(void)
1504{
1505 if (qp_cache)
1506 kmem_cache_destroy(qp_cache);
1507}
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
new file mode 100644
index 000000000000..b46bda1bf85d
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -0,0 +1,653 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * post_send/recv, poll_cq, req_notify
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Reinhard Ernst <rernst@de.ibm.com>
9 *
10 * Copyright (c) 2005 IBM Corporation
11 *
12 * All rights reserved.
13 *
14 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
15 * BSD.
16 *
17 * OpenIB BSD License
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * Redistributions of source code must retain the above copyright notice, this
23 * list of conditions and the following disclaimer.
24 *
25 * Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials
28 * provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42
43
44#include <asm-powerpc/system.h>
45#include "ehca_classes.h"
46#include "ehca_tools.h"
47#include "ehca_qes.h"
48#include "ehca_iverbs.h"
49#include "hcp_if.h"
50#include "hipz_fns.h"
51
52static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue,
53 struct ehca_wqe *wqe_p,
54 struct ib_recv_wr *recv_wr)
55{
56 u8 cnt_ds;
57 if (unlikely((recv_wr->num_sge < 0) ||
58 (recv_wr->num_sge > ipz_rqueue->act_nr_of_sg))) {
59 ehca_gen_err("Invalid number of WQE SGE. "
60 "num_sqe=%x max_nr_of_sg=%x",
61 recv_wr->num_sge, ipz_rqueue->act_nr_of_sg);
62 return -EINVAL; /* invalid SG list length */
63 }
64
65 /* clear wqe header until sglist */
66 memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list));
67
68 wqe_p->work_request_id = recv_wr->wr_id;
69 wqe_p->nr_of_data_seg = recv_wr->num_sge;
70
71 for (cnt_ds = 0; cnt_ds < recv_wr->num_sge; cnt_ds++) {
72 wqe_p->u.all_rcv.sg_list[cnt_ds].vaddr =
73 recv_wr->sg_list[cnt_ds].addr;
74 wqe_p->u.all_rcv.sg_list[cnt_ds].lkey =
75 recv_wr->sg_list[cnt_ds].lkey;
76 wqe_p->u.all_rcv.sg_list[cnt_ds].length =
77 recv_wr->sg_list[cnt_ds].length;
78 }
79
80 if (ehca_debug_level) {
81 ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p", ipz_rqueue);
82 ehca_dmp( wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "recv wqe");
83 }
84
85 return 0;
86}
87
88#if defined(DEBUG_GSI_SEND_WR)
89
90/* need ib_mad struct */
91#include <rdma/ib_mad.h>
92
93static void trace_send_wr_ud(const struct ib_send_wr *send_wr)
94{
95 int idx;
96 int j;
97 while (send_wr) {
98 struct ib_mad_hdr *mad_hdr = send_wr->wr.ud.mad_hdr;
99 struct ib_sge *sge = send_wr->sg_list;
100 ehca_gen_dbg("send_wr#%x wr_id=%lx num_sge=%x "
101 "send_flags=%x opcode=%x",idx, send_wr->wr_id,
102 send_wr->num_sge, send_wr->send_flags,
103 send_wr->opcode);
104 if (mad_hdr) {
105 ehca_gen_dbg("send_wr#%x mad_hdr base_version=%x "
106 "mgmt_class=%x class_version=%x method=%x "
107 "status=%x class_specific=%x tid=%lx "
108 "attr_id=%x resv=%x attr_mod=%x",
109 idx, mad_hdr->base_version,
110 mad_hdr->mgmt_class,
111 mad_hdr->class_version, mad_hdr->method,
112 mad_hdr->status, mad_hdr->class_specific,
113 mad_hdr->tid, mad_hdr->attr_id,
114 mad_hdr->resv,
115 mad_hdr->attr_mod);
116 }
117 for (j = 0; j < send_wr->num_sge; j++) {
118 u8 *data = (u8 *) abs_to_virt(sge->addr);
119 ehca_gen_dbg("send_wr#%x sge#%x addr=%p length=%x "
120 "lkey=%x",
121 idx, j, data, sge->length, sge->lkey);
122 /* assume length is n*16 */
123 ehca_dmp(data, sge->length, "send_wr#%x sge#%x",
124 idx, j);
125 sge++;
126 } /* eof for j */
127 idx++;
128 send_wr = send_wr->next;
129 } /* eof while send_wr */
130}
131
132#endif /* DEBUG_GSI_SEND_WR */
133
134static inline int ehca_write_swqe(struct ehca_qp *qp,
135 struct ehca_wqe *wqe_p,
136 const struct ib_send_wr *send_wr)
137{
138 u32 idx;
139 u64 dma_length;
140 struct ehca_av *my_av;
141 u32 remote_qkey = send_wr->wr.ud.remote_qkey;
142
143 if (unlikely((send_wr->num_sge < 0) ||
144 (send_wr->num_sge > qp->ipz_squeue.act_nr_of_sg))) {
145 ehca_gen_err("Invalid number of WQE SGE. "
146 "num_sqe=%x max_nr_of_sg=%x",
147 send_wr->num_sge, qp->ipz_squeue.act_nr_of_sg);
148 return -EINVAL; /* invalid SG list length */
149 }
150
151 /* clear wqe header until sglist */
152 memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list));
153
154 wqe_p->work_request_id = send_wr->wr_id;
155
156 switch (send_wr->opcode) {
157 case IB_WR_SEND:
158 case IB_WR_SEND_WITH_IMM:
159 wqe_p->optype = WQE_OPTYPE_SEND;
160 break;
161 case IB_WR_RDMA_WRITE:
162 case IB_WR_RDMA_WRITE_WITH_IMM:
163 wqe_p->optype = WQE_OPTYPE_RDMAWRITE;
164 break;
165 case IB_WR_RDMA_READ:
166 wqe_p->optype = WQE_OPTYPE_RDMAREAD;
167 break;
168 default:
169 ehca_gen_err("Invalid opcode=%x", send_wr->opcode);
170 return -EINVAL; /* invalid opcode */
171 }
172
173 wqe_p->wqef = (send_wr->opcode) & WQEF_HIGH_NIBBLE;
174
175 wqe_p->wr_flag = 0;
176
177 if (send_wr->send_flags & IB_SEND_SIGNALED)
178 wqe_p->wr_flag |= WQE_WRFLAG_REQ_SIGNAL_COM;
179
180 if (send_wr->opcode == IB_WR_SEND_WITH_IMM ||
181 send_wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) {
182 /* this might not work as long as HW does not support it */
183 wqe_p->immediate_data = be32_to_cpu(send_wr->imm_data);
184 wqe_p->wr_flag |= WQE_WRFLAG_IMM_DATA_PRESENT;
185 }
186
187 wqe_p->nr_of_data_seg = send_wr->num_sge;
188
189 switch (qp->qp_type) {
190 case IB_QPT_SMI:
191 case IB_QPT_GSI:
192 /* no break is intential here */
193 case IB_QPT_UD:
194 /* IB 1.2 spec C10-15 compliance */
195 if (send_wr->wr.ud.remote_qkey & 0x80000000)
196 remote_qkey = qp->qkey;
197
198 wqe_p->destination_qp_number = send_wr->wr.ud.remote_qpn << 8;
199 wqe_p->local_ee_context_qkey = remote_qkey;
200 if (!send_wr->wr.ud.ah) {
201 ehca_gen_err("wr.ud.ah is NULL. qp=%p", qp);
202 return -EINVAL;
203 }
204 my_av = container_of(send_wr->wr.ud.ah, struct ehca_av, ib_ah);
205 wqe_p->u.ud_av.ud_av = my_av->av;
206
207 /*
208 * omitted check of IB_SEND_INLINE
209 * since HW does not support it
210 */
211 for (idx = 0; idx < send_wr->num_sge; idx++) {
212 wqe_p->u.ud_av.sg_list[idx].vaddr =
213 send_wr->sg_list[idx].addr;
214 wqe_p->u.ud_av.sg_list[idx].lkey =
215 send_wr->sg_list[idx].lkey;
216 wqe_p->u.ud_av.sg_list[idx].length =
217 send_wr->sg_list[idx].length;
218 } /* eof for idx */
219 if (qp->qp_type == IB_QPT_SMI ||
220 qp->qp_type == IB_QPT_GSI)
221 wqe_p->u.ud_av.ud_av.pmtu = 1;
222 if (qp->qp_type == IB_QPT_GSI) {
223 wqe_p->pkeyi = send_wr->wr.ud.pkey_index;
224#ifdef DEBUG_GSI_SEND_WR
225 trace_send_wr_ud(send_wr);
226#endif /* DEBUG_GSI_SEND_WR */
227 }
228 break;
229
230 case IB_QPT_UC:
231 if (send_wr->send_flags & IB_SEND_FENCE)
232 wqe_p->wr_flag |= WQE_WRFLAG_FENCE;
233 /* no break is intentional here */
234 case IB_QPT_RC:
235 /* TODO: atomic not implemented */
236 wqe_p->u.nud.remote_virtual_adress =
237 send_wr->wr.rdma.remote_addr;
238 wqe_p->u.nud.rkey = send_wr->wr.rdma.rkey;
239
240 /*
241 * omitted checking of IB_SEND_INLINE
242 * since HW does not support it
243 */
244 dma_length = 0;
245 for (idx = 0; idx < send_wr->num_sge; idx++) {
246 wqe_p->u.nud.sg_list[idx].vaddr =
247 send_wr->sg_list[idx].addr;
248 wqe_p->u.nud.sg_list[idx].lkey =
249 send_wr->sg_list[idx].lkey;
250 wqe_p->u.nud.sg_list[idx].length =
251 send_wr->sg_list[idx].length;
252 dma_length += send_wr->sg_list[idx].length;
253 } /* eof idx */
254 wqe_p->u.nud.atomic_1st_op_dma_len = dma_length;
255
256 break;
257
258 default:
259 ehca_gen_err("Invalid qptype=%x", qp->qp_type);
260 return -EINVAL;
261 }
262
263 if (ehca_debug_level) {
264 ehca_gen_dbg("SEND WQE written into queue qp=%p ", qp);
265 ehca_dmp( wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "send wqe");
266 }
267 return 0;
268}
269
270/* map_ib_wc_status converts raw cqe_status to ib_wc_status */
271static inline void map_ib_wc_status(u32 cqe_status,
272 enum ib_wc_status *wc_status)
273{
274 if (unlikely(cqe_status & WC_STATUS_ERROR_BIT)) {
275 switch (cqe_status & 0x3F) {
276 case 0x01:
277 case 0x21:
278 *wc_status = IB_WC_LOC_LEN_ERR;
279 break;
280 case 0x02:
281 case 0x22:
282 *wc_status = IB_WC_LOC_QP_OP_ERR;
283 break;
284 case 0x03:
285 case 0x23:
286 *wc_status = IB_WC_LOC_EEC_OP_ERR;
287 break;
288 case 0x04:
289 case 0x24:
290 *wc_status = IB_WC_LOC_PROT_ERR;
291 break;
292 case 0x05:
293 case 0x25:
294 *wc_status = IB_WC_WR_FLUSH_ERR;
295 break;
296 case 0x06:
297 *wc_status = IB_WC_MW_BIND_ERR;
298 break;
299 case 0x07: /* remote error - look into bits 20:24 */
300 switch ((cqe_status
301 & WC_STATUS_REMOTE_ERROR_FLAGS) >> 11) {
302 case 0x0:
303 /*
304 * PSN Sequence Error!
305 * couldn't find a matching status!
306 */
307 *wc_status = IB_WC_GENERAL_ERR;
308 break;
309 case 0x1:
310 *wc_status = IB_WC_REM_INV_REQ_ERR;
311 break;
312 case 0x2:
313 *wc_status = IB_WC_REM_ACCESS_ERR;
314 break;
315 case 0x3:
316 *wc_status = IB_WC_REM_OP_ERR;
317 break;
318 case 0x4:
319 *wc_status = IB_WC_REM_INV_RD_REQ_ERR;
320 break;
321 }
322 break;
323 case 0x08:
324 *wc_status = IB_WC_RETRY_EXC_ERR;
325 break;
326 case 0x09:
327 *wc_status = IB_WC_RNR_RETRY_EXC_ERR;
328 break;
329 case 0x0A:
330 case 0x2D:
331 *wc_status = IB_WC_REM_ABORT_ERR;
332 break;
333 case 0x0B:
334 case 0x2E:
335 *wc_status = IB_WC_INV_EECN_ERR;
336 break;
337 case 0x0C:
338 case 0x2F:
339 *wc_status = IB_WC_INV_EEC_STATE_ERR;
340 break;
341 case 0x0D:
342 *wc_status = IB_WC_BAD_RESP_ERR;
343 break;
344 case 0x10:
345 /* WQE purged */
346 *wc_status = IB_WC_WR_FLUSH_ERR;
347 break;
348 default:
349 *wc_status = IB_WC_FATAL_ERR;
350
351 }
352 } else
353 *wc_status = IB_WC_SUCCESS;
354}
355
356int ehca_post_send(struct ib_qp *qp,
357 struct ib_send_wr *send_wr,
358 struct ib_send_wr **bad_send_wr)
359{
360 struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp);
361 struct ib_send_wr *cur_send_wr;
362 struct ehca_wqe *wqe_p;
363 int wqe_cnt = 0;
364 int ret = 0;
365 unsigned long spl_flags;
366
367 /* LOCK the QUEUE */
368 spin_lock_irqsave(&my_qp->spinlock_s, spl_flags);
369
370 /* loop processes list of send reqs */
371 for (cur_send_wr = send_wr; cur_send_wr != NULL;
372 cur_send_wr = cur_send_wr->next) {
373 u64 start_offset = my_qp->ipz_squeue.current_q_offset;
374 /* get pointer next to free WQE */
375 wqe_p = ipz_qeit_get_inc(&my_qp->ipz_squeue);
376 if (unlikely(!wqe_p)) {
377 /* too many posted work requests: queue overflow */
378 if (bad_send_wr)
379 *bad_send_wr = cur_send_wr;
380 if (wqe_cnt == 0) {
381 ret = -ENOMEM;
382 ehca_err(qp->device, "Too many posted WQEs "
383 "qp_num=%x", qp->qp_num);
384 }
385 goto post_send_exit0;
386 }
387 /* write a SEND WQE into the QUEUE */
388 ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr);
389 /*
390 * if something failed,
391 * reset the free entry pointer to the start value
392 */
393 if (unlikely(ret)) {
394 my_qp->ipz_squeue.current_q_offset = start_offset;
395 *bad_send_wr = cur_send_wr;
396 if (wqe_cnt == 0) {
397 ret = -EINVAL;
398 ehca_err(qp->device, "Could not write WQE "
399 "qp_num=%x", qp->qp_num);
400 }
401 goto post_send_exit0;
402 }
403 wqe_cnt++;
404 ehca_dbg(qp->device, "ehca_qp=%p qp_num=%x wqe_cnt=%d",
405 my_qp, qp->qp_num, wqe_cnt);
406 } /* eof for cur_send_wr */
407
408post_send_exit0:
409 /* UNLOCK the QUEUE */
410 spin_unlock_irqrestore(&my_qp->spinlock_s, spl_flags);
411 iosync(); /* serialize GAL register access */
412 hipz_update_sqa(my_qp, wqe_cnt);
413 return ret;
414}
415
416int ehca_post_recv(struct ib_qp *qp,
417 struct ib_recv_wr *recv_wr,
418 struct ib_recv_wr **bad_recv_wr)
419{
420 struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp);
421 struct ib_recv_wr *cur_recv_wr;
422 struct ehca_wqe *wqe_p;
423 int wqe_cnt = 0;
424 int ret = 0;
425 unsigned long spl_flags;
426
427 /* LOCK the QUEUE */
428 spin_lock_irqsave(&my_qp->spinlock_r, spl_flags);
429
430 /* loop processes list of send reqs */
431 for (cur_recv_wr = recv_wr; cur_recv_wr != NULL;
432 cur_recv_wr = cur_recv_wr->next) {
433 u64 start_offset = my_qp->ipz_rqueue.current_q_offset;
434 /* get pointer next to free WQE */
435 wqe_p = ipz_qeit_get_inc(&my_qp->ipz_rqueue);
436 if (unlikely(!wqe_p)) {
437 /* too many posted work requests: queue overflow */
438 if (bad_recv_wr)
439 *bad_recv_wr = cur_recv_wr;
440 if (wqe_cnt == 0) {
441 ret = -ENOMEM;
442 ehca_err(qp->device, "Too many posted WQEs "
443 "qp_num=%x", qp->qp_num);
444 }
445 goto post_recv_exit0;
446 }
447 /* write a RECV WQE into the QUEUE */
448 ret = ehca_write_rwqe(&my_qp->ipz_rqueue, wqe_p, cur_recv_wr);
449 /*
450 * if something failed,
451 * reset the free entry pointer to the start value
452 */
453 if (unlikely(ret)) {
454 my_qp->ipz_rqueue.current_q_offset = start_offset;
455 *bad_recv_wr = cur_recv_wr;
456 if (wqe_cnt == 0) {
457 ret = -EINVAL;
458 ehca_err(qp->device, "Could not write WQE "
459 "qp_num=%x", qp->qp_num);
460 }
461 goto post_recv_exit0;
462 }
463 wqe_cnt++;
464 ehca_gen_dbg("ehca_qp=%p qp_num=%x wqe_cnt=%d",
465 my_qp, qp->qp_num, wqe_cnt);
466 } /* eof for cur_recv_wr */
467
468post_recv_exit0:
469 spin_unlock_irqrestore(&my_qp->spinlock_r, spl_flags);
470 iosync(); /* serialize GAL register access */
471 hipz_update_rqa(my_qp, wqe_cnt);
472 return ret;
473}
474
475/*
476 * ib_wc_opcode table converts ehca wc opcode to ib
477 * Since we use zero to indicate invalid opcode, the actual ib opcode must
478 * be decremented!!!
479 */
480static const u8 ib_wc_opcode[255] = {
481 [0x01] = IB_WC_RECV+1,
482 [0x02] = IB_WC_RECV_RDMA_WITH_IMM+1,
483 [0x04] = IB_WC_BIND_MW+1,
484 [0x08] = IB_WC_FETCH_ADD+1,
485 [0x10] = IB_WC_COMP_SWAP+1,
486 [0x20] = IB_WC_RDMA_WRITE+1,
487 [0x40] = IB_WC_RDMA_READ+1,
488 [0x80] = IB_WC_SEND+1
489};
490
491/* internal function to poll one entry of cq */
492static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc)
493{
494 int ret = 0;
495 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
496 struct ehca_cqe *cqe;
497 int cqe_count = 0;
498
499poll_cq_one_read_cqe:
500 cqe = (struct ehca_cqe *)
501 ipz_qeit_get_inc_valid(&my_cq->ipz_queue);
502 if (!cqe) {
503 ret = -EAGAIN;
504 ehca_dbg(cq->device, "Completion queue is empty ehca_cq=%p "
505 "cq_num=%x ret=%x", my_cq, my_cq->cq_number, ret);
506 goto poll_cq_one_exit0;
507 }
508
509 /* prevents loads being reordered across this point */
510 rmb();
511
512 cqe_count++;
513 if (unlikely(cqe->status & WC_STATUS_PURGE_BIT)) {
514 struct ehca_qp *qp=ehca_cq_get_qp(my_cq, cqe->local_qp_number);
515 int purgeflag;
516 unsigned long spl_flags;
517 if (!qp) {
518 ehca_err(cq->device, "cq_num=%x qp_num=%x "
519 "could not find qp -> ignore cqe",
520 my_cq->cq_number, cqe->local_qp_number);
521 ehca_dmp(cqe, 64, "cq_num=%x qp_num=%x",
522 my_cq->cq_number, cqe->local_qp_number);
523 /* ignore this purged cqe */
524 goto poll_cq_one_read_cqe;
525 }
526 spin_lock_irqsave(&qp->spinlock_s, spl_flags);
527 purgeflag = qp->sqerr_purgeflag;
528 spin_unlock_irqrestore(&qp->spinlock_s, spl_flags);
529
530 if (purgeflag) {
531 ehca_dbg(cq->device, "Got CQE with purged bit qp_num=%x "
532 "src_qp=%x",
533 cqe->local_qp_number, cqe->remote_qp_number);
534 if (ehca_debug_level)
535 ehca_dmp(cqe, 64, "qp_num=%x src_qp=%x",
536 cqe->local_qp_number,
537 cqe->remote_qp_number);
538 /*
539 * ignore this to avoid double cqes of bad wqe
540 * that caused sqe and turn off purge flag
541 */
542 qp->sqerr_purgeflag = 0;
543 goto poll_cq_one_read_cqe;
544 }
545 }
546
547 /* tracing cqe */
548 if (ehca_debug_level) {
549 ehca_dbg(cq->device,
550 "Received COMPLETION ehca_cq=%p cq_num=%x -----",
551 my_cq, my_cq->cq_number);
552 ehca_dmp(cqe, 64, "ehca_cq=%p cq_num=%x",
553 my_cq, my_cq->cq_number);
554 ehca_dbg(cq->device,
555 "ehca_cq=%p cq_num=%x -------------------------",
556 my_cq, my_cq->cq_number);
557 }
558
559 /* we got a completion! */
560 wc->wr_id = cqe->work_request_id;
561
562 /* eval ib_wc_opcode */
563 wc->opcode = ib_wc_opcode[cqe->optype]-1;
564 if (unlikely(wc->opcode == -1)) {
565 ehca_err(cq->device, "Invalid cqe->OPType=%x cqe->status=%x "
566 "ehca_cq=%p cq_num=%x",
567 cqe->optype, cqe->status, my_cq, my_cq->cq_number);
568 /* dump cqe for other infos */
569 ehca_dmp(cqe, 64, "ehca_cq=%p cq_num=%x",
570 my_cq, my_cq->cq_number);
571 /* update also queue adder to throw away this entry!!! */
572 goto poll_cq_one_exit0;
573 }
574 /* eval ib_wc_status */
575 if (unlikely(cqe->status & WC_STATUS_ERROR_BIT)) {
576 /* complete with errors */
577 map_ib_wc_status(cqe->status, &wc->status);
578 wc->vendor_err = wc->status;
579 } else
580 wc->status = IB_WC_SUCCESS;
581
582 wc->qp_num = cqe->local_qp_number;
583 wc->byte_len = cqe->nr_bytes_transferred;
584 wc->pkey_index = cqe->pkey_index;
585 wc->slid = cqe->rlid;
586 wc->dlid_path_bits = cqe->dlid;
587 wc->src_qp = cqe->remote_qp_number;
588 wc->wc_flags = cqe->w_completion_flags;
589 wc->imm_data = cpu_to_be32(cqe->immediate_data);
590 wc->sl = cqe->service_level;
591
592 if (wc->status != IB_WC_SUCCESS)
593 ehca_dbg(cq->device,
594 "ehca_cq=%p cq_num=%x WARNING unsuccessful cqe "
595 "OPType=%x status=%x qp_num=%x src_qp=%x wr_id=%lx "
596 "cqe=%p", my_cq, my_cq->cq_number, cqe->optype,
597 cqe->status, cqe->local_qp_number,
598 cqe->remote_qp_number, cqe->work_request_id, cqe);
599
600poll_cq_one_exit0:
601 if (cqe_count > 0)
602 hipz_update_feca(my_cq, cqe_count);
603
604 return ret;
605}
606
607int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc)
608{
609 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
610 int nr;
611 struct ib_wc *current_wc = wc;
612 int ret = 0;
613 unsigned long spl_flags;
614
615 if (num_entries < 1) {
616 ehca_err(cq->device, "Invalid num_entries=%d ehca_cq=%p "
617 "cq_num=%x", num_entries, my_cq, my_cq->cq_number);
618 ret = -EINVAL;
619 goto poll_cq_exit0;
620 }
621
622 spin_lock_irqsave(&my_cq->spinlock, spl_flags);
623 for (nr = 0; nr < num_entries; nr++) {
624 ret = ehca_poll_cq_one(cq, current_wc);
625 if (ret)
626 break;
627 current_wc++;
628 } /* eof for nr */
629 spin_unlock_irqrestore(&my_cq->spinlock, spl_flags);
630 if (ret == -EAGAIN || !ret)
631 ret = nr;
632
633poll_cq_exit0:
634 return ret;
635}
636
637int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify cq_notify)
638{
639 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
640
641 switch (cq_notify) {
642 case IB_CQ_SOLICITED:
643 hipz_set_cqx_n0(my_cq, 1);
644 break;
645 case IB_CQ_NEXT_COMP:
646 hipz_set_cqx_n1(my_cq, 1);
647 break;
648 default:
649 return -EINVAL;
650 }
651
652 return 0;
653}
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c
new file mode 100644
index 000000000000..9f16e9c79394
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_sqp.c
@@ -0,0 +1,111 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * SQP functions
5 *
6 * Authors: Khadija Souissi <souissi@de.ibm.com>
7 * Heiko J Schick <schickhj@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42
43#include <linux/module.h>
44#include <linux/err.h>
45#include "ehca_classes.h"
46#include "ehca_tools.h"
47#include "ehca_qes.h"
48#include "ehca_iverbs.h"
49#include "hcp_if.h"
50
51
52/**
53 * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
54 * pair is created successfully, the corresponding port gets active.
55 *
56 * Define Special Queue pair 0 (SMI QP) is still not supported.
57 *
58 * @qp_init_attr: Queue pair init attributes with port and queue pair type
59 */
60
61u64 ehca_define_sqp(struct ehca_shca *shca,
62 struct ehca_qp *ehca_qp,
63 struct ib_qp_init_attr *qp_init_attr)
64{
65 u32 pma_qp_nr, bma_qp_nr;
66 u64 ret;
67 u8 port = qp_init_attr->port_num;
68 int counter;
69
70 shca->sport[port - 1].port_state = IB_PORT_DOWN;
71
72 switch (qp_init_attr->qp_type) {
73 case IB_QPT_SMI:
74 /* function not supported yet */
75 break;
76 case IB_QPT_GSI:
77 ret = hipz_h_define_aqp1(shca->ipz_hca_handle,
78 ehca_qp->ipz_qp_handle,
79 ehca_qp->galpas.kernel,
80 (u32) qp_init_attr->port_num,
81 &pma_qp_nr, &bma_qp_nr);
82
83 if (ret != H_SUCCESS) {
84 ehca_err(&shca->ib_device,
85 "Can't define AQP1 for port %x. rc=%lx",
86 port, ret);
87 return ret;
88 }
89 break;
90 default:
91 ehca_err(&shca->ib_device, "invalid qp_type=%x",
92 qp_init_attr->qp_type);
93 return H_PARAMETER;
94 }
95
96 for (counter = 0;
97 shca->sport[port - 1].port_state != IB_PORT_ACTIVE &&
98 counter < ehca_port_act_time;
99 counter++) {
100 ehca_dbg(&shca->ib_device, "... wait until port %x is active",
101 port);
102 msleep_interruptible(1000);
103 }
104
105 if (counter == ehca_port_act_time) {
106 ehca_err(&shca->ib_device, "Port %x is not active.", port);
107 return H_HARDWARE;
108 }
109
110 return H_SUCCESS;
111}
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
new file mode 100644
index 000000000000..9f56bb846d93
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -0,0 +1,172 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * auxiliary functions
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Khadija Souissi <souissik@de.ibm.com>
9 * Waleri Fomin <fomin@de.ibm.com>
10 * Heiko J Schick <schickhj@de.ibm.com>
11 *
12 * Copyright (c) 2005 IBM Corporation
13 *
14 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
15 * BSD.
16 *
17 * OpenIB BSD License
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * Redistributions of source code must retain the above copyright notice, this
23 * list of conditions and the following disclaimer.
24 *
25 * Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials
28 * provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42
43
44#ifndef EHCA_TOOLS_H
45#define EHCA_TOOLS_H
46
47#include <linux/kernel.h>
48#include <linux/spinlock.h>
49#include <linux/delay.h>
50#include <linux/idr.h>
51#include <linux/kthread.h>
52#include <linux/mm.h>
53#include <linux/mman.h>
54#include <linux/module.h>
55#include <linux/moduleparam.h>
56#include <linux/vmalloc.h>
57#include <linux/version.h>
58#include <linux/notifier.h>
59#include <linux/cpu.h>
60#include <linux/device.h>
61
62#include <asm/abs_addr.h>
63#include <asm/ibmebus.h>
64#include <asm/io.h>
65#include <asm/pgtable.h>
66
67extern int ehca_debug_level;
68
69#define ehca_dbg(ib_dev, format, arg...) \
70 do { \
71 if (unlikely(ehca_debug_level)) \
72 dev_printk(KERN_DEBUG, (ib_dev)->dma_device, \
73 "PU%04x EHCA_DBG:%s " format "\n", \
74 get_paca()->paca_index, __FUNCTION__, \
75 ## arg); \
76 } while (0)
77
78#define ehca_info(ib_dev, format, arg...) \
79 dev_info((ib_dev)->dma_device, "PU%04x EHCA_INFO:%s " format "\n", \
80 get_paca()->paca_index, __FUNCTION__, ## arg)
81
82#define ehca_warn(ib_dev, format, arg...) \
83 dev_warn((ib_dev)->dma_device, "PU%04x EHCA_WARN:%s " format "\n", \
84 get_paca()->paca_index, __FUNCTION__, ## arg)
85
86#define ehca_err(ib_dev, format, arg...) \
87 dev_err((ib_dev)->dma_device, "PU%04x EHCA_ERR:%s " format "\n", \
88 get_paca()->paca_index, __FUNCTION__, ## arg)
89
90/* use this one only if no ib_dev available */
91#define ehca_gen_dbg(format, arg...) \
92 do { \
93 if (unlikely(ehca_debug_level)) \
94 printk(KERN_DEBUG "PU%04x EHCA_DBG:%s " format "\n",\
95 get_paca()->paca_index, __FUNCTION__, ## arg); \
96 } while (0)
97
98#define ehca_gen_warn(format, arg...) \
99 do { \
100 if (unlikely(ehca_debug_level)) \
101 printk(KERN_INFO "PU%04x EHCA_WARN:%s " format "\n",\
102 get_paca()->paca_index, __FUNCTION__, ## arg); \
103 } while (0)
104
105#define ehca_gen_err(format, arg...) \
106 printk(KERN_ERR "PU%04x EHCA_ERR:%s " format "\n", \
107 get_paca()->paca_index, __FUNCTION__, ## arg)
108
109/**
110 * ehca_dmp - printk a memory block, whose length is n*8 bytes.
111 * Each line has the following layout:
112 * <format string> adr=X ofs=Y <8 bytes hex> <8 bytes hex>
113 */
114#define ehca_dmp(adr, len, format, args...) \
115 do { \
116 unsigned int x; \
117 unsigned int l = (unsigned int)(len); \
118 unsigned char *deb = (unsigned char*)(adr); \
119 for (x = 0; x < l; x += 16) { \
120 printk("EHCA_DMP:%s" format \
121 " adr=%p ofs=%04x %016lx %016lx\n", \
122 __FUNCTION__, ##args, deb, x, \
123 *((u64 *)&deb[0]), *((u64 *)&deb[8])); \
124 deb += 16; \
125 } \
126 } while (0)
127
128/* define a bitmask, little endian version */
129#define EHCA_BMASK(pos,length) (((pos)<<16)+(length))
130
131/* define a bitmask, the ibm way... */
132#define EHCA_BMASK_IBM(from,to) (((63-to)<<16)+((to)-(from)+1))
133
134/* internal function, don't use */
135#define EHCA_BMASK_SHIFTPOS(mask) (((mask)>>16)&0xffff)
136
137/* internal function, don't use */
138#define EHCA_BMASK_MASK(mask) (0xffffffffffffffffULL >> ((64-(mask))&0xffff))
139
140/**
141 * EHCA_BMASK_SET - return value shifted and masked by mask
142 * variable|=EHCA_BMASK_SET(MY_MASK,0x4711) ORs the bits in variable
143 * variable&=~EHCA_BMASK_SET(MY_MASK,-1) clears the bits from the mask
144 * in variable
145 */
146#define EHCA_BMASK_SET(mask,value) \
147 ((EHCA_BMASK_MASK(mask) & ((u64)(value)))<<EHCA_BMASK_SHIFTPOS(mask))
148
149/**
150 * EHCA_BMASK_GET - extract a parameter from value by mask
151 */
152#define EHCA_BMASK_GET(mask,value) \
153 (EHCA_BMASK_MASK(mask)& (((u64)(value))>>EHCA_BMASK_SHIFTPOS(mask)))
154
155
156/* Converts ehca to ib return code */
157static inline int ehca2ib_return_code(u64 ehca_rc)
158{
159 switch (ehca_rc) {
160 case H_SUCCESS:
161 return 0;
162 case H_BUSY:
163 return -EBUSY;
164 case H_NO_MEM:
165 return -ENOMEM;
166 default:
167 return -EINVAL;
168 }
169}
170
171
172#endif /* EHCA_TOOLS_H */
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
new file mode 100644
index 000000000000..e08764e4aef2
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -0,0 +1,392 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * userspace support verbs
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Heiko J Schick <schickhj@de.ibm.com>
9 *
10 * Copyright (c) 2005 IBM Corporation
11 *
12 * All rights reserved.
13 *
14 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
15 * BSD.
16 *
17 * OpenIB BSD License
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * Redistributions of source code must retain the above copyright notice, this
23 * list of conditions and the following disclaimer.
24 *
25 * Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials
28 * provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42
43#include <asm/current.h>
44
45#include "ehca_classes.h"
46#include "ehca_iverbs.h"
47#include "ehca_mrmw.h"
48#include "ehca_tools.h"
49#include "hcp_if.h"
50
51struct ib_ucontext *ehca_alloc_ucontext(struct ib_device *device,
52 struct ib_udata *udata)
53{
54 struct ehca_ucontext *my_context;
55
56 my_context = kzalloc(sizeof *my_context, GFP_KERNEL);
57 if (!my_context) {
58 ehca_err(device, "Out of memory device=%p", device);
59 return ERR_PTR(-ENOMEM);
60 }
61
62 return &my_context->ib_ucontext;
63}
64
65int ehca_dealloc_ucontext(struct ib_ucontext *context)
66{
67 kfree(container_of(context, struct ehca_ucontext, ib_ucontext));
68 return 0;
69}
70
71struct page *ehca_nopage(struct vm_area_struct *vma,
72 unsigned long address, int *type)
73{
74 struct page *mypage = NULL;
75 u64 fileoffset = vma->vm_pgoff << PAGE_SHIFT;
76 u32 idr_handle = fileoffset >> 32;
77 u32 q_type = (fileoffset >> 28) & 0xF; /* CQ, QP,... */
78 u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */
79 u32 cur_pid = current->tgid;
80 unsigned long flags;
81 struct ehca_cq *cq;
82 struct ehca_qp *qp;
83 struct ehca_pd *pd;
84 u64 offset;
85 void *vaddr;
86
87 switch (q_type) {
88 case 1: /* CQ */
89 spin_lock_irqsave(&ehca_cq_idr_lock, flags);
90 cq = idr_find(&ehca_cq_idr, idr_handle);
91 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
92
93 /* make sure this mmap really belongs to the authorized user */
94 if (!cq) {
95 ehca_gen_err("cq is NULL ret=NOPAGE_SIGBUS");
96 return NOPAGE_SIGBUS;
97 }
98
99 if (cq->ownpid != cur_pid) {
100 ehca_err(cq->ib_cq.device,
101 "Invalid caller pid=%x ownpid=%x",
102 cur_pid, cq->ownpid);
103 return NOPAGE_SIGBUS;
104 }
105
106 if (rsrc_type == 2) {
107 ehca_dbg(cq->ib_cq.device, "cq=%p cq queuearea", cq);
108 offset = address - vma->vm_start;
109 vaddr = ipz_qeit_calc(&cq->ipz_queue, offset);
110 ehca_dbg(cq->ib_cq.device, "offset=%lx vaddr=%p",
111 offset, vaddr);
112 mypage = virt_to_page(vaddr);
113 }
114 break;
115
116 case 2: /* QP */
117 spin_lock_irqsave(&ehca_qp_idr_lock, flags);
118 qp = idr_find(&ehca_qp_idr, idr_handle);
119 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
120
121 /* make sure this mmap really belongs to the authorized user */
122 if (!qp) {
123 ehca_gen_err("qp is NULL ret=NOPAGE_SIGBUS");
124 return NOPAGE_SIGBUS;
125 }
126
127 pd = container_of(qp->ib_qp.pd, struct ehca_pd, ib_pd);
128 if (pd->ownpid != cur_pid) {
129 ehca_err(qp->ib_qp.device,
130 "Invalid caller pid=%x ownpid=%x",
131 cur_pid, pd->ownpid);
132 return NOPAGE_SIGBUS;
133 }
134
135 if (rsrc_type == 2) { /* rqueue */
136 ehca_dbg(qp->ib_qp.device, "qp=%p qp rqueuearea", qp);
137 offset = address - vma->vm_start;
138 vaddr = ipz_qeit_calc(&qp->ipz_rqueue, offset);
139 ehca_dbg(qp->ib_qp.device, "offset=%lx vaddr=%p",
140 offset, vaddr);
141 mypage = virt_to_page(vaddr);
142 } else if (rsrc_type == 3) { /* squeue */
143 ehca_dbg(qp->ib_qp.device, "qp=%p qp squeuearea", qp);
144 offset = address - vma->vm_start;
145 vaddr = ipz_qeit_calc(&qp->ipz_squeue, offset);
146 ehca_dbg(qp->ib_qp.device, "offset=%lx vaddr=%p",
147 offset, vaddr);
148 mypage = virt_to_page(vaddr);
149 }
150 break;
151
152 default:
153 ehca_gen_err("bad queue type %x", q_type);
154 return NOPAGE_SIGBUS;
155 }
156
157 if (!mypage) {
158 ehca_gen_err("Invalid page adr==NULL ret=NOPAGE_SIGBUS");
159 return NOPAGE_SIGBUS;
160 }
161 get_page(mypage);
162
163 return mypage;
164}
165
166static struct vm_operations_struct ehcau_vm_ops = {
167 .nopage = ehca_nopage,
168};
169
170int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
171{
172 u64 fileoffset = vma->vm_pgoff << PAGE_SHIFT;
173 u32 idr_handle = fileoffset >> 32;
174 u32 q_type = (fileoffset >> 28) & 0xF; /* CQ, QP,... */
175 u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */
176 u32 cur_pid = current->tgid;
177 u32 ret;
178 u64 vsize, physical;
179 unsigned long flags;
180 struct ehca_cq *cq;
181 struct ehca_qp *qp;
182 struct ehca_pd *pd;
183
184 switch (q_type) {
185 case 1: /* CQ */
186 spin_lock_irqsave(&ehca_cq_idr_lock, flags);
187 cq = idr_find(&ehca_cq_idr, idr_handle);
188 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
189
190 /* make sure this mmap really belongs to the authorized user */
191 if (!cq)
192 return -EINVAL;
193
194 if (cq->ownpid != cur_pid) {
195 ehca_err(cq->ib_cq.device,
196 "Invalid caller pid=%x ownpid=%x",
197 cur_pid, cq->ownpid);
198 return -ENOMEM;
199 }
200
201 if (!cq->ib_cq.uobject || cq->ib_cq.uobject->context != context)
202 return -EINVAL;
203
204 switch (rsrc_type) {
205 case 1: /* galpa fw handle */
206 ehca_dbg(cq->ib_cq.device, "cq=%p cq triggerarea", cq);
207 vma->vm_flags |= VM_RESERVED;
208 vsize = vma->vm_end - vma->vm_start;
209 if (vsize != EHCA_PAGESIZE) {
210 ehca_err(cq->ib_cq.device, "invalid vsize=%lx",
211 vma->vm_end - vma->vm_start);
212 return -EINVAL;
213 }
214
215 physical = cq->galpas.user.fw_handle;
216 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
217 vma->vm_flags |= VM_IO | VM_RESERVED;
218
219 ehca_dbg(cq->ib_cq.device,
220 "vsize=%lx physical=%lx", vsize, physical);
221 ret = remap_pfn_range(vma, vma->vm_start,
222 physical >> PAGE_SHIFT, vsize,
223 vma->vm_page_prot);
224 if (ret) {
225 ehca_err(cq->ib_cq.device,
226 "remap_pfn_range() failed ret=%x",
227 ret);
228 return -ENOMEM;
229 }
230 break;
231
232 case 2: /* cq queue_addr */
233 ehca_dbg(cq->ib_cq.device, "cq=%p cq q_addr", cq);
234 vma->vm_flags |= VM_RESERVED;
235 vma->vm_ops = &ehcau_vm_ops;
236 break;
237
238 default:
239 ehca_err(cq->ib_cq.device, "bad resource type %x",
240 rsrc_type);
241 return -EINVAL;
242 }
243 break;
244
245 case 2: /* QP */
246 spin_lock_irqsave(&ehca_qp_idr_lock, flags);
247 qp = idr_find(&ehca_qp_idr, idr_handle);
248 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
249
250 /* make sure this mmap really belongs to the authorized user */
251 if (!qp)
252 return -EINVAL;
253
254 pd = container_of(qp->ib_qp.pd, struct ehca_pd, ib_pd);
255 if (pd->ownpid != cur_pid) {
256 ehca_err(qp->ib_qp.device,
257 "Invalid caller pid=%x ownpid=%x",
258 cur_pid, pd->ownpid);
259 return -ENOMEM;
260 }
261
262 if (!qp->ib_qp.uobject || qp->ib_qp.uobject->context != context)
263 return -EINVAL;
264
265 switch (rsrc_type) {
266 case 1: /* galpa fw handle */
267 ehca_dbg(qp->ib_qp.device, "qp=%p qp triggerarea", qp);
268 vma->vm_flags |= VM_RESERVED;
269 vsize = vma->vm_end - vma->vm_start;
270 if (vsize != EHCA_PAGESIZE) {
271 ehca_err(qp->ib_qp.device, "invalid vsize=%lx",
272 vma->vm_end - vma->vm_start);
273 return -EINVAL;
274 }
275
276 physical = qp->galpas.user.fw_handle;
277 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
278 vma->vm_flags |= VM_IO | VM_RESERVED;
279
280 ehca_dbg(qp->ib_qp.device, "vsize=%lx physical=%lx",
281 vsize, physical);
282 ret = remap_pfn_range(vma, vma->vm_start,
283 physical >> PAGE_SHIFT, vsize,
284 vma->vm_page_prot);
285 if (ret) {
286 ehca_err(qp->ib_qp.device,
287 "remap_pfn_range() failed ret=%x",
288 ret);
289 return -ENOMEM;
290 }
291 break;
292
293 case 2: /* qp rqueue_addr */
294 ehca_dbg(qp->ib_qp.device, "qp=%p qp rqueue_addr", qp);
295 vma->vm_flags |= VM_RESERVED;
296 vma->vm_ops = &ehcau_vm_ops;
297 break;
298
299 case 3: /* qp squeue_addr */
300 ehca_dbg(qp->ib_qp.device, "qp=%p qp squeue_addr", qp);
301 vma->vm_flags |= VM_RESERVED;
302 vma->vm_ops = &ehcau_vm_ops;
303 break;
304
305 default:
306 ehca_err(qp->ib_qp.device, "bad resource type %x",
307 rsrc_type);
308 return -EINVAL;
309 }
310 break;
311
312 default:
313 ehca_gen_err("bad queue type %x", q_type);
314 return -EINVAL;
315 }
316
317 return 0;
318}
319
320int ehca_mmap_nopage(u64 foffset, u64 length, void **mapped,
321 struct vm_area_struct **vma)
322{
323 down_write(&current->mm->mmap_sem);
324 *mapped = (void*)do_mmap(NULL,0, length, PROT_WRITE,
325 MAP_SHARED | MAP_ANONYMOUS,
326 foffset);
327 up_write(&current->mm->mmap_sem);
328 if (!(*mapped)) {
329 ehca_gen_err("couldn't mmap foffset=%lx length=%lx",
330 foffset, length);
331 return -EINVAL;
332 }
333
334 *vma = find_vma(current->mm, (u64)*mapped);
335 if (!(*vma)) {
336 down_write(&current->mm->mmap_sem);
337 do_munmap(current->mm, 0, length);
338 up_write(&current->mm->mmap_sem);
339 ehca_gen_err("couldn't find vma queue=%p", *mapped);
340 return -EINVAL;
341 }
342 (*vma)->vm_flags |= VM_RESERVED;
343 (*vma)->vm_ops = &ehcau_vm_ops;
344
345 return 0;
346}
347
348int ehca_mmap_register(u64 physical, void **mapped,
349 struct vm_area_struct **vma)
350{
351 int ret;
352 unsigned long vsize;
353 /* ehca hw supports only 4k page */
354 ret = ehca_mmap_nopage(0, EHCA_PAGESIZE, mapped, vma);
355 if (ret) {
356 ehca_gen_err("could'nt mmap physical=%lx", physical);
357 return ret;
358 }
359
360 (*vma)->vm_flags |= VM_RESERVED;
361 vsize = (*vma)->vm_end - (*vma)->vm_start;
362 if (vsize != EHCA_PAGESIZE) {
363 ehca_gen_err("invalid vsize=%lx",
364 (*vma)->vm_end - (*vma)->vm_start);
365 return -EINVAL;
366 }
367
368 (*vma)->vm_page_prot = pgprot_noncached((*vma)->vm_page_prot);
369 (*vma)->vm_flags |= VM_IO | VM_RESERVED;
370
371 ret = remap_pfn_range((*vma), (*vma)->vm_start,
372 physical >> PAGE_SHIFT, vsize,
373 (*vma)->vm_page_prot);
374 if (ret) {
375 ehca_gen_err("remap_pfn_range() failed ret=%x", ret);
376 return -ENOMEM;
377 }
378
379 return 0;
380
381}
382
383int ehca_munmap(unsigned long addr, size_t len) {
384 int ret = 0;
385 struct mm_struct *mm = current->mm;
386 if (mm) {
387 down_write(&mm->mmap_sem);
388 ret = do_munmap(mm, addr, len);
389 up_write(&mm->mmap_sem);
390 }
391 return ret;
392}
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
new file mode 100644
index 000000000000..3fb46e67df87
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -0,0 +1,874 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Firmware Infiniband Interface code for POWER
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Gerd Bayer <gerd.bayer@de.ibm.com>
9 * Waleri Fomin <fomin@de.ibm.com>
10 *
11 * Copyright (c) 2005 IBM Corporation
12 *
13 * All rights reserved.
14 *
15 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
16 * BSD.
17 *
18 * OpenIB BSD License
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *
23 * Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
25 *
26 * Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials
29 * provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44#include <asm/hvcall.h>
45#include "ehca_tools.h"
46#include "hcp_if.h"
47#include "hcp_phyp.h"
48#include "hipz_fns.h"
49#include "ipz_pt_fn.h"
50
51#define H_ALL_RES_QP_ENHANCED_OPS EHCA_BMASK_IBM(9, 11)
52#define H_ALL_RES_QP_PTE_PIN EHCA_BMASK_IBM(12, 12)
53#define H_ALL_RES_QP_SERVICE_TYPE EHCA_BMASK_IBM(13, 15)
54#define H_ALL_RES_QP_LL_RQ_CQE_POSTING EHCA_BMASK_IBM(18, 18)
55#define H_ALL_RES_QP_LL_SQ_CQE_POSTING EHCA_BMASK_IBM(19, 21)
56#define H_ALL_RES_QP_SIGNALING_TYPE EHCA_BMASK_IBM(22, 23)
57#define H_ALL_RES_QP_UD_AV_LKEY_CTRL EHCA_BMASK_IBM(31, 31)
58#define H_ALL_RES_QP_RESOURCE_TYPE EHCA_BMASK_IBM(56, 63)
59
60#define H_ALL_RES_QP_MAX_OUTST_SEND_WR EHCA_BMASK_IBM(0, 15)
61#define H_ALL_RES_QP_MAX_OUTST_RECV_WR EHCA_BMASK_IBM(16, 31)
62#define H_ALL_RES_QP_MAX_SEND_SGE EHCA_BMASK_IBM(32, 39)
63#define H_ALL_RES_QP_MAX_RECV_SGE EHCA_BMASK_IBM(40, 47)
64
65#define H_ALL_RES_QP_ACT_OUTST_SEND_WR EHCA_BMASK_IBM(16, 31)
66#define H_ALL_RES_QP_ACT_OUTST_RECV_WR EHCA_BMASK_IBM(48, 63)
67#define H_ALL_RES_QP_ACT_SEND_SGE EHCA_BMASK_IBM(8, 15)
68#define H_ALL_RES_QP_ACT_RECV_SGE EHCA_BMASK_IBM(24, 31)
69
70#define H_ALL_RES_QP_SQUEUE_SIZE_PAGES EHCA_BMASK_IBM(0, 31)
71#define H_ALL_RES_QP_RQUEUE_SIZE_PAGES EHCA_BMASK_IBM(32, 63)
72
73/* direct access qp controls */
74#define DAQP_CTRL_ENABLE 0x01
75#define DAQP_CTRL_SEND_COMP 0x20
76#define DAQP_CTRL_RECV_COMP 0x40
77
78static u32 get_longbusy_msecs(int longbusy_rc)
79{
80 switch (longbusy_rc) {
81 case H_LONG_BUSY_ORDER_1_MSEC:
82 return 1;
83 case H_LONG_BUSY_ORDER_10_MSEC:
84 return 10;
85 case H_LONG_BUSY_ORDER_100_MSEC:
86 return 100;
87 case H_LONG_BUSY_ORDER_1_SEC:
88 return 1000;
89 case H_LONG_BUSY_ORDER_10_SEC:
90 return 10000;
91 case H_LONG_BUSY_ORDER_100_SEC:
92 return 100000;
93 default:
94 return 1;
95 }
96}
97
98static long ehca_plpar_hcall_norets(unsigned long opcode,
99 unsigned long arg1,
100 unsigned long arg2,
101 unsigned long arg3,
102 unsigned long arg4,
103 unsigned long arg5,
104 unsigned long arg6,
105 unsigned long arg7)
106{
107 long ret;
108 int i, sleep_msecs;
109
110 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
111 "arg5=%lx arg6=%lx arg7=%lx",
112 opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
113
114 for (i = 0; i < 5; i++) {
115 ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4,
116 arg5, arg6, arg7);
117
118 if (H_IS_LONG_BUSY(ret)) {
119 sleep_msecs = get_longbusy_msecs(ret);
120 msleep_interruptible(sleep_msecs);
121 continue;
122 }
123
124 if (ret < H_SUCCESS)
125 ehca_gen_err("opcode=%lx ret=%lx"
126 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
127 " arg5=%lx arg6=%lx arg7=%lx ",
128 opcode, ret,
129 arg1, arg2, arg3, arg4, arg5,
130 arg6, arg7);
131
132 ehca_gen_dbg("opcode=%lx ret=%lx", opcode, ret);
133 return ret;
134
135 }
136
137 return H_BUSY;
138}
139
140static long ehca_plpar_hcall9(unsigned long opcode,
141 unsigned long *outs, /* array of 9 outputs */
142 unsigned long arg1,
143 unsigned long arg2,
144 unsigned long arg3,
145 unsigned long arg4,
146 unsigned long arg5,
147 unsigned long arg6,
148 unsigned long arg7,
149 unsigned long arg8,
150 unsigned long arg9)
151{
152 long ret;
153 int i, sleep_msecs;
154
155 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
156 "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
157 opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
158 arg8, arg9);
159
160 for (i = 0; i < 5; i++) {
161 ret = plpar_hcall9(opcode, outs,
162 arg1, arg2, arg3, arg4, arg5,
163 arg6, arg7, arg8, arg9);
164
165 if (H_IS_LONG_BUSY(ret)) {
166 sleep_msecs = get_longbusy_msecs(ret);
167 msleep_interruptible(sleep_msecs);
168 continue;
169 }
170
171 if (ret < H_SUCCESS)
172 ehca_gen_err("opcode=%lx ret=%lx"
173 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
174 " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
175 " arg9=%lx"
176 " out1=%lx out2=%lx out3=%lx out4=%lx"
177 " out5=%lx out6=%lx out7=%lx out8=%lx"
178 " out9=%lx",
179 opcode, ret,
180 arg1, arg2, arg3, arg4, arg5,
181 arg6, arg7, arg8, arg9,
182 outs[0], outs[1], outs[2], outs[3],
183 outs[4], outs[5], outs[6], outs[7],
184 outs[8]);
185
186 ehca_gen_dbg("opcode=%lx ret=%lx out1=%lx out2=%lx out3=%lx "
187 "out4=%lx out5=%lx out6=%lx out7=%lx out8=%lx "
188 "out9=%lx",
189 opcode, ret, outs[0], outs[1], outs[2], outs[3],
190 outs[4], outs[5], outs[6], outs[7], outs[8]);
191 return ret;
192
193 }
194
195 return H_BUSY;
196}
197u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
198 struct ehca_pfeq *pfeq,
199 const u32 neq_control,
200 const u32 number_of_entries,
201 struct ipz_eq_handle *eq_handle,
202 u32 *act_nr_of_entries,
203 u32 *act_pages,
204 u32 *eq_ist)
205{
206 u64 ret;
207 u64 outs[PLPAR_HCALL9_BUFSIZE];
208 u64 allocate_controls;
209
210 /* resource type */
211 allocate_controls = 3ULL;
212
213 /* ISN is associated */
214 if (neq_control != 1)
215 allocate_controls = (1ULL << (63 - 7)) | allocate_controls;
216 else /* notification event queue */
217 allocate_controls = (1ULL << 63) | allocate_controls;
218
219 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
220 adapter_handle.handle, /* r4 */
221 allocate_controls, /* r5 */
222 number_of_entries, /* r6 */
223 0, 0, 0, 0, 0, 0);
224 eq_handle->handle = outs[0];
225 *act_nr_of_entries = (u32)outs[3];
226 *act_pages = (u32)outs[4];
227 *eq_ist = (u32)outs[5];
228
229 if (ret == H_NOT_ENOUGH_RESOURCES)
230 ehca_gen_err("Not enough resource - ret=%lx ", ret);
231
232 return ret;
233}
234
235u64 hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle,
236 struct ipz_eq_handle eq_handle,
237 const u64 event_mask)
238{
239 return ehca_plpar_hcall_norets(H_RESET_EVENTS,
240 adapter_handle.handle, /* r4 */
241 eq_handle.handle, /* r5 */
242 event_mask, /* r6 */
243 0, 0, 0, 0);
244}
245
246u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
247 struct ehca_cq *cq,
248 struct ehca_alloc_cq_parms *param)
249{
250 u64 ret;
251 u64 outs[PLPAR_HCALL9_BUFSIZE];
252
253 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
254 adapter_handle.handle, /* r4 */
255 2, /* r5 */
256 param->eq_handle.handle, /* r6 */
257 cq->token, /* r7 */
258 param->nr_cqe, /* r8 */
259 0, 0, 0, 0);
260 cq->ipz_cq_handle.handle = outs[0];
261 param->act_nr_of_entries = (u32)outs[3];
262 param->act_pages = (u32)outs[4];
263
264 if (ret == H_SUCCESS)
265 hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]);
266
267 if (ret == H_NOT_ENOUGH_RESOURCES)
268 ehca_gen_err("Not enough resources. ret=%lx", ret);
269
270 return ret;
271}
272
273u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
274 struct ehca_qp *qp,
275 struct ehca_alloc_qp_parms *parms)
276{
277 u64 ret;
278 u64 allocate_controls;
279 u64 max_r10_reg;
280 u64 outs[PLPAR_HCALL9_BUFSIZE];
281 u16 max_nr_receive_wqes = qp->init_attr.cap.max_recv_wr + 1;
282 u16 max_nr_send_wqes = qp->init_attr.cap.max_send_wr + 1;
283 int daqp_ctrl = parms->daqp_ctrl;
284
285 allocate_controls =
286 EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS,
287 (daqp_ctrl & DAQP_CTRL_ENABLE) ? 1 : 0)
288 | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
289 | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
290 | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
291 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
292 (daqp_ctrl & DAQP_CTRL_RECV_COMP) ? 1 : 0)
293 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
294 (daqp_ctrl & DAQP_CTRL_SEND_COMP) ? 1 : 0)
295 | EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
296 parms->ud_av_l_key_ctl)
297 | EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);
298
299 max_r10_reg =
300 EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
301 max_nr_send_wqes)
302 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
303 max_nr_receive_wqes)
304 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
305 parms->max_send_sge)
306 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
307 parms->max_recv_sge);
308
309 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
310 adapter_handle.handle, /* r4 */
311 allocate_controls, /* r5 */
312 qp->send_cq->ipz_cq_handle.handle,
313 qp->recv_cq->ipz_cq_handle.handle,
314 parms->ipz_eq_handle.handle,
315 ((u64)qp->token << 32) | parms->pd.value,
316 max_r10_reg, /* r10 */
317 parms->ud_av_l_key_ctl, /* r11 */
318 0);
319 qp->ipz_qp_handle.handle = outs[0];
320 qp->real_qp_num = (u32)outs[1];
321 parms->act_nr_send_sges =
322 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
323 parms->act_nr_recv_wqes =
324 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
325 parms->act_nr_send_sges =
326 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]);
327 parms->act_nr_recv_sges =
328 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]);
329 parms->nr_sq_pages =
330 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]);
331 parms->nr_rq_pages =
332 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
333
334 if (ret == H_SUCCESS)
335 hcp_galpas_ctor(&qp->galpas, outs[6], outs[6]);
336
337 if (ret == H_NOT_ENOUGH_RESOURCES)
338 ehca_gen_err("Not enough resources. ret=%lx", ret);
339
340 return ret;
341}
342
343u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
344 const u8 port_id,
345 struct hipz_query_port *query_port_response_block)
346{
347 u64 ret;
348 u64 r_cb = virt_to_abs(query_port_response_block);
349
350 if (r_cb & (EHCA_PAGESIZE-1)) {
351 ehca_gen_err("response block not page aligned");
352 return H_PARAMETER;
353 }
354
355 ret = ehca_plpar_hcall_norets(H_QUERY_PORT,
356 adapter_handle.handle, /* r4 */
357 port_id, /* r5 */
358 r_cb, /* r6 */
359 0, 0, 0, 0);
360
361 if (ehca_debug_level)
362 ehca_dmp(query_port_response_block, 64, "response_block");
363
364 return ret;
365}
366
367u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
368 struct hipz_query_hca *query_hca_rblock)
369{
370 u64 r_cb = virt_to_abs(query_hca_rblock);
371
372 if (r_cb & (EHCA_PAGESIZE-1)) {
373 ehca_gen_err("response_block=%p not page aligned",
374 query_hca_rblock);
375 return H_PARAMETER;
376 }
377
378 return ehca_plpar_hcall_norets(H_QUERY_HCA,
379 adapter_handle.handle, /* r4 */
380 r_cb, /* r5 */
381 0, 0, 0, 0, 0);
382}
383
384u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
385 const u8 pagesize,
386 const u8 queue_type,
387 const u64 resource_handle,
388 const u64 logical_address_of_page,
389 u64 count)
390{
391 return ehca_plpar_hcall_norets(H_REGISTER_RPAGES,
392 adapter_handle.handle, /* r4 */
393 queue_type | pagesize << 8, /* r5 */
394 resource_handle, /* r6 */
395 logical_address_of_page, /* r7 */
396 count, /* r8 */
397 0, 0);
398}
399
400u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,
401 const struct ipz_eq_handle eq_handle,
402 struct ehca_pfeq *pfeq,
403 const u8 pagesize,
404 const u8 queue_type,
405 const u64 logical_address_of_page,
406 const u64 count)
407{
408 if (count != 1) {
409 ehca_gen_err("Ppage counter=%lx", count);
410 return H_PARAMETER;
411 }
412 return hipz_h_register_rpage(adapter_handle,
413 pagesize,
414 queue_type,
415 eq_handle.handle,
416 logical_address_of_page, count);
417}
418
419u64 hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle,
420 u32 ist)
421{
422 u64 ret;
423 ret = ehca_plpar_hcall_norets(H_QUERY_INT_STATE,
424 adapter_handle.handle, /* r4 */
425 ist, /* r5 */
426 0, 0, 0, 0, 0);
427
428 if (ret != H_SUCCESS && ret != H_BUSY)
429 ehca_gen_err("Could not query interrupt state.");
430
431 return ret;
432}
433
434u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,
435 const struct ipz_cq_handle cq_handle,
436 struct ehca_pfcq *pfcq,
437 const u8 pagesize,
438 const u8 queue_type,
439 const u64 logical_address_of_page,
440 const u64 count,
441 const struct h_galpa gal)
442{
443 if (count != 1) {
444 ehca_gen_err("Page counter=%lx", count);
445 return H_PARAMETER;
446 }
447
448 return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
449 cq_handle.handle, logical_address_of_page,
450 count);
451}
452
453u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
454 const struct ipz_qp_handle qp_handle,
455 struct ehca_pfqp *pfqp,
456 const u8 pagesize,
457 const u8 queue_type,
458 const u64 logical_address_of_page,
459 const u64 count,
460 const struct h_galpa galpa)
461{
462 if (count != 1) {
463 ehca_gen_err("Page counter=%lx", count);
464 return H_PARAMETER;
465 }
466
467 return hipz_h_register_rpage(adapter_handle,pagesize,queue_type,
468 qp_handle.handle,logical_address_of_page,
469 count);
470}
471
472u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
473 const struct ipz_qp_handle qp_handle,
474 struct ehca_pfqp *pfqp,
475 void **log_addr_next_sq_wqe2processed,
476 void **log_addr_next_rq_wqe2processed,
477 int dis_and_get_function_code)
478{
479 u64 ret;
480 u64 outs[PLPAR_HCALL9_BUFSIZE];
481
482 ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
483 adapter_handle.handle, /* r4 */
484 dis_and_get_function_code, /* r5 */
485 qp_handle.handle, /* r6 */
486 0, 0, 0, 0, 0, 0);
487 if (log_addr_next_sq_wqe2processed)
488 *log_addr_next_sq_wqe2processed = (void*)outs[0];
489 if (log_addr_next_rq_wqe2processed)
490 *log_addr_next_rq_wqe2processed = (void*)outs[1];
491
492 return ret;
493}
494
495u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
496 const struct ipz_qp_handle qp_handle,
497 struct ehca_pfqp *pfqp,
498 const u64 update_mask,
499 struct hcp_modify_qp_control_block *mqpcb,
500 struct h_galpa gal)
501{
502 u64 ret;
503 u64 outs[PLPAR_HCALL9_BUFSIZE];
504 ret = ehca_plpar_hcall9(H_MODIFY_QP, outs,
505 adapter_handle.handle, /* r4 */
506 qp_handle.handle, /* r5 */
507 update_mask, /* r6 */
508 virt_to_abs(mqpcb), /* r7 */
509 0, 0, 0, 0, 0);
510
511 if (ret == H_NOT_ENOUGH_RESOURCES)
512 ehca_gen_err("Insufficient resources ret=%lx", ret);
513
514 return ret;
515}
516
517u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,
518 const struct ipz_qp_handle qp_handle,
519 struct ehca_pfqp *pfqp,
520 struct hcp_modify_qp_control_block *qqpcb,
521 struct h_galpa gal)
522{
523 return ehca_plpar_hcall_norets(H_QUERY_QP,
524 adapter_handle.handle, /* r4 */
525 qp_handle.handle, /* r5 */
526 virt_to_abs(qqpcb), /* r6 */
527 0, 0, 0, 0);
528}
529
530u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
531 struct ehca_qp *qp)
532{
533 u64 ret;
534 u64 outs[PLPAR_HCALL9_BUFSIZE];
535
536 ret = hcp_galpas_dtor(&qp->galpas);
537 if (ret) {
538 ehca_gen_err("Could not destruct qp->galpas");
539 return H_RESOURCE;
540 }
541 ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
542 adapter_handle.handle, /* r4 */
543 /* function code */
544 1, /* r5 */
545 qp->ipz_qp_handle.handle, /* r6 */
546 0, 0, 0, 0, 0, 0);
547 if (ret == H_HARDWARE)
548 ehca_gen_err("HCA not operational. ret=%lx", ret);
549
550 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
551 adapter_handle.handle, /* r4 */
552 qp->ipz_qp_handle.handle, /* r5 */
553 0, 0, 0, 0, 0);
554
555 if (ret == H_RESOURCE)
556 ehca_gen_err("Resource still in use. ret=%lx", ret);
557
558 return ret;
559}
560
561u64 hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle,
562 const struct ipz_qp_handle qp_handle,
563 struct h_galpa gal,
564 u32 port)
565{
566 return ehca_plpar_hcall_norets(H_DEFINE_AQP0,
567 adapter_handle.handle, /* r4 */
568 qp_handle.handle, /* r5 */
569 port, /* r6 */
570 0, 0, 0, 0);
571}
572
573u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
574 const struct ipz_qp_handle qp_handle,
575 struct h_galpa gal,
576 u32 port, u32 * pma_qp_nr,
577 u32 * bma_qp_nr)
578{
579 u64 ret;
580 u64 outs[PLPAR_HCALL9_BUFSIZE];
581
582 ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs,
583 adapter_handle.handle, /* r4 */
584 qp_handle.handle, /* r5 */
585 port, /* r6 */
586 0, 0, 0, 0, 0, 0);
587 *pma_qp_nr = (u32)outs[0];
588 *bma_qp_nr = (u32)outs[1];
589
590 if (ret == H_ALIAS_EXIST)
591 ehca_gen_err("AQP1 already exists. ret=%lx", ret);
592
593 return ret;
594}
595
596u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,
597 const struct ipz_qp_handle qp_handle,
598 struct h_galpa gal,
599 u16 mcg_dlid,
600 u64 subnet_prefix, u64 interface_id)
601{
602 u64 ret;
603
604 ret = ehca_plpar_hcall_norets(H_ATTACH_MCQP,
605 adapter_handle.handle, /* r4 */
606 qp_handle.handle, /* r5 */
607 mcg_dlid, /* r6 */
608 interface_id, /* r7 */
609 subnet_prefix, /* r8 */
610 0, 0);
611
612 if (ret == H_NOT_ENOUGH_RESOURCES)
613 ehca_gen_err("Not enough resources. ret=%lx", ret);
614
615 return ret;
616}
617
618u64 hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle,
619 const struct ipz_qp_handle qp_handle,
620 struct h_galpa gal,
621 u16 mcg_dlid,
622 u64 subnet_prefix, u64 interface_id)
623{
624 return ehca_plpar_hcall_norets(H_DETACH_MCQP,
625 adapter_handle.handle, /* r4 */
626 qp_handle.handle, /* r5 */
627 mcg_dlid, /* r6 */
628 interface_id, /* r7 */
629 subnet_prefix, /* r8 */
630 0, 0);
631}
632
633u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,
634 struct ehca_cq *cq,
635 u8 force_flag)
636{
637 u64 ret;
638
639 ret = hcp_galpas_dtor(&cq->galpas);
640 if (ret) {
641 ehca_gen_err("Could not destruct cp->galpas");
642 return H_RESOURCE;
643 }
644
645 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
646 adapter_handle.handle, /* r4 */
647 cq->ipz_cq_handle.handle, /* r5 */
648 force_flag != 0 ? 1L : 0L, /* r6 */
649 0, 0, 0, 0);
650
651 if (ret == H_RESOURCE)
652 ehca_gen_err("H_FREE_RESOURCE failed ret=%lx ", ret);
653
654 return ret;
655}
656
657u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,
658 struct ehca_eq *eq)
659{
660 u64 ret;
661
662 ret = hcp_galpas_dtor(&eq->galpas);
663 if (ret) {
664 ehca_gen_err("Could not destruct eq->galpas");
665 return H_RESOURCE;
666 }
667
668 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
669 adapter_handle.handle, /* r4 */
670 eq->ipz_eq_handle.handle, /* r5 */
671 0, 0, 0, 0, 0);
672
673 if (ret == H_RESOURCE)
674 ehca_gen_err("Resource in use. ret=%lx ", ret);
675
676 return ret;
677}
678
679u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
680 const struct ehca_mr *mr,
681 const u64 vaddr,
682 const u64 length,
683 const u32 access_ctrl,
684 const struct ipz_pd pd,
685 struct ehca_mr_hipzout_parms *outparms)
686{
687 u64 ret;
688 u64 outs[PLPAR_HCALL9_BUFSIZE];
689
690 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
691 adapter_handle.handle, /* r4 */
692 5, /* r5 */
693 vaddr, /* r6 */
694 length, /* r7 */
695 (((u64)access_ctrl) << 32ULL), /* r8 */
696 pd.value, /* r9 */
697 0, 0, 0);
698 outparms->handle.handle = outs[0];
699 outparms->lkey = (u32)outs[2];
700 outparms->rkey = (u32)outs[3];
701
702 return ret;
703}
704
705u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
706 const struct ehca_mr *mr,
707 const u8 pagesize,
708 const u8 queue_type,
709 const u64 logical_address_of_page,
710 const u64 count)
711{
712 u64 ret;
713
714 if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
715 ehca_gen_err("logical_address_of_page not on a 4k boundary "
716 "adapter_handle=%lx mr=%p mr_handle=%lx "
717 "pagesize=%x queue_type=%x "
718 "logical_address_of_page=%lx count=%lx",
719 adapter_handle.handle, mr,
720 mr->ipz_mr_handle.handle, pagesize, queue_type,
721 logical_address_of_page, count);
722 ret = H_PARAMETER;
723 } else
724 ret = hipz_h_register_rpage(adapter_handle, pagesize,
725 queue_type,
726 mr->ipz_mr_handle.handle,
727 logical_address_of_page, count);
728 return ret;
729}
730
731u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
732 const struct ehca_mr *mr,
733 struct ehca_mr_hipzout_parms *outparms)
734{
735 u64 ret;
736 u64 outs[PLPAR_HCALL9_BUFSIZE];
737
738 ret = ehca_plpar_hcall9(H_QUERY_MR, outs,
739 adapter_handle.handle, /* r4 */
740 mr->ipz_mr_handle.handle, /* r5 */
741 0, 0, 0, 0, 0, 0, 0);
742 outparms->len = outs[0];
743 outparms->vaddr = outs[1];
744 outparms->acl = outs[4] >> 32;
745 outparms->lkey = (u32)(outs[5] >> 32);
746 outparms->rkey = (u32)(outs[5] & (0xffffffff));
747
748 return ret;
749}
750
751u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle,
752 const struct ehca_mr *mr)
753{
754 return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
755 adapter_handle.handle, /* r4 */
756 mr->ipz_mr_handle.handle, /* r5 */
757 0, 0, 0, 0, 0);
758}
759
760u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
761 const struct ehca_mr *mr,
762 const u64 vaddr_in,
763 const u64 length,
764 const u32 access_ctrl,
765 const struct ipz_pd pd,
766 const u64 mr_addr_cb,
767 struct ehca_mr_hipzout_parms *outparms)
768{
769 u64 ret;
770 u64 outs[PLPAR_HCALL9_BUFSIZE];
771
772 ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs,
773 adapter_handle.handle, /* r4 */
774 mr->ipz_mr_handle.handle, /* r5 */
775 vaddr_in, /* r6 */
776 length, /* r7 */
777 /* r8 */
778 ((((u64)access_ctrl) << 32ULL) | pd.value),
779 mr_addr_cb, /* r9 */
780 0, 0, 0);
781 outparms->vaddr = outs[1];
782 outparms->lkey = (u32)outs[2];
783 outparms->rkey = (u32)outs[3];
784
785 return ret;
786}
787
788u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
789 const struct ehca_mr *mr,
790 const struct ehca_mr *orig_mr,
791 const u64 vaddr_in,
792 const u32 access_ctrl,
793 const struct ipz_pd pd,
794 struct ehca_mr_hipzout_parms *outparms)
795{
796 u64 ret;
797 u64 outs[PLPAR_HCALL9_BUFSIZE];
798
799 ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs,
800 adapter_handle.handle, /* r4 */
801 orig_mr->ipz_mr_handle.handle, /* r5 */
802 vaddr_in, /* r6 */
803 (((u64)access_ctrl) << 32ULL), /* r7 */
804 pd.value, /* r8 */
805 0, 0, 0, 0);
806 outparms->handle.handle = outs[0];
807 outparms->lkey = (u32)outs[2];
808 outparms->rkey = (u32)outs[3];
809
810 return ret;
811}
812
813u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
814 const struct ehca_mw *mw,
815 const struct ipz_pd pd,
816 struct ehca_mw_hipzout_parms *outparms)
817{
818 u64 ret;
819 u64 outs[PLPAR_HCALL9_BUFSIZE];
820
821 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
822 adapter_handle.handle, /* r4 */
823 6, /* r5 */
824 pd.value, /* r6 */
825 0, 0, 0, 0, 0, 0);
826 outparms->handle.handle = outs[0];
827 outparms->rkey = (u32)outs[3];
828
829 return ret;
830}
831
832u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
833 const struct ehca_mw *mw,
834 struct ehca_mw_hipzout_parms *outparms)
835{
836 u64 ret;
837 u64 outs[PLPAR_HCALL9_BUFSIZE];
838
839 ret = ehca_plpar_hcall9(H_QUERY_MW, outs,
840 adapter_handle.handle, /* r4 */
841 mw->ipz_mw_handle.handle, /* r5 */
842 0, 0, 0, 0, 0, 0, 0);
843 outparms->rkey = (u32)outs[3];
844
845 return ret;
846}
847
848u64 hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle,
849 const struct ehca_mw *mw)
850{
851 return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
852 adapter_handle.handle, /* r4 */
853 mw->ipz_mw_handle.handle, /* r5 */
854 0, 0, 0, 0, 0);
855}
856
857u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
858 const u64 ressource_handle,
859 void *rblock,
860 unsigned long *byte_count)
861{
862 u64 r_cb = virt_to_abs(rblock);
863
864 if (r_cb & (EHCA_PAGESIZE-1)) {
865 ehca_gen_err("rblock not page aligned.");
866 return H_PARAMETER;
867 }
868
869 return ehca_plpar_hcall_norets(H_ERROR_DATA,
870 adapter_handle.handle,
871 ressource_handle,
872 r_cb,
873 0, 0, 0, 0);
874}
diff --git a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h
new file mode 100644
index 000000000000..587ebd470959
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/hcp_if.h
@@ -0,0 +1,261 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Firmware Infiniband Interface code for POWER
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Gerd Bayer <gerd.bayer@de.ibm.com>
9 * Waleri Fomin <fomin@de.ibm.com>
10 *
11 * Copyright (c) 2005 IBM Corporation
12 *
13 * All rights reserved.
14 *
15 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
16 * BSD.
17 *
18 * OpenIB BSD License
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *
23 * Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
25 *
26 * Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials
29 * provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44#ifndef __HCP_IF_H__
45#define __HCP_IF_H__
46
47#include "ehca_classes.h"
48#include "ehca_tools.h"
49#include "hipz_hw.h"
50
51/*
52 * hipz_h_alloc_resource_eq allocates EQ resources in HW and FW, initalize
53 * resources, create the empty EQPT (ring).
54 */
55u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
56 struct ehca_pfeq *pfeq,
57 const u32 neq_control,
58 const u32 number_of_entries,
59 struct ipz_eq_handle *eq_handle,
60 u32 * act_nr_of_entries,
61 u32 * act_pages,
62 u32 * eq_ist);
63
64u64 hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle,
65 struct ipz_eq_handle eq_handle,
66 const u64 event_mask);
67/*
68 * hipz_h_allocate_resource_cq allocates CQ resources in HW and FW, initialize
69 * resources, create the empty CQPT (ring).
70 */
71u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
72 struct ehca_cq *cq,
73 struct ehca_alloc_cq_parms *param);
74
75
76/*
77 * hipz_h_alloc_resource_qp allocates QP resources in HW and FW,
78 * initialize resources, create empty QPPTs (2 rings).
79 */
80u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
81 struct ehca_qp *qp,
82 struct ehca_alloc_qp_parms *parms);
83
84u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
85 const u8 port_id,
86 struct hipz_query_port *query_port_response_block);
87
88u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
89 struct hipz_query_hca *query_hca_rblock);
90
91/*
92 * hipz_h_register_rpage internal function in hcp_if.h for all
93 * hcp_H_REGISTER_RPAGE calls.
94 */
95u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
96 const u8 pagesize,
97 const u8 queue_type,
98 const u64 resource_handle,
99 const u64 logical_address_of_page,
100 u64 count);
101
102u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,
103 const struct ipz_eq_handle eq_handle,
104 struct ehca_pfeq *pfeq,
105 const u8 pagesize,
106 const u8 queue_type,
107 const u64 logical_address_of_page,
108 const u64 count);
109
110u64 hipz_h_query_int_state(const struct ipz_adapter_handle
111 hcp_adapter_handle,
112 u32 ist);
113
114u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,
115 const struct ipz_cq_handle cq_handle,
116 struct ehca_pfcq *pfcq,
117 const u8 pagesize,
118 const u8 queue_type,
119 const u64 logical_address_of_page,
120 const u64 count,
121 const struct h_galpa gal);
122
123u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
124 const struct ipz_qp_handle qp_handle,
125 struct ehca_pfqp *pfqp,
126 const u8 pagesize,
127 const u8 queue_type,
128 const u64 logical_address_of_page,
129 const u64 count,
130 const struct h_galpa galpa);
131
132u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
133 const struct ipz_qp_handle qp_handle,
134 struct ehca_pfqp *pfqp,
135 void **log_addr_next_sq_wqe_tb_processed,
136 void **log_addr_next_rq_wqe_tb_processed,
137 int dis_and_get_function_code);
138enum hcall_sigt {
139 HCALL_SIGT_NO_CQE = 0,
140 HCALL_SIGT_BY_WQE = 1,
141 HCALL_SIGT_EVERY = 2
142};
143
144u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
145 const struct ipz_qp_handle qp_handle,
146 struct ehca_pfqp *pfqp,
147 const u64 update_mask,
148 struct hcp_modify_qp_control_block *mqpcb,
149 struct h_galpa gal);
150
151u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,
152 const struct ipz_qp_handle qp_handle,
153 struct ehca_pfqp *pfqp,
154 struct hcp_modify_qp_control_block *qqpcb,
155 struct h_galpa gal);
156
157u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
158 struct ehca_qp *qp);
159
160u64 hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle,
161 const struct ipz_qp_handle qp_handle,
162 struct h_galpa gal,
163 u32 port);
164
165u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
166 const struct ipz_qp_handle qp_handle,
167 struct h_galpa gal,
168 u32 port, u32 * pma_qp_nr,
169 u32 * bma_qp_nr);
170
171u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,
172 const struct ipz_qp_handle qp_handle,
173 struct h_galpa gal,
174 u16 mcg_dlid,
175 u64 subnet_prefix, u64 interface_id);
176
177u64 hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle,
178 const struct ipz_qp_handle qp_handle,
179 struct h_galpa gal,
180 u16 mcg_dlid,
181 u64 subnet_prefix, u64 interface_id);
182
183u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,
184 struct ehca_cq *cq,
185 u8 force_flag);
186
187u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,
188 struct ehca_eq *eq);
189
190/*
191 * hipz_h_alloc_resource_mr allocates MR resources in HW and FW, initialize
192 * resources.
193 */
194u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
195 const struct ehca_mr *mr,
196 const u64 vaddr,
197 const u64 length,
198 const u32 access_ctrl,
199 const struct ipz_pd pd,
200 struct ehca_mr_hipzout_parms *outparms);
201
202/* hipz_h_register_rpage_mr registers MR resource pages in HW and FW */
203u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
204 const struct ehca_mr *mr,
205 const u8 pagesize,
206 const u8 queue_type,
207 const u64 logical_address_of_page,
208 const u64 count);
209
210/* hipz_h_query_mr queries MR in HW and FW */
211u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
212 const struct ehca_mr *mr,
213 struct ehca_mr_hipzout_parms *outparms);
214
215/* hipz_h_free_resource_mr frees MR resources in HW and FW */
216u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle,
217 const struct ehca_mr *mr);
218
219/* hipz_h_reregister_pmr reregisters MR in HW and FW */
220u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
221 const struct ehca_mr *mr,
222 const u64 vaddr_in,
223 const u64 length,
224 const u32 access_ctrl,
225 const struct ipz_pd pd,
226 const u64 mr_addr_cb,
227 struct ehca_mr_hipzout_parms *outparms);
228
229/* hipz_h_register_smr register shared MR in HW and FW */
230u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
231 const struct ehca_mr *mr,
232 const struct ehca_mr *orig_mr,
233 const u64 vaddr_in,
234 const u32 access_ctrl,
235 const struct ipz_pd pd,
236 struct ehca_mr_hipzout_parms *outparms);
237
238/*
239 * hipz_h_alloc_resource_mw allocates MW resources in HW and FW, initialize
240 * resources.
241 */
242u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
243 const struct ehca_mw *mw,
244 const struct ipz_pd pd,
245 struct ehca_mw_hipzout_parms *outparms);
246
247/* hipz_h_query_mw queries MW in HW and FW */
248u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
249 const struct ehca_mw *mw,
250 struct ehca_mw_hipzout_parms *outparms);
251
252/* hipz_h_free_resource_mw frees MW resources in HW and FW */
253u64 hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle,
254 const struct ehca_mw *mw);
255
256u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
257 const u64 ressource_handle,
258 void *rblock,
259 unsigned long *byte_count);
260
261#endif /* __HCP_IF_H__ */
diff --git a/drivers/infiniband/hw/ehca/hcp_phyp.c b/drivers/infiniband/hw/ehca/hcp_phyp.c
new file mode 100644
index 000000000000..0b1a4772c78a
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/hcp_phyp.c
@@ -0,0 +1,80 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * load store abstraction for ehca register access with tracing
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#include "ehca_classes.h"
43#include "hipz_hw.h"
44
45int hcall_map_page(u64 physaddr, u64 *mapaddr)
46{
47 *mapaddr = (u64)(ioremap(physaddr, EHCA_PAGESIZE));
48 return 0;
49}
50
51int hcall_unmap_page(u64 mapaddr)
52{
53 iounmap((volatile void __iomem*)mapaddr);
54 return 0;
55}
56
57int hcp_galpas_ctor(struct h_galpas *galpas,
58 u64 paddr_kernel, u64 paddr_user)
59{
60 int ret = hcall_map_page(paddr_kernel, &galpas->kernel.fw_handle);
61 if (ret)
62 return ret;
63
64 galpas->user.fw_handle = paddr_user;
65
66 return 0;
67}
68
69int hcp_galpas_dtor(struct h_galpas *galpas)
70{
71 if (galpas->kernel.fw_handle) {
72 int ret = hcall_unmap_page(galpas->kernel.fw_handle);
73 if (ret)
74 return ret;
75 }
76
77 galpas->user.fw_handle = galpas->kernel.fw_handle = 0;
78
79 return 0;
80}
diff --git a/drivers/infiniband/hw/ehca/hcp_phyp.h b/drivers/infiniband/hw/ehca/hcp_phyp.h
new file mode 100644
index 000000000000..5305c2a3ed94
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/hcp_phyp.h
@@ -0,0 +1,90 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * Firmware calls
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Waleri Fomin <fomin@de.ibm.com>
9 * Gerd Bayer <gerd.bayer@de.ibm.com>
10 *
11 * Copyright (c) 2005 IBM Corporation
12 *
13 * All rights reserved.
14 *
15 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
16 * BSD.
17 *
18 * OpenIB BSD License
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *
23 * Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
25 *
26 * Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials
29 * provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44#ifndef __HCP_PHYP_H__
45#define __HCP_PHYP_H__
46
47
48/*
49 * eHCA page (mapped into memory)
50 * resource to access eHCA register pages in CPU address space
51*/
52struct h_galpa {
53 u64 fw_handle;
54 /* for pSeries this is a 64bit memory address where
55 I/O memory is mapped into CPU address space (kv) */
56};
57
58/*
59 * resource to access eHCA address space registers, all types
60 */
61struct h_galpas {
62 u32 pid; /*PID of userspace galpa checking */
63 struct h_galpa user; /* user space accessible resource,
64 set to 0 if unused */
65 struct h_galpa kernel; /* kernel space accessible resource,
66 set to 0 if unused */
67};
68
69static inline u64 hipz_galpa_load(struct h_galpa galpa, u32 offset)
70{
71 u64 addr = galpa.fw_handle + offset;
72 return *(volatile u64 __force *)addr;
73}
74
75static inline void hipz_galpa_store(struct h_galpa galpa, u32 offset, u64 value)
76{
77 u64 addr = galpa.fw_handle + offset;
78 *(volatile u64 __force *)addr = value;
79}
80
81int hcp_galpas_ctor(struct h_galpas *galpas,
82 u64 paddr_kernel, u64 paddr_user);
83
84int hcp_galpas_dtor(struct h_galpas *galpas);
85
86int hcall_map_page(u64 physaddr, u64 * mapaddr);
87
88int hcall_unmap_page(u64 mapaddr);
89
90#endif
diff --git a/drivers/infiniband/hw/ehca/hipz_fns.h b/drivers/infiniband/hw/ehca/hipz_fns.h
new file mode 100644
index 000000000000..9dac93d02140
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/hipz_fns.h
@@ -0,0 +1,68 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * HW abstraction register functions
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Reinhard Ernst <rernst@de.ibm.com>
8 *
9 * Copyright (c) 2005 IBM Corporation
10 *
11 * All rights reserved.
12 *
13 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
14 * BSD.
15 *
16 * OpenIB BSD License
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are met:
20 *
21 * Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following disclaimer.
23 *
24 * Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials
27 * provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#ifndef __HIPZ_FNS_H__
43#define __HIPZ_FNS_H__
44
45#include "ehca_classes.h"
46#include "hipz_hw.h"
47
48#include "hipz_fns_core.h"
49
50#define hipz_galpa_store_eq(gal, offset, value) \
51 hipz_galpa_store(gal, EQTEMM_OFFSET(offset), value)
52
53#define hipz_galpa_load_eq(gal, offset) \
54 hipz_galpa_load(gal, EQTEMM_OFFSET(offset))
55
56#define hipz_galpa_store_qped(gal, offset, value) \
57 hipz_galpa_store(gal, QPEDMM_OFFSET(offset), value)
58
59#define hipz_galpa_load_qped(gal, offset) \
60 hipz_galpa_load(gal, QPEDMM_OFFSET(offset))
61
62#define hipz_galpa_store_mrmw(gal, offset, value) \
63 hipz_galpa_store(gal, MRMWMM_OFFSET(offset), value)
64
65#define hipz_galpa_load_mrmw(gal, offset) \
66 hipz_galpa_load(gal, MRMWMM_OFFSET(offset))
67
68#endif
diff --git a/drivers/infiniband/hw/ehca/hipz_fns_core.h b/drivers/infiniband/hw/ehca/hipz_fns_core.h
new file mode 100644
index 000000000000..20898a153446
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/hipz_fns_core.h
@@ -0,0 +1,100 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * HW abstraction register functions
5 *
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Heiko J Schick <schickhj@de.ibm.com>
8 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
9 * Reinhard Ernst <rernst@de.ibm.com>
10 *
11 * Copyright (c) 2005 IBM Corporation
12 *
13 * All rights reserved.
14 *
15 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
16 * BSD.
17 *
18 * OpenIB BSD License
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *
23 * Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
25 *
26 * Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials
29 * provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44#ifndef __HIPZ_FNS_CORE_H__
45#define __HIPZ_FNS_CORE_H__
46
47#include "hcp_phyp.h"
48#include "hipz_hw.h"
49
50#define hipz_galpa_store_cq(gal, offset, value) \
51 hipz_galpa_store(gal, CQTEMM_OFFSET(offset), value)
52
53#define hipz_galpa_load_cq(gal, offset) \
54 hipz_galpa_load(gal, CQTEMM_OFFSET(offset))
55
56#define hipz_galpa_store_qp(gal,offset, value) \
57 hipz_galpa_store(gal, QPTEMM_OFFSET(offset), value)
58#define hipz_galpa_load_qp(gal, offset) \
59 hipz_galpa_load(gal,QPTEMM_OFFSET(offset))
60
61static inline void hipz_update_sqa(struct ehca_qp *qp, u16 nr_wqes)
62{
63 /* ringing doorbell :-) */
64 hipz_galpa_store_qp(qp->galpas.kernel, qpx_sqa,
65 EHCA_BMASK_SET(QPX_SQADDER, nr_wqes));
66}
67
68static inline void hipz_update_rqa(struct ehca_qp *qp, u16 nr_wqes)
69{
70 /* ringing doorbell :-) */
71 hipz_galpa_store_qp(qp->galpas.kernel, qpx_rqa,
72 EHCA_BMASK_SET(QPX_RQADDER, nr_wqes));
73}
74
75static inline void hipz_update_feca(struct ehca_cq *cq, u32 nr_cqes)
76{
77 hipz_galpa_store_cq(cq->galpas.kernel, cqx_feca,
78 EHCA_BMASK_SET(CQX_FECADDER, nr_cqes));
79}
80
81static inline void hipz_set_cqx_n0(struct ehca_cq *cq, u32 value)
82{
83 u64 cqx_n0_reg;
84
85 hipz_galpa_store_cq(cq->galpas.kernel, cqx_n0,
86 EHCA_BMASK_SET(CQX_N0_GENERATE_SOLICITED_COMP_EVENT,
87 value));
88 cqx_n0_reg = hipz_galpa_load_cq(cq->galpas.kernel, cqx_n0);
89}
90
91static inline void hipz_set_cqx_n1(struct ehca_cq *cq, u32 value)
92{
93 u64 cqx_n1_reg;
94
95 hipz_galpa_store_cq(cq->galpas.kernel, cqx_n1,
96 EHCA_BMASK_SET(CQX_N1_GENERATE_COMP_EVENT, value));
97 cqx_n1_reg = hipz_galpa_load_cq(cq->galpas.kernel, cqx_n1);
98}
99
100#endif /* __HIPZ_FNC_CORE_H__ */
diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h
new file mode 100644
index 000000000000..3fc92b031c50
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/hipz_hw.h
@@ -0,0 +1,388 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * eHCA register definitions
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Christoph Raisch <raisch@de.ibm.com>
8 * Reinhard Ernst <rernst@de.ibm.com>
9 *
10 * Copyright (c) 2005 IBM Corporation
11 *
12 * All rights reserved.
13 *
14 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
15 * BSD.
16 *
17 * OpenIB BSD License
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * Redistributions of source code must retain the above copyright notice, this
23 * list of conditions and the following disclaimer.
24 *
25 * Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials
28 * provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42
43#ifndef __HIPZ_HW_H__
44#define __HIPZ_HW_H__
45
46#include "ehca_tools.h"
47
48/* QP Table Entry Memory Map */
49struct hipz_qptemm {
50 u64 qpx_hcr;
51 u64 qpx_c;
52 u64 qpx_herr;
53 u64 qpx_aer;
54/* 0x20*/
55 u64 qpx_sqa;
56 u64 qpx_sqc;
57 u64 qpx_rqa;
58 u64 qpx_rqc;
59/* 0x40*/
60 u64 qpx_st;
61 u64 qpx_pmstate;
62 u64 qpx_pmfa;
63 u64 qpx_pkey;
64/* 0x60*/
65 u64 qpx_pkeya;
66 u64 qpx_pkeyb;
67 u64 qpx_pkeyc;
68 u64 qpx_pkeyd;
69/* 0x80*/
70 u64 qpx_qkey;
71 u64 qpx_dqp;
72 u64 qpx_dlidp;
73 u64 qpx_portp;
74/* 0xa0*/
75 u64 qpx_slidp;
76 u64 qpx_slidpp;
77 u64 qpx_dlida;
78 u64 qpx_porta;
79/* 0xc0*/
80 u64 qpx_slida;
81 u64 qpx_slidpa;
82 u64 qpx_slvl;
83 u64 qpx_ipd;
84/* 0xe0*/
85 u64 qpx_mtu;
86 u64 qpx_lato;
87 u64 qpx_rlimit;
88 u64 qpx_rnrlimit;
89/* 0x100*/
90 u64 qpx_t;
91 u64 qpx_sqhp;
92 u64 qpx_sqptp;
93 u64 qpx_nspsn;
94/* 0x120*/
95 u64 qpx_nspsnhwm;
96 u64 reserved1;
97 u64 qpx_sdsi;
98 u64 qpx_sdsbc;
99/* 0x140*/
100 u64 qpx_sqwsize;
101 u64 qpx_sqwts;
102 u64 qpx_lsn;
103 u64 qpx_nssn;
104/* 0x160 */
105 u64 qpx_mor;
106 u64 qpx_cor;
107 u64 qpx_sqsize;
108 u64 qpx_erc;
109/* 0x180*/
110 u64 qpx_rnrrc;
111 u64 qpx_ernrwt;
112 u64 qpx_rnrresp;
113 u64 qpx_lmsna;
114/* 0x1a0 */
115 u64 qpx_sqhpc;
116 u64 qpx_sqcptp;
117 u64 qpx_sigt;
118 u64 qpx_wqecnt;
119/* 0x1c0*/
120 u64 qpx_rqhp;
121 u64 qpx_rqptp;
122 u64 qpx_rqsize;
123 u64 qpx_nrr;
124/* 0x1e0*/
125 u64 qpx_rdmac;
126 u64 qpx_nrpsn;
127 u64 qpx_lapsn;
128 u64 qpx_lcr;
129/* 0x200*/
130 u64 qpx_rwc;
131 u64 qpx_rwva;
132 u64 qpx_rdsi;
133 u64 qpx_rdsbc;
134/* 0x220*/
135 u64 qpx_rqwsize;
136 u64 qpx_crmsn;
137 u64 qpx_rdd;
138 u64 qpx_larpsn;
139/* 0x240*/
140 u64 qpx_pd;
141 u64 qpx_scqn;
142 u64 qpx_rcqn;
143 u64 qpx_aeqn;
144/* 0x260*/
145 u64 qpx_aaelog;
146 u64 qpx_ram;
147 u64 qpx_rdmaqe0;
148 u64 qpx_rdmaqe1;
149/* 0x280*/
150 u64 qpx_rdmaqe2;
151 u64 qpx_rdmaqe3;
152 u64 qpx_nrpsnhwm;
153/* 0x298*/
154 u64 reserved[(0x400 - 0x298) / 8];
155/* 0x400 extended data */
156 u64 reserved_ext[(0x500 - 0x400) / 8];
157/* 0x500 */
158 u64 reserved2[(0x1000 - 0x500) / 8];
159/* 0x1000 */
160};
161
162#define QPX_SQADDER EHCA_BMASK_IBM(48,63)
163#define QPX_RQADDER EHCA_BMASK_IBM(48,63)
164
165#define QPTEMM_OFFSET(x) offsetof(struct hipz_qptemm,x)
166
167/* MRMWPT Entry Memory Map */
168struct hipz_mrmwmm {
169 /* 0x00 */
170 u64 mrx_hcr;
171
172 u64 mrx_c;
173 u64 mrx_herr;
174 u64 mrx_aer;
175 /* 0x20 */
176 u64 mrx_pp;
177 u64 reserved1;
178 u64 reserved2;
179 u64 reserved3;
180 /* 0x40 */
181 u64 reserved4[(0x200 - 0x40) / 8];
182 /* 0x200 */
183 u64 mrx_ctl[64];
184
185};
186
187#define MRMWMM_OFFSET(x) offsetof(struct hipz_mrmwmm,x)
188
189struct hipz_qpedmm {
190 /* 0x00 */
191 u64 reserved0[(0x400) / 8];
192 /* 0x400 */
193 u64 qpedx_phh;
194 u64 qpedx_ppsgp;
195 /* 0x410 */
196 u64 qpedx_ppsgu;
197 u64 qpedx_ppdgp;
198 /* 0x420 */
199 u64 qpedx_ppdgu;
200 u64 qpedx_aph;
201 /* 0x430 */
202 u64 qpedx_apsgp;
203 u64 qpedx_apsgu;
204 /* 0x440 */
205 u64 qpedx_apdgp;
206 u64 qpedx_apdgu;
207 /* 0x450 */
208 u64 qpedx_apav;
209 u64 qpedx_apsav;
210 /* 0x460 */
211 u64 qpedx_hcr;
212 u64 reserved1[4];
213 /* 0x488 */
214 u64 qpedx_rrl0;
215 /* 0x490 */
216 u64 qpedx_rrrkey0;
217 u64 qpedx_rrva0;
218 /* 0x4a0 */
219 u64 reserved2;
220 u64 qpedx_rrl1;
221 /* 0x4b0 */
222 u64 qpedx_rrrkey1;
223 u64 qpedx_rrva1;
224 /* 0x4c0 */
225 u64 reserved3;
226 u64 qpedx_rrl2;
227 /* 0x4d0 */
228 u64 qpedx_rrrkey2;
229 u64 qpedx_rrva2;
230 /* 0x4e0 */
231 u64 reserved4;
232 u64 qpedx_rrl3;
233 /* 0x4f0 */
234 u64 qpedx_rrrkey3;
235 u64 qpedx_rrva3;
236};
237
238#define QPEDMM_OFFSET(x) offsetof(struct hipz_qpedmm,x)
239
240/* CQ Table Entry Memory Map */
241struct hipz_cqtemm {
242 u64 cqx_hcr;
243 u64 cqx_c;
244 u64 cqx_herr;
245 u64 cqx_aer;
246/* 0x20 */
247 u64 cqx_ptp;
248 u64 cqx_tp;
249 u64 cqx_fec;
250 u64 cqx_feca;
251/* 0x40 */
252 u64 cqx_ep;
253 u64 cqx_eq;
254/* 0x50 */
255 u64 reserved1;
256 u64 cqx_n0;
257/* 0x60 */
258 u64 cqx_n1;
259 u64 reserved2[(0x1000 - 0x60) / 8];
260/* 0x1000 */
261};
262
263#define CQX_FEC_CQE_CNT EHCA_BMASK_IBM(32,63)
264#define CQX_FECADDER EHCA_BMASK_IBM(32,63)
265#define CQX_N0_GENERATE_SOLICITED_COMP_EVENT EHCA_BMASK_IBM(0,0)
266#define CQX_N1_GENERATE_COMP_EVENT EHCA_BMASK_IBM(0,0)
267
268#define CQTEMM_OFFSET(x) offsetof(struct hipz_cqtemm,x)
269
270/* EQ Table Entry Memory Map */
271struct hipz_eqtemm {
272 u64 eqx_hcr;
273 u64 eqx_c;
274
275 u64 eqx_herr;
276 u64 eqx_aer;
277/* 0x20 */
278 u64 eqx_ptp;
279 u64 eqx_tp;
280 u64 eqx_ssba;
281 u64 eqx_psba;
282
283/* 0x40 */
284 u64 eqx_cec;
285 u64 eqx_meql;
286 u64 eqx_xisbi;
287 u64 eqx_xisc;
288/* 0x60 */
289 u64 eqx_it;
290
291};
292
293#define EQTEMM_OFFSET(x) offsetof(struct hipz_eqtemm,x)
294
295/* access control defines for MR/MW */
296#define HIPZ_ACCESSCTRL_L_WRITE 0x00800000
297#define HIPZ_ACCESSCTRL_R_WRITE 0x00400000
298#define HIPZ_ACCESSCTRL_R_READ 0x00200000
299#define HIPZ_ACCESSCTRL_R_ATOMIC 0x00100000
300#define HIPZ_ACCESSCTRL_MW_BIND 0x00080000
301
302/* query hca response block */
303struct hipz_query_hca {
304 u32 cur_reliable_dg;
305 u32 cur_qp;
306 u32 cur_cq;
307 u32 cur_eq;
308 u32 cur_mr;
309 u32 cur_mw;
310 u32 cur_ee_context;
311 u32 cur_mcast_grp;
312 u32 cur_qp_attached_mcast_grp;
313 u32 reserved1;
314 u32 cur_ipv6_qp;
315 u32 cur_eth_qp;
316 u32 cur_hp_mr;
317 u32 reserved2[3];
318 u32 max_rd_domain;
319 u32 max_qp;
320 u32 max_cq;
321 u32 max_eq;
322 u32 max_mr;
323 u32 max_hp_mr;
324 u32 max_mw;
325 u32 max_mrwpte;
326 u32 max_special_mrwpte;
327 u32 max_rd_ee_context;
328 u32 max_mcast_grp;
329 u32 max_total_mcast_qp_attach;
330 u32 max_mcast_qp_attach;
331 u32 max_raw_ipv6_qp;
332 u32 max_raw_ethy_qp;
333 u32 internal_clock_frequency;
334 u32 max_pd;
335 u32 max_ah;
336 u32 max_cqe;
337 u32 max_wqes_wq;
338 u32 max_partitions;
339 u32 max_rr_ee_context;
340 u32 max_rr_qp;
341 u32 max_rr_hca;
342 u32 max_act_wqs_ee_context;
343 u32 max_act_wqs_qp;
344 u32 max_sge;
345 u32 max_sge_rd;
346 u32 memory_page_size_supported;
347 u64 max_mr_size;
348 u32 local_ca_ack_delay;
349 u32 num_ports;
350 u32 vendor_id;
351 u32 vendor_part_id;
352 u32 hw_ver;
353 u64 node_guid;
354 u64 hca_cap_indicators;
355 u32 data_counter_register_size;
356 u32 max_shared_rq;
357 u32 max_isns_eq;
358 u32 max_neq;
359} __attribute__ ((packed));
360
361/* query port response block */
362struct hipz_query_port {
363 u32 state;
364 u32 bad_pkey_cntr;
365 u32 lmc;
366 u32 lid;
367 u32 subnet_timeout;
368 u32 qkey_viol_cntr;
369 u32 sm_sl;
370 u32 sm_lid;
371 u32 capability_mask;
372 u32 init_type_reply;
373 u32 pkey_tbl_len;
374 u32 gid_tbl_len;
375 u64 gid_prefix;
376 u32 port_nr;
377 u16 pkey_entries[16];
378 u8 reserved1[32];
379 u32 trent_size;
380 u32 trbuf_size;
381 u64 max_msg_sz;
382 u32 max_mtu;
383 u32 vl_cap;
384 u8 reserved2[1900];
385 u64 guid_entries[255];
386} __attribute__ ((packed));
387
388#endif
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
new file mode 100644
index 000000000000..e028ff1588cc
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -0,0 +1,149 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * internal queue handling
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Reinhard Ernst <rernst@de.ibm.com>
8 * Christoph Raisch <raisch@de.ibm.com>
9 *
10 * Copyright (c) 2005 IBM Corporation
11 *
12 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
13 * BSD.
14 *
15 * OpenIB BSD License
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are met:
19 *
20 * Redistributions of source code must retain the above copyright notice, this
21 * list of conditions and the following disclaimer.
22 *
23 * Redistributions in binary form must reproduce the above copyright notice,
24 * this list of conditions and the following disclaimer in the documentation
25 * and/or other materials
26 * provided with the distribution.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#include "ehca_tools.h"
42#include "ipz_pt_fn.h"
43
44void *ipz_qpageit_get_inc(struct ipz_queue *queue)
45{
46 void *ret = ipz_qeit_get(queue);
47 queue->current_q_offset += queue->pagesize;
48 if (queue->current_q_offset > queue->queue_length) {
49 queue->current_q_offset -= queue->pagesize;
50 ret = NULL;
51 }
52 if (((u64)ret) % EHCA_PAGESIZE) {
53 ehca_gen_err("ERROR!! not at PAGE-Boundary");
54 return NULL;
55 }
56 return ret;
57}
58
59void *ipz_qeit_eq_get_inc(struct ipz_queue *queue)
60{
61 void *ret = ipz_qeit_get(queue);
62 u64 last_entry_in_q = queue->queue_length - queue->qe_size;
63
64 queue->current_q_offset += queue->qe_size;
65 if (queue->current_q_offset > last_entry_in_q) {
66 queue->current_q_offset = 0;
67 queue->toggle_state = (~queue->toggle_state) & 1;
68 }
69
70 return ret;
71}
72
73int ipz_queue_ctor(struct ipz_queue *queue,
74 const u32 nr_of_pages,
75 const u32 pagesize, const u32 qe_size, const u32 nr_of_sg)
76{
77 int pages_per_kpage = PAGE_SIZE >> EHCA_PAGESHIFT;
78 int f;
79
80 if (pagesize > PAGE_SIZE) {
81 ehca_gen_err("FATAL ERROR: pagesize=%x is greater "
82 "than kernel page size", pagesize);
83 return 0;
84 }
85 if (!pages_per_kpage) {
86 ehca_gen_err("FATAL ERROR: invalid kernel page size. "
87 "pages_per_kpage=%x", pages_per_kpage);
88 return 0;
89 }
90 queue->queue_length = nr_of_pages * pagesize;
91 queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *));
92 if (!queue->queue_pages) {
93 ehca_gen_err("ERROR!! didn't get the memory");
94 return 0;
95 }
96 memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *));
97 /*
98 * allocate pages for queue:
99 * outer loop allocates whole kernel pages (page aligned) and
100 * inner loop divides a kernel page into smaller hca queue pages
101 */
102 f = 0;
103 while (f < nr_of_pages) {
104 u8 *kpage = (u8*)get_zeroed_page(GFP_KERNEL);
105 int k;
106 if (!kpage)
107 goto ipz_queue_ctor_exit0; /*NOMEM*/
108 for (k = 0; k < pages_per_kpage && f < nr_of_pages; k++) {
109 (queue->queue_pages)[f] = (struct ipz_page *)kpage;
110 kpage += EHCA_PAGESIZE;
111 f++;
112 }
113 }
114
115 queue->current_q_offset = 0;
116 queue->qe_size = qe_size;
117 queue->act_nr_of_sg = nr_of_sg;
118 queue->pagesize = pagesize;
119 queue->toggle_state = 1;
120 return 1;
121
122 ipz_queue_ctor_exit0:
123 ehca_gen_err("Couldn't get alloc pages queue=%p f=%x nr_of_pages=%x",
124 queue, f, nr_of_pages);
125 for (f = 0; f < nr_of_pages; f += pages_per_kpage) {
126 if (!(queue->queue_pages)[f])
127 break;
128 free_page((unsigned long)(queue->queue_pages)[f]);
129 }
130 return 0;
131}
132
133int ipz_queue_dtor(struct ipz_queue *queue)
134{
135 int pages_per_kpage = PAGE_SIZE >> EHCA_PAGESHIFT;
136 int g;
137 int nr_pages;
138
139 if (!queue || !queue->queue_pages) {
140 ehca_gen_dbg("queue or queue_pages is NULL");
141 return 0;
142 }
143 nr_pages = queue->queue_length / queue->pagesize;
144 for (g = 0; g < nr_pages; g += pages_per_kpage)
145 free_page((unsigned long)(queue->queue_pages)[g]);
146 vfree(queue->queue_pages);
147
148 return 1;
149}
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
new file mode 100644
index 000000000000..2f13509d5257
--- /dev/null
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
@@ -0,0 +1,247 @@
1/*
2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
3 *
4 * internal queue handling
5 *
6 * Authors: Waleri Fomin <fomin@de.ibm.com>
7 * Reinhard Ernst <rernst@de.ibm.com>
8 * Christoph Raisch <raisch@de.ibm.com>
9 *
10 * Copyright (c) 2005 IBM Corporation
11 *
12 * All rights reserved.
13 *
14 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
15 * BSD.
16 *
17 * OpenIB BSD License
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * Redistributions of source code must retain the above copyright notice, this
23 * list of conditions and the following disclaimer.
24 *
25 * Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials
28 * provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42
43#ifndef __IPZ_PT_FN_H__
44#define __IPZ_PT_FN_H__
45
46#define EHCA_PAGESHIFT 12
47#define EHCA_PAGESIZE 4096UL
48#define EHCA_PAGEMASK (~(EHCA_PAGESIZE-1))
49#define EHCA_PT_ENTRIES 512UL
50
51#include "ehca_tools.h"
52#include "ehca_qes.h"
53
54/* struct generic ehca page */
55struct ipz_page {
56 u8 entries[EHCA_PAGESIZE];
57};
58
59/* struct generic queue in linux kernel virtual memory (kv) */
60struct ipz_queue {
61 u64 current_q_offset; /* current queue entry */
62
63 struct ipz_page **queue_pages; /* array of pages belonging to queue */
64 u32 qe_size; /* queue entry size */
65 u32 act_nr_of_sg;
66 u32 queue_length; /* queue length allocated in bytes */
67 u32 pagesize;
68 u32 toggle_state; /* toggle flag - per page */
69 u32 dummy3; /* 64 bit alignment */
70};
71
72/*
73 * return current Queue Entry for a certain q_offset
74 * returns address (kv) of Queue Entry
75 */
76static inline void *ipz_qeit_calc(struct ipz_queue *queue, u64 q_offset)
77{
78 struct ipz_page *current_page;
79 if (q_offset >= queue->queue_length)
80 return NULL;
81 current_page = (queue->queue_pages)[q_offset >> EHCA_PAGESHIFT];
82 return &current_page->entries[q_offset & (EHCA_PAGESIZE - 1)];
83}
84
85/*
86 * return current Queue Entry
87 * returns address (kv) of Queue Entry
88 */
89static inline void *ipz_qeit_get(struct ipz_queue *queue)
90{
91 return ipz_qeit_calc(queue, queue->current_q_offset);
92}
93
94/*
95 * return current Queue Page , increment Queue Page iterator from
96 * page to page in struct ipz_queue, last increment will return 0! and
97 * NOT wrap
98 * returns address (kv) of Queue Page
99 * warning don't use in parallel with ipz_QE_get_inc()
100 */
101void *ipz_qpageit_get_inc(struct ipz_queue *queue);
102
103/*
104 * return current Queue Entry, increment Queue Entry iterator by one
105 * step in struct ipz_queue, will wrap in ringbuffer
106 * returns address (kv) of Queue Entry BEFORE increment
107 * warning don't use in parallel with ipz_qpageit_get_inc()
108 * warning unpredictable results may occur if steps>act_nr_of_queue_entries
109 */
110static inline void *ipz_qeit_get_inc(struct ipz_queue *queue)
111{
112 void *ret = ipz_qeit_get(queue);
113 queue->current_q_offset += queue->qe_size;
114 if (queue->current_q_offset >= queue->queue_length) {
115 queue->current_q_offset = 0;
116 /* toggle the valid flag */
117 queue->toggle_state = (~queue->toggle_state) & 1;
118 }
119
120 return ret;
121}
122
123/*
124 * return current Queue Entry, increment Queue Entry iterator by one
125 * step in struct ipz_queue, will wrap in ringbuffer
126 * returns address (kv) of Queue Entry BEFORE increment
127 * returns 0 and does not increment, if wrong valid state
128 * warning don't use in parallel with ipz_qpageit_get_inc()
129 * warning unpredictable results may occur if steps>act_nr_of_queue_entries
130 */
131static inline void *ipz_qeit_get_inc_valid(struct ipz_queue *queue)
132{
133 struct ehca_cqe *cqe = ipz_qeit_get(queue);
134 u32 cqe_flags = cqe->cqe_flags;
135
136 if ((cqe_flags >> 7) != (queue->toggle_state & 1))
137 return NULL;
138
139 ipz_qeit_get_inc(queue);
140 return cqe;
141}
142
143/*
144 * returns and resets Queue Entry iterator
145 * returns address (kv) of first Queue Entry
146 */
147static inline void *ipz_qeit_reset(struct ipz_queue *queue)
148{
149 queue->current_q_offset = 0;
150 return ipz_qeit_get(queue);
151}
152
153/* struct generic page table */
154struct ipz_pt {
155 u64 entries[EHCA_PT_ENTRIES];
156};
157
158/* struct page table for a queue, only to be used in pf */
159struct ipz_qpt {
160 /* queue page tables (kv), use u64 because we know the element length */
161 u64 *qpts;
162 u32 n_qpts;
163 u32 n_ptes; /* number of page table entries */
164 u64 *current_pte_addr;
165};
166
167/*
168 * constructor for a ipz_queue_t, placement new for ipz_queue_t,
169 * new for all dependent datastructors
170 * all QP Tables are the same
171 * flow:
172 * allocate+pin queue
173 * see ipz_qpt_ctor()
174 * returns true if ok, false if out of memory
175 */
176int ipz_queue_ctor(struct ipz_queue *queue, const u32 nr_of_pages,
177 const u32 pagesize, const u32 qe_size,
178 const u32 nr_of_sg);
179
180/*
181 * destructor for a ipz_queue_t
182 * -# free queue
183 * see ipz_queue_ctor()
184 * returns true if ok, false if queue was NULL-ptr of free failed
185 */
186int ipz_queue_dtor(struct ipz_queue *queue);
187
188/*
189 * constructor for a ipz_qpt_t,
190 * placement new for struct ipz_queue, new for all dependent datastructors
191 * all QP Tables are the same,
192 * flow:
193 * -# allocate+pin queue
194 * -# initialise ptcb
195 * -# allocate+pin PTs
196 * -# link PTs to a ring, according to HCA Arch, set bit62 id needed
197 * -# the ring must have room for exactly nr_of_PTEs
198 * see ipz_qpt_ctor()
199 */
200void ipz_qpt_ctor(struct ipz_qpt *qpt,
201 const u32 nr_of_qes,
202 const u32 pagesize,
203 const u32 qe_size,
204 const u8 lowbyte, const u8 toggle,
205 u32 * act_nr_of_QEs, u32 * act_nr_of_pages);
206
207/*
208 * return current Queue Entry, increment Queue Entry iterator by one
209 * step in struct ipz_queue, will wrap in ringbuffer
210 * returns address (kv) of Queue Entry BEFORE increment
211 * warning don't use in parallel with ipz_qpageit_get_inc()
212 * warning unpredictable results may occur if steps>act_nr_of_queue_entries
213 * fix EQ page problems
214 */
215void *ipz_qeit_eq_get_inc(struct ipz_queue *queue);
216
217/*
218 * return current Event Queue Entry, increment Queue Entry iterator
219 * by one step in struct ipz_queue if valid, will wrap in ringbuffer
220 * returns address (kv) of Queue Entry BEFORE increment
221 * returns 0 and does not increment, if wrong valid state
222 * warning don't use in parallel with ipz_queue_QPageit_get_inc()
223 * warning unpredictable results may occur if steps>act_nr_of_queue_entries
224 */
225static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue)
226{
227 void *ret = ipz_qeit_get(queue);
228 u32 qe = *(u8 *) ret;
229 if ((qe >> 7) != (queue->toggle_state & 1))
230 return NULL;
231 ipz_qeit_eq_get_inc(queue); /* this is a good one */
232 return ret;
233}
234
235/* returns address (GX) of first queue entry */
236static inline u64 ipz_qpt_get_firstpage(struct ipz_qpt *qpt)
237{
238 return be64_to_cpu(qpt->qpts[0]);
239}
240
241/* returns address (kv) of first page of queue page table */
242static inline void *ipz_qpt_get_qpt(struct ipz_qpt *qpt)
243{
244 return qpt->qpts;
245}
246
247#endif /* __IPZ_PT_FN_H__ */
diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig
index 1db9489f1e82..574a678e7fdd 100644
--- a/drivers/infiniband/hw/ipath/Kconfig
+++ b/drivers/infiniband/hw/ipath/Kconfig
@@ -1,16 +1,9 @@
1config IPATH_CORE
2 tristate "QLogic InfiniPath Driver"
3 depends on 64BIT && PCI_MSI && NET
4 ---help---
5 This is a low-level driver for QLogic InfiniPath host channel
6 adapters (HCAs) based on the HT-400 and PE-800 chips.
7
8config INFINIBAND_IPATH 1config INFINIBAND_IPATH
9 tristate "QLogic InfiniPath Verbs Driver" 2 tristate "QLogic InfiniPath Driver"
10 depends on IPATH_CORE && INFINIBAND 3 depends on PCI_MSI && 64BIT && INFINIBAND
11 ---help--- 4 ---help---
12 This is a driver that provides InfiniBand verbs support for 5 This is a driver for QLogic InfiniPath host channel adapters,
13 QLogic InfiniPath host channel adapters (HCAs). This 6 including InfiniBand verbs support. This driver allows these
14 allows these devices to be used with both kernel upper level 7 devices to be used with both kernel upper level protocols such
15 protocols such as IP-over-InfiniBand as well as with userspace 8 as IP-over-InfiniBand as well as with userspace applications
16 applications (in conjunction with InfiniBand userspace access). 9 (in conjunction with InfiniBand userspace access).
diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile
index b0bf72864130..5e29cb0095e5 100644
--- a/drivers/infiniband/hw/ipath/Makefile
+++ b/drivers/infiniband/hw/ipath/Makefile
@@ -1,36 +1,35 @@
1EXTRA_CFLAGS += -DIPATH_IDSTR='"QLogic kernel.org driver"' \ 1EXTRA_CFLAGS += -DIPATH_IDSTR='"QLogic kernel.org driver"' \
2 -DIPATH_KERN_TYPE=0 2 -DIPATH_KERN_TYPE=0
3 3
4obj-$(CONFIG_IPATH_CORE) += ipath_core.o
5obj-$(CONFIG_INFINIBAND_IPATH) += ib_ipath.o 4obj-$(CONFIG_INFINIBAND_IPATH) += ib_ipath.o
6 5
7ipath_core-y := \ 6ib_ipath-y := \
7 ipath_cq.o \
8 ipath_diag.o \ 8 ipath_diag.o \
9 ipath_driver.o \ 9 ipath_driver.o \
10 ipath_eeprom.o \ 10 ipath_eeprom.o \
11 ipath_file_ops.o \ 11 ipath_file_ops.o \
12 ipath_fs.o \ 12 ipath_fs.o \
13 ipath_ht400.o \ 13 ipath_iba6110.o \
14 ipath_iba6120.o \
14 ipath_init_chip.o \ 15 ipath_init_chip.o \
15 ipath_intr.o \ 16 ipath_intr.o \
16 ipath_layer.o \
17 ipath_pe800.o \
18 ipath_stats.o \
19 ipath_sysfs.o \
20 ipath_user_pages.o
21
22ipath_core-$(CONFIG_X86_64) += ipath_wc_x86_64.o
23
24ib_ipath-y := \
25 ipath_cq.o \
26 ipath_keys.o \ 17 ipath_keys.o \
18 ipath_layer.o \
27 ipath_mad.o \ 19 ipath_mad.o \
20 ipath_mmap.o \
28 ipath_mr.o \ 21 ipath_mr.o \
29 ipath_qp.o \ 22 ipath_qp.o \
30 ipath_rc.o \ 23 ipath_rc.o \
31 ipath_ruc.o \ 24 ipath_ruc.o \
32 ipath_srq.o \ 25 ipath_srq.o \
26 ipath_stats.o \
27 ipath_sysfs.o \
33 ipath_uc.o \ 28 ipath_uc.o \
34 ipath_ud.o \ 29 ipath_ud.o \
35 ipath_verbs.o \ 30 ipath_user_pages.o \
36 ipath_verbs_mcast.o 31 ipath_verbs_mcast.o \
32 ipath_verbs.o
33
34ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o
35ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h
index 062bd392e7e5..f577905e3aca 100644
--- a/drivers/infiniband/hw/ipath/ipath_common.h
+++ b/drivers/infiniband/hw/ipath/ipath_common.h
@@ -106,9 +106,9 @@ struct infinipath_stats {
106 __u64 sps_ether_spkts; 106 __u64 sps_ether_spkts;
107 /* number of "ethernet" packets received by driver */ 107 /* number of "ethernet" packets received by driver */
108 __u64 sps_ether_rpkts; 108 __u64 sps_ether_rpkts;
109 /* number of SMA packets sent by driver */ 109 /* number of SMA packets sent by driver. Obsolete. */
110 __u64 sps_sma_spkts; 110 __u64 sps_sma_spkts;
111 /* number of SMA packets received by driver */ 111 /* number of SMA packets received by driver. Obsolete. */
112 __u64 sps_sma_rpkts; 112 __u64 sps_sma_rpkts;
113 /* number of times all ports rcvhdrq was full and packet dropped */ 113 /* number of times all ports rcvhdrq was full and packet dropped */
114 __u64 sps_hdrqfull; 114 __u64 sps_hdrqfull;
@@ -138,7 +138,7 @@ struct infinipath_stats {
138 __u64 sps_pageunlocks; 138 __u64 sps_pageunlocks;
139 /* 139 /*
140 * Number of packets dropped in kernel other than errors (ether 140 * Number of packets dropped in kernel other than errors (ether
141 * packets if ipath not configured, sma/mad, etc.) 141 * packets if ipath not configured, etc.)
142 */ 142 */
143 __u64 sps_krdrops; 143 __u64 sps_krdrops;
144 /* pad for future growth */ 144 /* pad for future growth */
@@ -153,8 +153,6 @@ struct infinipath_stats {
153#define IPATH_STATUS_DISABLED 0x2 /* hardware disabled */ 153#define IPATH_STATUS_DISABLED 0x2 /* hardware disabled */
154/* Device has been disabled via admin request */ 154/* Device has been disabled via admin request */
155#define IPATH_STATUS_ADMIN_DISABLED 0x4 155#define IPATH_STATUS_ADMIN_DISABLED 0x4
156#define IPATH_STATUS_OIB_SMA 0x8 /* ipath_mad kernel SMA running */
157#define IPATH_STATUS_SMA 0x10 /* user SMA running */
158/* Chip has been found and initted */ 156/* Chip has been found and initted */
159#define IPATH_STATUS_CHIP_PRESENT 0x20 157#define IPATH_STATUS_CHIP_PRESENT 0x20
160/* IB link is at ACTIVE, usable for data traffic */ 158/* IB link is at ACTIVE, usable for data traffic */
@@ -465,12 +463,11 @@ struct __ipath_sendpkt {
465 struct ipath_iovec sps_iov[4]; 463 struct ipath_iovec sps_iov[4];
466}; 464};
467 465
468/* Passed into SMA special file's ->read and ->write methods. */ 466/* Passed into diag data special file's ->write method. */
469struct ipath_sma_pkt 467struct ipath_diag_pkt {
470{ 468 __u32 unit;
471 __u32 unit; /* unit on which to send packet */ 469 __u64 data;
472 __u64 data; /* address of payload in userspace */ 470 __u32 len;
473 __u32 len; /* length of payload */
474}; 471};
475 472
476/* 473/*
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c
index 3efee341c9bc..049221bc590e 100644
--- a/drivers/infiniband/hw/ipath/ipath_cq.c
+++ b/drivers/infiniband/hw/ipath/ipath_cq.c
@@ -42,20 +42,28 @@
42 * @entry: work completion entry to add 42 * @entry: work completion entry to add
43 * @sig: true if @entry is a solicitated entry 43 * @sig: true if @entry is a solicitated entry
44 * 44 *
45 * This may be called with one of the qp->s_lock or qp->r_rq.lock held. 45 * This may be called with qp->s_lock held.
46 */ 46 */
47void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited) 47void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
48{ 48{
49 struct ipath_cq_wc *wc = cq->queue;
49 unsigned long flags; 50 unsigned long flags;
51 u32 head;
50 u32 next; 52 u32 next;
51 53
52 spin_lock_irqsave(&cq->lock, flags); 54 spin_lock_irqsave(&cq->lock, flags);
53 55
54 if (cq->head == cq->ibcq.cqe) 56 /*
57 * Note that the head pointer might be writable by user processes.
58 * Take care to verify it is a sane value.
59 */
60 head = wc->head;
61 if (head >= (unsigned) cq->ibcq.cqe) {
62 head = cq->ibcq.cqe;
55 next = 0; 63 next = 0;
56 else 64 } else
57 next = cq->head + 1; 65 next = head + 1;
58 if (unlikely(next == cq->tail)) { 66 if (unlikely(next == wc->tail)) {
59 spin_unlock_irqrestore(&cq->lock, flags); 67 spin_unlock_irqrestore(&cq->lock, flags);
60 if (cq->ibcq.event_handler) { 68 if (cq->ibcq.event_handler) {
61 struct ib_event ev; 69 struct ib_event ev;
@@ -67,8 +75,8 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
67 } 75 }
68 return; 76 return;
69 } 77 }
70 cq->queue[cq->head] = *entry; 78 wc->queue[head] = *entry;
71 cq->head = next; 79 wc->head = next;
72 80
73 if (cq->notify == IB_CQ_NEXT_COMP || 81 if (cq->notify == IB_CQ_NEXT_COMP ||
74 (cq->notify == IB_CQ_SOLICITED && solicited)) { 82 (cq->notify == IB_CQ_SOLICITED && solicited)) {
@@ -101,19 +109,20 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
101int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) 109int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
102{ 110{
103 struct ipath_cq *cq = to_icq(ibcq); 111 struct ipath_cq *cq = to_icq(ibcq);
112 struct ipath_cq_wc *wc = cq->queue;
104 unsigned long flags; 113 unsigned long flags;
105 int npolled; 114 int npolled;
106 115
107 spin_lock_irqsave(&cq->lock, flags); 116 spin_lock_irqsave(&cq->lock, flags);
108 117
109 for (npolled = 0; npolled < num_entries; ++npolled, ++entry) { 118 for (npolled = 0; npolled < num_entries; ++npolled, ++entry) {
110 if (cq->tail == cq->head) 119 if (wc->tail == wc->head)
111 break; 120 break;
112 *entry = cq->queue[cq->tail]; 121 *entry = wc->queue[wc->tail];
113 if (cq->tail == cq->ibcq.cqe) 122 if (wc->tail >= cq->ibcq.cqe)
114 cq->tail = 0; 123 wc->tail = 0;
115 else 124 else
116 cq->tail++; 125 wc->tail++;
117 } 126 }
118 127
119 spin_unlock_irqrestore(&cq->lock, flags); 128 spin_unlock_irqrestore(&cq->lock, flags);
@@ -160,38 +169,74 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
160{ 169{
161 struct ipath_ibdev *dev = to_idev(ibdev); 170 struct ipath_ibdev *dev = to_idev(ibdev);
162 struct ipath_cq *cq; 171 struct ipath_cq *cq;
163 struct ib_wc *wc; 172 struct ipath_cq_wc *wc;
164 struct ib_cq *ret; 173 struct ib_cq *ret;
165 174
166 if (entries > ib_ipath_max_cqes) { 175 if (entries < 1 || entries > ib_ipath_max_cqes) {
167 ret = ERR_PTR(-EINVAL); 176 ret = ERR_PTR(-EINVAL);
168 goto bail; 177 goto done;
169 } 178 }
170 179
171 if (dev->n_cqs_allocated == ib_ipath_max_cqs) { 180 if (dev->n_cqs_allocated == ib_ipath_max_cqs) {
172 ret = ERR_PTR(-ENOMEM); 181 ret = ERR_PTR(-ENOMEM);
173 goto bail; 182 goto done;
174 } 183 }
175 184
176 /* 185 /* Allocate the completion queue structure. */
177 * Need to use vmalloc() if we want to support large #s of
178 * entries.
179 */
180 cq = kmalloc(sizeof(*cq), GFP_KERNEL); 186 cq = kmalloc(sizeof(*cq), GFP_KERNEL);
181 if (!cq) { 187 if (!cq) {
182 ret = ERR_PTR(-ENOMEM); 188 ret = ERR_PTR(-ENOMEM);
183 goto bail; 189 goto done;
184 } 190 }
185 191
186 /* 192 /*
187 * Need to use vmalloc() if we want to support large #s of entries. 193 * Allocate the completion queue entries and head/tail pointers.
194 * This is allocated separately so that it can be resized and
195 * also mapped into user space.
196 * We need to use vmalloc() in order to support mmap and large
197 * numbers of entries.
188 */ 198 */
189 wc = vmalloc(sizeof(*wc) * (entries + 1)); 199 wc = vmalloc_user(sizeof(*wc) + sizeof(struct ib_wc) * entries);
190 if (!wc) { 200 if (!wc) {
191 kfree(cq);
192 ret = ERR_PTR(-ENOMEM); 201 ret = ERR_PTR(-ENOMEM);
193 goto bail; 202 goto bail_cq;
194 } 203 }
204
205 /*
206 * Return the address of the WC as the offset to mmap.
207 * See ipath_mmap() for details.
208 */
209 if (udata && udata->outlen >= sizeof(__u64)) {
210 struct ipath_mmap_info *ip;
211 __u64 offset = (__u64) wc;
212 int err;
213
214 err = ib_copy_to_udata(udata, &offset, sizeof(offset));
215 if (err) {
216 ret = ERR_PTR(err);
217 goto bail_wc;
218 }
219
220 /* Allocate info for ipath_mmap(). */
221 ip = kmalloc(sizeof(*ip), GFP_KERNEL);
222 if (!ip) {
223 ret = ERR_PTR(-ENOMEM);
224 goto bail_wc;
225 }
226 cq->ip = ip;
227 ip->context = context;
228 ip->obj = wc;
229 kref_init(&ip->ref);
230 ip->mmap_cnt = 0;
231 ip->size = PAGE_ALIGN(sizeof(*wc) +
232 sizeof(struct ib_wc) * entries);
233 spin_lock_irq(&dev->pending_lock);
234 ip->next = dev->pending_mmaps;
235 dev->pending_mmaps = ip;
236 spin_unlock_irq(&dev->pending_lock);
237 } else
238 cq->ip = NULL;
239
195 /* 240 /*
196 * ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe. 241 * ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe.
197 * The number of entries should be >= the number requested or return 242 * The number of entries should be >= the number requested or return
@@ -202,15 +247,22 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
202 cq->triggered = 0; 247 cq->triggered = 0;
203 spin_lock_init(&cq->lock); 248 spin_lock_init(&cq->lock);
204 tasklet_init(&cq->comptask, send_complete, (unsigned long)cq); 249 tasklet_init(&cq->comptask, send_complete, (unsigned long)cq);
205 cq->head = 0; 250 wc->head = 0;
206 cq->tail = 0; 251 wc->tail = 0;
207 cq->queue = wc; 252 cq->queue = wc;
208 253
209 ret = &cq->ibcq; 254 ret = &cq->ibcq;
210 255
211 dev->n_cqs_allocated++; 256 dev->n_cqs_allocated++;
257 goto done;
212 258
213bail: 259bail_wc:
260 vfree(wc);
261
262bail_cq:
263 kfree(cq);
264
265done:
214 return ret; 266 return ret;
215} 267}
216 268
@@ -229,7 +281,10 @@ int ipath_destroy_cq(struct ib_cq *ibcq)
229 281
230 tasklet_kill(&cq->comptask); 282 tasklet_kill(&cq->comptask);
231 dev->n_cqs_allocated--; 283 dev->n_cqs_allocated--;
232 vfree(cq->queue); 284 if (cq->ip)
285 kref_put(&cq->ip->ref, ipath_release_mmap_info);
286 else
287 vfree(cq->queue);
233 kfree(cq); 288 kfree(cq);
234 289
235 return 0; 290 return 0;
@@ -253,7 +308,7 @@ int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
253 spin_lock_irqsave(&cq->lock, flags); 308 spin_lock_irqsave(&cq->lock, flags);
254 /* 309 /*
255 * Don't change IB_CQ_NEXT_COMP to IB_CQ_SOLICITED but allow 310 * Don't change IB_CQ_NEXT_COMP to IB_CQ_SOLICITED but allow
256 * any other transitions. 311 * any other transitions (see C11-31 and C11-32 in ch. 11.4.2.2).
257 */ 312 */
258 if (cq->notify != IB_CQ_NEXT_COMP) 313 if (cq->notify != IB_CQ_NEXT_COMP)
259 cq->notify = notify; 314 cq->notify = notify;
@@ -264,46 +319,86 @@ int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
264int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) 319int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
265{ 320{
266 struct ipath_cq *cq = to_icq(ibcq); 321 struct ipath_cq *cq = to_icq(ibcq);
267 struct ib_wc *wc, *old_wc; 322 struct ipath_cq_wc *old_wc = cq->queue;
268 u32 n; 323 struct ipath_cq_wc *wc;
324 u32 head, tail, n;
269 int ret; 325 int ret;
270 326
327 if (cqe < 1 || cqe > ib_ipath_max_cqes) {
328 ret = -EINVAL;
329 goto bail;
330 }
331
271 /* 332 /*
272 * Need to use vmalloc() if we want to support large #s of entries. 333 * Need to use vmalloc() if we want to support large #s of entries.
273 */ 334 */
274 wc = vmalloc(sizeof(*wc) * (cqe + 1)); 335 wc = vmalloc_user(sizeof(*wc) + sizeof(struct ib_wc) * cqe);
275 if (!wc) { 336 if (!wc) {
276 ret = -ENOMEM; 337 ret = -ENOMEM;
277 goto bail; 338 goto bail;
278 } 339 }
279 340
341 /*
342 * Return the address of the WC as the offset to mmap.
343 * See ipath_mmap() for details.
344 */
345 if (udata && udata->outlen >= sizeof(__u64)) {
346 __u64 offset = (__u64) wc;
347
348 ret = ib_copy_to_udata(udata, &offset, sizeof(offset));
349 if (ret)
350 goto bail;
351 }
352
280 spin_lock_irq(&cq->lock); 353 spin_lock_irq(&cq->lock);
281 if (cq->head < cq->tail) 354 /*
282 n = cq->ibcq.cqe + 1 + cq->head - cq->tail; 355 * Make sure head and tail are sane since they
356 * might be user writable.
357 */
358 head = old_wc->head;
359 if (head > (u32) cq->ibcq.cqe)
360 head = (u32) cq->ibcq.cqe;
361 tail = old_wc->tail;
362 if (tail > (u32) cq->ibcq.cqe)
363 tail = (u32) cq->ibcq.cqe;
364 if (head < tail)
365 n = cq->ibcq.cqe + 1 + head - tail;
283 else 366 else
284 n = cq->head - cq->tail; 367 n = head - tail;
285 if (unlikely((u32)cqe < n)) { 368 if (unlikely((u32)cqe < n)) {
286 spin_unlock_irq(&cq->lock); 369 spin_unlock_irq(&cq->lock);
287 vfree(wc); 370 vfree(wc);
288 ret = -EOVERFLOW; 371 ret = -EOVERFLOW;
289 goto bail; 372 goto bail;
290 } 373 }
291 for (n = 0; cq->tail != cq->head; n++) { 374 for (n = 0; tail != head; n++) {
292 wc[n] = cq->queue[cq->tail]; 375 wc->queue[n] = old_wc->queue[tail];
293 if (cq->tail == cq->ibcq.cqe) 376 if (tail == (u32) cq->ibcq.cqe)
294 cq->tail = 0; 377 tail = 0;
295 else 378 else
296 cq->tail++; 379 tail++;
297 } 380 }
298 cq->ibcq.cqe = cqe; 381 cq->ibcq.cqe = cqe;
299 cq->head = n; 382 wc->head = n;
300 cq->tail = 0; 383 wc->tail = 0;
301 old_wc = cq->queue;
302 cq->queue = wc; 384 cq->queue = wc;
303 spin_unlock_irq(&cq->lock); 385 spin_unlock_irq(&cq->lock);
304 386
305 vfree(old_wc); 387 vfree(old_wc);
306 388
389 if (cq->ip) {
390 struct ipath_ibdev *dev = to_idev(ibcq->device);
391 struct ipath_mmap_info *ip = cq->ip;
392
393 ip->obj = wc;
394 ip->size = PAGE_ALIGN(sizeof(*wc) +
395 sizeof(struct ib_wc) * cqe);
396 spin_lock_irq(&dev->pending_lock);
397 ip->next = dev->pending_mmaps;
398 dev->pending_mmaps = ip;
399 spin_unlock_irq(&dev->pending_lock);
400 }
401
307 ret = 0; 402 ret = 0;
308 403
309bail: 404bail:
diff --git a/drivers/infiniband/hw/ipath/ipath_debug.h b/drivers/infiniband/hw/ipath/ipath_debug.h
index f415beda0d32..df69f0d80b8b 100644
--- a/drivers/infiniband/hw/ipath/ipath_debug.h
+++ b/drivers/infiniband/hw/ipath/ipath_debug.h
@@ -60,7 +60,6 @@
60#define __IPATH_USER_SEND 0x1000 /* use user mode send */ 60#define __IPATH_USER_SEND 0x1000 /* use user mode send */
61#define __IPATH_KERNEL_SEND 0x2000 /* use kernel mode send */ 61#define __IPATH_KERNEL_SEND 0x2000 /* use kernel mode send */
62#define __IPATH_EPKTDBG 0x4000 /* print ethernet packet data */ 62#define __IPATH_EPKTDBG 0x4000 /* print ethernet packet data */
63#define __IPATH_SMADBG 0x8000 /* sma packet debug */
64#define __IPATH_IPATHDBG 0x10000 /* Ethernet (IPATH) gen debug */ 63#define __IPATH_IPATHDBG 0x10000 /* Ethernet (IPATH) gen debug */
65#define __IPATH_IPATHWARN 0x20000 /* Ethernet (IPATH) warnings */ 64#define __IPATH_IPATHWARN 0x20000 /* Ethernet (IPATH) warnings */
66#define __IPATH_IPATHERR 0x40000 /* Ethernet (IPATH) errors */ 65#define __IPATH_IPATHERR 0x40000 /* Ethernet (IPATH) errors */
@@ -84,7 +83,6 @@
84/* print mmap/nopage stuff, not using VDBG any more */ 83/* print mmap/nopage stuff, not using VDBG any more */
85#define __IPATH_MMDBG 0x0 84#define __IPATH_MMDBG 0x0
86#define __IPATH_EPKTDBG 0x0 /* print ethernet packet data */ 85#define __IPATH_EPKTDBG 0x0 /* print ethernet packet data */
87#define __IPATH_SMADBG 0x0 /* process startup (init)/exit messages */
88#define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */ 86#define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */
89#define __IPATH_IPATHWARN 0x0 /* Ethernet (IPATH) warnings on */ 87#define __IPATH_IPATHWARN 0x0 /* Ethernet (IPATH) warnings on */
90#define __IPATH_IPATHERR 0x0 /* Ethernet (IPATH) errors on */ 88#define __IPATH_IPATHERR 0x0 /* Ethernet (IPATH) errors on */
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c
index 147dd89e21c9..28b6b46c106a 100644
--- a/drivers/infiniband/hw/ipath/ipath_diag.c
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c
@@ -41,11 +41,11 @@
41 * through the /sys/bus/pci resource mmap interface. 41 * through the /sys/bus/pci resource mmap interface.
42 */ 42 */
43 43
44#include <linux/io.h>
44#include <linux/pci.h> 45#include <linux/pci.h>
45#include <asm/uaccess.h> 46#include <asm/uaccess.h>
46 47
47#include "ipath_kernel.h" 48#include "ipath_kernel.h"
48#include "ipath_layer.h"
49#include "ipath_common.h" 49#include "ipath_common.h"
50 50
51int ipath_diag_inuse; 51int ipath_diag_inuse;
@@ -274,6 +274,158 @@ bail:
274 return ret; 274 return ret;
275} 275}
276 276
277static ssize_t ipath_diagpkt_write(struct file *fp,
278 const char __user *data,
279 size_t count, loff_t *off);
280
281static struct file_operations diagpkt_file_ops = {
282 .owner = THIS_MODULE,
283 .write = ipath_diagpkt_write,
284};
285
286static struct cdev *diagpkt_cdev;
287static struct class_device *diagpkt_class_dev;
288
289int __init ipath_diagpkt_add(void)
290{
291 return ipath_cdev_init(IPATH_DIAGPKT_MINOR,
292 "ipath_diagpkt", &diagpkt_file_ops,
293 &diagpkt_cdev, &diagpkt_class_dev);
294}
295
296void __exit ipath_diagpkt_remove(void)
297{
298 ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev);
299}
300
301/**
302 * ipath_diagpkt_write - write an IB packet
303 * @fp: the diag data device file pointer
304 * @data: ipath_diag_pkt structure saying where to get the packet
305 * @count: size of data to write
306 * @off: unused by this code
307 */
308static ssize_t ipath_diagpkt_write(struct file *fp,
309 const char __user *data,
310 size_t count, loff_t *off)
311{
312 u32 __iomem *piobuf;
313 u32 plen, clen, pbufn;
314 struct ipath_diag_pkt dp;
315 u32 *tmpbuf = NULL;
316 struct ipath_devdata *dd;
317 ssize_t ret = 0;
318 u64 val;
319
320 if (count < sizeof(dp)) {
321 ret = -EINVAL;
322 goto bail;
323 }
324
325 if (copy_from_user(&dp, data, sizeof(dp))) {
326 ret = -EFAULT;
327 goto bail;
328 }
329
330 /* send count must be an exact number of dwords */
331 if (dp.len & 3) {
332 ret = -EINVAL;
333 goto bail;
334 }
335
336 clen = dp.len >> 2;
337
338 dd = ipath_lookup(dp.unit);
339 if (!dd || !(dd->ipath_flags & IPATH_PRESENT) ||
340 !dd->ipath_kregbase) {
341 ipath_cdbg(VERBOSE, "illegal unit %u for diag data send\n",
342 dp.unit);
343 ret = -ENODEV;
344 goto bail;
345 }
346
347 if (ipath_diag_inuse && !diag_set_link &&
348 !(dd->ipath_flags & IPATH_LINKACTIVE)) {
349 diag_set_link = 1;
350 ipath_cdbg(VERBOSE, "Trying to set to set link active for "
351 "diag pkt\n");
352 ipath_set_linkstate(dd, IPATH_IB_LINKARM);
353 ipath_set_linkstate(dd, IPATH_IB_LINKACTIVE);
354 }
355
356 if (!(dd->ipath_flags & IPATH_INITTED)) {
357 /* no hardware, freeze, etc. */
358 ipath_cdbg(VERBOSE, "unit %u not usable\n", dd->ipath_unit);
359 ret = -ENODEV;
360 goto bail;
361 }
362 val = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK;
363 if (val != IPATH_IBSTATE_INIT && val != IPATH_IBSTATE_ARM &&
364 val != IPATH_IBSTATE_ACTIVE) {
365 ipath_cdbg(VERBOSE, "unit %u not ready (state %llx)\n",
366 dd->ipath_unit, (unsigned long long) val);
367 ret = -EINVAL;
368 goto bail;
369 }
370
371 /* need total length before first word written */
372 /* +1 word is for the qword padding */
373 plen = sizeof(u32) + dp.len;
374
375 if ((plen + 4) > dd->ipath_ibmaxlen) {
376 ipath_dbg("Pkt len 0x%x > ibmaxlen %x\n",
377 plen - 4, dd->ipath_ibmaxlen);
378 ret = -EINVAL;
379 goto bail; /* before writing pbc */
380 }
381 tmpbuf = vmalloc(plen);
382 if (!tmpbuf) {
383 dev_info(&dd->pcidev->dev, "Unable to allocate tmp buffer, "
384 "failing\n");
385 ret = -ENOMEM;
386 goto bail;
387 }
388
389 if (copy_from_user(tmpbuf,
390 (const void __user *) (unsigned long) dp.data,
391 dp.len)) {
392 ret = -EFAULT;
393 goto bail;
394 }
395
396 piobuf = ipath_getpiobuf(dd, &pbufn);
397 if (!piobuf) {
398 ipath_cdbg(VERBOSE, "No PIO buffers avail unit for %u\n",
399 dd->ipath_unit);
400 ret = -EBUSY;
401 goto bail;
402 }
403
404 plen >>= 2; /* in dwords */
405
406 if (ipath_debug & __IPATH_PKTDBG)
407 ipath_cdbg(VERBOSE, "unit %u 0x%x+1w pio%d\n",
408 dd->ipath_unit, plen - 1, pbufn);
409
410 /* we have to flush after the PBC for correctness on some cpus
411 * or WC buffer can be written out of order */
412 writeq(plen, piobuf);
413 ipath_flush_wc();
414 /* copy all by the trigger word, then flush, so it's written
415 * to chip before trigger word, then write trigger word, then
416 * flush again, so packet is sent. */
417 __iowrite32_copy(piobuf + 2, tmpbuf, clen - 1);
418 ipath_flush_wc();
419 __raw_writel(tmpbuf[clen - 1], piobuf + clen + 1);
420 ipath_flush_wc();
421
422 ret = sizeof(dp);
423
424bail:
425 vfree(tmpbuf);
426 return ret;
427}
428
277static int ipath_diag_release(struct inode *in, struct file *fp) 429static int ipath_diag_release(struct inode *in, struct file *fp)
278{ 430{
279 mutex_lock(&ipath_mutex); 431 mutex_lock(&ipath_mutex);
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index f98518d912b5..2108466c7e33 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -39,7 +39,7 @@
39#include <linux/vmalloc.h> 39#include <linux/vmalloc.h>
40 40
41#include "ipath_kernel.h" 41#include "ipath_kernel.h"
42#include "ipath_layer.h" 42#include "ipath_verbs.h"
43#include "ipath_common.h" 43#include "ipath_common.h"
44 44
45static void ipath_update_pio_bufs(struct ipath_devdata *); 45static void ipath_update_pio_bufs(struct ipath_devdata *);
@@ -51,8 +51,6 @@ const char *ipath_get_unit_name(int unit)
51 return iname; 51 return iname;
52} 52}
53 53
54EXPORT_SYMBOL_GPL(ipath_get_unit_name);
55
56#define DRIVER_LOAD_MSG "QLogic " IPATH_DRV_NAME " loaded: " 54#define DRIVER_LOAD_MSG "QLogic " IPATH_DRV_NAME " loaded: "
57#define PFX IPATH_DRV_NAME ": " 55#define PFX IPATH_DRV_NAME ": "
58 56
@@ -60,13 +58,13 @@ EXPORT_SYMBOL_GPL(ipath_get_unit_name);
60 * The size has to be longer than this string, so we can append 58 * The size has to be longer than this string, so we can append
61 * board/chip information to it in the init code. 59 * board/chip information to it in the init code.
62 */ 60 */
63const char ipath_core_version[] = IPATH_IDSTR "\n"; 61const char ib_ipath_version[] = IPATH_IDSTR "\n";
64 62
65static struct idr unit_table; 63static struct idr unit_table;
66DEFINE_SPINLOCK(ipath_devs_lock); 64DEFINE_SPINLOCK(ipath_devs_lock);
67LIST_HEAD(ipath_dev_list); 65LIST_HEAD(ipath_dev_list);
68 66
69wait_queue_head_t ipath_sma_state_wait; 67wait_queue_head_t ipath_state_wait;
70 68
71unsigned ipath_debug = __IPATH_INFO; 69unsigned ipath_debug = __IPATH_INFO;
72 70
@@ -403,10 +401,10 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
403 /* setup the chip-specific functions, as early as possible. */ 401 /* setup the chip-specific functions, as early as possible. */
404 switch (ent->device) { 402 switch (ent->device) {
405 case PCI_DEVICE_ID_INFINIPATH_HT: 403 case PCI_DEVICE_ID_INFINIPATH_HT:
406 ipath_init_ht400_funcs(dd); 404 ipath_init_iba6110_funcs(dd);
407 break; 405 break;
408 case PCI_DEVICE_ID_INFINIPATH_PE800: 406 case PCI_DEVICE_ID_INFINIPATH_PE800:
409 ipath_init_pe800_funcs(dd); 407 ipath_init_iba6120_funcs(dd);
410 break; 408 break;
411 default: 409 default:
412 ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, " 410 ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, "
@@ -440,7 +438,13 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
440 } 438 }
441 dd->ipath_pcirev = rev; 439 dd->ipath_pcirev = rev;
442 440
441#if defined(__powerpc__)
442 /* There isn't a generic way to specify writethrough mappings */
443 dd->ipath_kregbase = __ioremap(addr, len,
444 (_PAGE_NO_CACHE|_PAGE_WRITETHRU));
445#else
443 dd->ipath_kregbase = ioremap_nocache(addr, len); 446 dd->ipath_kregbase = ioremap_nocache(addr, len);
447#endif
444 448
445 if (!dd->ipath_kregbase) { 449 if (!dd->ipath_kregbase) {
446 ipath_dbg("Unable to map io addr %llx to kvirt, failing\n", 450 ipath_dbg("Unable to map io addr %llx to kvirt, failing\n",
@@ -503,7 +507,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
503 ipathfs_add_device(dd); 507 ipathfs_add_device(dd);
504 ipath_user_add(dd); 508 ipath_user_add(dd);
505 ipath_diag_add(dd); 509 ipath_diag_add(dd);
506 ipath_layer_add(dd); 510 ipath_register_ib_device(dd);
507 511
508 goto bail; 512 goto bail;
509 513
@@ -532,7 +536,7 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev)
532 return; 536 return;
533 537
534 dd = pci_get_drvdata(pdev); 538 dd = pci_get_drvdata(pdev);
535 ipath_layer_remove(dd); 539 ipath_unregister_ib_device(dd->verbs_dev);
536 ipath_diag_remove(dd); 540 ipath_diag_remove(dd);
537 ipath_user_remove(dd); 541 ipath_user_remove(dd);
538 ipathfs_remove_device(dd); 542 ipathfs_remove_device(dd);
@@ -607,21 +611,23 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
607 * 611 *
608 * wait up to msecs milliseconds for IB link state change to occur for 612 * wait up to msecs milliseconds for IB link state change to occur for
609 * now, take the easy polling route. Currently used only by 613 * now, take the easy polling route. Currently used only by
610 * ipath_layer_set_linkstate. Returns 0 if state reached, otherwise 614 * ipath_set_linkstate. Returns 0 if state reached, otherwise
611 * -ETIMEDOUT state can have multiple states set, for any of several 615 * -ETIMEDOUT state can have multiple states set, for any of several
612 * transitions. 616 * transitions.
613 */ 617 */
614int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, int msecs) 618static int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state,
619 int msecs)
615{ 620{
616 dd->ipath_sma_state_wanted = state; 621 dd->ipath_state_wanted = state;
617 wait_event_interruptible_timeout(ipath_sma_state_wait, 622 wait_event_interruptible_timeout(ipath_state_wait,
618 (dd->ipath_flags & state), 623 (dd->ipath_flags & state),
619 msecs_to_jiffies(msecs)); 624 msecs_to_jiffies(msecs));
620 dd->ipath_sma_state_wanted = 0; 625 dd->ipath_state_wanted = 0;
621 626
622 if (!(dd->ipath_flags & state)) { 627 if (!(dd->ipath_flags & state)) {
623 u64 val; 628 u64 val;
624 ipath_cdbg(SMA, "Didn't reach linkstate %s within %u ms\n", 629 ipath_cdbg(VERBOSE, "Didn't reach linkstate %s within %u"
630 " ms\n",
625 /* test INIT ahead of DOWN, both can be set */ 631 /* test INIT ahead of DOWN, both can be set */
626 (state & IPATH_LINKINIT) ? "INIT" : 632 (state & IPATH_LINKINIT) ? "INIT" :
627 ((state & IPATH_LINKDOWN) ? "DOWN" : 633 ((state & IPATH_LINKDOWN) ? "DOWN" :
@@ -807,58 +813,6 @@ bail:
807 return skb; 813 return skb;
808} 814}
809 815
810/**
811 * ipath_rcv_layer - receive a packet for the layered (ethernet) driver
812 * @dd: the infinipath device
813 * @etail: the sk_buff number
814 * @tlen: the total packet length
815 * @hdr: the ethernet header
816 *
817 * Separate routine for better overall optimization
818 */
819static void ipath_rcv_layer(struct ipath_devdata *dd, u32 etail,
820 u32 tlen, struct ether_header *hdr)
821{
822 u32 elen;
823 u8 pad, *bthbytes;
824 struct sk_buff *skb, *nskb;
825
826 if (dd->ipath_port0_skbs &&
827 hdr->sub_opcode == IPATH_ITH4X_OPCODE_ENCAP) {
828 /*
829 * Allocate a new sk_buff to replace the one we give
830 * to the network stack.
831 */
832 nskb = ipath_alloc_skb(dd, GFP_ATOMIC);
833 if (!nskb) {
834 /* count OK packets that we drop */
835 ipath_stats.sps_krdrops++;
836 return;
837 }
838
839 bthbytes = (u8 *) hdr->bth;
840 pad = (bthbytes[1] >> 4) & 3;
841 /* +CRC32 */
842 elen = tlen - (sizeof(*hdr) + pad + sizeof(u32));
843
844 skb = dd->ipath_port0_skbs[etail];
845 dd->ipath_port0_skbs[etail] = nskb;
846 skb_put(skb, elen);
847
848 dd->ipath_f_put_tid(dd, etail + (u64 __iomem *)
849 ((char __iomem *) dd->ipath_kregbase
850 + dd->ipath_rcvegrbase), 0,
851 virt_to_phys(nskb->data));
852
853 __ipath_layer_rcv(dd, hdr, skb);
854
855 /* another ether packet received */
856 ipath_stats.sps_ether_rpkts++;
857 }
858 else if (hdr->sub_opcode == IPATH_ITH4X_OPCODE_LID_ARP)
859 __ipath_layer_rcv_lid(dd, hdr);
860}
861
862static void ipath_rcv_hdrerr(struct ipath_devdata *dd, 816static void ipath_rcv_hdrerr(struct ipath_devdata *dd,
863 u32 eflags, 817 u32 eflags,
864 u32 l, 818 u32 l,
@@ -972,26 +926,17 @@ reloop:
972 if (unlikely(eflags)) 926 if (unlikely(eflags))
973 ipath_rcv_hdrerr(dd, eflags, l, etail, rc); 927 ipath_rcv_hdrerr(dd, eflags, l, etail, rc);
974 else if (etype == RCVHQ_RCV_TYPE_NON_KD) { 928 else if (etype == RCVHQ_RCV_TYPE_NON_KD) {
975 int ret = __ipath_verbs_rcv(dd, rc + 1, 929 ipath_ib_rcv(dd->verbs_dev, rc + 1, ebuf, tlen);
976 ebuf, tlen); 930 if (dd->ipath_lli_counter)
977 if (ret == -ENODEV) 931 dd->ipath_lli_counter--;
978 ipath_cdbg(VERBOSE, 932 ipath_cdbg(PKT, "typ %x, opcode %x (eager, "
979 "received IB packet, " 933 "qp=%x), len %x; ignored\n",
980 "not SMA (QP=%x)\n", qp); 934 etype, bthbytes[0], qp, tlen);
981 if (dd->ipath_lli_counter)
982 dd->ipath_lli_counter--;
983
984 } else if (etype == RCVHQ_RCV_TYPE_EAGER) {
985 if (qp == IPATH_KD_QP &&
986 bthbytes[0] == ipath_layer_rcv_opcode &&
987 ebuf)
988 ipath_rcv_layer(dd, etail, tlen,
989 (struct ether_header *)hdr);
990 else
991 ipath_cdbg(PKT, "typ %x, opcode %x (eager, "
992 "qp=%x), len %x; ignored\n",
993 etype, bthbytes[0], qp, tlen);
994 } 935 }
936 else if (etype == RCVHQ_RCV_TYPE_EAGER)
937 ipath_cdbg(PKT, "typ %x, opcode %x (eager, "
938 "qp=%x), len %x; ignored\n",
939 etype, bthbytes[0], qp, tlen);
995 else if (etype == RCVHQ_RCV_TYPE_EXPECTED) 940 else if (etype == RCVHQ_RCV_TYPE_EXPECTED)
996 ipath_dbg("Bug: Expected TID, opcode %x; ignored\n", 941 ipath_dbg("Bug: Expected TID, opcode %x; ignored\n",
997 be32_to_cpu(hdr->bth[0]) & 0xff); 942 be32_to_cpu(hdr->bth[0]) & 0xff);
@@ -1024,7 +969,8 @@ reloop:
1024 */ 969 */
1025 if (l == hdrqtail || (i && !(i&0xf))) { 970 if (l == hdrqtail || (i && !(i&0xf))) {
1026 u64 lval; 971 u64 lval;
1027 if (l == hdrqtail) /* PE-800 interrupt only on last */ 972 if (l == hdrqtail)
973 /* request IBA6120 interrupt only on last */
1028 lval = dd->ipath_rhdrhead_intr_off | l; 974 lval = dd->ipath_rhdrhead_intr_off | l;
1029 else 975 else
1030 lval = l; 976 lval = l;
@@ -1038,7 +984,7 @@ reloop:
1038 } 984 }
1039 985
1040 if (!dd->ipath_rhdrhead_intr_off && !reloop) { 986 if (!dd->ipath_rhdrhead_intr_off && !reloop) {
1041 /* HT-400 workaround; we can have a race clearing chip 987 /* IBA6110 workaround; we can have a race clearing chip
1042 * interrupt with another interrupt about to be delivered, 988 * interrupt with another interrupt about to be delivered,
1043 * and can clear it before it is delivered on the GPIO 989 * and can clear it before it is delivered on the GPIO
1044 * workaround. By doing the extra check here for the 990 * workaround. By doing the extra check here for the
@@ -1211,7 +1157,7 @@ int ipath_setrcvhdrsize(struct ipath_devdata *dd, unsigned rhdrsize)
1211 * 1157 *
1212 * do appropriate marking as busy, etc. 1158 * do appropriate marking as busy, etc.
1213 * returns buffer number if one found (>=0), negative number is error. 1159 * returns buffer number if one found (>=0), negative number is error.
1214 * Used by ipath_sma_send_pkt and ipath_layer_send 1160 * Used by ipath_layer_send
1215 */ 1161 */
1216u32 __iomem *ipath_getpiobuf(struct ipath_devdata *dd, u32 * pbufnum) 1162u32 __iomem *ipath_getpiobuf(struct ipath_devdata *dd, u32 * pbufnum)
1217{ 1163{
@@ -1317,13 +1263,6 @@ rescan:
1317 goto bail; 1263 goto bail;
1318 } 1264 }
1319 1265
1320 if (updated)
1321 /*
1322 * ran out of bufs, now some (at least this one we just
1323 * got) are now available, so tell the layered driver.
1324 */
1325 __ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE);
1326
1327 /* 1266 /*
1328 * set next starting place. Since it's just an optimization, 1267 * set next starting place. Since it's just an optimization,
1329 * it doesn't matter who wins on this, so no locking 1268 * it doesn't matter who wins on this, so no locking
@@ -1500,7 +1439,7 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd)
1500 return ret; 1439 return ret;
1501} 1440}
1502 1441
1503void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) 1442static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1504{ 1443{
1505 static const char *what[4] = { 1444 static const char *what[4] = {
1506 [0] = "DOWN", 1445 [0] = "DOWN",
@@ -1511,7 +1450,7 @@ void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1511 int linkcmd = (which >> INFINIPATH_IBCC_LINKCMD_SHIFT) & 1450 int linkcmd = (which >> INFINIPATH_IBCC_LINKCMD_SHIFT) &
1512 INFINIPATH_IBCC_LINKCMD_MASK; 1451 INFINIPATH_IBCC_LINKCMD_MASK;
1513 1452
1514 ipath_cdbg(SMA, "Trying to move unit %u to %s, current ltstate " 1453 ipath_cdbg(VERBOSE, "Trying to move unit %u to %s, current ltstate "
1515 "is %s\n", dd->ipath_unit, 1454 "is %s\n", dd->ipath_unit,
1516 what[linkcmd], 1455 what[linkcmd],
1517 ipath_ibcstatus_str[ 1456 ipath_ibcstatus_str[
@@ -1520,7 +1459,7 @@ void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1520 INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) & 1459 INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) &
1521 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]); 1460 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]);
1522 /* flush all queued sends when going to DOWN or INIT, to be sure that 1461 /* flush all queued sends when going to DOWN or INIT, to be sure that
1523 * they don't block SMA and other MAD packets */ 1462 * they don't block MAD packets */
1524 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) { 1463 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) {
1525 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 1464 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1526 INFINIPATH_S_ABORT); 1465 INFINIPATH_S_ABORT);
@@ -1534,6 +1473,180 @@ void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1534 dd->ipath_ibcctrl | which); 1473 dd->ipath_ibcctrl | which);
1535} 1474}
1536 1475
1476int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate)
1477{
1478 u32 lstate;
1479 int ret;
1480
1481 switch (newstate) {
1482 case IPATH_IB_LINKDOWN:
1483 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_POLL <<
1484 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
1485 /* don't wait */
1486 ret = 0;
1487 goto bail;
1488
1489 case IPATH_IB_LINKDOWN_SLEEP:
1490 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_SLEEP <<
1491 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
1492 /* don't wait */
1493 ret = 0;
1494 goto bail;
1495
1496 case IPATH_IB_LINKDOWN_DISABLE:
1497 ipath_set_ib_lstate(dd,
1498 INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
1499 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
1500 /* don't wait */
1501 ret = 0;
1502 goto bail;
1503
1504 case IPATH_IB_LINKINIT:
1505 if (dd->ipath_flags & IPATH_LINKINIT) {
1506 ret = 0;
1507 goto bail;
1508 }
1509 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_INIT <<
1510 INFINIPATH_IBCC_LINKCMD_SHIFT);
1511 lstate = IPATH_LINKINIT;
1512 break;
1513
1514 case IPATH_IB_LINKARM:
1515 if (dd->ipath_flags & IPATH_LINKARMED) {
1516 ret = 0;
1517 goto bail;
1518 }
1519 if (!(dd->ipath_flags &
1520 (IPATH_LINKINIT | IPATH_LINKACTIVE))) {
1521 ret = -EINVAL;
1522 goto bail;
1523 }
1524 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_ARMED <<
1525 INFINIPATH_IBCC_LINKCMD_SHIFT);
1526 /*
1527 * Since the port can transition to ACTIVE by receiving
1528 * a non VL 15 packet, wait for either state.
1529 */
1530 lstate = IPATH_LINKARMED | IPATH_LINKACTIVE;
1531 break;
1532
1533 case IPATH_IB_LINKACTIVE:
1534 if (dd->ipath_flags & IPATH_LINKACTIVE) {
1535 ret = 0;
1536 goto bail;
1537 }
1538 if (!(dd->ipath_flags & IPATH_LINKARMED)) {
1539 ret = -EINVAL;
1540 goto bail;
1541 }
1542 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_ACTIVE <<
1543 INFINIPATH_IBCC_LINKCMD_SHIFT);
1544 lstate = IPATH_LINKACTIVE;
1545 break;
1546
1547 default:
1548 ipath_dbg("Invalid linkstate 0x%x requested\n", newstate);
1549 ret = -EINVAL;
1550 goto bail;
1551 }
1552 ret = ipath_wait_linkstate(dd, lstate, 2000);
1553
1554bail:
1555 return ret;
1556}
1557
1558/**
1559 * ipath_set_mtu - set the MTU
1560 * @dd: the infinipath device
1561 * @arg: the new MTU
1562 *
1563 * we can handle "any" incoming size, the issue here is whether we
1564 * need to restrict our outgoing size. For now, we don't do any
1565 * sanity checking on this, and we don't deal with what happens to
1566 * programs that are already running when the size changes.
1567 * NOTE: changing the MTU will usually cause the IBC to go back to
1568 * link initialize (IPATH_IBSTATE_INIT) state...
1569 */
1570int ipath_set_mtu(struct ipath_devdata *dd, u16 arg)
1571{
1572 u32 piosize;
1573 int changed = 0;
1574 int ret;
1575
1576 /*
1577 * mtu is IB data payload max. It's the largest power of 2 less
1578 * than piosize (or even larger, since it only really controls the
1579 * largest we can receive; we can send the max of the mtu and
1580 * piosize). We check that it's one of the valid IB sizes.
1581 */
1582 if (arg != 256 && arg != 512 && arg != 1024 && arg != 2048 &&
1583 arg != 4096) {
1584 ipath_dbg("Trying to set invalid mtu %u, failing\n", arg);
1585 ret = -EINVAL;
1586 goto bail;
1587 }
1588 if (dd->ipath_ibmtu == arg) {
1589 ret = 0; /* same as current */
1590 goto bail;
1591 }
1592
1593 piosize = dd->ipath_ibmaxlen;
1594 dd->ipath_ibmtu = arg;
1595
1596 if (arg >= (piosize - IPATH_PIO_MAXIBHDR)) {
1597 /* Only if it's not the initial value (or reset to it) */
1598 if (piosize != dd->ipath_init_ibmaxlen) {
1599 dd->ipath_ibmaxlen = piosize;
1600 changed = 1;
1601 }
1602 } else if ((arg + IPATH_PIO_MAXIBHDR) != dd->ipath_ibmaxlen) {
1603 piosize = arg + IPATH_PIO_MAXIBHDR;
1604 ipath_cdbg(VERBOSE, "ibmaxlen was 0x%x, setting to 0x%x "
1605 "(mtu 0x%x)\n", dd->ipath_ibmaxlen, piosize,
1606 arg);
1607 dd->ipath_ibmaxlen = piosize;
1608 changed = 1;
1609 }
1610
1611 if (changed) {
1612 /*
1613 * set the IBC maxpktlength to the size of our pio
1614 * buffers in words
1615 */
1616 u64 ibc = dd->ipath_ibcctrl;
1617 ibc &= ~(INFINIPATH_IBCC_MAXPKTLEN_MASK <<
1618 INFINIPATH_IBCC_MAXPKTLEN_SHIFT);
1619
1620 piosize = piosize - 2 * sizeof(u32); /* ignore pbc */
1621 dd->ipath_ibmaxlen = piosize;
1622 piosize /= sizeof(u32); /* in words */
1623 /*
1624 * for ICRC, which we only send in diag test pkt mode, and
1625 * we don't need to worry about that for mtu
1626 */
1627 piosize += 1;
1628
1629 ibc |= piosize << INFINIPATH_IBCC_MAXPKTLEN_SHIFT;
1630 dd->ipath_ibcctrl = ibc;
1631 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
1632 dd->ipath_ibcctrl);
1633 dd->ipath_f_tidtemplate(dd);
1634 }
1635
1636 ret = 0;
1637
1638bail:
1639 return ret;
1640}
1641
1642int ipath_set_lid(struct ipath_devdata *dd, u32 arg, u8 lmc)
1643{
1644 dd->ipath_lid = arg;
1645 dd->ipath_lmc = lmc;
1646
1647 return 0;
1648}
1649
1537/** 1650/**
1538 * ipath_read_kreg64_port - read a device's per-port 64-bit kernel register 1651 * ipath_read_kreg64_port - read a device's per-port 64-bit kernel register
1539 * @dd: the infinipath device 1652 * @dd: the infinipath device
@@ -1637,13 +1750,6 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
1637 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << 1750 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
1638 INFINIPATH_IBCC_LINKINITCMD_SHIFT); 1751 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
1639 1752
1640 /*
1641 * we are shutting down, so tell the layered driver. We don't do
1642 * this on just a link state change, much like ethernet, a cable
1643 * unplug, etc. doesn't change driver state
1644 */
1645 ipath_layer_intr(dd, IPATH_LAYER_INT_IF_DOWN);
1646
1647 /* disable IBC */ 1753 /* disable IBC */
1648 dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; 1754 dd->ipath_control &= ~INFINIPATH_C_LINKENABLE;
1649 ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 1755 ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
@@ -1743,7 +1849,7 @@ static int __init infinipath_init(void)
1743{ 1849{
1744 int ret; 1850 int ret;
1745 1851
1746 ipath_dbg(KERN_INFO DRIVER_LOAD_MSG "%s", ipath_core_version); 1852 ipath_dbg(KERN_INFO DRIVER_LOAD_MSG "%s", ib_ipath_version);
1747 1853
1748 /* 1854 /*
1749 * These must be called before the driver is registered with 1855 * These must be called before the driver is registered with
@@ -1776,8 +1882,18 @@ static int __init infinipath_init(void)
1776 goto bail_group; 1882 goto bail_group;
1777 } 1883 }
1778 1884
1885 ret = ipath_diagpkt_add();
1886 if (ret < 0) {
1887 printk(KERN_ERR IPATH_DRV_NAME ": Unable to create "
1888 "diag data device: error %d\n", -ret);
1889 goto bail_ipathfs;
1890 }
1891
1779 goto bail; 1892 goto bail;
1780 1893
1894bail_ipathfs:
1895 ipath_exit_ipathfs();
1896
1781bail_group: 1897bail_group:
1782 ipath_driver_remove_group(&ipath_driver.driver); 1898 ipath_driver_remove_group(&ipath_driver.driver);
1783 1899
@@ -1888,6 +2004,8 @@ static void __exit infinipath_cleanup(void)
1888 struct ipath_devdata *dd, *tmp; 2004 struct ipath_devdata *dd, *tmp;
1889 unsigned long flags; 2005 unsigned long flags;
1890 2006
2007 ipath_diagpkt_remove();
2008
1891 ipath_exit_ipathfs(); 2009 ipath_exit_ipathfs();
1892 2010
1893 ipath_driver_remove_group(&ipath_driver.driver); 2011 ipath_driver_remove_group(&ipath_driver.driver);
@@ -1998,5 +2116,22 @@ bail:
1998 return ret; 2116 return ret;
1999} 2117}
2000 2118
2119int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv)
2120{
2121 u64 val;
2122 if ( new_pol_inv > INFINIPATH_XGXS_RX_POL_MASK ) {
2123 return -1;
2124 }
2125 if ( dd->ipath_rx_pol_inv != new_pol_inv ) {
2126 dd->ipath_rx_pol_inv = new_pol_inv;
2127 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig);
2128 val &= ~(INFINIPATH_XGXS_RX_POL_MASK <<
2129 INFINIPATH_XGXS_RX_POL_SHIFT);
2130 val |= ((u64)dd->ipath_rx_pol_inv) <<
2131 INFINIPATH_XGXS_RX_POL_SHIFT;
2132 ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
2133 }
2134 return 0;
2135}
2001module_init(infinipath_init); 2136module_init(infinipath_init);
2002module_exit(infinipath_cleanup); 2137module_exit(infinipath_cleanup);
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index bbaa70e57db1..29930e22318e 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -39,7 +39,6 @@
39#include <asm/pgtable.h> 39#include <asm/pgtable.h>
40 40
41#include "ipath_kernel.h" 41#include "ipath_kernel.h"
42#include "ipath_layer.h"
43#include "ipath_common.h" 42#include "ipath_common.h"
44 43
45static int ipath_open(struct inode *, struct file *); 44static int ipath_open(struct inode *, struct file *);
@@ -985,15 +984,17 @@ static int mmap_piobufs(struct vm_area_struct *vma,
985 * write combining behavior we want on the PIO buffers! 984 * write combining behavior we want on the PIO buffers!
986 */ 985 */
987 986
988 if (vma->vm_flags & VM_READ) { 987#if defined(__powerpc__)
989 dev_info(&dd->pcidev->dev, 988 /* There isn't a generic way to specify writethrough mappings */
990 "Can't map piobufs as readable (flags=%lx)\n", 989 pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
991 vma->vm_flags); 990 pgprot_val(vma->vm_page_prot) |= _PAGE_WRITETHRU;
992 ret = -EPERM; 991 pgprot_val(vma->vm_page_prot) &= ~_PAGE_GUARDED;
993 goto bail; 992#endif
994 }
995 993
996 /* don't allow them to later change to readable with mprotect */ 994 /*
995 * don't allow them to later change to readable with mprotect (for when
996 * not initially mapped readable, as is normally the case)
997 */
997 vma->vm_flags &= ~VM_MAYREAD; 998 vma->vm_flags &= ~VM_MAYREAD;
998 vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; 999 vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND;
999 1000
@@ -1109,7 +1110,7 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
1109 ret = mmap_rcvegrbufs(vma, pd); 1110 ret = mmap_rcvegrbufs(vma, pd);
1110 else if (pgaddr == (u64) pd->port_rcvhdrq_phys) { 1111 else if (pgaddr == (u64) pd->port_rcvhdrq_phys) {
1111 /* 1112 /*
1112 * The rcvhdrq itself; readonly except on HT-400 (so have 1113 * The rcvhdrq itself; readonly except on HT (so have
1113 * to allow writable mapping), multiple pages, contiguous 1114 * to allow writable mapping), multiple pages, contiguous
1114 * from an i/o perspective. 1115 * from an i/o perspective.
1115 */ 1116 */
@@ -1149,6 +1150,7 @@ static unsigned int ipath_poll(struct file *fp,
1149 struct ipath_portdata *pd; 1150 struct ipath_portdata *pd;
1150 u32 head, tail; 1151 u32 head, tail;
1151 int bit; 1152 int bit;
1153 unsigned pollflag = 0;
1152 struct ipath_devdata *dd; 1154 struct ipath_devdata *dd;
1153 1155
1154 pd = port_fp(fp); 1156 pd = port_fp(fp);
@@ -1185,9 +1187,12 @@ static unsigned int ipath_poll(struct file *fp,
1185 clear_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag); 1187 clear_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
1186 pd->port_rcvwait_to++; 1188 pd->port_rcvwait_to++;
1187 } 1189 }
1190 else
1191 pollflag = POLLIN | POLLRDNORM;
1188 } 1192 }
1189 else { 1193 else {
1190 /* it's already happened; don't do wait_event overhead */ 1194 /* it's already happened; don't do wait_event overhead */
1195 pollflag = POLLIN | POLLRDNORM;
1191 pd->port_rcvnowait++; 1196 pd->port_rcvnowait++;
1192 } 1197 }
1193 1198
@@ -1195,7 +1200,7 @@ static unsigned int ipath_poll(struct file *fp,
1195 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, 1200 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
1196 dd->ipath_rcvctrl); 1201 dd->ipath_rcvctrl);
1197 1202
1198 return 0; 1203 return pollflag;
1199} 1204}
1200 1205
1201static int try_alloc_port(struct ipath_devdata *dd, int port, 1206static int try_alloc_port(struct ipath_devdata *dd, int port,
@@ -1297,14 +1302,14 @@ static int find_best_unit(struct file *fp)
1297 * This code is present to allow a knowledgeable person to 1302 * This code is present to allow a knowledgeable person to
1298 * specify the layout of processes to processors before opening 1303 * specify the layout of processes to processors before opening
1299 * this driver, and then we'll assign the process to the "closest" 1304 * this driver, and then we'll assign the process to the "closest"
1300 * HT-400 to that processor (we assume reasonable connectivity, 1305 * InfiniPath chip to that processor (we assume reasonable connectivity,
1301 * for now). This code assumes that if affinity has been set 1306 * for now). This code assumes that if affinity has been set
1302 * before this point, that at most one cpu is set; for now this 1307 * before this point, that at most one cpu is set; for now this
1303 * is reasonable. I check for both cpus_empty() and cpus_full(), 1308 * is reasonable. I check for both cpus_empty() and cpus_full(),
1304 * in case some kernel variant sets none of the bits when no 1309 * in case some kernel variant sets none of the bits when no
1305 * affinity is set. 2.6.11 and 12 kernels have all present 1310 * affinity is set. 2.6.11 and 12 kernels have all present
1306 * cpus set. Some day we'll have to fix it up further to handle 1311 * cpus set. Some day we'll have to fix it up further to handle
1307 * a cpu subset. This algorithm fails for two HT-400's connected 1312 * a cpu subset. This algorithm fails for two HT chips connected
1308 * in tunnel fashion. Eventually this needs real topology 1313 * in tunnel fashion. Eventually this needs real topology
1309 * information. There may be some issues with dual core numbering 1314 * information. There may be some issues with dual core numbering
1310 * as well. This needs more work prior to release. 1315 * as well. This needs more work prior to release.
@@ -1815,7 +1820,7 @@ int ipath_user_add(struct ipath_devdata *dd)
1815 if (ret < 0) { 1820 if (ret < 0) {
1816 ipath_dev_err(dd, "Could not create wildcard " 1821 ipath_dev_err(dd, "Could not create wildcard "
1817 "minor: error %d\n", -ret); 1822 "minor: error %d\n", -ret);
1818 goto bail_sma; 1823 goto bail_user;
1819 } 1824 }
1820 1825
1821 atomic_set(&user_setup, 1); 1826 atomic_set(&user_setup, 1);
@@ -1831,7 +1836,7 @@ int ipath_user_add(struct ipath_devdata *dd)
1831 1836
1832 goto bail; 1837 goto bail;
1833 1838
1834bail_sma: 1839bail_user:
1835 user_cleanup(); 1840 user_cleanup();
1836bail: 1841bail:
1837 return ret; 1842 return ret;
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 0936d8e8d704..a5eb30a06a5c 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -191,8 +191,8 @@ static ssize_t atomic_port_info_read(struct file *file, char __user *buf,
191 portinfo[4] = (dd->ipath_lid << 16); 191 portinfo[4] = (dd->ipath_lid << 16);
192 192
193 /* 193 /*
194 * Notimpl yet SMLID (should we store this in the driver, in case 194 * Notimpl yet SMLID.
195 * SMA dies?) CapabilityMask is 0, we don't support any of these 195 * CapabilityMask is 0, we don't support any of these
196 * DiagCode is 0; we don't store any diag info for now Notimpl yet 196 * DiagCode is 0; we don't store any diag info for now Notimpl yet
197 * M_KeyLeasePeriod (we don't support M_Key) 197 * M_KeyLeasePeriod (we don't support M_Key)
198 */ 198 */
diff --git a/drivers/infiniband/hw/ipath/ipath_ht400.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index 3db015da6e77..bf2455a6d562 100644
--- a/drivers/infiniband/hw/ipath/ipath_ht400.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -33,7 +33,7 @@
33 33
34/* 34/*
35 * This file contains all of the code that is specific to the InfiniPath 35 * This file contains all of the code that is specific to the InfiniPath
36 * HT-400 chip. 36 * HT chip.
37 */ 37 */
38 38
39#include <linux/pci.h> 39#include <linux/pci.h>
@@ -43,7 +43,7 @@
43#include "ipath_registers.h" 43#include "ipath_registers.h"
44 44
45/* 45/*
46 * This lists the InfiniPath HT400 registers, in the actual chip layout. 46 * This lists the InfiniPath registers, in the actual chip layout.
47 * This structure should never be directly accessed. 47 * This structure should never be directly accessed.
48 * 48 *
49 * The names are in InterCap form because they're taken straight from 49 * The names are in InterCap form because they're taken straight from
@@ -461,8 +461,9 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
461 * times. 461 * times.
462 */ 462 */
463 if (dd->ipath_flags & IPATH_INITTED) { 463 if (dd->ipath_flags & IPATH_INITTED) {
464 ipath_dev_err(dd, "Fatal Error (freeze " 464 ipath_dev_err(dd, "Fatal Hardware Error (freeze "
465 "mode), no longer usable\n"); 465 "mode), no longer usable, SN %.16s\n",
466 dd->ipath_serial);
466 isfatal = 1; 467 isfatal = 1;
467 } 468 }
468 *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY; 469 *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY;
@@ -537,7 +538,7 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
537 if (hwerrs & INFINIPATH_HWE_HTCMISCERR7) 538 if (hwerrs & INFINIPATH_HWE_HTCMISCERR7)
538 strlcat(msg, "[HT core Misc7]", msgl); 539 strlcat(msg, "[HT core Misc7]", msgl);
539 if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) { 540 if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) {
540 strlcat(msg, "[Memory BIST test failed, HT-400 unusable]", 541 strlcat(msg, "[Memory BIST test failed, InfiniPath hardware unusable]",
541 msgl); 542 msgl);
542 /* ignore from now on, so disable until driver reloaded */ 543 /* ignore from now on, so disable until driver reloaded */
543 dd->ipath_hwerrmask &= ~INFINIPATH_HWE_MEMBISTFAILED; 544 dd->ipath_hwerrmask &= ~INFINIPATH_HWE_MEMBISTFAILED;
@@ -553,7 +554,7 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
553 554
554 if (hwerrs & _IPATH_PLL_FAIL) { 555 if (hwerrs & _IPATH_PLL_FAIL) {
555 snprintf(bitsmsg, sizeof bitsmsg, 556 snprintf(bitsmsg, sizeof bitsmsg,
556 "[PLL failed (%llx), HT-400 unusable]", 557 "[PLL failed (%llx), InfiniPath hardware unusable]",
557 (unsigned long long) (hwerrs & _IPATH_PLL_FAIL)); 558 (unsigned long long) (hwerrs & _IPATH_PLL_FAIL));
558 strlcat(msg, bitsmsg, msgl); 559 strlcat(msg, bitsmsg, msgl);
559 /* ignore from now on, so disable until driver reloaded */ 560 /* ignore from now on, so disable until driver reloaded */
@@ -610,18 +611,18 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
610 break; 611 break;
611 case 5: 612 case 5:
612 /* 613 /*
613 * HT-460 original production board; two production levels, with 614 * original production board; two production levels, with
614 * different serial number ranges. See ipath_ht_early_init() for 615 * different serial number ranges. See ipath_ht_early_init() for
615 * case where we enable IPATH_GPIO_INTR for later serial # range. 616 * case where we enable IPATH_GPIO_INTR for later serial # range.
616 */ 617 */
617 n = "InfiniPath_HT-460"; 618 n = "InfiniPath_QHT7040";
618 break; 619 break;
619 case 6: 620 case 6:
620 n = "OEM_Board_3"; 621 n = "OEM_Board_3";
621 break; 622 break;
622 case 7: 623 case 7:
623 /* HT-460 small form factor production board */ 624 /* small form factor production board */
624 n = "InfiniPath_HT-465"; 625 n = "InfiniPath_QHT7140";
625 break; 626 break;
626 case 8: 627 case 8:
627 n = "LS/X-1"; 628 n = "LS/X-1";
@@ -633,7 +634,7 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
633 n = "OEM_Board_2"; 634 n = "OEM_Board_2";
634 break; 635 break;
635 case 11: 636 case 11:
636 n = "InfiniPath_HT-470"; 637 n = "InfiniPath_HT-470"; /* obsoleted */
637 break; 638 break;
638 case 12: 639 case 12:
639 n = "OEM_Board_4"; 640 n = "OEM_Board_4";
@@ -641,7 +642,7 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
641 default: /* don't know, just print the number */ 642 default: /* don't know, just print the number */
642 ipath_dev_err(dd, "Don't yet know about board " 643 ipath_dev_err(dd, "Don't yet know about board "
643 "with ID %u\n", boardrev); 644 "with ID %u\n", boardrev);
644 snprintf(name, namelen, "Unknown_InfiniPath_HT-4xx_%u", 645 snprintf(name, namelen, "Unknown_InfiniPath_QHT7xxx_%u",
645 boardrev); 646 boardrev);
646 break; 647 break;
647 } 648 }
@@ -650,11 +651,10 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
650 651
651 if (dd->ipath_majrev != 3 || (dd->ipath_minrev < 2 || dd->ipath_minrev > 3)) { 652 if (dd->ipath_majrev != 3 || (dd->ipath_minrev < 2 || dd->ipath_minrev > 3)) {
652 /* 653 /*
653 * This version of the driver only supports the HT-400 654 * This version of the driver only supports Rev 3.2 and 3.3
654 * Rev 3.2
655 */ 655 */
656 ipath_dev_err(dd, 656 ipath_dev_err(dd,
657 "Unsupported HT-400 revision %u.%u!\n", 657 "Unsupported InfiniPath hardware revision %u.%u!\n",
658 dd->ipath_majrev, dd->ipath_minrev); 658 dd->ipath_majrev, dd->ipath_minrev);
659 ret = 1; 659 ret = 1;
660 goto bail; 660 goto bail;
@@ -738,7 +738,7 @@ static void ipath_check_htlink(struct ipath_devdata *dd)
738 738
739static int ipath_setup_ht_reset(struct ipath_devdata *dd) 739static int ipath_setup_ht_reset(struct ipath_devdata *dd)
740{ 740{
741 ipath_dbg("No reset possible for HT-400\n"); 741 ipath_dbg("No reset possible for this InfiniPath hardware\n");
742 return 0; 742 return 0;
743} 743}
744 744
@@ -925,7 +925,7 @@ static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev,
925 925
926 /* 926 /*
927 * kernels with CONFIG_PCI_MSI set the vector in the irq field of 927 * kernels with CONFIG_PCI_MSI set the vector in the irq field of
928 * struct pci_device, so we use that to program the HT-400 internal 928 * struct pci_device, so we use that to program the internal
929 * interrupt register (not config space) with that value. The BIOS 929 * interrupt register (not config space) with that value. The BIOS
930 * must still have done the basic MSI setup. 930 * must still have done the basic MSI setup.
931 */ 931 */
@@ -1013,7 +1013,7 @@ bail:
1013 * @dd: the infinipath device 1013 * @dd: the infinipath device
1014 * 1014 *
1015 * Called during driver unload. 1015 * Called during driver unload.
1016 * This is currently a nop for the HT-400, not for all chips 1016 * This is currently a nop for the HT chip, not for all chips
1017 */ 1017 */
1018static void ipath_setup_ht_cleanup(struct ipath_devdata *dd) 1018static void ipath_setup_ht_cleanup(struct ipath_devdata *dd)
1019{ 1019{
@@ -1290,6 +1290,15 @@ static int ipath_ht_bringup_serdes(struct ipath_devdata *dd)
1290 val &= ~INFINIPATH_XGXS_RESET; 1290 val &= ~INFINIPATH_XGXS_RESET;
1291 change = 1; 1291 change = 1;
1292 } 1292 }
1293 if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) &
1294 INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) {
1295 /* need to compensate for Tx inversion in partner */
1296 val &= ~(INFINIPATH_XGXS_RX_POL_MASK <<
1297 INFINIPATH_XGXS_RX_POL_SHIFT);
1298 val |= dd->ipath_rx_pol_inv <<
1299 INFINIPATH_XGXS_RX_POL_SHIFT;
1300 change = 1;
1301 }
1293 if (change) 1302 if (change)
1294 ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); 1303 ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
1295 1304
@@ -1470,7 +1479,7 @@ static int ipath_ht_early_init(struct ipath_devdata *dd)
1470 dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; 1479 dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE;
1471 1480
1472 /* 1481 /*
1473 * For HT-400, we allocate a somewhat overly large eager buffer, 1482 * For HT, we allocate a somewhat overly large eager buffer,
1474 * such that we can guarantee that we can receive the largest 1483 * such that we can guarantee that we can receive the largest
1475 * packet that we can send out. To truly support a 4KB MTU, 1484 * packet that we can send out. To truly support a 4KB MTU,
1476 * we need to bump this to a large value. To date, other than 1485 * we need to bump this to a large value. To date, other than
@@ -1531,7 +1540,7 @@ static int ipath_ht_early_init(struct ipath_devdata *dd)
1531 if(dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' && 1540 if(dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' &&
1532 dd->ipath_serial[1] == '2' && dd->ipath_serial[2] == '8') { 1541 dd->ipath_serial[1] == '2' && dd->ipath_serial[2] == '8') {
1533 /* 1542 /*
1534 * Later production HT-460 has same changes as HT-465, so 1543 * Later production QHT7040 has same changes as QHT7140, so
1535 * can use GPIO interrupts. They have serial #'s starting 1544 * can use GPIO interrupts. They have serial #'s starting
1536 * with 128, rather than 112. 1545 * with 128, rather than 112.
1537 */ 1546 */
@@ -1560,13 +1569,13 @@ static int ipath_ht_get_base_info(struct ipath_portdata *pd, void *kbase)
1560} 1569}
1561 1570
1562/** 1571/**
1563 * ipath_init_ht400_funcs - set up the chip-specific function pointers 1572 * ipath_init_iba6110_funcs - set up the chip-specific function pointers
1564 * @dd: the infinipath device 1573 * @dd: the infinipath device
1565 * 1574 *
1566 * This is global, and is called directly at init to set up the 1575 * This is global, and is called directly at init to set up the
1567 * chip-specific function pointers for later use. 1576 * chip-specific function pointers for later use.
1568 */ 1577 */
1569void ipath_init_ht400_funcs(struct ipath_devdata *dd) 1578void ipath_init_iba6110_funcs(struct ipath_devdata *dd)
1570{ 1579{
1571 dd->ipath_f_intrsetup = ipath_ht_intconfig; 1580 dd->ipath_f_intrsetup = ipath_ht_intconfig;
1572 dd->ipath_f_bus = ipath_setup_ht_config; 1581 dd->ipath_f_bus = ipath_setup_ht_config;
diff --git a/drivers/infiniband/hw/ipath/ipath_pe800.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index b83f66d8262c..d86516d23df6 100644
--- a/drivers/infiniband/hw/ipath/ipath_pe800.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -32,7 +32,7 @@
32 */ 32 */
33/* 33/*
34 * This file contains all of the code that is specific to the 34 * This file contains all of the code that is specific to the
35 * InfiniPath PE-800 chip. 35 * InfiniPath PCIe chip.
36 */ 36 */
37 37
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
@@ -45,9 +45,9 @@
45 45
46/* 46/*
47 * This file contains all the chip-specific register information and 47 * This file contains all the chip-specific register information and
48 * access functions for the QLogic InfiniPath PE800, the PCI-Express chip. 48 * access functions for the QLogic InfiniPath PCI-Express chip.
49 * 49 *
50 * This lists the InfiniPath PE800 registers, in the actual chip layout. 50 * This lists the InfiniPath registers, in the actual chip layout.
51 * This structure should never be directly accessed. 51 * This structure should never be directly accessed.
52 */ 52 */
53struct _infinipath_do_not_use_kernel_regs { 53struct _infinipath_do_not_use_kernel_regs {
@@ -213,7 +213,6 @@ static const struct ipath_kregs ipath_pe_kregs = {
213 .kr_rcvhdraddr = IPATH_KREG_OFFSET(RcvHdrAddr0), 213 .kr_rcvhdraddr = IPATH_KREG_OFFSET(RcvHdrAddr0),
214 .kr_rcvhdrtailaddr = IPATH_KREG_OFFSET(RcvHdrTailAddr0), 214 .kr_rcvhdrtailaddr = IPATH_KREG_OFFSET(RcvHdrTailAddr0),
215 215
216 /* This group is pe-800-specific; and used only in this file */
217 /* The rcvpktled register controls one of the debug port signals, so 216 /* The rcvpktled register controls one of the debug port signals, so
218 * a packet activity LED can be connected to it. */ 217 * a packet activity LED can be connected to it. */
219 .kr_rcvpktledcnt = IPATH_KREG_OFFSET(RcvPktLEDCnt), 218 .kr_rcvpktledcnt = IPATH_KREG_OFFSET(RcvPktLEDCnt),
@@ -364,8 +363,9 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
364 * and we get here multiple times 363 * and we get here multiple times
365 */ 364 */
366 if (dd->ipath_flags & IPATH_INITTED) { 365 if (dd->ipath_flags & IPATH_INITTED) {
367 ipath_dev_err(dd, "Fatal Error (freeze " 366 ipath_dev_err(dd, "Fatal Hardware Error (freeze "
368 "mode), no longer usable\n"); 367 "mode), no longer usable, SN %.16s\n",
368 dd->ipath_serial);
369 isfatal = 1; 369 isfatal = 1;
370 } 370 }
371 /* 371 /*
@@ -388,7 +388,7 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
388 *msg = '\0'; 388 *msg = '\0';
389 389
390 if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) { 390 if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) {
391 strlcat(msg, "[Memory BIST test failed, PE-800 unusable]", 391 strlcat(msg, "[Memory BIST test failed, InfiniPath hardware unusable]",
392 msgl); 392 msgl);
393 /* ignore from now on, so disable until driver reloaded */ 393 /* ignore from now on, so disable until driver reloaded */
394 *dd->ipath_statusp |= IPATH_STATUS_HWERROR; 394 *dd->ipath_statusp |= IPATH_STATUS_HWERROR;
@@ -433,7 +433,7 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
433 433
434 if (hwerrs & _IPATH_PLL_FAIL) { 434 if (hwerrs & _IPATH_PLL_FAIL) {
435 snprintf(bitsmsg, sizeof bitsmsg, 435 snprintf(bitsmsg, sizeof bitsmsg,
436 "[PLL failed (%llx), PE-800 unusable]", 436 "[PLL failed (%llx), InfiniPath hardware unusable]",
437 (unsigned long long) hwerrs & _IPATH_PLL_FAIL); 437 (unsigned long long) hwerrs & _IPATH_PLL_FAIL);
438 strlcat(msg, bitsmsg, msgl); 438 strlcat(msg, bitsmsg, msgl);
439 /* ignore from now on, so disable until driver reloaded */ 439 /* ignore from now on, so disable until driver reloaded */
@@ -511,22 +511,25 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name,
511 n = "InfiniPath_Emulation"; 511 n = "InfiniPath_Emulation";
512 break; 512 break;
513 case 1: 513 case 1:
514 n = "InfiniPath_PE-800-Bringup"; 514 n = "InfiniPath_QLE7140-Bringup";
515 break; 515 break;
516 case 2: 516 case 2:
517 n = "InfiniPath_PE-880"; 517 n = "InfiniPath_QLE7140";
518 break; 518 break;
519 case 3: 519 case 3:
520 n = "InfiniPath_PE-850"; 520 n = "InfiniPath_QMI7140";
521 break; 521 break;
522 case 4: 522 case 4:
523 n = "InfiniPath_PE-860"; 523 n = "InfiniPath_QEM7140";
524 break;
525 case 5:
526 n = "InfiniPath_QMH7140";
524 break; 527 break;
525 default: 528 default:
526 ipath_dev_err(dd, 529 ipath_dev_err(dd,
527 "Don't yet know about board with ID %u\n", 530 "Don't yet know about board with ID %u\n",
528 boardrev); 531 boardrev);
529 snprintf(name, namelen, "Unknown_InfiniPath_PE-8xx_%u", 532 snprintf(name, namelen, "Unknown_InfiniPath_PCIe_%u",
530 boardrev); 533 boardrev);
531 break; 534 break;
532 } 535 }
@@ -534,7 +537,7 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name,
534 snprintf(name, namelen, "%s", n); 537 snprintf(name, namelen, "%s", n);
535 538
536 if (dd->ipath_majrev != 4 || !dd->ipath_minrev || dd->ipath_minrev>2) { 539 if (dd->ipath_majrev != 4 || !dd->ipath_minrev || dd->ipath_minrev>2) {
537 ipath_dev_err(dd, "Unsupported PE-800 revision %u.%u!\n", 540 ipath_dev_err(dd, "Unsupported InfiniPath hardware revision %u.%u!\n",
538 dd->ipath_majrev, dd->ipath_minrev); 541 dd->ipath_majrev, dd->ipath_minrev);
539 ret = 1; 542 ret = 1;
540 } else 543 } else
@@ -651,6 +654,15 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
651 val &= ~INFINIPATH_XGXS_RESET; 654 val &= ~INFINIPATH_XGXS_RESET;
652 change = 1; 655 change = 1;
653 } 656 }
657 if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) &
658 INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) {
659 /* need to compensate for Tx inversion in partner */
660 val &= ~(INFINIPATH_XGXS_RX_POL_MASK <<
661 INFINIPATH_XGXS_RX_POL_SHIFT);
662 val |= dd->ipath_rx_pol_inv <<
663 INFINIPATH_XGXS_RX_POL_SHIFT;
664 change = 1;
665 }
654 if (change) 666 if (change)
655 ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); 667 ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
656 668
@@ -705,7 +717,7 @@ static void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
705 ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); 717 ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
706} 718}
707 719
708/* this is not yet needed on the PE800, so just return 0. */ 720/* this is not yet needed on this chip, so just return 0. */
709static int ipath_pe_intconfig(struct ipath_devdata *dd) 721static int ipath_pe_intconfig(struct ipath_devdata *dd)
710{ 722{
711 return 0; 723 return 0;
@@ -759,8 +771,8 @@ static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst,
759 * 771 *
760 * This is called during driver unload. 772 * This is called during driver unload.
761 * We do the pci_disable_msi here, not in generic code, because it 773 * We do the pci_disable_msi here, not in generic code, because it
762 * isn't used for the HT-400. If we do end up needing pci_enable_msi 774 * isn't used for the HT chips. If we do end up needing pci_enable_msi
763 * at some point in the future for HT-400, we'll move the call back 775 * at some point in the future for HT, we'll move the call back
764 * into the main init_one code. 776 * into the main init_one code.
765 */ 777 */
766static void ipath_setup_pe_cleanup(struct ipath_devdata *dd) 778static void ipath_setup_pe_cleanup(struct ipath_devdata *dd)
@@ -780,10 +792,10 @@ static void ipath_setup_pe_cleanup(struct ipath_devdata *dd)
780 * late in 2.6.16). 792 * late in 2.6.16).
781 * All that can be done is to edit the kernel source to remove the quirk 793 * All that can be done is to edit the kernel source to remove the quirk
782 * check until that is fixed. 794 * check until that is fixed.
783 * We do not need to call enable_msi() for our HyperTransport chip (HT-400), 795 * We do not need to call enable_msi() for our HyperTransport chip,
784 * even those it uses MSI, and we want to avoid the quirk warning, so 796 * even though it uses MSI, and we want to avoid the quirk warning, so
785 * So we call enable_msi only for the PE-800. If we do end up needing 797 * So we call enable_msi only for PCIe. If we do end up needing
786 * pci_enable_msi at some point in the future for HT-400, we'll move the 798 * pci_enable_msi at some point in the future for HT, we'll move the
787 * call back into the main init_one code. 799 * call back into the main init_one code.
788 * We save the msi lo and hi values, so we can restore them after 800 * We save the msi lo and hi values, so we can restore them after
789 * chip reset (the kernel PCI infrastructure doesn't yet handle that 801 * chip reset (the kernel PCI infrastructure doesn't yet handle that
@@ -971,8 +983,7 @@ static int ipath_setup_pe_reset(struct ipath_devdata *dd)
971 int ret; 983 int ret;
972 984
973 /* Use ERROR so it shows up in logs, etc. */ 985 /* Use ERROR so it shows up in logs, etc. */
974 ipath_dev_err(dd, "Resetting PE-800 unit %u\n", 986 ipath_dev_err(dd, "Resetting InfiniPath unit %u\n", dd->ipath_unit);
975 dd->ipath_unit);
976 /* keep chip from being accessed in a few places */ 987 /* keep chip from being accessed in a few places */
977 dd->ipath_flags &= ~(IPATH_INITTED|IPATH_PRESENT); 988 dd->ipath_flags &= ~(IPATH_INITTED|IPATH_PRESENT);
978 val = dd->ipath_control | INFINIPATH_C_RESET; 989 val = dd->ipath_control | INFINIPATH_C_RESET;
@@ -1078,7 +1089,7 @@ static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
1078 * @port: the port 1089 * @port: the port
1079 * 1090 *
1080 * clear all TID entries for a port, expected and eager. 1091 * clear all TID entries for a port, expected and eager.
1081 * Used from ipath_close(). On PE800, TIDs are only 32 bits, 1092 * Used from ipath_close(). On this chip, TIDs are only 32 bits,
1082 * not 64, but they are still on 64 bit boundaries, so tidbase 1093 * not 64, but they are still on 64 bit boundaries, so tidbase
1083 * is declared as u64 * for the pointer math, even though we write 32 bits 1094 * is declared as u64 * for the pointer math, even though we write 32 bits
1084 */ 1095 */
@@ -1148,9 +1159,9 @@ static int ipath_pe_early_init(struct ipath_devdata *dd)
1148 dd->ipath_flags |= IPATH_4BYTE_TID; 1159 dd->ipath_flags |= IPATH_4BYTE_TID;
1149 1160
1150 /* 1161 /*
1151 * For openib, we need to be able to handle an IB header of 96 bytes 1162 * For openfabrics, we need to be able to handle an IB header of
1152 * or 24 dwords. HT-400 has arbitrary sized receive buffers, so we 1163 * 24 dwords. HT chip has arbitrary sized receive buffers, so we
1153 * made them the same size as the PIO buffers. The PE-800 does not 1164 * made them the same size as the PIO buffers. This chip does not
1154 * handle arbitrary size buffers, so we need the header large enough 1165 * handle arbitrary size buffers, so we need the header large enough
1155 * to handle largest IB header, but still have room for a 2KB MTU 1166 * to handle largest IB header, but still have room for a 2KB MTU
1156 * standard IB packet. 1167 * standard IB packet.
@@ -1158,11 +1169,10 @@ static int ipath_pe_early_init(struct ipath_devdata *dd)
1158 dd->ipath_rcvhdrentsize = 24; 1169 dd->ipath_rcvhdrentsize = 24;
1159 dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; 1170 dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE;
1160 1171
1161 /* For HT-400, we allocate a somewhat overly large eager buffer, 1172 /*
1162 * such that we can guarantee that we can receive the largest packet 1173 * To truly support a 4KB MTU (for usermode), we need to
1163 * that we can send out. To truly support a 4KB MTU, we need to 1174 * bump this to a larger value. For now, we use them for
1164 * bump this to a larger value. We'll do this when I get around to 1175 * the kernel only.
1165 * testing 4KB sends on the PE-800, which I have not yet done.
1166 */ 1176 */
1167 dd->ipath_rcvegrbufsize = 2048; 1177 dd->ipath_rcvegrbufsize = 2048;
1168 /* 1178 /*
@@ -1175,9 +1185,9 @@ static int ipath_pe_early_init(struct ipath_devdata *dd)
1175 dd->ipath_init_ibmaxlen = dd->ipath_ibmaxlen; 1185 dd->ipath_init_ibmaxlen = dd->ipath_ibmaxlen;
1176 1186
1177 /* 1187 /*
1178 * For PE-800, we can request a receive interrupt for 1 or 1188 * We can request a receive interrupt for 1 or
1179 * more packets from current offset. For now, we set this 1189 * more packets from current offset. For now, we set this
1180 * up for a single packet, to match the HT-400 behavior. 1190 * up for a single packet.
1181 */ 1191 */
1182 dd->ipath_rhdrhead_intr_off = 1ULL<<32; 1192 dd->ipath_rhdrhead_intr_off = 1ULL<<32;
1183 1193
@@ -1216,13 +1226,13 @@ static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
1216} 1226}
1217 1227
1218/** 1228/**
1219 * ipath_init_pe800_funcs - set up the chip-specific function pointers 1229 * ipath_init_iba6120_funcs - set up the chip-specific function pointers
1220 * @dd: the infinipath device 1230 * @dd: the infinipath device
1221 * 1231 *
1222 * This is global, and is called directly at init to set up the 1232 * This is global, and is called directly at init to set up the
1223 * chip-specific function pointers for later use. 1233 * chip-specific function pointers for later use.
1224 */ 1234 */
1225void ipath_init_pe800_funcs(struct ipath_devdata *dd) 1235void ipath_init_iba6120_funcs(struct ipath_devdata *dd)
1226{ 1236{
1227 dd->ipath_f_intrsetup = ipath_pe_intconfig; 1237 dd->ipath_f_intrsetup = ipath_pe_intconfig;
1228 dd->ipath_f_bus = ipath_setup_pe_config; 1238 dd->ipath_f_bus = ipath_setup_pe_config;
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 414cdd1d80a6..44669dc2e22d 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -53,8 +53,8 @@ module_param_named(cfgports, ipath_cfgports, ushort, S_IRUGO);
53MODULE_PARM_DESC(cfgports, "Set max number of ports to use"); 53MODULE_PARM_DESC(cfgports, "Set max number of ports to use");
54 54
55/* 55/*
56 * Number of buffers reserved for driver (layered drivers and SMA 56 * Number of buffers reserved for driver (verbs and layered drivers.)
57 * send). Reserved at end of buffer list. Initialized based on 57 * Reserved at end of buffer list. Initialized based on
58 * number of PIO buffers if not set via module interface. 58 * number of PIO buffers if not set via module interface.
59 * The problem with this is that it's global, but we'll use different 59 * The problem with this is that it's global, but we'll use different
60 * numbers for different chip types. So the default value is not 60 * numbers for different chip types. So the default value is not
@@ -80,7 +80,7 @@ MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver");
80 * 80 *
81 * Allocate the eager TID buffers and program them into infinipath. 81 * Allocate the eager TID buffers and program them into infinipath.
82 * We use the network layer alloc_skb() allocator to allocate the 82 * We use the network layer alloc_skb() allocator to allocate the
83 * memory, and either use the buffers as is for things like SMA 83 * memory, and either use the buffers as is for things like verbs
84 * packets, or pass the buffers up to the ipath layered driver and 84 * packets, or pass the buffers up to the ipath layered driver and
85 * thence the network layer, replacing them as we do so (see 85 * thence the network layer, replacing them as we do so (see
86 * ipath_rcv_layer()). 86 * ipath_rcv_layer()).
@@ -240,7 +240,11 @@ static int init_chip_first(struct ipath_devdata *dd,
240 "only supports %u\n", ipath_cfgports, 240 "only supports %u\n", ipath_cfgports,
241 dd->ipath_portcnt); 241 dd->ipath_portcnt);
242 } 242 }
243 dd->ipath_pd = kzalloc(sizeof(*dd->ipath_pd) * dd->ipath_cfgports, 243 /*
244 * Allocate full portcnt array, rather than just cfgports, because
245 * cleanup iterates across all possible ports.
246 */
247 dd->ipath_pd = kzalloc(sizeof(*dd->ipath_pd) * dd->ipath_portcnt,
244 GFP_KERNEL); 248 GFP_KERNEL);
245 249
246 if (!dd->ipath_pd) { 250 if (!dd->ipath_pd) {
@@ -446,9 +450,9 @@ static void enable_chip(struct ipath_devdata *dd,
446 u32 val; 450 u32 val;
447 int i; 451 int i;
448 452
449 if (!reinit) { 453 if (!reinit)
450 init_waitqueue_head(&ipath_sma_state_wait); 454 init_waitqueue_head(&ipath_state_wait);
451 } 455
452 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, 456 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
453 dd->ipath_rcvctrl); 457 dd->ipath_rcvctrl);
454 458
@@ -687,7 +691,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
687 dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2) 691 dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2)
688 / (sizeof(u64) * BITS_PER_BYTE / 2); 692 / (sizeof(u64) * BITS_PER_BYTE / 2);
689 if (ipath_kpiobufs == 0) { 693 if (ipath_kpiobufs == 0) {
690 /* not set by user, or set explictly to default */ 694 /* not set by user (this is default) */
691 if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > 128) 695 if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > 128)
692 kpiobufs = 32; 696 kpiobufs = 32;
693 else 697 else
@@ -946,6 +950,7 @@ static int ipath_set_kpiobufs(const char *str, struct kernel_param *kp)
946 dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - val; 950 dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - val;
947 } 951 }
948 952
953 ipath_kpiobufs = val;
949 ret = 0; 954 ret = 0;
950bail: 955bail:
951 spin_unlock_irqrestore(&ipath_devs_lock, flags); 956 spin_unlock_irqrestore(&ipath_devs_lock, flags);
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 280e732660a1..49bf7bb15b04 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -34,7 +34,7 @@
34#include <linux/pci.h> 34#include <linux/pci.h>
35 35
36#include "ipath_kernel.h" 36#include "ipath_kernel.h"
37#include "ipath_layer.h" 37#include "ipath_verbs.h"
38#include "ipath_common.h" 38#include "ipath_common.h"
39 39
40/* These are all rcv-related errors which we want to count for stats */ 40/* These are all rcv-related errors which we want to count for stats */
@@ -201,7 +201,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
201 ib_linkstate(lstate)); 201 ib_linkstate(lstate));
202 } 202 }
203 else 203 else
204 ipath_cdbg(SMA, "Unit %u link state %s, last " 204 ipath_cdbg(VERBOSE, "Unit %u link state %s, last "
205 "was %s\n", dd->ipath_unit, 205 "was %s\n", dd->ipath_unit,
206 ib_linkstate(lstate), 206 ib_linkstate(lstate),
207 ib_linkstate((unsigned) 207 ib_linkstate((unsigned)
@@ -213,7 +213,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
213 if (lstate == IPATH_IBSTATE_INIT || 213 if (lstate == IPATH_IBSTATE_INIT ||
214 lstate == IPATH_IBSTATE_ARM || 214 lstate == IPATH_IBSTATE_ARM ||
215 lstate == IPATH_IBSTATE_ACTIVE) 215 lstate == IPATH_IBSTATE_ACTIVE)
216 ipath_cdbg(SMA, "Unit %u link state down" 216 ipath_cdbg(VERBOSE, "Unit %u link state down"
217 " (state 0x%x), from %s\n", 217 " (state 0x%x), from %s\n",
218 dd->ipath_unit, 218 dd->ipath_unit,
219 (u32)val & IPATH_IBSTATE_MASK, 219 (u32)val & IPATH_IBSTATE_MASK,
@@ -269,7 +269,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
269 INFINIPATH_IBCS_LINKSTATE_MASK) 269 INFINIPATH_IBCS_LINKSTATE_MASK)
270 == INFINIPATH_IBCS_L_STATE_ACTIVE) 270 == INFINIPATH_IBCS_L_STATE_ACTIVE)
271 /* if from up to down be more vocal */ 271 /* if from up to down be more vocal */
272 ipath_cdbg(SMA, 272 ipath_cdbg(VERBOSE,
273 "Unit %u link now down (%s)\n", 273 "Unit %u link now down (%s)\n",
274 dd->ipath_unit, 274 dd->ipath_unit,
275 ipath_ibcstatus_str[ltstate]); 275 ipath_ibcstatus_str[ltstate]);
@@ -289,8 +289,6 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
289 *dd->ipath_statusp |= 289 *dd->ipath_statusp |=
290 IPATH_STATUS_IB_READY | IPATH_STATUS_IB_CONF; 290 IPATH_STATUS_IB_READY | IPATH_STATUS_IB_CONF;
291 dd->ipath_f_setextled(dd, lstate, ltstate); 291 dd->ipath_f_setextled(dd, lstate, ltstate);
292
293 __ipath_layer_intr(dd, IPATH_LAYER_INT_IF_UP);
294 } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_INIT) { 292 } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_INIT) {
295 /* 293 /*
296 * set INIT and DOWN. Down is checked by most of the other 294 * set INIT and DOWN. Down is checked by most of the other
@@ -598,11 +596,11 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
598 596
599 if (!noprint && *msg) 597 if (!noprint && *msg)
600 ipath_dev_err(dd, "%s error\n", msg); 598 ipath_dev_err(dd, "%s error\n", msg);
601 if (dd->ipath_sma_state_wanted & dd->ipath_flags) { 599 if (dd->ipath_state_wanted & dd->ipath_flags) {
602 ipath_cdbg(VERBOSE, "sma wanted state %x, iflags now %x, " 600 ipath_cdbg(VERBOSE, "driver wanted state %x, iflags now %x, "
603 "waking\n", dd->ipath_sma_state_wanted, 601 "waking\n", dd->ipath_state_wanted,
604 dd->ipath_flags); 602 dd->ipath_flags);
605 wake_up_interruptible(&ipath_sma_state_wait); 603 wake_up_interruptible(&ipath_state_wait);
606 } 604 }
607 605
608 return chkerrpkts; 606 return chkerrpkts;
@@ -708,11 +706,7 @@ static void handle_layer_pioavail(struct ipath_devdata *dd)
708{ 706{
709 int ret; 707 int ret;
710 708
711 ret = __ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE); 709 ret = ipath_ib_piobufavail(dd->verbs_dev);
712 if (ret > 0)
713 goto set;
714
715 ret = __ipath_verbs_piobufavail(dd);
716 if (ret > 0) 710 if (ret > 0)
717 goto set; 711 goto set;
718 712
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index e9f374fb641e..a8a56276ff1d 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -132,12 +132,6 @@ struct _ipath_layer {
132 void *l_arg; 132 void *l_arg;
133}; 133};
134 134
135/* Verbs layer interface */
136struct _verbs_layer {
137 void *l_arg;
138 struct timer_list l_timer;
139};
140
141struct ipath_devdata { 135struct ipath_devdata {
142 struct list_head ipath_list; 136 struct list_head ipath_list;
143 137
@@ -198,7 +192,8 @@ struct ipath_devdata {
198 void (*ipath_f_setextled)(struct ipath_devdata *, u64, u64); 192 void (*ipath_f_setextled)(struct ipath_devdata *, u64, u64);
199 /* fill out chip-specific fields */ 193 /* fill out chip-specific fields */
200 int (*ipath_f_get_base_info)(struct ipath_portdata *, void *); 194 int (*ipath_f_get_base_info)(struct ipath_portdata *, void *);
201 struct _verbs_layer verbs_layer; 195 struct ipath_ibdev *verbs_dev;
196 struct timer_list verbs_timer;
202 /* total dwords sent (summed from counter) */ 197 /* total dwords sent (summed from counter) */
203 u64 ipath_sword; 198 u64 ipath_sword;
204 /* total dwords rcvd (summed from counter) */ 199 /* total dwords rcvd (summed from counter) */
@@ -241,7 +236,7 @@ struct ipath_devdata {
241 u64 ipath_tidtemplate; 236 u64 ipath_tidtemplate;
242 /* value to write to free TIDs */ 237 /* value to write to free TIDs */
243 u64 ipath_tidinvalid; 238 u64 ipath_tidinvalid;
244 /* PE-800 rcv interrupt setup */ 239 /* IBA6120 rcv interrupt setup */
245 u64 ipath_rhdrhead_intr_off; 240 u64 ipath_rhdrhead_intr_off;
246 241
247 /* size of memory at ipath_kregbase */ 242 /* size of memory at ipath_kregbase */
@@ -250,8 +245,8 @@ struct ipath_devdata {
250 u32 ipath_pioavregs; 245 u32 ipath_pioavregs;
251 /* IPATH_POLL, etc. */ 246 /* IPATH_POLL, etc. */
252 u32 ipath_flags; 247 u32 ipath_flags;
253 /* ipath_flags sma is waiting for */ 248 /* ipath_flags driver is waiting for */
254 u32 ipath_sma_state_wanted; 249 u32 ipath_state_wanted;
255 /* last buffer for user use, first buf for kernel use is this 250 /* last buffer for user use, first buf for kernel use is this
256 * index. */ 251 * index. */
257 u32 ipath_lastport_piobuf; 252 u32 ipath_lastport_piobuf;
@@ -311,10 +306,6 @@ struct ipath_devdata {
311 u32 ipath_pcibar0; 306 u32 ipath_pcibar0;
312 /* so we can rewrite it after a chip reset */ 307 /* so we can rewrite it after a chip reset */
313 u32 ipath_pcibar1; 308 u32 ipath_pcibar1;
314 /* sequential tries for SMA send and no bufs */
315 u32 ipath_nosma_bufs;
316 /* duration (seconds) ipath_nosma_bufs set */
317 u32 ipath_nosma_secs;
318 309
319 /* HT/PCI Vendor ID (here for NodeInfo) */ 310 /* HT/PCI Vendor ID (here for NodeInfo) */
320 u16 ipath_vendorid; 311 u16 ipath_vendorid;
@@ -512,6 +503,8 @@ struct ipath_devdata {
512 u8 ipath_pci_cacheline; 503 u8 ipath_pci_cacheline;
513 /* LID mask control */ 504 /* LID mask control */
514 u8 ipath_lmc; 505 u8 ipath_lmc;
506 /* Rx Polarity inversion (compensate for ~tx on partner) */
507 u8 ipath_rx_pol_inv;
515 508
516 /* local link integrity counter */ 509 /* local link integrity counter */
517 u32 ipath_lli_counter; 510 u32 ipath_lli_counter;
@@ -523,18 +516,6 @@ extern struct list_head ipath_dev_list;
523extern spinlock_t ipath_devs_lock; 516extern spinlock_t ipath_devs_lock;
524extern struct ipath_devdata *ipath_lookup(int unit); 517extern struct ipath_devdata *ipath_lookup(int unit);
525 518
526extern u16 ipath_layer_rcv_opcode;
527extern int __ipath_layer_intr(struct ipath_devdata *, u32);
528extern int ipath_layer_intr(struct ipath_devdata *, u32);
529extern int __ipath_layer_rcv(struct ipath_devdata *, void *,
530 struct sk_buff *);
531extern int __ipath_layer_rcv_lid(struct ipath_devdata *, void *);
532extern int __ipath_verbs_piobufavail(struct ipath_devdata *);
533extern int __ipath_verbs_rcv(struct ipath_devdata *, void *, void *, u32);
534
535void ipath_layer_add(struct ipath_devdata *);
536void ipath_layer_remove(struct ipath_devdata *);
537
538int ipath_init_chip(struct ipath_devdata *, int); 519int ipath_init_chip(struct ipath_devdata *, int);
539int ipath_enable_wc(struct ipath_devdata *dd); 520int ipath_enable_wc(struct ipath_devdata *dd);
540void ipath_disable_wc(struct ipath_devdata *dd); 521void ipath_disable_wc(struct ipath_devdata *dd);
@@ -549,9 +530,8 @@ void ipath_cdev_cleanup(struct cdev **cdevp,
549 530
550int ipath_diag_add(struct ipath_devdata *); 531int ipath_diag_add(struct ipath_devdata *);
551void ipath_diag_remove(struct ipath_devdata *); 532void ipath_diag_remove(struct ipath_devdata *);
552void ipath_diag_bringup_link(struct ipath_devdata *);
553 533
554extern wait_queue_head_t ipath_sma_state_wait; 534extern wait_queue_head_t ipath_state_wait;
555 535
556int ipath_user_add(struct ipath_devdata *dd); 536int ipath_user_add(struct ipath_devdata *dd);
557void ipath_user_remove(struct ipath_devdata *dd); 537void ipath_user_remove(struct ipath_devdata *dd);
@@ -582,12 +562,14 @@ void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *);
582 562
583int ipath_parse_ushort(const char *str, unsigned short *valp); 563int ipath_parse_ushort(const char *str, unsigned short *valp);
584 564
585int ipath_wait_linkstate(struct ipath_devdata *, u32, int);
586void ipath_set_ib_lstate(struct ipath_devdata *, int);
587void ipath_kreceive(struct ipath_devdata *); 565void ipath_kreceive(struct ipath_devdata *);
588int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned); 566int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned);
589int ipath_reset_device(int); 567int ipath_reset_device(int);
590void ipath_get_faststats(unsigned long); 568void ipath_get_faststats(unsigned long);
569int ipath_set_linkstate(struct ipath_devdata *, u8);
570int ipath_set_mtu(struct ipath_devdata *, u16);
571int ipath_set_lid(struct ipath_devdata *, u32, u8);
572int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
591 573
592/* for use in system calls, where we want to know device type, etc. */ 574/* for use in system calls, where we want to know device type, etc. */
593#define port_fp(fp) ((struct ipath_portdata *) (fp)->private_data) 575#define port_fp(fp) ((struct ipath_portdata *) (fp)->private_data)
@@ -642,10 +624,8 @@ void ipath_free_data(struct ipath_portdata *dd);
642int ipath_waitfor_mdio_cmdready(struct ipath_devdata *); 624int ipath_waitfor_mdio_cmdready(struct ipath_devdata *);
643int ipath_waitfor_complete(struct ipath_devdata *, ipath_kreg, u64, u64 *); 625int ipath_waitfor_complete(struct ipath_devdata *, ipath_kreg, u64, u64 *);
644u32 __iomem *ipath_getpiobuf(struct ipath_devdata *, u32 *); 626u32 __iomem *ipath_getpiobuf(struct ipath_devdata *, u32 *);
645/* init PE-800-specific func */ 627void ipath_init_iba6120_funcs(struct ipath_devdata *);
646void ipath_init_pe800_funcs(struct ipath_devdata *); 628void ipath_init_iba6110_funcs(struct ipath_devdata *);
647/* init HT-400-specific func */
648void ipath_init_ht400_funcs(struct ipath_devdata *);
649void ipath_get_eeprom_info(struct ipath_devdata *); 629void ipath_get_eeprom_info(struct ipath_devdata *);
650u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg); 630u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);
651 631
@@ -801,7 +781,7 @@ static inline u32 ipath_read_creg32(const struct ipath_devdata *dd,
801 781
802struct device_driver; 782struct device_driver;
803 783
804extern const char ipath_core_version[]; 784extern const char ib_ipath_version[];
805 785
806int ipath_driver_create_group(struct device_driver *); 786int ipath_driver_create_group(struct device_driver *);
807void ipath_driver_remove_group(struct device_driver *); 787void ipath_driver_remove_group(struct device_driver *);
@@ -810,6 +790,9 @@ int ipath_device_create_group(struct device *, struct ipath_devdata *);
810void ipath_device_remove_group(struct device *, struct ipath_devdata *); 790void ipath_device_remove_group(struct device *, struct ipath_devdata *);
811int ipath_expose_reset(struct device *); 791int ipath_expose_reset(struct device *);
812 792
793int ipath_diagpkt_add(void);
794void ipath_diagpkt_remove(void);
795
813int ipath_init_ipathfs(void); 796int ipath_init_ipathfs(void);
814void ipath_exit_ipathfs(void); 797void ipath_exit_ipathfs(void);
815int ipathfs_add_device(struct ipath_devdata *); 798int ipathfs_add_device(struct ipath_devdata *);
@@ -831,10 +814,10 @@ const char *ipath_get_unit_name(int unit);
831 814
832extern struct mutex ipath_mutex; 815extern struct mutex ipath_mutex;
833 816
834#define IPATH_DRV_NAME "ipath_core" 817#define IPATH_DRV_NAME "ib_ipath"
835#define IPATH_MAJOR 233 818#define IPATH_MAJOR 233
836#define IPATH_USER_MINOR_BASE 0 819#define IPATH_USER_MINOR_BASE 0
837#define IPATH_SMA_MINOR 128 820#define IPATH_DIAGPKT_MINOR 127
838#define IPATH_DIAG_MINOR_BASE 129 821#define IPATH_DIAG_MINOR_BASE 129
839#define IPATH_NMINORS 255 822#define IPATH_NMINORS 255
840 823
diff --git a/drivers/infiniband/hw/ipath/ipath_keys.c b/drivers/infiniband/hw/ipath/ipath_keys.c
index a5ca279370aa..ba1b93226caa 100644
--- a/drivers/infiniband/hw/ipath/ipath_keys.c
+++ b/drivers/infiniband/hw/ipath/ipath_keys.c
@@ -34,6 +34,7 @@
34#include <asm/io.h> 34#include <asm/io.h>
35 35
36#include "ipath_verbs.h" 36#include "ipath_verbs.h"
37#include "ipath_kernel.h"
37 38
38/** 39/**
39 * ipath_alloc_lkey - allocate an lkey 40 * ipath_alloc_lkey - allocate an lkey
@@ -60,7 +61,7 @@ int ipath_alloc_lkey(struct ipath_lkey_table *rkt, struct ipath_mregion *mr)
60 r = (r + 1) & (rkt->max - 1); 61 r = (r + 1) & (rkt->max - 1);
61 if (r == n) { 62 if (r == n) {
62 spin_unlock_irqrestore(&rkt->lock, flags); 63 spin_unlock_irqrestore(&rkt->lock, flags);
63 _VERBS_INFO("LKEY table full\n"); 64 ipath_dbg(KERN_INFO "LKEY table full\n");
64 ret = 0; 65 ret = 0;
65 goto bail; 66 goto bail;
66 } 67 }
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.c b/drivers/infiniband/hw/ipath/ipath_layer.c
index b28c6f81c731..e46aa4ed2a7e 100644
--- a/drivers/infiniband/hw/ipath/ipath_layer.c
+++ b/drivers/infiniband/hw/ipath/ipath_layer.c
@@ -42,26 +42,20 @@
42 42
43#include "ipath_kernel.h" 43#include "ipath_kernel.h"
44#include "ipath_layer.h" 44#include "ipath_layer.h"
45#include "ipath_verbs.h"
45#include "ipath_common.h" 46#include "ipath_common.h"
46 47
47/* Acquire before ipath_devs_lock. */ 48/* Acquire before ipath_devs_lock. */
48static DEFINE_MUTEX(ipath_layer_mutex); 49static DEFINE_MUTEX(ipath_layer_mutex);
49 50
50static int ipath_verbs_registered;
51
52u16 ipath_layer_rcv_opcode; 51u16 ipath_layer_rcv_opcode;
53 52
54static int (*layer_intr)(void *, u32); 53static int (*layer_intr)(void *, u32);
55static int (*layer_rcv)(void *, void *, struct sk_buff *); 54static int (*layer_rcv)(void *, void *, struct sk_buff *);
56static int (*layer_rcv_lid)(void *, void *); 55static int (*layer_rcv_lid)(void *, void *);
57static int (*verbs_piobufavail)(void *);
58static void (*verbs_rcv)(void *, void *, void *, u32);
59 56
60static void *(*layer_add_one)(int, struct ipath_devdata *); 57static void *(*layer_add_one)(int, struct ipath_devdata *);
61static void (*layer_remove_one)(void *); 58static void (*layer_remove_one)(void *);
62static void *(*verbs_add_one)(int, struct ipath_devdata *);
63static void (*verbs_remove_one)(void *);
64static void (*verbs_timer_cb)(void *);
65 59
66int __ipath_layer_intr(struct ipath_devdata *dd, u32 arg) 60int __ipath_layer_intr(struct ipath_devdata *dd, u32 arg)
67{ 61{
@@ -107,302 +101,16 @@ int __ipath_layer_rcv_lid(struct ipath_devdata *dd, void *hdr)
107 return ret; 101 return ret;
108} 102}
109 103
110int __ipath_verbs_piobufavail(struct ipath_devdata *dd) 104void ipath_layer_lid_changed(struct ipath_devdata *dd)
111{
112 int ret = -ENODEV;
113
114 if (dd->verbs_layer.l_arg && verbs_piobufavail)
115 ret = verbs_piobufavail(dd->verbs_layer.l_arg);
116
117 return ret;
118}
119
120int __ipath_verbs_rcv(struct ipath_devdata *dd, void *rc, void *ebuf,
121 u32 tlen)
122{
123 int ret = -ENODEV;
124
125 if (dd->verbs_layer.l_arg && verbs_rcv) {
126 verbs_rcv(dd->verbs_layer.l_arg, rc, ebuf, tlen);
127 ret = 0;
128 }
129
130 return ret;
131}
132
133int ipath_layer_set_linkstate(struct ipath_devdata *dd, u8 newstate)
134{ 105{
135 u32 lstate;
136 int ret;
137
138 switch (newstate) {
139 case IPATH_IB_LINKDOWN:
140 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_POLL <<
141 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
142 /* don't wait */
143 ret = 0;
144 goto bail;
145
146 case IPATH_IB_LINKDOWN_SLEEP:
147 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_SLEEP <<
148 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
149 /* don't wait */
150 ret = 0;
151 goto bail;
152
153 case IPATH_IB_LINKDOWN_DISABLE:
154 ipath_set_ib_lstate(dd,
155 INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
156 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
157 /* don't wait */
158 ret = 0;
159 goto bail;
160
161 case IPATH_IB_LINKINIT:
162 if (dd->ipath_flags & IPATH_LINKINIT) {
163 ret = 0;
164 goto bail;
165 }
166 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_INIT <<
167 INFINIPATH_IBCC_LINKCMD_SHIFT);
168 lstate = IPATH_LINKINIT;
169 break;
170
171 case IPATH_IB_LINKARM:
172 if (dd->ipath_flags & IPATH_LINKARMED) {
173 ret = 0;
174 goto bail;
175 }
176 if (!(dd->ipath_flags &
177 (IPATH_LINKINIT | IPATH_LINKACTIVE))) {
178 ret = -EINVAL;
179 goto bail;
180 }
181 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_ARMED <<
182 INFINIPATH_IBCC_LINKCMD_SHIFT);
183 /*
184 * Since the port can transition to ACTIVE by receiving
185 * a non VL 15 packet, wait for either state.
186 */
187 lstate = IPATH_LINKARMED | IPATH_LINKACTIVE;
188 break;
189
190 case IPATH_IB_LINKACTIVE:
191 if (dd->ipath_flags & IPATH_LINKACTIVE) {
192 ret = 0;
193 goto bail;
194 }
195 if (!(dd->ipath_flags & IPATH_LINKARMED)) {
196 ret = -EINVAL;
197 goto bail;
198 }
199 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_ACTIVE <<
200 INFINIPATH_IBCC_LINKCMD_SHIFT);
201 lstate = IPATH_LINKACTIVE;
202 break;
203
204 default:
205 ipath_dbg("Invalid linkstate 0x%x requested\n", newstate);
206 ret = -EINVAL;
207 goto bail;
208 }
209 ret = ipath_wait_linkstate(dd, lstate, 2000);
210
211bail:
212 return ret;
213}
214
215EXPORT_SYMBOL_GPL(ipath_layer_set_linkstate);
216
217/**
218 * ipath_layer_set_mtu - set the MTU
219 * @dd: the infinipath device
220 * @arg: the new MTU
221 *
222 * we can handle "any" incoming size, the issue here is whether we
223 * need to restrict our outgoing size. For now, we don't do any
224 * sanity checking on this, and we don't deal with what happens to
225 * programs that are already running when the size changes.
226 * NOTE: changing the MTU will usually cause the IBC to go back to
227 * link initialize (IPATH_IBSTATE_INIT) state...
228 */
229int ipath_layer_set_mtu(struct ipath_devdata *dd, u16 arg)
230{
231 u32 piosize;
232 int changed = 0;
233 int ret;
234
235 /*
236 * mtu is IB data payload max. It's the largest power of 2 less
237 * than piosize (or even larger, since it only really controls the
238 * largest we can receive; we can send the max of the mtu and
239 * piosize). We check that it's one of the valid IB sizes.
240 */
241 if (arg != 256 && arg != 512 && arg != 1024 && arg != 2048 &&
242 arg != 4096) {
243 ipath_dbg("Trying to set invalid mtu %u, failing\n", arg);
244 ret = -EINVAL;
245 goto bail;
246 }
247 if (dd->ipath_ibmtu == arg) {
248 ret = 0; /* same as current */
249 goto bail;
250 }
251
252 piosize = dd->ipath_ibmaxlen;
253 dd->ipath_ibmtu = arg;
254
255 if (arg >= (piosize - IPATH_PIO_MAXIBHDR)) {
256 /* Only if it's not the initial value (or reset to it) */
257 if (piosize != dd->ipath_init_ibmaxlen) {
258 dd->ipath_ibmaxlen = piosize;
259 changed = 1;
260 }
261 } else if ((arg + IPATH_PIO_MAXIBHDR) != dd->ipath_ibmaxlen) {
262 piosize = arg + IPATH_PIO_MAXIBHDR;
263 ipath_cdbg(VERBOSE, "ibmaxlen was 0x%x, setting to 0x%x "
264 "(mtu 0x%x)\n", dd->ipath_ibmaxlen, piosize,
265 arg);
266 dd->ipath_ibmaxlen = piosize;
267 changed = 1;
268 }
269
270 if (changed) {
271 /*
272 * set the IBC maxpktlength to the size of our pio
273 * buffers in words
274 */
275 u64 ibc = dd->ipath_ibcctrl;
276 ibc &= ~(INFINIPATH_IBCC_MAXPKTLEN_MASK <<
277 INFINIPATH_IBCC_MAXPKTLEN_SHIFT);
278
279 piosize = piosize - 2 * sizeof(u32); /* ignore pbc */
280 dd->ipath_ibmaxlen = piosize;
281 piosize /= sizeof(u32); /* in words */
282 /*
283 * for ICRC, which we only send in diag test pkt mode, and
284 * we don't need to worry about that for mtu
285 */
286 piosize += 1;
287
288 ibc |= piosize << INFINIPATH_IBCC_MAXPKTLEN_SHIFT;
289 dd->ipath_ibcctrl = ibc;
290 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
291 dd->ipath_ibcctrl);
292 dd->ipath_f_tidtemplate(dd);
293 }
294
295 ret = 0;
296
297bail:
298 return ret;
299}
300
301EXPORT_SYMBOL_GPL(ipath_layer_set_mtu);
302
303int ipath_set_lid(struct ipath_devdata *dd, u32 arg, u8 lmc)
304{
305 dd->ipath_lid = arg;
306 dd->ipath_lmc = lmc;
307
308 mutex_lock(&ipath_layer_mutex); 106 mutex_lock(&ipath_layer_mutex);
309 107
310 if (dd->ipath_layer.l_arg && layer_intr) 108 if (dd->ipath_layer.l_arg && layer_intr)
311 layer_intr(dd->ipath_layer.l_arg, IPATH_LAYER_INT_LID); 109 layer_intr(dd->ipath_layer.l_arg, IPATH_LAYER_INT_LID);
312 110
313 mutex_unlock(&ipath_layer_mutex); 111 mutex_unlock(&ipath_layer_mutex);
314
315 return 0;
316}
317
318EXPORT_SYMBOL_GPL(ipath_set_lid);
319
320int ipath_layer_set_guid(struct ipath_devdata *dd, __be64 guid)
321{
322 /* XXX - need to inform anyone who cares this just happened. */
323 dd->ipath_guid = guid;
324 return 0;
325}
326
327EXPORT_SYMBOL_GPL(ipath_layer_set_guid);
328
329__be64 ipath_layer_get_guid(struct ipath_devdata *dd)
330{
331 return dd->ipath_guid;
332}
333
334EXPORT_SYMBOL_GPL(ipath_layer_get_guid);
335
336u32 ipath_layer_get_nguid(struct ipath_devdata *dd)
337{
338 return dd->ipath_nguid;
339}
340
341EXPORT_SYMBOL_GPL(ipath_layer_get_nguid);
342
343u32 ipath_layer_get_majrev(struct ipath_devdata *dd)
344{
345 return dd->ipath_majrev;
346} 112}
347 113
348EXPORT_SYMBOL_GPL(ipath_layer_get_majrev);
349
350u32 ipath_layer_get_minrev(struct ipath_devdata *dd)
351{
352 return dd->ipath_minrev;
353}
354
355EXPORT_SYMBOL_GPL(ipath_layer_get_minrev);
356
357u32 ipath_layer_get_pcirev(struct ipath_devdata *dd)
358{
359 return dd->ipath_pcirev;
360}
361
362EXPORT_SYMBOL_GPL(ipath_layer_get_pcirev);
363
364u32 ipath_layer_get_flags(struct ipath_devdata *dd)
365{
366 return dd->ipath_flags;
367}
368
369EXPORT_SYMBOL_GPL(ipath_layer_get_flags);
370
371struct device *ipath_layer_get_device(struct ipath_devdata *dd)
372{
373 return &dd->pcidev->dev;
374}
375
376EXPORT_SYMBOL_GPL(ipath_layer_get_device);
377
378u16 ipath_layer_get_deviceid(struct ipath_devdata *dd)
379{
380 return dd->ipath_deviceid;
381}
382
383EXPORT_SYMBOL_GPL(ipath_layer_get_deviceid);
384
385u32 ipath_layer_get_vendorid(struct ipath_devdata *dd)
386{
387 return dd->ipath_vendorid;
388}
389
390EXPORT_SYMBOL_GPL(ipath_layer_get_vendorid);
391
392u64 ipath_layer_get_lastibcstat(struct ipath_devdata *dd)
393{
394 return dd->ipath_lastibcstat;
395}
396
397EXPORT_SYMBOL_GPL(ipath_layer_get_lastibcstat);
398
399u32 ipath_layer_get_ibmtu(struct ipath_devdata *dd)
400{
401 return dd->ipath_ibmtu;
402}
403
404EXPORT_SYMBOL_GPL(ipath_layer_get_ibmtu);
405
406void ipath_layer_add(struct ipath_devdata *dd) 114void ipath_layer_add(struct ipath_devdata *dd)
407{ 115{
408 mutex_lock(&ipath_layer_mutex); 116 mutex_lock(&ipath_layer_mutex);
@@ -411,10 +119,6 @@ void ipath_layer_add(struct ipath_devdata *dd)
411 dd->ipath_layer.l_arg = 119 dd->ipath_layer.l_arg =
412 layer_add_one(dd->ipath_unit, dd); 120 layer_add_one(dd->ipath_unit, dd);
413 121
414 if (verbs_add_one)
415 dd->verbs_layer.l_arg =
416 verbs_add_one(dd->ipath_unit, dd);
417
418 mutex_unlock(&ipath_layer_mutex); 122 mutex_unlock(&ipath_layer_mutex);
419} 123}
420 124
@@ -427,11 +131,6 @@ void ipath_layer_remove(struct ipath_devdata *dd)
427 dd->ipath_layer.l_arg = NULL; 131 dd->ipath_layer.l_arg = NULL;
428 } 132 }
429 133
430 if (dd->verbs_layer.l_arg && verbs_remove_one) {
431 verbs_remove_one(dd->verbs_layer.l_arg);
432 dd->verbs_layer.l_arg = NULL;
433 }
434
435 mutex_unlock(&ipath_layer_mutex); 134 mutex_unlock(&ipath_layer_mutex);
436} 135}
437 136
@@ -463,9 +162,6 @@ int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *),
463 if (dd->ipath_layer.l_arg) 162 if (dd->ipath_layer.l_arg)
464 continue; 163 continue;
465 164
466 if (!(*dd->ipath_statusp & IPATH_STATUS_SMA))
467 *dd->ipath_statusp |= IPATH_STATUS_OIB_SMA;
468
469 spin_unlock_irqrestore(&ipath_devs_lock, flags); 165 spin_unlock_irqrestore(&ipath_devs_lock, flags);
470 dd->ipath_layer.l_arg = l_add(dd->ipath_unit, dd); 166 dd->ipath_layer.l_arg = l_add(dd->ipath_unit, dd);
471 spin_lock_irqsave(&ipath_devs_lock, flags); 167 spin_lock_irqsave(&ipath_devs_lock, flags);
@@ -509,107 +205,6 @@ void ipath_layer_unregister(void)
509 205
510EXPORT_SYMBOL_GPL(ipath_layer_unregister); 206EXPORT_SYMBOL_GPL(ipath_layer_unregister);
511 207
512static void __ipath_verbs_timer(unsigned long arg)
513{
514 struct ipath_devdata *dd = (struct ipath_devdata *) arg;
515
516 /*
517 * If port 0 receive packet interrupts are not available, or
518 * can be missed, poll the receive queue
519 */
520 if (dd->ipath_flags & IPATH_POLL_RX_INTR)
521 ipath_kreceive(dd);
522
523 /* Handle verbs layer timeouts. */
524 if (dd->verbs_layer.l_arg && verbs_timer_cb)
525 verbs_timer_cb(dd->verbs_layer.l_arg);
526
527 mod_timer(&dd->verbs_layer.l_timer, jiffies + 1);
528}
529
530/**
531 * ipath_verbs_register - verbs layer registration
532 * @l_piobufavail: callback for when PIO buffers become available
533 * @l_rcv: callback for receiving a packet
534 * @l_timer_cb: timer callback
535 * @ipath_devdata: device data structure is put here
536 */
537int ipath_verbs_register(void *(*l_add)(int, struct ipath_devdata *),
538 void (*l_remove)(void *arg),
539 int (*l_piobufavail) (void *arg),
540 void (*l_rcv) (void *arg, void *rhdr,
541 void *data, u32 tlen),
542 void (*l_timer_cb) (void *arg))
543{
544 struct ipath_devdata *dd, *tmp;
545 unsigned long flags;
546
547 mutex_lock(&ipath_layer_mutex);
548
549 verbs_add_one = l_add;
550 verbs_remove_one = l_remove;
551 verbs_piobufavail = l_piobufavail;
552 verbs_rcv = l_rcv;
553 verbs_timer_cb = l_timer_cb;
554
555 spin_lock_irqsave(&ipath_devs_lock, flags);
556
557 list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
558 if (!(dd->ipath_flags & IPATH_INITTED))
559 continue;
560
561 if (dd->verbs_layer.l_arg)
562 continue;
563
564 spin_unlock_irqrestore(&ipath_devs_lock, flags);
565 dd->verbs_layer.l_arg = l_add(dd->ipath_unit, dd);
566 spin_lock_irqsave(&ipath_devs_lock, flags);
567 }
568
569 spin_unlock_irqrestore(&ipath_devs_lock, flags);
570 mutex_unlock(&ipath_layer_mutex);
571
572 ipath_verbs_registered = 1;
573
574 return 0;
575}
576
577EXPORT_SYMBOL_GPL(ipath_verbs_register);
578
579void ipath_verbs_unregister(void)
580{
581 struct ipath_devdata *dd, *tmp;
582 unsigned long flags;
583
584 mutex_lock(&ipath_layer_mutex);
585 spin_lock_irqsave(&ipath_devs_lock, flags);
586
587 list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
588 *dd->ipath_statusp &= ~IPATH_STATUS_OIB_SMA;
589
590 if (dd->verbs_layer.l_arg && verbs_remove_one) {
591 spin_unlock_irqrestore(&ipath_devs_lock, flags);
592 verbs_remove_one(dd->verbs_layer.l_arg);
593 spin_lock_irqsave(&ipath_devs_lock, flags);
594 dd->verbs_layer.l_arg = NULL;
595 }
596 }
597
598 spin_unlock_irqrestore(&ipath_devs_lock, flags);
599
600 verbs_add_one = NULL;
601 verbs_remove_one = NULL;
602 verbs_piobufavail = NULL;
603 verbs_rcv = NULL;
604 verbs_timer_cb = NULL;
605
606 ipath_verbs_registered = 0;
607
608 mutex_unlock(&ipath_layer_mutex);
609}
610
611EXPORT_SYMBOL_GPL(ipath_verbs_unregister);
612
613int ipath_layer_open(struct ipath_devdata *dd, u32 * pktmax) 208int ipath_layer_open(struct ipath_devdata *dd, u32 * pktmax)
614{ 209{
615 int ret; 210 int ret;
@@ -698,390 +293,6 @@ u16 ipath_layer_get_bcast(struct ipath_devdata *dd)
698 293
699EXPORT_SYMBOL_GPL(ipath_layer_get_bcast); 294EXPORT_SYMBOL_GPL(ipath_layer_get_bcast);
700 295
701u32 ipath_layer_get_cr_errpkey(struct ipath_devdata *dd)
702{
703 return ipath_read_creg32(dd, dd->ipath_cregs->cr_errpkey);
704}
705
706EXPORT_SYMBOL_GPL(ipath_layer_get_cr_errpkey);
707
708static void update_sge(struct ipath_sge_state *ss, u32 length)
709{
710 struct ipath_sge *sge = &ss->sge;
711
712 sge->vaddr += length;
713 sge->length -= length;
714 sge->sge_length -= length;
715 if (sge->sge_length == 0) {
716 if (--ss->num_sge)
717 *sge = *ss->sg_list++;
718 } else if (sge->length == 0 && sge->mr != NULL) {
719 if (++sge->n >= IPATH_SEGSZ) {
720 if (++sge->m >= sge->mr->mapsz)
721 return;
722 sge->n = 0;
723 }
724 sge->vaddr = sge->mr->map[sge->m]->segs[sge->n].vaddr;
725 sge->length = sge->mr->map[sge->m]->segs[sge->n].length;
726 }
727}
728
729#ifdef __LITTLE_ENDIAN
730static inline u32 get_upper_bits(u32 data, u32 shift)
731{
732 return data >> shift;
733}
734
735static inline u32 set_upper_bits(u32 data, u32 shift)
736{
737 return data << shift;
738}
739
740static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off)
741{
742 data <<= ((sizeof(u32) - n) * BITS_PER_BYTE);
743 data >>= ((sizeof(u32) - n - off) * BITS_PER_BYTE);
744 return data;
745}
746#else
747static inline u32 get_upper_bits(u32 data, u32 shift)
748{
749 return data << shift;
750}
751
752static inline u32 set_upper_bits(u32 data, u32 shift)
753{
754 return data >> shift;
755}
756
757static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off)
758{
759 data >>= ((sizeof(u32) - n) * BITS_PER_BYTE);
760 data <<= ((sizeof(u32) - n - off) * BITS_PER_BYTE);
761 return data;
762}
763#endif
764
765static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss,
766 u32 length)
767{
768 u32 extra = 0;
769 u32 data = 0;
770 u32 last;
771
772 while (1) {
773 u32 len = ss->sge.length;
774 u32 off;
775
776 BUG_ON(len == 0);
777 if (len > length)
778 len = length;
779 if (len > ss->sge.sge_length)
780 len = ss->sge.sge_length;
781 /* If the source address is not aligned, try to align it. */
782 off = (unsigned long)ss->sge.vaddr & (sizeof(u32) - 1);
783 if (off) {
784 u32 *addr = (u32 *)((unsigned long)ss->sge.vaddr &
785 ~(sizeof(u32) - 1));
786 u32 v = get_upper_bits(*addr, off * BITS_PER_BYTE);
787 u32 y;
788
789 y = sizeof(u32) - off;
790 if (len > y)
791 len = y;
792 if (len + extra >= sizeof(u32)) {
793 data |= set_upper_bits(v, extra *
794 BITS_PER_BYTE);
795 len = sizeof(u32) - extra;
796 if (len == length) {
797 last = data;
798 break;
799 }
800 __raw_writel(data, piobuf);
801 piobuf++;
802 extra = 0;
803 data = 0;
804 } else {
805 /* Clear unused upper bytes */
806 data |= clear_upper_bytes(v, len, extra);
807 if (len == length) {
808 last = data;
809 break;
810 }
811 extra += len;
812 }
813 } else if (extra) {
814 /* Source address is aligned. */
815 u32 *addr = (u32 *) ss->sge.vaddr;
816 int shift = extra * BITS_PER_BYTE;
817 int ushift = 32 - shift;
818 u32 l = len;
819
820 while (l >= sizeof(u32)) {
821 u32 v = *addr;
822
823 data |= set_upper_bits(v, shift);
824 __raw_writel(data, piobuf);
825 data = get_upper_bits(v, ushift);
826 piobuf++;
827 addr++;
828 l -= sizeof(u32);
829 }
830 /*
831 * We still have 'extra' number of bytes leftover.
832 */
833 if (l) {
834 u32 v = *addr;
835
836 if (l + extra >= sizeof(u32)) {
837 data |= set_upper_bits(v, shift);
838 len -= l + extra - sizeof(u32);
839 if (len == length) {
840 last = data;
841 break;
842 }
843 __raw_writel(data, piobuf);
844 piobuf++;
845 extra = 0;
846 data = 0;
847 } else {
848 /* Clear unused upper bytes */
849 data |= clear_upper_bytes(v, l,
850 extra);
851 if (len == length) {
852 last = data;
853 break;
854 }
855 extra += l;
856 }
857 } else if (len == length) {
858 last = data;
859 break;
860 }
861 } else if (len == length) {
862 u32 w;
863
864 /*
865 * Need to round up for the last dword in the
866 * packet.
867 */
868 w = (len + 3) >> 2;
869 __iowrite32_copy(piobuf, ss->sge.vaddr, w - 1);
870 piobuf += w - 1;
871 last = ((u32 *) ss->sge.vaddr)[w - 1];
872 break;
873 } else {
874 u32 w = len >> 2;
875
876 __iowrite32_copy(piobuf, ss->sge.vaddr, w);
877 piobuf += w;
878
879 extra = len & (sizeof(u32) - 1);
880 if (extra) {
881 u32 v = ((u32 *) ss->sge.vaddr)[w];
882
883 /* Clear unused upper bytes */
884 data = clear_upper_bytes(v, extra, 0);
885 }
886 }
887 update_sge(ss, len);
888 length -= len;
889 }
890 /* Update address before sending packet. */
891 update_sge(ss, length);
892 /* must flush early everything before trigger word */
893 ipath_flush_wc();
894 __raw_writel(last, piobuf);
895 /* be sure trigger word is written */
896 ipath_flush_wc();
897}
898
899/**
900 * ipath_verbs_send - send a packet from the verbs layer
901 * @dd: the infinipath device
902 * @hdrwords: the number of words in the header
903 * @hdr: the packet header
904 * @len: the length of the packet in bytes
905 * @ss: the SGE to send
906 *
907 * This is like ipath_sma_send_pkt() in that we need to be able to send
908 * packets after the chip is initialized (MADs) but also like
909 * ipath_layer_send_hdr() since its used by the verbs layer.
910 */
911int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
912 u32 *hdr, u32 len, struct ipath_sge_state *ss)
913{
914 u32 __iomem *piobuf;
915 u32 plen;
916 int ret;
917
918 /* +1 is for the qword padding of pbc */
919 plen = hdrwords + ((len + 3) >> 2) + 1;
920 if (unlikely((plen << 2) > dd->ipath_ibmaxlen)) {
921 ipath_dbg("packet len 0x%x too long, failing\n", plen);
922 ret = -EINVAL;
923 goto bail;
924 }
925
926 /* Get a PIO buffer to use. */
927 piobuf = ipath_getpiobuf(dd, NULL);
928 if (unlikely(piobuf == NULL)) {
929 ret = -EBUSY;
930 goto bail;
931 }
932
933 /*
934 * Write len to control qword, no flags.
935 * We have to flush after the PBC for correctness on some cpus
936 * or WC buffer can be written out of order.
937 */
938 writeq(plen, piobuf);
939 ipath_flush_wc();
940 piobuf += 2;
941 if (len == 0) {
942 /*
943 * If there is just the header portion, must flush before
944 * writing last word of header for correctness, and after
945 * the last header word (trigger word).
946 */
947 __iowrite32_copy(piobuf, hdr, hdrwords - 1);
948 ipath_flush_wc();
949 __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords - 1);
950 ipath_flush_wc();
951 ret = 0;
952 goto bail;
953 }
954
955 __iowrite32_copy(piobuf, hdr, hdrwords);
956 piobuf += hdrwords;
957
958 /* The common case is aligned and contained in one segment. */
959 if (likely(ss->num_sge == 1 && len <= ss->sge.length &&
960 !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) {
961 u32 w;
962 u32 *addr = (u32 *) ss->sge.vaddr;
963
964 /* Update address before sending packet. */
965 update_sge(ss, len);
966 /* Need to round up for the last dword in the packet. */
967 w = (len + 3) >> 2;
968 __iowrite32_copy(piobuf, addr, w - 1);
969 /* must flush early everything before trigger word */
970 ipath_flush_wc();
971 __raw_writel(addr[w - 1], piobuf + w - 1);
972 /* be sure trigger word is written */
973 ipath_flush_wc();
974 ret = 0;
975 goto bail;
976 }
977 copy_io(piobuf, ss, len);
978 ret = 0;
979
980bail:
981 return ret;
982}
983
984EXPORT_SYMBOL_GPL(ipath_verbs_send);
985
986int ipath_layer_snapshot_counters(struct ipath_devdata *dd, u64 *swords,
987 u64 *rwords, u64 *spkts, u64 *rpkts,
988 u64 *xmit_wait)
989{
990 int ret;
991
992 if (!(dd->ipath_flags & IPATH_INITTED)) {
993 /* no hardware, freeze, etc. */
994 ipath_dbg("unit %u not usable\n", dd->ipath_unit);
995 ret = -EINVAL;
996 goto bail;
997 }
998 *swords = ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt);
999 *rwords = ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt);
1000 *spkts = ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt);
1001 *rpkts = ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt);
1002 *xmit_wait = ipath_snap_cntr(dd, dd->ipath_cregs->cr_sendstallcnt);
1003
1004 ret = 0;
1005
1006bail:
1007 return ret;
1008}
1009
1010EXPORT_SYMBOL_GPL(ipath_layer_snapshot_counters);
1011
1012/**
1013 * ipath_layer_get_counters - get various chip counters
1014 * @dd: the infinipath device
1015 * @cntrs: counters are placed here
1016 *
1017 * Return the counters needed by recv_pma_get_portcounters().
1018 */
1019int ipath_layer_get_counters(struct ipath_devdata *dd,
1020 struct ipath_layer_counters *cntrs)
1021{
1022 int ret;
1023
1024 if (!(dd->ipath_flags & IPATH_INITTED)) {
1025 /* no hardware, freeze, etc. */
1026 ipath_dbg("unit %u not usable\n", dd->ipath_unit);
1027 ret = -EINVAL;
1028 goto bail;
1029 }
1030 cntrs->symbol_error_counter =
1031 ipath_snap_cntr(dd, dd->ipath_cregs->cr_ibsymbolerrcnt);
1032 cntrs->link_error_recovery_counter =
1033 ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt);
1034 /*
1035 * The link downed counter counts when the other side downs the
1036 * connection. We add in the number of times we downed the link
1037 * due to local link integrity errors to compensate.
1038 */
1039 cntrs->link_downed_counter =
1040 ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkdowncnt);
1041 cntrs->port_rcv_errors =
1042 ipath_snap_cntr(dd, dd->ipath_cregs->cr_rxdroppktcnt) +
1043 ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvovflcnt) +
1044 ipath_snap_cntr(dd, dd->ipath_cregs->cr_portovflcnt) +
1045 ipath_snap_cntr(dd, dd->ipath_cregs->cr_err_rlencnt) +
1046 ipath_snap_cntr(dd, dd->ipath_cregs->cr_invalidrlencnt) +
1047 ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) +
1048 ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) +
1049 ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) +
1050 ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt);
1051 cntrs->port_rcv_remphys_errors =
1052 ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt);
1053 cntrs->port_xmit_discards =
1054 ipath_snap_cntr(dd, dd->ipath_cregs->cr_unsupvlcnt);
1055 cntrs->port_xmit_data =
1056 ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt);
1057 cntrs->port_rcv_data =
1058 ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt);
1059 cntrs->port_xmit_packets =
1060 ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt);
1061 cntrs->port_rcv_packets =
1062 ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt);
1063 cntrs->local_link_integrity_errors = dd->ipath_lli_errors;
1064 cntrs->excessive_buffer_overrun_errors = 0; /* XXX */
1065
1066 ret = 0;
1067
1068bail:
1069 return ret;
1070}
1071
1072EXPORT_SYMBOL_GPL(ipath_layer_get_counters);
1073
1074int ipath_layer_want_buffer(struct ipath_devdata *dd)
1075{
1076 set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl);
1077 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1078 dd->ipath_sendctrl);
1079
1080 return 0;
1081}
1082
1083EXPORT_SYMBOL_GPL(ipath_layer_want_buffer);
1084
1085int ipath_layer_send_hdr(struct ipath_devdata *dd, struct ether_header *hdr) 296int ipath_layer_send_hdr(struct ipath_devdata *dd, struct ether_header *hdr)
1086{ 297{
1087 int ret = 0; 298 int ret = 0;
@@ -1153,389 +364,3 @@ int ipath_layer_set_piointbufavail_int(struct ipath_devdata *dd)
1153} 364}
1154 365
1155EXPORT_SYMBOL_GPL(ipath_layer_set_piointbufavail_int); 366EXPORT_SYMBOL_GPL(ipath_layer_set_piointbufavail_int);
1156
1157int ipath_layer_enable_timer(struct ipath_devdata *dd)
1158{
1159 /*
1160 * HT-400 has a design flaw where the chip and kernel idea
1161 * of the tail register don't always agree, and therefore we won't
1162 * get an interrupt on the next packet received.
1163 * If the board supports per packet receive interrupts, use it.
1164 * Otherwise, the timer function periodically checks for packets
1165 * to cover this case.
1166 * Either way, the timer is needed for verbs layer related
1167 * processing.
1168 */
1169 if (dd->ipath_flags & IPATH_GPIO_INTR) {
1170 ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect,
1171 0x2074076542310ULL);
1172 /* Enable GPIO bit 2 interrupt */
1173 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask,
1174 (u64) (1 << 2));
1175 }
1176
1177 init_timer(&dd->verbs_layer.l_timer);
1178 dd->verbs_layer.l_timer.function = __ipath_verbs_timer;
1179 dd->verbs_layer.l_timer.data = (unsigned long)dd;
1180 dd->verbs_layer.l_timer.expires = jiffies + 1;
1181 add_timer(&dd->verbs_layer.l_timer);
1182
1183 return 0;
1184}
1185
1186EXPORT_SYMBOL_GPL(ipath_layer_enable_timer);
1187
1188int ipath_layer_disable_timer(struct ipath_devdata *dd)
1189{
1190 /* Disable GPIO bit 2 interrupt */
1191 if (dd->ipath_flags & IPATH_GPIO_INTR)
1192 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, 0);
1193
1194 del_timer_sync(&dd->verbs_layer.l_timer);
1195
1196 return 0;
1197}
1198
1199EXPORT_SYMBOL_GPL(ipath_layer_disable_timer);
1200
1201/**
1202 * ipath_layer_set_verbs_flags - set the verbs layer flags
1203 * @dd: the infinipath device
1204 * @flags: the flags to set
1205 */
1206int ipath_layer_set_verbs_flags(struct ipath_devdata *dd, unsigned flags)
1207{
1208 struct ipath_devdata *ss;
1209 unsigned long lflags;
1210
1211 spin_lock_irqsave(&ipath_devs_lock, lflags);
1212
1213 list_for_each_entry(ss, &ipath_dev_list, ipath_list) {
1214 if (!(ss->ipath_flags & IPATH_INITTED))
1215 continue;
1216 if ((flags & IPATH_VERBS_KERNEL_SMA) &&
1217 !(*ss->ipath_statusp & IPATH_STATUS_SMA))
1218 *ss->ipath_statusp |= IPATH_STATUS_OIB_SMA;
1219 else
1220 *ss->ipath_statusp &= ~IPATH_STATUS_OIB_SMA;
1221 }
1222
1223 spin_unlock_irqrestore(&ipath_devs_lock, lflags);
1224
1225 return 0;
1226}
1227
1228EXPORT_SYMBOL_GPL(ipath_layer_set_verbs_flags);
1229
1230/**
1231 * ipath_layer_get_npkeys - return the size of the PKEY table for port 0
1232 * @dd: the infinipath device
1233 */
1234unsigned ipath_layer_get_npkeys(struct ipath_devdata *dd)
1235{
1236 return ARRAY_SIZE(dd->ipath_pd[0]->port_pkeys);
1237}
1238
1239EXPORT_SYMBOL_GPL(ipath_layer_get_npkeys);
1240
1241/**
1242 * ipath_layer_get_pkey - return the indexed PKEY from the port 0 PKEY table
1243 * @dd: the infinipath device
1244 * @index: the PKEY index
1245 */
1246unsigned ipath_layer_get_pkey(struct ipath_devdata *dd, unsigned index)
1247{
1248 unsigned ret;
1249
1250 if (index >= ARRAY_SIZE(dd->ipath_pd[0]->port_pkeys))
1251 ret = 0;
1252 else
1253 ret = dd->ipath_pd[0]->port_pkeys[index];
1254
1255 return ret;
1256}
1257
1258EXPORT_SYMBOL_GPL(ipath_layer_get_pkey);
1259
1260/**
1261 * ipath_layer_get_pkeys - return the PKEY table for port 0
1262 * @dd: the infinipath device
1263 * @pkeys: the pkey table is placed here
1264 */
1265int ipath_layer_get_pkeys(struct ipath_devdata *dd, u16 * pkeys)
1266{
1267 struct ipath_portdata *pd = dd->ipath_pd[0];
1268
1269 memcpy(pkeys, pd->port_pkeys, sizeof(pd->port_pkeys));
1270
1271 return 0;
1272}
1273
1274EXPORT_SYMBOL_GPL(ipath_layer_get_pkeys);
1275
1276/**
1277 * rm_pkey - decrecment the reference count for the given PKEY
1278 * @dd: the infinipath device
1279 * @key: the PKEY index
1280 *
1281 * Return true if this was the last reference and the hardware table entry
1282 * needs to be changed.
1283 */
1284static int rm_pkey(struct ipath_devdata *dd, u16 key)
1285{
1286 int i;
1287 int ret;
1288
1289 for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
1290 if (dd->ipath_pkeys[i] != key)
1291 continue;
1292 if (atomic_dec_and_test(&dd->ipath_pkeyrefs[i])) {
1293 dd->ipath_pkeys[i] = 0;
1294 ret = 1;
1295 goto bail;
1296 }
1297 break;
1298 }
1299
1300 ret = 0;
1301
1302bail:
1303 return ret;
1304}
1305
1306/**
1307 * add_pkey - add the given PKEY to the hardware table
1308 * @dd: the infinipath device
1309 * @key: the PKEY
1310 *
1311 * Return an error code if unable to add the entry, zero if no change,
1312 * or 1 if the hardware PKEY register needs to be updated.
1313 */
1314static int add_pkey(struct ipath_devdata *dd, u16 key)
1315{
1316 int i;
1317 u16 lkey = key & 0x7FFF;
1318 int any = 0;
1319 int ret;
1320
1321 if (lkey == 0x7FFF) {
1322 ret = 0;
1323 goto bail;
1324 }
1325
1326 /* Look for an empty slot or a matching PKEY. */
1327 for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
1328 if (!dd->ipath_pkeys[i]) {
1329 any++;
1330 continue;
1331 }
1332 /* If it matches exactly, try to increment the ref count */
1333 if (dd->ipath_pkeys[i] == key) {
1334 if (atomic_inc_return(&dd->ipath_pkeyrefs[i]) > 1) {
1335 ret = 0;
1336 goto bail;
1337 }
1338 /* Lost the race. Look for an empty slot below. */
1339 atomic_dec(&dd->ipath_pkeyrefs[i]);
1340 any++;
1341 }
1342 /*
1343 * It makes no sense to have both the limited and unlimited
1344 * PKEY set at the same time since the unlimited one will
1345 * disable the limited one.
1346 */
1347 if ((dd->ipath_pkeys[i] & 0x7FFF) == lkey) {
1348 ret = -EEXIST;
1349 goto bail;
1350 }
1351 }
1352 if (!any) {
1353 ret = -EBUSY;
1354 goto bail;
1355 }
1356 for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
1357 if (!dd->ipath_pkeys[i] &&
1358 atomic_inc_return(&dd->ipath_pkeyrefs[i]) == 1) {
1359 /* for ipathstats, etc. */
1360 ipath_stats.sps_pkeys[i] = lkey;
1361 dd->ipath_pkeys[i] = key;
1362 ret = 1;
1363 goto bail;
1364 }
1365 }
1366 ret = -EBUSY;
1367
1368bail:
1369 return ret;
1370}
1371
1372/**
1373 * ipath_layer_set_pkeys - set the PKEY table for port 0
1374 * @dd: the infinipath device
1375 * @pkeys: the PKEY table
1376 */
1377int ipath_layer_set_pkeys(struct ipath_devdata *dd, u16 * pkeys)
1378{
1379 struct ipath_portdata *pd;
1380 int i;
1381 int changed = 0;
1382
1383 pd = dd->ipath_pd[0];
1384
1385 for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) {
1386 u16 key = pkeys[i];
1387 u16 okey = pd->port_pkeys[i];
1388
1389 if (key == okey)
1390 continue;
1391 /*
1392 * The value of this PKEY table entry is changing.
1393 * Remove the old entry in the hardware's array of PKEYs.
1394 */
1395 if (okey & 0x7FFF)
1396 changed |= rm_pkey(dd, okey);
1397 if (key & 0x7FFF) {
1398 int ret = add_pkey(dd, key);
1399
1400 if (ret < 0)
1401 key = 0;
1402 else
1403 changed |= ret;
1404 }
1405 pd->port_pkeys[i] = key;
1406 }
1407 if (changed) {
1408 u64 pkey;
1409
1410 pkey = (u64) dd->ipath_pkeys[0] |
1411 ((u64) dd->ipath_pkeys[1] << 16) |
1412 ((u64) dd->ipath_pkeys[2] << 32) |
1413 ((u64) dd->ipath_pkeys[3] << 48);
1414 ipath_cdbg(VERBOSE, "p0 new pkey reg %llx\n",
1415 (unsigned long long) pkey);
1416 ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey,
1417 pkey);
1418 }
1419 return 0;
1420}
1421
1422EXPORT_SYMBOL_GPL(ipath_layer_set_pkeys);
1423
1424/**
1425 * ipath_layer_get_linkdowndefaultstate - get the default linkdown state
1426 * @dd: the infinipath device
1427 *
1428 * Returns zero if the default is POLL, 1 if the default is SLEEP.
1429 */
1430int ipath_layer_get_linkdowndefaultstate(struct ipath_devdata *dd)
1431{
1432 return !!(dd->ipath_ibcctrl & INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE);
1433}
1434
1435EXPORT_SYMBOL_GPL(ipath_layer_get_linkdowndefaultstate);
1436
1437/**
1438 * ipath_layer_set_linkdowndefaultstate - set the default linkdown state
1439 * @dd: the infinipath device
1440 * @sleep: the new state
1441 *
1442 * Note that this will only take effect when the link state changes.
1443 */
1444int ipath_layer_set_linkdowndefaultstate(struct ipath_devdata *dd,
1445 int sleep)
1446{
1447 if (sleep)
1448 dd->ipath_ibcctrl |= INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE;
1449 else
1450 dd->ipath_ibcctrl &= ~INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE;
1451 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
1452 dd->ipath_ibcctrl);
1453 return 0;
1454}
1455
1456EXPORT_SYMBOL_GPL(ipath_layer_set_linkdowndefaultstate);
1457
1458int ipath_layer_get_phyerrthreshold(struct ipath_devdata *dd)
1459{
1460 return (dd->ipath_ibcctrl >>
1461 INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
1462 INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
1463}
1464
1465EXPORT_SYMBOL_GPL(ipath_layer_get_phyerrthreshold);
1466
1467/**
1468 * ipath_layer_set_phyerrthreshold - set the physical error threshold
1469 * @dd: the infinipath device
1470 * @n: the new threshold
1471 *
1472 * Note that this will only take effect when the link state changes.
1473 */
1474int ipath_layer_set_phyerrthreshold(struct ipath_devdata *dd, unsigned n)
1475{
1476 unsigned v;
1477
1478 v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
1479 INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
1480 if (v != n) {
1481 dd->ipath_ibcctrl &=
1482 ~(INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK <<
1483 INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT);
1484 dd->ipath_ibcctrl |=
1485 (u64) n << INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT;
1486 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
1487 dd->ipath_ibcctrl);
1488 }
1489 return 0;
1490}
1491
1492EXPORT_SYMBOL_GPL(ipath_layer_set_phyerrthreshold);
1493
1494int ipath_layer_get_overrunthreshold(struct ipath_devdata *dd)
1495{
1496 return (dd->ipath_ibcctrl >>
1497 INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) &
1498 INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK;
1499}
1500
1501EXPORT_SYMBOL_GPL(ipath_layer_get_overrunthreshold);
1502
1503/**
1504 * ipath_layer_set_overrunthreshold - set the overrun threshold
1505 * @dd: the infinipath device
1506 * @n: the new threshold
1507 *
1508 * Note that this will only take effect when the link state changes.
1509 */
1510int ipath_layer_set_overrunthreshold(struct ipath_devdata *dd, unsigned n)
1511{
1512 unsigned v;
1513
1514 v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) &
1515 INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK;
1516 if (v != n) {
1517 dd->ipath_ibcctrl &=
1518 ~(INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK <<
1519 INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT);
1520 dd->ipath_ibcctrl |=
1521 (u64) n << INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT;
1522 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
1523 dd->ipath_ibcctrl);
1524 }
1525 return 0;
1526}
1527
1528EXPORT_SYMBOL_GPL(ipath_layer_set_overrunthreshold);
1529
1530int ipath_layer_get_boardname(struct ipath_devdata *dd, char *name,
1531 size_t namelen)
1532{
1533 return dd->ipath_f_get_boardname(dd, name, namelen);
1534}
1535EXPORT_SYMBOL_GPL(ipath_layer_get_boardname);
1536
1537u32 ipath_layer_get_rcvhdrentsize(struct ipath_devdata *dd)
1538{
1539 return dd->ipath_rcvhdrentsize;
1540}
1541EXPORT_SYMBOL_GPL(ipath_layer_get_rcvhdrentsize);
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.h b/drivers/infiniband/hw/ipath/ipath_layer.h
index 71485096fcac..3854a4eae684 100644
--- a/drivers/infiniband/hw/ipath/ipath_layer.h
+++ b/drivers/infiniband/hw/ipath/ipath_layer.h
@@ -40,73 +40,9 @@
40 */ 40 */
41 41
42struct sk_buff; 42struct sk_buff;
43struct ipath_sge_state;
44struct ipath_devdata; 43struct ipath_devdata;
45struct ether_header; 44struct ether_header;
46 45
47struct ipath_layer_counters {
48 u64 symbol_error_counter;
49 u64 link_error_recovery_counter;
50 u64 link_downed_counter;
51 u64 port_rcv_errors;
52 u64 port_rcv_remphys_errors;
53 u64 port_xmit_discards;
54 u64 port_xmit_data;
55 u64 port_rcv_data;
56 u64 port_xmit_packets;
57 u64 port_rcv_packets;
58 u32 local_link_integrity_errors;
59 u32 excessive_buffer_overrun_errors;
60};
61
62/*
63 * A segment is a linear region of low physical memory.
64 * XXX Maybe we should use phys addr here and kmap()/kunmap().
65 * Used by the verbs layer.
66 */
67struct ipath_seg {
68 void *vaddr;
69 size_t length;
70};
71
72/* The number of ipath_segs that fit in a page. */
73#define IPATH_SEGSZ (PAGE_SIZE / sizeof (struct ipath_seg))
74
75struct ipath_segarray {
76 struct ipath_seg segs[IPATH_SEGSZ];
77};
78
79struct ipath_mregion {
80 u64 user_base; /* User's address for this region */
81 u64 iova; /* IB start address of this region */
82 size_t length;
83 u32 lkey;
84 u32 offset; /* offset (bytes) to start of region */
85 int access_flags;
86 u32 max_segs; /* number of ipath_segs in all the arrays */
87 u32 mapsz; /* size of the map array */
88 struct ipath_segarray *map[0]; /* the segments */
89};
90
91/*
92 * These keep track of the copy progress within a memory region.
93 * Used by the verbs layer.
94 */
95struct ipath_sge {
96 struct ipath_mregion *mr;
97 void *vaddr; /* current pointer into the segment */
98 u32 sge_length; /* length of the SGE */
99 u32 length; /* remaining length of the segment */
100 u16 m; /* current index: mr->map[m] */
101 u16 n; /* current index: mr->map[m]->segs[n] */
102};
103
104struct ipath_sge_state {
105 struct ipath_sge *sg_list; /* next SGE to be used if any */
106 struct ipath_sge sge; /* progress state for the current SGE */
107 u8 num_sge;
108};
109
110int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *), 46int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *),
111 void (*l_remove)(void *), 47 void (*l_remove)(void *),
112 int (*l_intr)(void *, u32), 48 int (*l_intr)(void *, u32),
@@ -114,62 +50,14 @@ int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *),
114 struct sk_buff *), 50 struct sk_buff *),
115 u16 rcv_opcode, 51 u16 rcv_opcode,
116 int (*l_rcv_lid)(void *, void *)); 52 int (*l_rcv_lid)(void *, void *));
117int ipath_verbs_register(void *(*l_add)(int, struct ipath_devdata *),
118 void (*l_remove)(void *arg),
119 int (*l_piobufavail)(void *arg),
120 void (*l_rcv)(void *arg, void *rhdr,
121 void *data, u32 tlen),
122 void (*l_timer_cb)(void *arg));
123void ipath_layer_unregister(void); 53void ipath_layer_unregister(void);
124void ipath_verbs_unregister(void);
125int ipath_layer_open(struct ipath_devdata *, u32 * pktmax); 54int ipath_layer_open(struct ipath_devdata *, u32 * pktmax);
126u16 ipath_layer_get_lid(struct ipath_devdata *dd); 55u16 ipath_layer_get_lid(struct ipath_devdata *dd);
127int ipath_layer_get_mac(struct ipath_devdata *dd, u8 *); 56int ipath_layer_get_mac(struct ipath_devdata *dd, u8 *);
128u16 ipath_layer_get_bcast(struct ipath_devdata *dd); 57u16 ipath_layer_get_bcast(struct ipath_devdata *dd);
129u32 ipath_layer_get_cr_errpkey(struct ipath_devdata *dd);
130int ipath_layer_set_linkstate(struct ipath_devdata *dd, u8 state);
131int ipath_layer_set_mtu(struct ipath_devdata *, u16);
132int ipath_set_lid(struct ipath_devdata *, u32, u8);
133int ipath_layer_send_hdr(struct ipath_devdata *dd, 58int ipath_layer_send_hdr(struct ipath_devdata *dd,
134 struct ether_header *hdr); 59 struct ether_header *hdr);
135int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
136 u32 * hdr, u32 len, struct ipath_sge_state *ss);
137int ipath_layer_set_piointbufavail_int(struct ipath_devdata *dd); 60int ipath_layer_set_piointbufavail_int(struct ipath_devdata *dd);
138int ipath_layer_get_boardname(struct ipath_devdata *dd, char *name,
139 size_t namelen);
140int ipath_layer_snapshot_counters(struct ipath_devdata *dd, u64 *swords,
141 u64 *rwords, u64 *spkts, u64 *rpkts,
142 u64 *xmit_wait);
143int ipath_layer_get_counters(struct ipath_devdata *dd,
144 struct ipath_layer_counters *cntrs);
145int ipath_layer_want_buffer(struct ipath_devdata *dd);
146int ipath_layer_set_guid(struct ipath_devdata *, __be64 guid);
147__be64 ipath_layer_get_guid(struct ipath_devdata *);
148u32 ipath_layer_get_nguid(struct ipath_devdata *);
149u32 ipath_layer_get_majrev(struct ipath_devdata *);
150u32 ipath_layer_get_minrev(struct ipath_devdata *);
151u32 ipath_layer_get_pcirev(struct ipath_devdata *);
152u32 ipath_layer_get_flags(struct ipath_devdata *dd);
153struct device *ipath_layer_get_device(struct ipath_devdata *dd);
154u16 ipath_layer_get_deviceid(struct ipath_devdata *dd);
155u32 ipath_layer_get_vendorid(struct ipath_devdata *);
156u64 ipath_layer_get_lastibcstat(struct ipath_devdata *dd);
157u32 ipath_layer_get_ibmtu(struct ipath_devdata *dd);
158int ipath_layer_enable_timer(struct ipath_devdata *dd);
159int ipath_layer_disable_timer(struct ipath_devdata *dd);
160int ipath_layer_set_verbs_flags(struct ipath_devdata *dd, unsigned flags);
161unsigned ipath_layer_get_npkeys(struct ipath_devdata *dd);
162unsigned ipath_layer_get_pkey(struct ipath_devdata *dd, unsigned index);
163int ipath_layer_get_pkeys(struct ipath_devdata *dd, u16 *pkeys);
164int ipath_layer_set_pkeys(struct ipath_devdata *dd, u16 *pkeys);
165int ipath_layer_get_linkdowndefaultstate(struct ipath_devdata *dd);
166int ipath_layer_set_linkdowndefaultstate(struct ipath_devdata *dd,
167 int sleep);
168int ipath_layer_get_phyerrthreshold(struct ipath_devdata *dd);
169int ipath_layer_set_phyerrthreshold(struct ipath_devdata *dd, unsigned n);
170int ipath_layer_get_overrunthreshold(struct ipath_devdata *dd);
171int ipath_layer_set_overrunthreshold(struct ipath_devdata *dd, unsigned n);
172u32 ipath_layer_get_rcvhdrentsize(struct ipath_devdata *dd);
173 61
174/* ipath_ether interrupt values */ 62/* ipath_ether interrupt values */
175#define IPATH_LAYER_INT_IF_UP 0x2 63#define IPATH_LAYER_INT_IF_UP 0x2
@@ -178,9 +66,6 @@ u32 ipath_layer_get_rcvhdrentsize(struct ipath_devdata *dd);
178#define IPATH_LAYER_INT_SEND_CONTINUE 0x10 66#define IPATH_LAYER_INT_SEND_CONTINUE 0x10
179#define IPATH_LAYER_INT_BCAST 0x40 67#define IPATH_LAYER_INT_BCAST 0x40
180 68
181/* _verbs_layer.l_flags */
182#define IPATH_VERBS_KERNEL_SMA 0x1
183
184extern unsigned ipath_debug; /* debugging bit mask */ 69extern unsigned ipath_debug; /* debugging bit mask */
185 70
186#endif /* _IPATH_LAYER_H */ 71#endif /* _IPATH_LAYER_H */
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c
index d3402341b7d0..72d1db89db8f 100644
--- a/drivers/infiniband/hw/ipath/ipath_mad.c
+++ b/drivers/infiniband/hw/ipath/ipath_mad.c
@@ -101,15 +101,15 @@ static int recv_subn_get_nodeinfo(struct ib_smp *smp,
101 nip->num_ports = ibdev->phys_port_cnt; 101 nip->num_ports = ibdev->phys_port_cnt;
102 /* This is already in network order */ 102 /* This is already in network order */
103 nip->sys_guid = to_idev(ibdev)->sys_image_guid; 103 nip->sys_guid = to_idev(ibdev)->sys_image_guid;
104 nip->node_guid = ipath_layer_get_guid(dd); 104 nip->node_guid = dd->ipath_guid;
105 nip->port_guid = nip->sys_guid; 105 nip->port_guid = nip->sys_guid;
106 nip->partition_cap = cpu_to_be16(ipath_layer_get_npkeys(dd)); 106 nip->partition_cap = cpu_to_be16(ipath_get_npkeys(dd));
107 nip->device_id = cpu_to_be16(ipath_layer_get_deviceid(dd)); 107 nip->device_id = cpu_to_be16(dd->ipath_deviceid);
108 majrev = ipath_layer_get_majrev(dd); 108 majrev = dd->ipath_majrev;
109 minrev = ipath_layer_get_minrev(dd); 109 minrev = dd->ipath_minrev;
110 nip->revision = cpu_to_be32((majrev << 16) | minrev); 110 nip->revision = cpu_to_be32((majrev << 16) | minrev);
111 nip->local_port_num = port; 111 nip->local_port_num = port;
112 vendor = ipath_layer_get_vendorid(dd); 112 vendor = dd->ipath_vendorid;
113 nip->vendor_id[0] = 0; 113 nip->vendor_id[0] = 0;
114 nip->vendor_id[1] = vendor >> 8; 114 nip->vendor_id[1] = vendor >> 8;
115 nip->vendor_id[2] = vendor; 115 nip->vendor_id[2] = vendor;
@@ -133,13 +133,89 @@ static int recv_subn_get_guidinfo(struct ib_smp *smp,
133 */ 133 */
134 if (startgx == 0) 134 if (startgx == 0)
135 /* The first is a copy of the read-only HW GUID. */ 135 /* The first is a copy of the read-only HW GUID. */
136 *p = ipath_layer_get_guid(to_idev(ibdev)->dd); 136 *p = to_idev(ibdev)->dd->ipath_guid;
137 else 137 else
138 smp->status |= IB_SMP_INVALID_FIELD; 138 smp->status |= IB_SMP_INVALID_FIELD;
139 139
140 return reply(smp); 140 return reply(smp);
141} 141}
142 142
143
144static int get_overrunthreshold(struct ipath_devdata *dd)
145{
146 return (dd->ipath_ibcctrl >>
147 INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) &
148 INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK;
149}
150
151/**
152 * set_overrunthreshold - set the overrun threshold
153 * @dd: the infinipath device
154 * @n: the new threshold
155 *
156 * Note that this will only take effect when the link state changes.
157 */
158static int set_overrunthreshold(struct ipath_devdata *dd, unsigned n)
159{
160 unsigned v;
161
162 v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) &
163 INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK;
164 if (v != n) {
165 dd->ipath_ibcctrl &=
166 ~(INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK <<
167 INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT);
168 dd->ipath_ibcctrl |=
169 (u64) n << INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT;
170 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
171 dd->ipath_ibcctrl);
172 }
173 return 0;
174}
175
176static int get_phyerrthreshold(struct ipath_devdata *dd)
177{
178 return (dd->ipath_ibcctrl >>
179 INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
180 INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
181}
182
183/**
184 * set_phyerrthreshold - set the physical error threshold
185 * @dd: the infinipath device
186 * @n: the new threshold
187 *
188 * Note that this will only take effect when the link state changes.
189 */
190static int set_phyerrthreshold(struct ipath_devdata *dd, unsigned n)
191{
192 unsigned v;
193
194 v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
195 INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
196 if (v != n) {
197 dd->ipath_ibcctrl &=
198 ~(INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK <<
199 INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT);
200 dd->ipath_ibcctrl |=
201 (u64) n << INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT;
202 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
203 dd->ipath_ibcctrl);
204 }
205 return 0;
206}
207
208/**
209 * get_linkdowndefaultstate - get the default linkdown state
210 * @dd: the infinipath device
211 *
212 * Returns zero if the default is POLL, 1 if the default is SLEEP.
213 */
214static int get_linkdowndefaultstate(struct ipath_devdata *dd)
215{
216 return !!(dd->ipath_ibcctrl & INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE);
217}
218
143static int recv_subn_get_portinfo(struct ib_smp *smp, 219static int recv_subn_get_portinfo(struct ib_smp *smp,
144 struct ib_device *ibdev, u8 port) 220 struct ib_device *ibdev, u8 port)
145{ 221{
@@ -166,7 +242,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp,
166 (dev->mkeyprot_resv_lmc >> 6) == 0) 242 (dev->mkeyprot_resv_lmc >> 6) == 0)
167 pip->mkey = dev->mkey; 243 pip->mkey = dev->mkey;
168 pip->gid_prefix = dev->gid_prefix; 244 pip->gid_prefix = dev->gid_prefix;
169 lid = ipath_layer_get_lid(dev->dd); 245 lid = dev->dd->ipath_lid;
170 pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE; 246 pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE;
171 pip->sm_lid = cpu_to_be16(dev->sm_lid); 247 pip->sm_lid = cpu_to_be16(dev->sm_lid);
172 pip->cap_mask = cpu_to_be32(dev->port_cap_flags); 248 pip->cap_mask = cpu_to_be32(dev->port_cap_flags);
@@ -177,14 +253,14 @@ static int recv_subn_get_portinfo(struct ib_smp *smp,
177 pip->link_width_supported = 3; /* 1x or 4x */ 253 pip->link_width_supported = 3; /* 1x or 4x */
178 pip->link_width_active = 2; /* 4x */ 254 pip->link_width_active = 2; /* 4x */
179 pip->linkspeed_portstate = 0x10; /* 2.5Gbps */ 255 pip->linkspeed_portstate = 0x10; /* 2.5Gbps */
180 ibcstat = ipath_layer_get_lastibcstat(dev->dd); 256 ibcstat = dev->dd->ipath_lastibcstat;
181 pip->linkspeed_portstate |= ((ibcstat >> 4) & 0x3) + 1; 257 pip->linkspeed_portstate |= ((ibcstat >> 4) & 0x3) + 1;
182 pip->portphysstate_linkdown = 258 pip->portphysstate_linkdown =
183 (ipath_cvt_physportstate[ibcstat & 0xf] << 4) | 259 (ipath_cvt_physportstate[ibcstat & 0xf] << 4) |
184 (ipath_layer_get_linkdowndefaultstate(dev->dd) ? 1 : 2); 260 (get_linkdowndefaultstate(dev->dd) ? 1 : 2);
185 pip->mkeyprot_resv_lmc = dev->mkeyprot_resv_lmc; 261 pip->mkeyprot_resv_lmc = dev->mkeyprot_resv_lmc;
186 pip->linkspeedactive_enabled = 0x11; /* 2.5Gbps, 2.5Gbps */ 262 pip->linkspeedactive_enabled = 0x11; /* 2.5Gbps, 2.5Gbps */
187 switch (ipath_layer_get_ibmtu(dev->dd)) { 263 switch (dev->dd->ipath_ibmtu) {
188 case 4096: 264 case 4096:
189 mtu = IB_MTU_4096; 265 mtu = IB_MTU_4096;
190 break; 266 break;
@@ -217,7 +293,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp,
217 pip->mkey_violations = cpu_to_be16(dev->mkey_violations); 293 pip->mkey_violations = cpu_to_be16(dev->mkey_violations);
218 /* P_KeyViolations are counted by hardware. */ 294 /* P_KeyViolations are counted by hardware. */
219 pip->pkey_violations = 295 pip->pkey_violations =
220 cpu_to_be16((ipath_layer_get_cr_errpkey(dev->dd) - 296 cpu_to_be16((ipath_get_cr_errpkey(dev->dd) -
221 dev->z_pkey_violations) & 0xFFFF); 297 dev->z_pkey_violations) & 0xFFFF);
222 pip->qkey_violations = cpu_to_be16(dev->qkey_violations); 298 pip->qkey_violations = cpu_to_be16(dev->qkey_violations);
223 /* Only the hardware GUID is supported for now */ 299 /* Only the hardware GUID is supported for now */
@@ -226,8 +302,8 @@ static int recv_subn_get_portinfo(struct ib_smp *smp,
226 /* 32.768 usec. response time (guessing) */ 302 /* 32.768 usec. response time (guessing) */
227 pip->resv_resptimevalue = 3; 303 pip->resv_resptimevalue = 3;
228 pip->localphyerrors_overrunerrors = 304 pip->localphyerrors_overrunerrors =
229 (ipath_layer_get_phyerrthreshold(dev->dd) << 4) | 305 (get_phyerrthreshold(dev->dd) << 4) |
230 ipath_layer_get_overrunthreshold(dev->dd); 306 get_overrunthreshold(dev->dd);
231 /* pip->max_credit_hint; */ 307 /* pip->max_credit_hint; */
232 /* pip->link_roundtrip_latency[3]; */ 308 /* pip->link_roundtrip_latency[3]; */
233 309
@@ -237,6 +313,20 @@ bail:
237 return ret; 313 return ret;
238} 314}
239 315
316/**
317 * get_pkeys - return the PKEY table for port 0
318 * @dd: the infinipath device
319 * @pkeys: the pkey table is placed here
320 */
321static int get_pkeys(struct ipath_devdata *dd, u16 * pkeys)
322{
323 struct ipath_portdata *pd = dd->ipath_pd[0];
324
325 memcpy(pkeys, pd->port_pkeys, sizeof(pd->port_pkeys));
326
327 return 0;
328}
329
240static int recv_subn_get_pkeytable(struct ib_smp *smp, 330static int recv_subn_get_pkeytable(struct ib_smp *smp,
241 struct ib_device *ibdev) 331 struct ib_device *ibdev)
242{ 332{
@@ -249,9 +339,9 @@ static int recv_subn_get_pkeytable(struct ib_smp *smp,
249 memset(smp->data, 0, sizeof(smp->data)); 339 memset(smp->data, 0, sizeof(smp->data));
250 if (startpx == 0) { 340 if (startpx == 0) {
251 struct ipath_ibdev *dev = to_idev(ibdev); 341 struct ipath_ibdev *dev = to_idev(ibdev);
252 unsigned i, n = ipath_layer_get_npkeys(dev->dd); 342 unsigned i, n = ipath_get_npkeys(dev->dd);
253 343
254 ipath_layer_get_pkeys(dev->dd, p); 344 get_pkeys(dev->dd, p);
255 345
256 for (i = 0; i < n; i++) 346 for (i = 0; i < n; i++)
257 q[i] = cpu_to_be16(p[i]); 347 q[i] = cpu_to_be16(p[i]);
@@ -269,6 +359,24 @@ static int recv_subn_set_guidinfo(struct ib_smp *smp,
269} 359}
270 360
271/** 361/**
362 * set_linkdowndefaultstate - set the default linkdown state
363 * @dd: the infinipath device
364 * @sleep: the new state
365 *
366 * Note that this will only take effect when the link state changes.
367 */
368static int set_linkdowndefaultstate(struct ipath_devdata *dd, int sleep)
369{
370 if (sleep)
371 dd->ipath_ibcctrl |= INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE;
372 else
373 dd->ipath_ibcctrl &= ~INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE;
374 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
375 dd->ipath_ibcctrl);
376 return 0;
377}
378
379/**
272 * recv_subn_set_portinfo - set port information 380 * recv_subn_set_portinfo - set port information
273 * @smp: the incoming SM packet 381 * @smp: the incoming SM packet
274 * @ibdev: the infiniband device 382 * @ibdev: the infiniband device
@@ -290,7 +398,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
290 u8 state; 398 u8 state;
291 u16 lstate; 399 u16 lstate;
292 u32 mtu; 400 u32 mtu;
293 int ret; 401 int ret, ore;
294 402
295 if (be32_to_cpu(smp->attr_mod) > ibdev->phys_port_cnt) 403 if (be32_to_cpu(smp->attr_mod) > ibdev->phys_port_cnt)
296 goto err; 404 goto err;
@@ -304,7 +412,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
304 dev->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period); 412 dev->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period);
305 413
306 lid = be16_to_cpu(pip->lid); 414 lid = be16_to_cpu(pip->lid);
307 if (lid != ipath_layer_get_lid(dev->dd)) { 415 if (lid != dev->dd->ipath_lid) {
308 /* Must be a valid unicast LID address. */ 416 /* Must be a valid unicast LID address. */
309 if (lid == 0 || lid >= IPATH_MULTICAST_LID_BASE) 417 if (lid == 0 || lid >= IPATH_MULTICAST_LID_BASE)
310 goto err; 418 goto err;
@@ -342,11 +450,11 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
342 case 0: /* NOP */ 450 case 0: /* NOP */
343 break; 451 break;
344 case 1: /* SLEEP */ 452 case 1: /* SLEEP */
345 if (ipath_layer_set_linkdowndefaultstate(dev->dd, 1)) 453 if (set_linkdowndefaultstate(dev->dd, 1))
346 goto err; 454 goto err;
347 break; 455 break;
348 case 2: /* POLL */ 456 case 2: /* POLL */
349 if (ipath_layer_set_linkdowndefaultstate(dev->dd, 0)) 457 if (set_linkdowndefaultstate(dev->dd, 0))
350 goto err; 458 goto err;
351 break; 459 break;
352 default: 460 default:
@@ -376,7 +484,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
376 /* XXX We have already partially updated our state! */ 484 /* XXX We have already partially updated our state! */
377 goto err; 485 goto err;
378 } 486 }
379 ipath_layer_set_mtu(dev->dd, mtu); 487 ipath_set_mtu(dev->dd, mtu);
380 488
381 dev->sm_sl = pip->neighbormtu_mastersmsl & 0xF; 489 dev->sm_sl = pip->neighbormtu_mastersmsl & 0xF;
382 490
@@ -392,20 +500,16 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
392 * later. 500 * later.
393 */ 501 */
394 if (pip->pkey_violations == 0) 502 if (pip->pkey_violations == 0)
395 dev->z_pkey_violations = 503 dev->z_pkey_violations = ipath_get_cr_errpkey(dev->dd);
396 ipath_layer_get_cr_errpkey(dev->dd);
397 504
398 if (pip->qkey_violations == 0) 505 if (pip->qkey_violations == 0)
399 dev->qkey_violations = 0; 506 dev->qkey_violations = 0;
400 507
401 if (ipath_layer_set_phyerrthreshold( 508 ore = pip->localphyerrors_overrunerrors;
402 dev->dd, 509 if (set_phyerrthreshold(dev->dd, (ore >> 4) & 0xF))
403 (pip->localphyerrors_overrunerrors >> 4) & 0xF))
404 goto err; 510 goto err;
405 511
406 if (ipath_layer_set_overrunthreshold( 512 if (set_overrunthreshold(dev->dd, (ore & 0xF)))
407 dev->dd,
408 (pip->localphyerrors_overrunerrors & 0xF)))
409 goto err; 513 goto err;
410 514
411 dev->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; 515 dev->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F;
@@ -423,7 +527,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
423 * is down or is being set to down. 527 * is down or is being set to down.
424 */ 528 */
425 state = pip->linkspeed_portstate & 0xF; 529 state = pip->linkspeed_portstate & 0xF;
426 flags = ipath_layer_get_flags(dev->dd); 530 flags = dev->dd->ipath_flags;
427 lstate = (pip->portphysstate_linkdown >> 4) & 0xF; 531 lstate = (pip->portphysstate_linkdown >> 4) & 0xF;
428 if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP)) 532 if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP))
429 goto err; 533 goto err;
@@ -439,7 +543,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
439 /* FALLTHROUGH */ 543 /* FALLTHROUGH */
440 case IB_PORT_DOWN: 544 case IB_PORT_DOWN:
441 if (lstate == 0) 545 if (lstate == 0)
442 if (ipath_layer_get_linkdowndefaultstate(dev->dd)) 546 if (get_linkdowndefaultstate(dev->dd))
443 lstate = IPATH_IB_LINKDOWN_SLEEP; 547 lstate = IPATH_IB_LINKDOWN_SLEEP;
444 else 548 else
445 lstate = IPATH_IB_LINKDOWN; 549 lstate = IPATH_IB_LINKDOWN;
@@ -451,7 +555,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
451 lstate = IPATH_IB_LINKDOWN_DISABLE; 555 lstate = IPATH_IB_LINKDOWN_DISABLE;
452 else 556 else
453 goto err; 557 goto err;
454 ipath_layer_set_linkstate(dev->dd, lstate); 558 ipath_set_linkstate(dev->dd, lstate);
455 if (flags & IPATH_LINKACTIVE) { 559 if (flags & IPATH_LINKACTIVE) {
456 event.event = IB_EVENT_PORT_ERR; 560 event.event = IB_EVENT_PORT_ERR;
457 ib_dispatch_event(&event); 561 ib_dispatch_event(&event);
@@ -460,7 +564,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
460 case IB_PORT_ARMED: 564 case IB_PORT_ARMED:
461 if (!(flags & (IPATH_LINKINIT | IPATH_LINKACTIVE))) 565 if (!(flags & (IPATH_LINKINIT | IPATH_LINKACTIVE)))
462 break; 566 break;
463 ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKARM); 567 ipath_set_linkstate(dev->dd, IPATH_IB_LINKARM);
464 if (flags & IPATH_LINKACTIVE) { 568 if (flags & IPATH_LINKACTIVE) {
465 event.event = IB_EVENT_PORT_ERR; 569 event.event = IB_EVENT_PORT_ERR;
466 ib_dispatch_event(&event); 570 ib_dispatch_event(&event);
@@ -469,7 +573,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
469 case IB_PORT_ACTIVE: 573 case IB_PORT_ACTIVE:
470 if (!(flags & IPATH_LINKARMED)) 574 if (!(flags & IPATH_LINKARMED))
471 break; 575 break;
472 ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKACTIVE); 576 ipath_set_linkstate(dev->dd, IPATH_IB_LINKACTIVE);
473 event.event = IB_EVENT_PORT_ACTIVE; 577 event.event = IB_EVENT_PORT_ACTIVE;
474 ib_dispatch_event(&event); 578 ib_dispatch_event(&event);
475 break; 579 break;
@@ -493,6 +597,152 @@ done:
493 return ret; 597 return ret;
494} 598}
495 599
600/**
601 * rm_pkey - decrecment the reference count for the given PKEY
602 * @dd: the infinipath device
603 * @key: the PKEY index
604 *
605 * Return true if this was the last reference and the hardware table entry
606 * needs to be changed.
607 */
608static int rm_pkey(struct ipath_devdata *dd, u16 key)
609{
610 int i;
611 int ret;
612
613 for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
614 if (dd->ipath_pkeys[i] != key)
615 continue;
616 if (atomic_dec_and_test(&dd->ipath_pkeyrefs[i])) {
617 dd->ipath_pkeys[i] = 0;
618 ret = 1;
619 goto bail;
620 }
621 break;
622 }
623
624 ret = 0;
625
626bail:
627 return ret;
628}
629
630/**
631 * add_pkey - add the given PKEY to the hardware table
632 * @dd: the infinipath device
633 * @key: the PKEY
634 *
635 * Return an error code if unable to add the entry, zero if no change,
636 * or 1 if the hardware PKEY register needs to be updated.
637 */
638static int add_pkey(struct ipath_devdata *dd, u16 key)
639{
640 int i;
641 u16 lkey = key & 0x7FFF;
642 int any = 0;
643 int ret;
644
645 if (lkey == 0x7FFF) {
646 ret = 0;
647 goto bail;
648 }
649
650 /* Look for an empty slot or a matching PKEY. */
651 for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
652 if (!dd->ipath_pkeys[i]) {
653 any++;
654 continue;
655 }
656 /* If it matches exactly, try to increment the ref count */
657 if (dd->ipath_pkeys[i] == key) {
658 if (atomic_inc_return(&dd->ipath_pkeyrefs[i]) > 1) {
659 ret = 0;
660 goto bail;
661 }
662 /* Lost the race. Look for an empty slot below. */
663 atomic_dec(&dd->ipath_pkeyrefs[i]);
664 any++;
665 }
666 /*
667 * It makes no sense to have both the limited and unlimited
668 * PKEY set at the same time since the unlimited one will
669 * disable the limited one.
670 */
671 if ((dd->ipath_pkeys[i] & 0x7FFF) == lkey) {
672 ret = -EEXIST;
673 goto bail;
674 }
675 }
676 if (!any) {
677 ret = -EBUSY;
678 goto bail;
679 }
680 for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
681 if (!dd->ipath_pkeys[i] &&
682 atomic_inc_return(&dd->ipath_pkeyrefs[i]) == 1) {
683 /* for ipathstats, etc. */
684 ipath_stats.sps_pkeys[i] = lkey;
685 dd->ipath_pkeys[i] = key;
686 ret = 1;
687 goto bail;
688 }
689 }
690 ret = -EBUSY;
691
692bail:
693 return ret;
694}
695
696/**
697 * set_pkeys - set the PKEY table for port 0
698 * @dd: the infinipath device
699 * @pkeys: the PKEY table
700 */
701static int set_pkeys(struct ipath_devdata *dd, u16 *pkeys)
702{
703 struct ipath_portdata *pd;
704 int i;
705 int changed = 0;
706
707 pd = dd->ipath_pd[0];
708
709 for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) {
710 u16 key = pkeys[i];
711 u16 okey = pd->port_pkeys[i];
712
713 if (key == okey)
714 continue;
715 /*
716 * The value of this PKEY table entry is changing.
717 * Remove the old entry in the hardware's array of PKEYs.
718 */
719 if (okey & 0x7FFF)
720 changed |= rm_pkey(dd, okey);
721 if (key & 0x7FFF) {
722 int ret = add_pkey(dd, key);
723
724 if (ret < 0)
725 key = 0;
726 else
727 changed |= ret;
728 }
729 pd->port_pkeys[i] = key;
730 }
731 if (changed) {
732 u64 pkey;
733
734 pkey = (u64) dd->ipath_pkeys[0] |
735 ((u64) dd->ipath_pkeys[1] << 16) |
736 ((u64) dd->ipath_pkeys[2] << 32) |
737 ((u64) dd->ipath_pkeys[3] << 48);
738 ipath_cdbg(VERBOSE, "p0 new pkey reg %llx\n",
739 (unsigned long long) pkey);
740 ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey,
741 pkey);
742 }
743 return 0;
744}
745
496static int recv_subn_set_pkeytable(struct ib_smp *smp, 746static int recv_subn_set_pkeytable(struct ib_smp *smp,
497 struct ib_device *ibdev) 747 struct ib_device *ibdev)
498{ 748{
@@ -500,13 +750,12 @@ static int recv_subn_set_pkeytable(struct ib_smp *smp,
500 __be16 *p = (__be16 *) smp->data; 750 __be16 *p = (__be16 *) smp->data;
501 u16 *q = (u16 *) smp->data; 751 u16 *q = (u16 *) smp->data;
502 struct ipath_ibdev *dev = to_idev(ibdev); 752 struct ipath_ibdev *dev = to_idev(ibdev);
503 unsigned i, n = ipath_layer_get_npkeys(dev->dd); 753 unsigned i, n = ipath_get_npkeys(dev->dd);
504 754
505 for (i = 0; i < n; i++) 755 for (i = 0; i < n; i++)
506 q[i] = be16_to_cpu(p[i]); 756 q[i] = be16_to_cpu(p[i]);
507 757
508 if (startpx != 0 || 758 if (startpx != 0 || set_pkeys(dev->dd, q) != 0)
509 ipath_layer_set_pkeys(dev->dd, q) != 0)
510 smp->status |= IB_SMP_INVALID_FIELD; 759 smp->status |= IB_SMP_INVALID_FIELD;
511 760
512 return recv_subn_get_pkeytable(smp, ibdev); 761 return recv_subn_get_pkeytable(smp, ibdev);
@@ -844,10 +1093,10 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
844 struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) 1093 struct ib_pma_portcounters *p = (struct ib_pma_portcounters *)
845 pmp->data; 1094 pmp->data;
846 struct ipath_ibdev *dev = to_idev(ibdev); 1095 struct ipath_ibdev *dev = to_idev(ibdev);
847 struct ipath_layer_counters cntrs; 1096 struct ipath_verbs_counters cntrs;
848 u8 port_select = p->port_select; 1097 u8 port_select = p->port_select;
849 1098
850 ipath_layer_get_counters(dev->dd, &cntrs); 1099 ipath_get_counters(dev->dd, &cntrs);
851 1100
852 /* Adjust counters for any resets done. */ 1101 /* Adjust counters for any resets done. */
853 cntrs.symbol_error_counter -= dev->z_symbol_error_counter; 1102 cntrs.symbol_error_counter -= dev->z_symbol_error_counter;
@@ -944,8 +1193,8 @@ static int recv_pma_get_portcounters_ext(struct ib_perf *pmp,
944 u64 swords, rwords, spkts, rpkts, xwait; 1193 u64 swords, rwords, spkts, rpkts, xwait;
945 u8 port_select = p->port_select; 1194 u8 port_select = p->port_select;
946 1195
947 ipath_layer_snapshot_counters(dev->dd, &swords, &rwords, &spkts, 1196 ipath_snapshot_counters(dev->dd, &swords, &rwords, &spkts,
948 &rpkts, &xwait); 1197 &rpkts, &xwait);
949 1198
950 /* Adjust counters for any resets done. */ 1199 /* Adjust counters for any resets done. */
951 swords -= dev->z_port_xmit_data; 1200 swords -= dev->z_port_xmit_data;
@@ -978,13 +1227,13 @@ static int recv_pma_set_portcounters(struct ib_perf *pmp,
978 struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) 1227 struct ib_pma_portcounters *p = (struct ib_pma_portcounters *)
979 pmp->data; 1228 pmp->data;
980 struct ipath_ibdev *dev = to_idev(ibdev); 1229 struct ipath_ibdev *dev = to_idev(ibdev);
981 struct ipath_layer_counters cntrs; 1230 struct ipath_verbs_counters cntrs;
982 1231
983 /* 1232 /*
984 * Since the HW doesn't support clearing counters, we save the 1233 * Since the HW doesn't support clearing counters, we save the
985 * current count and subtract it from future responses. 1234 * current count and subtract it from future responses.
986 */ 1235 */
987 ipath_layer_get_counters(dev->dd, &cntrs); 1236 ipath_get_counters(dev->dd, &cntrs);
988 1237
989 if (p->counter_select & IB_PMA_SEL_SYMBOL_ERROR) 1238 if (p->counter_select & IB_PMA_SEL_SYMBOL_ERROR)
990 dev->z_symbol_error_counter = cntrs.symbol_error_counter; 1239 dev->z_symbol_error_counter = cntrs.symbol_error_counter;
@@ -1041,8 +1290,8 @@ static int recv_pma_set_portcounters_ext(struct ib_perf *pmp,
1041 struct ipath_ibdev *dev = to_idev(ibdev); 1290 struct ipath_ibdev *dev = to_idev(ibdev);
1042 u64 swords, rwords, spkts, rpkts, xwait; 1291 u64 swords, rwords, spkts, rpkts, xwait;
1043 1292
1044 ipath_layer_snapshot_counters(dev->dd, &swords, &rwords, &spkts, 1293 ipath_snapshot_counters(dev->dd, &swords, &rwords, &spkts,
1045 &rpkts, &xwait); 1294 &rpkts, &xwait);
1046 1295
1047 if (p->counter_select & IB_PMA_SELX_PORT_XMIT_DATA) 1296 if (p->counter_select & IB_PMA_SELX_PORT_XMIT_DATA)
1048 dev->z_port_xmit_data = swords; 1297 dev->z_port_xmit_data = swords;
diff --git a/drivers/infiniband/hw/ipath/ipath_mmap.c b/drivers/infiniband/hw/ipath/ipath_mmap.c
new file mode 100644
index 000000000000..11b7378ff214
--- /dev/null
+++ b/drivers/infiniband/hw/ipath/ipath_mmap.c
@@ -0,0 +1,122 @@
1/*
2 * Copyright (c) 2006 QLogic, Inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include <linux/config.h>
34#include <linux/module.h>
35#include <linux/vmalloc.h>
36#include <linux/mm.h>
37#include <linux/errno.h>
38#include <asm/pgtable.h>
39
40#include "ipath_verbs.h"
41
42/**
43 * ipath_release_mmap_info - free mmap info structure
44 * @ref: a pointer to the kref within struct ipath_mmap_info
45 */
46void ipath_release_mmap_info(struct kref *ref)
47{
48 struct ipath_mmap_info *ip =
49 container_of(ref, struct ipath_mmap_info, ref);
50
51 vfree(ip->obj);
52 kfree(ip);
53}
54
55/*
56 * open and close keep track of how many times the CQ is mapped,
57 * to avoid releasing it.
58 */
59static void ipath_vma_open(struct vm_area_struct *vma)
60{
61 struct ipath_mmap_info *ip = vma->vm_private_data;
62
63 kref_get(&ip->ref);
64 ip->mmap_cnt++;
65}
66
67static void ipath_vma_close(struct vm_area_struct *vma)
68{
69 struct ipath_mmap_info *ip = vma->vm_private_data;
70
71 ip->mmap_cnt--;
72 kref_put(&ip->ref, ipath_release_mmap_info);
73}
74
75static struct vm_operations_struct ipath_vm_ops = {
76 .open = ipath_vma_open,
77 .close = ipath_vma_close,
78};
79
80/**
81 * ipath_mmap - create a new mmap region
82 * @context: the IB user context of the process making the mmap() call
83 * @vma: the VMA to be initialized
84 * Return zero if the mmap is OK. Otherwise, return an errno.
85 */
86int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
87{
88 struct ipath_ibdev *dev = to_idev(context->device);
89 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
90 unsigned long size = vma->vm_end - vma->vm_start;
91 struct ipath_mmap_info *ip, **pp;
92 int ret = -EINVAL;
93
94 /*
95 * Search the device's list of objects waiting for a mmap call.
96 * Normally, this list is very short since a call to create a
97 * CQ, QP, or SRQ is soon followed by a call to mmap().
98 */
99 spin_lock_irq(&dev->pending_lock);
100 for (pp = &dev->pending_mmaps; (ip = *pp); pp = &ip->next) {
101 /* Only the creator is allowed to mmap the object */
102 if (context != ip->context || (void *) offset != ip->obj)
103 continue;
104 /* Don't allow a mmap larger than the object. */
105 if (size > ip->size)
106 break;
107
108 *pp = ip->next;
109 spin_unlock_irq(&dev->pending_lock);
110
111 ret = remap_vmalloc_range(vma, ip->obj, 0);
112 if (ret)
113 goto done;
114 vma->vm_ops = &ipath_vm_ops;
115 vma->vm_private_data = ip;
116 ipath_vma_open(vma);
117 goto done;
118 }
119 spin_unlock_irq(&dev->pending_lock);
120done:
121 return ret;
122}
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index 4ac31a5da330..b36f6fb3e37a 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -36,6 +36,18 @@
36 36
37#include "ipath_verbs.h" 37#include "ipath_verbs.h"
38 38
39/* Fast memory region */
40struct ipath_fmr {
41 struct ib_fmr ibfmr;
42 u8 page_shift;
43 struct ipath_mregion mr; /* must be last */
44};
45
46static inline struct ipath_fmr *to_ifmr(struct ib_fmr *ibfmr)
47{
48 return container_of(ibfmr, struct ipath_fmr, ibfmr);
49}
50
39/** 51/**
40 * ipath_get_dma_mr - get a DMA memory region 52 * ipath_get_dma_mr - get a DMA memory region
41 * @pd: protection domain for this memory region 53 * @pd: protection domain for this memory region
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 83e557be591e..224b0f40767f 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -35,7 +35,7 @@
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36 36
37#include "ipath_verbs.h" 37#include "ipath_verbs.h"
38#include "ipath_common.h" 38#include "ipath_kernel.h"
39 39
40#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) 40#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE)
41#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) 41#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1)
@@ -44,19 +44,6 @@
44#define find_next_offset(map, off) find_next_zero_bit((map)->page, \ 44#define find_next_offset(map, off) find_next_zero_bit((map)->page, \
45 BITS_PER_PAGE, off) 45 BITS_PER_PAGE, off)
46 46
47#define TRANS_INVALID 0
48#define TRANS_ANY2RST 1
49#define TRANS_RST2INIT 2
50#define TRANS_INIT2INIT 3
51#define TRANS_INIT2RTR 4
52#define TRANS_RTR2RTS 5
53#define TRANS_RTS2RTS 6
54#define TRANS_SQERR2RTS 7
55#define TRANS_ANY2ERR 8
56#define TRANS_RTS2SQD 9 /* XXX Wait for expected ACKs & signal event */
57#define TRANS_SQD2SQD 10 /* error if not drained & parameter change */
58#define TRANS_SQD2RTS 11 /* error if not drained */
59
60/* 47/*
61 * Convert the AETH credit code into the number of credits. 48 * Convert the AETH credit code into the number of credits.
62 */ 49 */
@@ -287,7 +274,7 @@ void ipath_free_all_qps(struct ipath_qp_table *qpt)
287 free_qpn(qpt, qp->ibqp.qp_num); 274 free_qpn(qpt, qp->ibqp.qp_num);
288 if (!atomic_dec_and_test(&qp->refcount) || 275 if (!atomic_dec_and_test(&qp->refcount) ||
289 !ipath_destroy_qp(&qp->ibqp)) 276 !ipath_destroy_qp(&qp->ibqp))
290 _VERBS_INFO("QP memory leak!\n"); 277 ipath_dbg(KERN_INFO "QP memory leak!\n");
291 qp = nqp; 278 qp = nqp;
292 } 279 }
293 } 280 }
@@ -355,8 +342,10 @@ static void ipath_reset_qp(struct ipath_qp *qp)
355 qp->s_last = 0; 342 qp->s_last = 0;
356 qp->s_ssn = 1; 343 qp->s_ssn = 1;
357 qp->s_lsn = 0; 344 qp->s_lsn = 0;
358 qp->r_rq.head = 0; 345 if (qp->r_rq.wq) {
359 qp->r_rq.tail = 0; 346 qp->r_rq.wq->head = 0;
347 qp->r_rq.wq->tail = 0;
348 }
360 qp->r_reuse_sge = 0; 349 qp->r_reuse_sge = 0;
361} 350}
362 351
@@ -373,8 +362,8 @@ void ipath_error_qp(struct ipath_qp *qp)
373 struct ipath_ibdev *dev = to_idev(qp->ibqp.device); 362 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
374 struct ib_wc wc; 363 struct ib_wc wc;
375 364
376 _VERBS_INFO("QP%d/%d in error state\n", 365 ipath_dbg(KERN_INFO "QP%d/%d in error state\n",
377 qp->ibqp.qp_num, qp->remote_qpn); 366 qp->ibqp.qp_num, qp->remote_qpn);
378 367
379 spin_lock(&dev->pending_lock); 368 spin_lock(&dev->pending_lock);
380 /* XXX What if its already removed by the timeout code? */ 369 /* XXX What if its already removed by the timeout code? */
@@ -410,15 +399,32 @@ void ipath_error_qp(struct ipath_qp *qp)
410 qp->s_hdrwords = 0; 399 qp->s_hdrwords = 0;
411 qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; 400 qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
412 401
413 wc.opcode = IB_WC_RECV; 402 if (qp->r_rq.wq) {
414 spin_lock(&qp->r_rq.lock); 403 struct ipath_rwq *wq;
415 while (qp->r_rq.tail != qp->r_rq.head) { 404 u32 head;
416 wc.wr_id = get_rwqe_ptr(&qp->r_rq, qp->r_rq.tail)->wr_id; 405 u32 tail;
417 if (++qp->r_rq.tail >= qp->r_rq.size) 406
418 qp->r_rq.tail = 0; 407 spin_lock(&qp->r_rq.lock);
419 ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); 408
409 /* sanity check pointers before trusting them */
410 wq = qp->r_rq.wq;
411 head = wq->head;
412 if (head >= qp->r_rq.size)
413 head = 0;
414 tail = wq->tail;
415 if (tail >= qp->r_rq.size)
416 tail = 0;
417 wc.opcode = IB_WC_RECV;
418 while (tail != head) {
419 wc.wr_id = get_rwqe_ptr(&qp->r_rq, tail)->wr_id;
420 if (++tail >= qp->r_rq.size)
421 tail = 0;
422 ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
423 }
424 wq->tail = tail;
425
426 spin_unlock(&qp->r_rq.lock);
420 } 427 }
421 spin_unlock(&qp->r_rq.lock);
422} 428}
423 429
424/** 430/**
@@ -426,11 +432,12 @@ void ipath_error_qp(struct ipath_qp *qp)
426 * @ibqp: the queue pair who's attributes we're modifying 432 * @ibqp: the queue pair who's attributes we're modifying
427 * @attr: the new attributes 433 * @attr: the new attributes
428 * @attr_mask: the mask of attributes to modify 434 * @attr_mask: the mask of attributes to modify
435 * @udata: user data for ipathverbs.so
429 * 436 *
430 * Returns 0 on success, otherwise returns an errno. 437 * Returns 0 on success, otherwise returns an errno.
431 */ 438 */
432int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, 439int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
433 int attr_mask) 440 int attr_mask, struct ib_udata *udata)
434{ 441{
435 struct ipath_ibdev *dev = to_idev(ibqp->device); 442 struct ipath_ibdev *dev = to_idev(ibqp->device);
436 struct ipath_qp *qp = to_iqp(ibqp); 443 struct ipath_qp *qp = to_iqp(ibqp);
@@ -448,19 +455,46 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
448 attr_mask)) 455 attr_mask))
449 goto inval; 456 goto inval;
450 457
451 if (attr_mask & IB_QP_AV) 458 if (attr_mask & IB_QP_AV) {
452 if (attr->ah_attr.dlid == 0 || 459 if (attr->ah_attr.dlid == 0 ||
453 attr->ah_attr.dlid >= IPATH_MULTICAST_LID_BASE) 460 attr->ah_attr.dlid >= IPATH_MULTICAST_LID_BASE)
454 goto inval; 461 goto inval;
455 462
463 if ((attr->ah_attr.ah_flags & IB_AH_GRH) &&
464 (attr->ah_attr.grh.sgid_index > 1))
465 goto inval;
466 }
467
456 if (attr_mask & IB_QP_PKEY_INDEX) 468 if (attr_mask & IB_QP_PKEY_INDEX)
457 if (attr->pkey_index >= ipath_layer_get_npkeys(dev->dd)) 469 if (attr->pkey_index >= ipath_get_npkeys(dev->dd))
458 goto inval; 470 goto inval;
459 471
460 if (attr_mask & IB_QP_MIN_RNR_TIMER) 472 if (attr_mask & IB_QP_MIN_RNR_TIMER)
461 if (attr->min_rnr_timer > 31) 473 if (attr->min_rnr_timer > 31)
462 goto inval; 474 goto inval;
463 475
476 if (attr_mask & IB_QP_PORT)
477 if (attr->port_num == 0 ||
478 attr->port_num > ibqp->device->phys_port_cnt)
479 goto inval;
480
481 if (attr_mask & IB_QP_PATH_MTU)
482 if (attr->path_mtu > IB_MTU_4096)
483 goto inval;
484
485 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
486 if (attr->max_dest_rd_atomic > 1)
487 goto inval;
488
489 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC)
490 if (attr->max_rd_atomic > 1)
491 goto inval;
492
493 if (attr_mask & IB_QP_PATH_MIG_STATE)
494 if (attr->path_mig_state != IB_MIG_MIGRATED &&
495 attr->path_mig_state != IB_MIG_REARM)
496 goto inval;
497
464 switch (new_state) { 498 switch (new_state) {
465 case IB_QPS_RESET: 499 case IB_QPS_RESET:
466 ipath_reset_qp(qp); 500 ipath_reset_qp(qp);
@@ -511,6 +545,9 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
511 if (attr_mask & IB_QP_MIN_RNR_TIMER) 545 if (attr_mask & IB_QP_MIN_RNR_TIMER)
512 qp->r_min_rnr_timer = attr->min_rnr_timer; 546 qp->r_min_rnr_timer = attr->min_rnr_timer;
513 547
548 if (attr_mask & IB_QP_TIMEOUT)
549 qp->timeout = attr->timeout;
550
514 if (attr_mask & IB_QP_QKEY) 551 if (attr_mask & IB_QP_QKEY)
515 qp->qkey = attr->qkey; 552 qp->qkey = attr->qkey;
516 553
@@ -543,7 +580,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
543 attr->dest_qp_num = qp->remote_qpn; 580 attr->dest_qp_num = qp->remote_qpn;
544 attr->qp_access_flags = qp->qp_access_flags; 581 attr->qp_access_flags = qp->qp_access_flags;
545 attr->cap.max_send_wr = qp->s_size - 1; 582 attr->cap.max_send_wr = qp->s_size - 1;
546 attr->cap.max_recv_wr = qp->r_rq.size - 1; 583 attr->cap.max_recv_wr = qp->ibqp.srq ? 0 : qp->r_rq.size - 1;
547 attr->cap.max_send_sge = qp->s_max_sge; 584 attr->cap.max_send_sge = qp->s_max_sge;
548 attr->cap.max_recv_sge = qp->r_rq.max_sge; 585 attr->cap.max_recv_sge = qp->r_rq.max_sge;
549 attr->cap.max_inline_data = 0; 586 attr->cap.max_inline_data = 0;
@@ -557,7 +594,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
557 attr->max_dest_rd_atomic = 1; 594 attr->max_dest_rd_atomic = 1;
558 attr->min_rnr_timer = qp->r_min_rnr_timer; 595 attr->min_rnr_timer = qp->r_min_rnr_timer;
559 attr->port_num = 1; 596 attr->port_num = 1;
560 attr->timeout = 0; 597 attr->timeout = qp->timeout;
561 attr->retry_cnt = qp->s_retry_cnt; 598 attr->retry_cnt = qp->s_retry_cnt;
562 attr->rnr_retry = qp->s_rnr_retry; 599 attr->rnr_retry = qp->s_rnr_retry;
563 attr->alt_port_num = 0; 600 attr->alt_port_num = 0;
@@ -569,9 +606,10 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
569 init_attr->recv_cq = qp->ibqp.recv_cq; 606 init_attr->recv_cq = qp->ibqp.recv_cq;
570 init_attr->srq = qp->ibqp.srq; 607 init_attr->srq = qp->ibqp.srq;
571 init_attr->cap = attr->cap; 608 init_attr->cap = attr->cap;
572 init_attr->sq_sig_type = 609 if (qp->s_flags & (1 << IPATH_S_SIGNAL_REQ_WR))
573 (qp->s_flags & (1 << IPATH_S_SIGNAL_REQ_WR)) 610 init_attr->sq_sig_type = IB_SIGNAL_REQ_WR;
574 ? IB_SIGNAL_REQ_WR : 0; 611 else
612 init_attr->sq_sig_type = IB_SIGNAL_ALL_WR;
575 init_attr->qp_type = qp->ibqp.qp_type; 613 init_attr->qp_type = qp->ibqp.qp_type;
576 init_attr->port_num = 1; 614 init_attr->port_num = 1;
577 return 0; 615 return 0;
@@ -596,13 +634,23 @@ __be32 ipath_compute_aeth(struct ipath_qp *qp)
596 } else { 634 } else {
597 u32 min, max, x; 635 u32 min, max, x;
598 u32 credits; 636 u32 credits;
599 637 struct ipath_rwq *wq = qp->r_rq.wq;
638 u32 head;
639 u32 tail;
640
641 /* sanity check pointers before trusting them */
642 head = wq->head;
643 if (head >= qp->r_rq.size)
644 head = 0;
645 tail = wq->tail;
646 if (tail >= qp->r_rq.size)
647 tail = 0;
600 /* 648 /*
601 * Compute the number of credits available (RWQEs). 649 * Compute the number of credits available (RWQEs).
602 * XXX Not holding the r_rq.lock here so there is a small 650 * XXX Not holding the r_rq.lock here so there is a small
603 * chance that the pair of reads are not atomic. 651 * chance that the pair of reads are not atomic.
604 */ 652 */
605 credits = qp->r_rq.head - qp->r_rq.tail; 653 credits = head - tail;
606 if ((int)credits < 0) 654 if ((int)credits < 0)
607 credits += qp->r_rq.size; 655 credits += qp->r_rq.size;
608 /* 656 /*
@@ -679,27 +727,37 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
679 case IB_QPT_UD: 727 case IB_QPT_UD:
680 case IB_QPT_SMI: 728 case IB_QPT_SMI:
681 case IB_QPT_GSI: 729 case IB_QPT_GSI:
682 qp = kmalloc(sizeof(*qp), GFP_KERNEL); 730 sz = sizeof(*qp);
731 if (init_attr->srq) {
732 struct ipath_srq *srq = to_isrq(init_attr->srq);
733
734 sz += sizeof(*qp->r_sg_list) *
735 srq->rq.max_sge;
736 } else
737 sz += sizeof(*qp->r_sg_list) *
738 init_attr->cap.max_recv_sge;
739 qp = kmalloc(sz, GFP_KERNEL);
683 if (!qp) { 740 if (!qp) {
684 vfree(swq);
685 ret = ERR_PTR(-ENOMEM); 741 ret = ERR_PTR(-ENOMEM);
686 goto bail; 742 goto bail_swq;
687 } 743 }
688 if (init_attr->srq) { 744 if (init_attr->srq) {
745 sz = 0;
689 qp->r_rq.size = 0; 746 qp->r_rq.size = 0;
690 qp->r_rq.max_sge = 0; 747 qp->r_rq.max_sge = 0;
691 qp->r_rq.wq = NULL; 748 qp->r_rq.wq = NULL;
749 init_attr->cap.max_recv_wr = 0;
750 init_attr->cap.max_recv_sge = 0;
692 } else { 751 } else {
693 qp->r_rq.size = init_attr->cap.max_recv_wr + 1; 752 qp->r_rq.size = init_attr->cap.max_recv_wr + 1;
694 qp->r_rq.max_sge = init_attr->cap.max_recv_sge; 753 qp->r_rq.max_sge = init_attr->cap.max_recv_sge;
695 sz = (sizeof(struct ipath_sge) * qp->r_rq.max_sge) + 754 sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) +
696 sizeof(struct ipath_rwqe); 755 sizeof(struct ipath_rwqe);
697 qp->r_rq.wq = vmalloc(qp->r_rq.size * sz); 756 qp->r_rq.wq = vmalloc_user(sizeof(struct ipath_rwq) +
757 qp->r_rq.size * sz);
698 if (!qp->r_rq.wq) { 758 if (!qp->r_rq.wq) {
699 kfree(qp);
700 vfree(swq);
701 ret = ERR_PTR(-ENOMEM); 759 ret = ERR_PTR(-ENOMEM);
702 goto bail; 760 goto bail_qp;
703 } 761 }
704 } 762 }
705 763
@@ -719,24 +777,19 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
719 qp->s_wq = swq; 777 qp->s_wq = swq;
720 qp->s_size = init_attr->cap.max_send_wr + 1; 778 qp->s_size = init_attr->cap.max_send_wr + 1;
721 qp->s_max_sge = init_attr->cap.max_send_sge; 779 qp->s_max_sge = init_attr->cap.max_send_sge;
722 qp->s_flags = init_attr->sq_sig_type == IB_SIGNAL_REQ_WR ? 780 if (init_attr->sq_sig_type == IB_SIGNAL_REQ_WR)
723 1 << IPATH_S_SIGNAL_REQ_WR : 0; 781 qp->s_flags = 1 << IPATH_S_SIGNAL_REQ_WR;
782 else
783 qp->s_flags = 0;
724 dev = to_idev(ibpd->device); 784 dev = to_idev(ibpd->device);
725 err = ipath_alloc_qpn(&dev->qp_table, qp, 785 err = ipath_alloc_qpn(&dev->qp_table, qp,
726 init_attr->qp_type); 786 init_attr->qp_type);
727 if (err) { 787 if (err) {
728 vfree(swq);
729 vfree(qp->r_rq.wq);
730 kfree(qp);
731 ret = ERR_PTR(err); 788 ret = ERR_PTR(err);
732 goto bail; 789 goto bail_rwq;
733 } 790 }
791 qp->ip = NULL;
734 ipath_reset_qp(qp); 792 ipath_reset_qp(qp);
735
736 /* Tell the core driver that the kernel SMA is present. */
737 if (init_attr->qp_type == IB_QPT_SMI)
738 ipath_layer_set_verbs_flags(dev->dd,
739 IPATH_VERBS_KERNEL_SMA);
740 break; 793 break;
741 794
742 default: 795 default:
@@ -747,8 +800,63 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
747 800
748 init_attr->cap.max_inline_data = 0; 801 init_attr->cap.max_inline_data = 0;
749 802
803 /*
804 * Return the address of the RWQ as the offset to mmap.
805 * See ipath_mmap() for details.
806 */
807 if (udata && udata->outlen >= sizeof(__u64)) {
808 struct ipath_mmap_info *ip;
809 __u64 offset = (__u64) qp->r_rq.wq;
810 int err;
811
812 err = ib_copy_to_udata(udata, &offset, sizeof(offset));
813 if (err) {
814 ret = ERR_PTR(err);
815 goto bail_rwq;
816 }
817
818 if (qp->r_rq.wq) {
819 /* Allocate info for ipath_mmap(). */
820 ip = kmalloc(sizeof(*ip), GFP_KERNEL);
821 if (!ip) {
822 ret = ERR_PTR(-ENOMEM);
823 goto bail_rwq;
824 }
825 qp->ip = ip;
826 ip->context = ibpd->uobject->context;
827 ip->obj = qp->r_rq.wq;
828 kref_init(&ip->ref);
829 ip->mmap_cnt = 0;
830 ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) +
831 qp->r_rq.size * sz);
832 spin_lock_irq(&dev->pending_lock);
833 ip->next = dev->pending_mmaps;
834 dev->pending_mmaps = ip;
835 spin_unlock_irq(&dev->pending_lock);
836 }
837 }
838
839 spin_lock(&dev->n_qps_lock);
840 if (dev->n_qps_allocated == ib_ipath_max_qps) {
841 spin_unlock(&dev->n_qps_lock);
842 ret = ERR_PTR(-ENOMEM);
843 goto bail_ip;
844 }
845
846 dev->n_qps_allocated++;
847 spin_unlock(&dev->n_qps_lock);
848
750 ret = &qp->ibqp; 849 ret = &qp->ibqp;
850 goto bail;
751 851
852bail_ip:
853 kfree(qp->ip);
854bail_rwq:
855 vfree(qp->r_rq.wq);
856bail_qp:
857 kfree(qp);
858bail_swq:
859 vfree(swq);
752bail: 860bail:
753 return ret; 861 return ret;
754} 862}
@@ -768,15 +876,12 @@ int ipath_destroy_qp(struct ib_qp *ibqp)
768 struct ipath_ibdev *dev = to_idev(ibqp->device); 876 struct ipath_ibdev *dev = to_idev(ibqp->device);
769 unsigned long flags; 877 unsigned long flags;
770 878
771 /* Tell the core driver that the kernel SMA is gone. */ 879 spin_lock_irqsave(&qp->s_lock, flags);
772 if (qp->ibqp.qp_type == IB_QPT_SMI)
773 ipath_layer_set_verbs_flags(dev->dd, 0);
774
775 spin_lock_irqsave(&qp->r_rq.lock, flags);
776 spin_lock(&qp->s_lock);
777 qp->state = IB_QPS_ERR; 880 qp->state = IB_QPS_ERR;
778 spin_unlock(&qp->s_lock); 881 spin_unlock_irqrestore(&qp->s_lock, flags);
779 spin_unlock_irqrestore(&qp->r_rq.lock, flags); 882 spin_lock(&dev->n_qps_lock);
883 dev->n_qps_allocated--;
884 spin_unlock(&dev->n_qps_lock);
780 885
781 /* Stop the sending tasklet. */ 886 /* Stop the sending tasklet. */
782 tasklet_kill(&qp->s_task); 887 tasklet_kill(&qp->s_task);
@@ -797,8 +902,11 @@ int ipath_destroy_qp(struct ib_qp *ibqp)
797 if (atomic_read(&qp->refcount) != 0) 902 if (atomic_read(&qp->refcount) != 0)
798 ipath_free_qp(&dev->qp_table, qp); 903 ipath_free_qp(&dev->qp_table, qp);
799 904
905 if (qp->ip)
906 kref_put(&qp->ip->ref, ipath_release_mmap_info);
907 else
908 vfree(qp->r_rq.wq);
800 vfree(qp->s_wq); 909 vfree(qp->s_wq);
801 vfree(qp->r_rq.wq);
802 kfree(qp); 910 kfree(qp);
803 return 0; 911 return 0;
804} 912}
@@ -850,8 +958,8 @@ void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc)
850 struct ipath_ibdev *dev = to_idev(qp->ibqp.device); 958 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
851 struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); 959 struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
852 960
853 _VERBS_INFO("Send queue error on QP%d/%d: err: %d\n", 961 ipath_dbg(KERN_INFO "Send queue error on QP%d/%d: err: %d\n",
854 qp->ibqp.qp_num, qp->remote_qpn, wc->status); 962 qp->ibqp.qp_num, qp->remote_qpn, wc->status);
855 963
856 spin_lock(&dev->pending_lock); 964 spin_lock(&dev->pending_lock);
857 /* XXX What if its already removed by the timeout code? */ 965 /* XXX What if its already removed by the timeout code? */
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index 774d1615ce2f..a08654042c03 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -32,7 +32,7 @@
32 */ 32 */
33 33
34#include "ipath_verbs.h" 34#include "ipath_verbs.h"
35#include "ipath_common.h" 35#include "ipath_kernel.h"
36 36
37/* cut down ridiculously long IB macro names */ 37/* cut down ridiculously long IB macro names */
38#define OP(x) IB_OPCODE_RC_##x 38#define OP(x) IB_OPCODE_RC_##x
@@ -540,7 +540,7 @@ static void send_rc_ack(struct ipath_qp *qp)
540 lrh0 = IPATH_LRH_GRH; 540 lrh0 = IPATH_LRH_GRH;
541 } 541 }
542 /* read pkey_index w/o lock (its atomic) */ 542 /* read pkey_index w/o lock (its atomic) */
543 bth0 = ipath_layer_get_pkey(dev->dd, qp->s_pkey_index); 543 bth0 = ipath_get_pkey(dev->dd, qp->s_pkey_index);
544 if (qp->r_nak_state) 544 if (qp->r_nak_state)
545 ohdr->u.aeth = cpu_to_be32((qp->r_msn & IPATH_MSN_MASK) | 545 ohdr->u.aeth = cpu_to_be32((qp->r_msn & IPATH_MSN_MASK) |
546 (qp->r_nak_state << 546 (qp->r_nak_state <<
@@ -557,7 +557,7 @@ static void send_rc_ack(struct ipath_qp *qp)
557 hdr.lrh[0] = cpu_to_be16(lrh0); 557 hdr.lrh[0] = cpu_to_be16(lrh0);
558 hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); 558 hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid);
559 hdr.lrh[2] = cpu_to_be16(hwords + SIZE_OF_CRC); 559 hdr.lrh[2] = cpu_to_be16(hwords + SIZE_OF_CRC);
560 hdr.lrh[3] = cpu_to_be16(ipath_layer_get_lid(dev->dd)); 560 hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid);
561 ohdr->bth[0] = cpu_to_be32(bth0); 561 ohdr->bth[0] = cpu_to_be32(bth0);
562 ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); 562 ohdr->bth[1] = cpu_to_be32(qp->remote_qpn);
563 ohdr->bth[2] = cpu_to_be32(qp->r_ack_psn & IPATH_PSN_MASK); 563 ohdr->bth[2] = cpu_to_be32(qp->r_ack_psn & IPATH_PSN_MASK);
@@ -1323,8 +1323,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
1323 * the eager header buffer size to 56 bytes so the last 4 1323 * the eager header buffer size to 56 bytes so the last 4
1324 * bytes of the BTH header (PSN) is in the data buffer. 1324 * bytes of the BTH header (PSN) is in the data buffer.
1325 */ 1325 */
1326 header_in_data = 1326 header_in_data = dev->dd->ipath_rcvhdrentsize == 16;
1327 ipath_layer_get_rcvhdrentsize(dev->dd) == 16;
1328 if (header_in_data) { 1327 if (header_in_data) {
1329 psn = be32_to_cpu(((__be32 *) data)[0]); 1328 psn = be32_to_cpu(((__be32 *) data)[0]);
1330 data += sizeof(__be32); 1329 data += sizeof(__be32);
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h
index 89df8f5ea998..6e23b3d632b8 100644
--- a/drivers/infiniband/hw/ipath/ipath_registers.h
+++ b/drivers/infiniband/hw/ipath/ipath_registers.h
@@ -36,8 +36,7 @@
36 36
37/* 37/*
38 * This file should only be included by kernel source, and by the diags. It 38 * This file should only be included by kernel source, and by the diags. It
39 * defines the registers, and their contents, for the InfiniPath HT-400 39 * defines the registers, and their contents, for InfiniPath chips.
40 * chip.
41 */ 40 */
42 41
43/* 42/*
@@ -283,10 +282,12 @@
283#define INFINIPATH_XGXS_RESET 0x7ULL 282#define INFINIPATH_XGXS_RESET 0x7ULL
284#define INFINIPATH_XGXS_MDIOADDR_MASK 0xfULL 283#define INFINIPATH_XGXS_MDIOADDR_MASK 0xfULL
285#define INFINIPATH_XGXS_MDIOADDR_SHIFT 4 284#define INFINIPATH_XGXS_MDIOADDR_SHIFT 4
285#define INFINIPATH_XGXS_RX_POL_SHIFT 19
286#define INFINIPATH_XGXS_RX_POL_MASK 0xfULL
286 287
287#define INFINIPATH_RT_ADDR_MASK 0xFFFFFFFFFFULL /* 40 bits valid */ 288#define INFINIPATH_RT_ADDR_MASK 0xFFFFFFFFFFULL /* 40 bits valid */
288 289
289/* TID entries (memory), HT400-only */ 290/* TID entries (memory), HT-only */
290#define INFINIPATH_RT_VALID 0x8000000000000000ULL 291#define INFINIPATH_RT_VALID 0x8000000000000000ULL
291#define INFINIPATH_RT_ADDR_SHIFT 0 292#define INFINIPATH_RT_ADDR_SHIFT 0
292#define INFINIPATH_RT_BUFSIZE_MASK 0x3FFF 293#define INFINIPATH_RT_BUFSIZE_MASK 0x3FFF
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
index 772bc59fb85c..5c1da2d25e03 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -32,7 +32,7 @@
32 */ 32 */
33 33
34#include "ipath_verbs.h" 34#include "ipath_verbs.h"
35#include "ipath_common.h" 35#include "ipath_kernel.h"
36 36
37/* 37/*
38 * Convert the AETH RNR timeout code into the number of milliseconds. 38 * Convert the AETH RNR timeout code into the number of milliseconds.
@@ -106,6 +106,54 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp)
106 spin_unlock_irqrestore(&dev->pending_lock, flags); 106 spin_unlock_irqrestore(&dev->pending_lock, flags);
107} 107}
108 108
109static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
110{
111 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
112 int user = to_ipd(qp->ibqp.pd)->user;
113 int i, j, ret;
114 struct ib_wc wc;
115
116 qp->r_len = 0;
117 for (i = j = 0; i < wqe->num_sge; i++) {
118 if (wqe->sg_list[i].length == 0)
119 continue;
120 /* Check LKEY */
121 if ((user && wqe->sg_list[i].lkey == 0) ||
122 !ipath_lkey_ok(&dev->lk_table,
123 &qp->r_sg_list[j], &wqe->sg_list[i],
124 IB_ACCESS_LOCAL_WRITE))
125 goto bad_lkey;
126 qp->r_len += wqe->sg_list[i].length;
127 j++;
128 }
129 qp->r_sge.sge = qp->r_sg_list[0];
130 qp->r_sge.sg_list = qp->r_sg_list + 1;
131 qp->r_sge.num_sge = j;
132 ret = 1;
133 goto bail;
134
135bad_lkey:
136 wc.wr_id = wqe->wr_id;
137 wc.status = IB_WC_LOC_PROT_ERR;
138 wc.opcode = IB_WC_RECV;
139 wc.vendor_err = 0;
140 wc.byte_len = 0;
141 wc.imm_data = 0;
142 wc.qp_num = qp->ibqp.qp_num;
143 wc.src_qp = 0;
144 wc.wc_flags = 0;
145 wc.pkey_index = 0;
146 wc.slid = 0;
147 wc.sl = 0;
148 wc.dlid_path_bits = 0;
149 wc.port_num = 0;
150 /* Signal solicited completion event. */
151 ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
152 ret = 0;
153bail:
154 return ret;
155}
156
109/** 157/**
110 * ipath_get_rwqe - copy the next RWQE into the QP's RWQE 158 * ipath_get_rwqe - copy the next RWQE into the QP's RWQE
111 * @qp: the QP 159 * @qp: the QP
@@ -119,71 +167,71 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
119{ 167{
120 unsigned long flags; 168 unsigned long flags;
121 struct ipath_rq *rq; 169 struct ipath_rq *rq;
170 struct ipath_rwq *wq;
122 struct ipath_srq *srq; 171 struct ipath_srq *srq;
123 struct ipath_rwqe *wqe; 172 struct ipath_rwqe *wqe;
124 int ret = 1; 173 void (*handler)(struct ib_event *, void *);
174 u32 tail;
175 int ret;
125 176
126 if (!qp->ibqp.srq) { 177 if (qp->ibqp.srq) {
178 srq = to_isrq(qp->ibqp.srq);
179 handler = srq->ibsrq.event_handler;
180 rq = &srq->rq;
181 } else {
182 srq = NULL;
183 handler = NULL;
127 rq = &qp->r_rq; 184 rq = &qp->r_rq;
128 spin_lock_irqsave(&rq->lock, flags);
129
130 if (unlikely(rq->tail == rq->head)) {
131 ret = 0;
132 goto done;
133 }
134 wqe = get_rwqe_ptr(rq, rq->tail);
135 qp->r_wr_id = wqe->wr_id;
136 if (!wr_id_only) {
137 qp->r_sge.sge = wqe->sg_list[0];
138 qp->r_sge.sg_list = wqe->sg_list + 1;
139 qp->r_sge.num_sge = wqe->num_sge;
140 qp->r_len = wqe->length;
141 }
142 if (++rq->tail >= rq->size)
143 rq->tail = 0;
144 goto done;
145 } 185 }
146 186
147 srq = to_isrq(qp->ibqp.srq);
148 rq = &srq->rq;
149 spin_lock_irqsave(&rq->lock, flags); 187 spin_lock_irqsave(&rq->lock, flags);
150 188 wq = rq->wq;
151 if (unlikely(rq->tail == rq->head)) { 189 tail = wq->tail;
152 ret = 0; 190 /* Validate tail before using it since it is user writable. */
153 goto done; 191 if (tail >= rq->size)
154 } 192 tail = 0;
155 wqe = get_rwqe_ptr(rq, rq->tail); 193 do {
194 if (unlikely(tail == wq->head)) {
195 spin_unlock_irqrestore(&rq->lock, flags);
196 ret = 0;
197 goto bail;
198 }
199 wqe = get_rwqe_ptr(rq, tail);
200 if (++tail >= rq->size)
201 tail = 0;
202 } while (!wr_id_only && !init_sge(qp, wqe));
156 qp->r_wr_id = wqe->wr_id; 203 qp->r_wr_id = wqe->wr_id;
157 if (!wr_id_only) { 204 wq->tail = tail;
158 qp->r_sge.sge = wqe->sg_list[0]; 205
159 qp->r_sge.sg_list = wqe->sg_list + 1; 206 ret = 1;
160 qp->r_sge.num_sge = wqe->num_sge; 207 if (handler) {
161 qp->r_len = wqe->length;
162 }
163 if (++rq->tail >= rq->size)
164 rq->tail = 0;
165 if (srq->ibsrq.event_handler) {
166 struct ib_event ev;
167 u32 n; 208 u32 n;
168 209
169 if (rq->head < rq->tail) 210 /*
170 n = rq->size + rq->head - rq->tail; 211 * validate head pointer value and compute
212 * the number of remaining WQEs.
213 */
214 n = wq->head;
215 if (n >= rq->size)
216 n = 0;
217 if (n < tail)
218 n += rq->size - tail;
171 else 219 else
172 n = rq->head - rq->tail; 220 n -= tail;
173 if (n < srq->limit) { 221 if (n < srq->limit) {
222 struct ib_event ev;
223
174 srq->limit = 0; 224 srq->limit = 0;
175 spin_unlock_irqrestore(&rq->lock, flags); 225 spin_unlock_irqrestore(&rq->lock, flags);
176 ev.device = qp->ibqp.device; 226 ev.device = qp->ibqp.device;
177 ev.element.srq = qp->ibqp.srq; 227 ev.element.srq = qp->ibqp.srq;
178 ev.event = IB_EVENT_SRQ_LIMIT_REACHED; 228 ev.event = IB_EVENT_SRQ_LIMIT_REACHED;
179 srq->ibsrq.event_handler(&ev, 229 handler(&ev, srq->ibsrq.srq_context);
180 srq->ibsrq.srq_context);
181 goto bail; 230 goto bail;
182 } 231 }
183 } 232 }
184
185done:
186 spin_unlock_irqrestore(&rq->lock, flags); 233 spin_unlock_irqrestore(&rq->lock, flags);
234
187bail: 235bail:
188 return ret; 236 return ret;
189} 237}
@@ -422,6 +470,15 @@ done:
422 wake_up(&qp->wait); 470 wake_up(&qp->wait);
423} 471}
424 472
473static int want_buffer(struct ipath_devdata *dd)
474{
475 set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl);
476 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
477 dd->ipath_sendctrl);
478
479 return 0;
480}
481
425/** 482/**
426 * ipath_no_bufs_available - tell the layer driver we need buffers 483 * ipath_no_bufs_available - tell the layer driver we need buffers
427 * @qp: the QP that caused the problem 484 * @qp: the QP that caused the problem
@@ -438,7 +495,7 @@ void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev)
438 list_add_tail(&qp->piowait, &dev->piowait); 495 list_add_tail(&qp->piowait, &dev->piowait);
439 spin_unlock_irqrestore(&dev->pending_lock, flags); 496 spin_unlock_irqrestore(&dev->pending_lock, flags);
440 /* 497 /*
441 * Note that as soon as ipath_layer_want_buffer() is called and 498 * Note that as soon as want_buffer() is called and
442 * possibly before it returns, ipath_ib_piobufavail() 499 * possibly before it returns, ipath_ib_piobufavail()
443 * could be called. If we are still in the tasklet function, 500 * could be called. If we are still in the tasklet function,
444 * tasklet_hi_schedule() will not call us until the next time 501 * tasklet_hi_schedule() will not call us until the next time
@@ -448,7 +505,7 @@ void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev)
448 */ 505 */
449 clear_bit(IPATH_S_BUSY, &qp->s_flags); 506 clear_bit(IPATH_S_BUSY, &qp->s_flags);
450 tasklet_unlock(&qp->s_task); 507 tasklet_unlock(&qp->s_task);
451 ipath_layer_want_buffer(dev->dd); 508 want_buffer(dev->dd);
452 dev->n_piowait++; 509 dev->n_piowait++;
453} 510}
454 511
@@ -563,7 +620,7 @@ u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr,
563 hdr->hop_limit = grh->hop_limit; 620 hdr->hop_limit = grh->hop_limit;
564 /* The SGID is 32-bit aligned. */ 621 /* The SGID is 32-bit aligned. */
565 hdr->sgid.global.subnet_prefix = dev->gid_prefix; 622 hdr->sgid.global.subnet_prefix = dev->gid_prefix;
566 hdr->sgid.global.interface_id = ipath_layer_get_guid(dev->dd); 623 hdr->sgid.global.interface_id = dev->dd->ipath_guid;
567 hdr->dgid = grh->dgid; 624 hdr->dgid = grh->dgid;
568 625
569 /* GRH header size in 32-bit words. */ 626 /* GRH header size in 32-bit words. */
@@ -595,8 +652,7 @@ void ipath_do_ruc_send(unsigned long data)
595 if (test_and_set_bit(IPATH_S_BUSY, &qp->s_flags)) 652 if (test_and_set_bit(IPATH_S_BUSY, &qp->s_flags))
596 goto bail; 653 goto bail;
597 654
598 if (unlikely(qp->remote_ah_attr.dlid == 655 if (unlikely(qp->remote_ah_attr.dlid == dev->dd->ipath_lid)) {
599 ipath_layer_get_lid(dev->dd))) {
600 ipath_ruc_loopback(qp); 656 ipath_ruc_loopback(qp);
601 goto clear; 657 goto clear;
602 } 658 }
@@ -663,8 +719,8 @@ again:
663 qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); 719 qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid);
664 qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + 720 qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords +
665 SIZE_OF_CRC); 721 SIZE_OF_CRC);
666 qp->s_hdr.lrh[3] = cpu_to_be16(ipath_layer_get_lid(dev->dd)); 722 qp->s_hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid);
667 bth0 |= ipath_layer_get_pkey(dev->dd, qp->s_pkey_index); 723 bth0 |= ipath_get_pkey(dev->dd, qp->s_pkey_index);
668 bth0 |= extra_bytes << 20; 724 bth0 |= extra_bytes << 20;
669 ohdr->bth[0] = cpu_to_be32(bth0); 725 ohdr->bth[0] = cpu_to_be32(bth0);
670 ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); 726 ohdr->bth[1] = cpu_to_be32(qp->remote_qpn);
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
index f760434660bd..941e866d9517 100644
--- a/drivers/infiniband/hw/ipath/ipath_srq.c
+++ b/drivers/infiniband/hw/ipath/ipath_srq.c
@@ -48,66 +48,39 @@ int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
48 struct ib_recv_wr **bad_wr) 48 struct ib_recv_wr **bad_wr)
49{ 49{
50 struct ipath_srq *srq = to_isrq(ibsrq); 50 struct ipath_srq *srq = to_isrq(ibsrq);
51 struct ipath_ibdev *dev = to_idev(ibsrq->device); 51 struct ipath_rwq *wq;
52 unsigned long flags; 52 unsigned long flags;
53 int ret; 53 int ret;
54 54
55 for (; wr; wr = wr->next) { 55 for (; wr; wr = wr->next) {
56 struct ipath_rwqe *wqe; 56 struct ipath_rwqe *wqe;
57 u32 next; 57 u32 next;
58 int i, j; 58 int i;
59 59
60 if (wr->num_sge > srq->rq.max_sge) { 60 if ((unsigned) wr->num_sge > srq->rq.max_sge) {
61 *bad_wr = wr; 61 *bad_wr = wr;
62 ret = -ENOMEM; 62 ret = -ENOMEM;
63 goto bail; 63 goto bail;
64 } 64 }
65 65
66 spin_lock_irqsave(&srq->rq.lock, flags); 66 spin_lock_irqsave(&srq->rq.lock, flags);
67 next = srq->rq.head + 1; 67 wq = srq->rq.wq;
68 next = wq->head + 1;
68 if (next >= srq->rq.size) 69 if (next >= srq->rq.size)
69 next = 0; 70 next = 0;
70 if (next == srq->rq.tail) { 71 if (next == wq->tail) {
71 spin_unlock_irqrestore(&srq->rq.lock, flags); 72 spin_unlock_irqrestore(&srq->rq.lock, flags);
72 *bad_wr = wr; 73 *bad_wr = wr;
73 ret = -ENOMEM; 74 ret = -ENOMEM;
74 goto bail; 75 goto bail;
75 } 76 }
76 77
77 wqe = get_rwqe_ptr(&srq->rq, srq->rq.head); 78 wqe = get_rwqe_ptr(&srq->rq, wq->head);
78 wqe->wr_id = wr->wr_id; 79 wqe->wr_id = wr->wr_id;
79 wqe->sg_list[0].mr = NULL; 80 wqe->num_sge = wr->num_sge;
80 wqe->sg_list[0].vaddr = NULL; 81 for (i = 0; i < wr->num_sge; i++)
81 wqe->sg_list[0].length = 0; 82 wqe->sg_list[i] = wr->sg_list[i];
82 wqe->sg_list[0].sge_length = 0; 83 wq->head = next;
83 wqe->length = 0;
84 for (i = 0, j = 0; i < wr->num_sge; i++) {
85 /* Check LKEY */
86 if (to_ipd(srq->ibsrq.pd)->user &&
87 wr->sg_list[i].lkey == 0) {
88 spin_unlock_irqrestore(&srq->rq.lock,
89 flags);
90 *bad_wr = wr;
91 ret = -EINVAL;
92 goto bail;
93 }
94 if (wr->sg_list[i].length == 0)
95 continue;
96 if (!ipath_lkey_ok(&dev->lk_table,
97 &wqe->sg_list[j],
98 &wr->sg_list[i],
99 IB_ACCESS_LOCAL_WRITE)) {
100 spin_unlock_irqrestore(&srq->rq.lock,
101 flags);
102 *bad_wr = wr;
103 ret = -EINVAL;
104 goto bail;
105 }
106 wqe->length += wr->sg_list[i].length;
107 j++;
108 }
109 wqe->num_sge = j;
110 srq->rq.head = next;
111 spin_unlock_irqrestore(&srq->rq.lock, flags); 84 spin_unlock_irqrestore(&srq->rq.lock, flags);
112 } 85 }
113 ret = 0; 86 ret = 0;
@@ -133,53 +106,95 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
133 106
134 if (dev->n_srqs_allocated == ib_ipath_max_srqs) { 107 if (dev->n_srqs_allocated == ib_ipath_max_srqs) {
135 ret = ERR_PTR(-ENOMEM); 108 ret = ERR_PTR(-ENOMEM);
136 goto bail; 109 goto done;
137 } 110 }
138 111
139 if (srq_init_attr->attr.max_wr == 0) { 112 if (srq_init_attr->attr.max_wr == 0) {
140 ret = ERR_PTR(-EINVAL); 113 ret = ERR_PTR(-EINVAL);
141 goto bail; 114 goto done;
142 } 115 }
143 116
144 if ((srq_init_attr->attr.max_sge > ib_ipath_max_srq_sges) || 117 if ((srq_init_attr->attr.max_sge > ib_ipath_max_srq_sges) ||
145 (srq_init_attr->attr.max_wr > ib_ipath_max_srq_wrs)) { 118 (srq_init_attr->attr.max_wr > ib_ipath_max_srq_wrs)) {
146 ret = ERR_PTR(-EINVAL); 119 ret = ERR_PTR(-EINVAL);
147 goto bail; 120 goto done;
148 } 121 }
149 122
150 srq = kmalloc(sizeof(*srq), GFP_KERNEL); 123 srq = kmalloc(sizeof(*srq), GFP_KERNEL);
151 if (!srq) { 124 if (!srq) {
152 ret = ERR_PTR(-ENOMEM); 125 ret = ERR_PTR(-ENOMEM);
153 goto bail; 126 goto done;
154 } 127 }
155 128
156 /* 129 /*
157 * Need to use vmalloc() if we want to support large #s of entries. 130 * Need to use vmalloc() if we want to support large #s of entries.
158 */ 131 */
159 srq->rq.size = srq_init_attr->attr.max_wr + 1; 132 srq->rq.size = srq_init_attr->attr.max_wr + 1;
160 sz = sizeof(struct ipath_sge) * srq_init_attr->attr.max_sge + 133 srq->rq.max_sge = srq_init_attr->attr.max_sge;
134 sz = sizeof(struct ib_sge) * srq->rq.max_sge +
161 sizeof(struct ipath_rwqe); 135 sizeof(struct ipath_rwqe);
162 srq->rq.wq = vmalloc(srq->rq.size * sz); 136 srq->rq.wq = vmalloc_user(sizeof(struct ipath_rwq) + srq->rq.size * sz);
163 if (!srq->rq.wq) { 137 if (!srq->rq.wq) {
164 kfree(srq);
165 ret = ERR_PTR(-ENOMEM); 138 ret = ERR_PTR(-ENOMEM);
166 goto bail; 139 goto bail_srq;
167 } 140 }
168 141
169 /* 142 /*
143 * Return the address of the RWQ as the offset to mmap.
144 * See ipath_mmap() for details.
145 */
146 if (udata && udata->outlen >= sizeof(__u64)) {
147 struct ipath_mmap_info *ip;
148 __u64 offset = (__u64) srq->rq.wq;
149 int err;
150
151 err = ib_copy_to_udata(udata, &offset, sizeof(offset));
152 if (err) {
153 ret = ERR_PTR(err);
154 goto bail_wq;
155 }
156
157 /* Allocate info for ipath_mmap(). */
158 ip = kmalloc(sizeof(*ip), GFP_KERNEL);
159 if (!ip) {
160 ret = ERR_PTR(-ENOMEM);
161 goto bail_wq;
162 }
163 srq->ip = ip;
164 ip->context = ibpd->uobject->context;
165 ip->obj = srq->rq.wq;
166 kref_init(&ip->ref);
167 ip->mmap_cnt = 0;
168 ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) +
169 srq->rq.size * sz);
170 spin_lock_irq(&dev->pending_lock);
171 ip->next = dev->pending_mmaps;
172 dev->pending_mmaps = ip;
173 spin_unlock_irq(&dev->pending_lock);
174 } else
175 srq->ip = NULL;
176
177 /*
170 * ib_create_srq() will initialize srq->ibsrq. 178 * ib_create_srq() will initialize srq->ibsrq.
171 */ 179 */
172 spin_lock_init(&srq->rq.lock); 180 spin_lock_init(&srq->rq.lock);
173 srq->rq.head = 0; 181 srq->rq.wq->head = 0;
174 srq->rq.tail = 0; 182 srq->rq.wq->tail = 0;
175 srq->rq.max_sge = srq_init_attr->attr.max_sge; 183 srq->rq.max_sge = srq_init_attr->attr.max_sge;
176 srq->limit = srq_init_attr->attr.srq_limit; 184 srq->limit = srq_init_attr->attr.srq_limit;
177 185
186 dev->n_srqs_allocated++;
187
178 ret = &srq->ibsrq; 188 ret = &srq->ibsrq;
189 goto done;
179 190
180 dev->n_srqs_allocated++; 191bail_wq:
192 vfree(srq->rq.wq);
181 193
182bail: 194bail_srq:
195 kfree(srq);
196
197done:
183 return ret; 198 return ret;
184} 199}
185 200
@@ -188,83 +203,130 @@ bail:
188 * @ibsrq: the SRQ to modify 203 * @ibsrq: the SRQ to modify
189 * @attr: the new attributes of the SRQ 204 * @attr: the new attributes of the SRQ
190 * @attr_mask: indicates which attributes to modify 205 * @attr_mask: indicates which attributes to modify
206 * @udata: user data for ipathverbs.so
191 */ 207 */
192int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, 208int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
193 enum ib_srq_attr_mask attr_mask) 209 enum ib_srq_attr_mask attr_mask,
210 struct ib_udata *udata)
194{ 211{
195 struct ipath_srq *srq = to_isrq(ibsrq); 212 struct ipath_srq *srq = to_isrq(ibsrq);
196 unsigned long flags; 213 int ret = 0;
197 int ret;
198 214
199 if (attr_mask & IB_SRQ_MAX_WR) 215 if (attr_mask & IB_SRQ_MAX_WR) {
200 if ((attr->max_wr > ib_ipath_max_srq_wrs) || 216 struct ipath_rwq *owq;
201 (attr->max_sge > srq->rq.max_sge)) { 217 struct ipath_rwq *wq;
202 ret = -EINVAL; 218 struct ipath_rwqe *p;
203 goto bail; 219 u32 sz, size, n, head, tail;
204 }
205 220
206 if (attr_mask & IB_SRQ_LIMIT) 221 /* Check that the requested sizes are below the limits. */
207 if (attr->srq_limit >= srq->rq.size) { 222 if ((attr->max_wr > ib_ipath_max_srq_wrs) ||
223 ((attr_mask & IB_SRQ_LIMIT) ?
224 attr->srq_limit : srq->limit) > attr->max_wr) {
208 ret = -EINVAL; 225 ret = -EINVAL;
209 goto bail; 226 goto bail;
210 } 227 }
211 228
212 if (attr_mask & IB_SRQ_MAX_WR) {
213 struct ipath_rwqe *wq, *p;
214 u32 sz, size, n;
215
216 sz = sizeof(struct ipath_rwqe) + 229 sz = sizeof(struct ipath_rwqe) +
217 attr->max_sge * sizeof(struct ipath_sge); 230 srq->rq.max_sge * sizeof(struct ib_sge);
218 size = attr->max_wr + 1; 231 size = attr->max_wr + 1;
219 wq = vmalloc(size * sz); 232 wq = vmalloc_user(sizeof(struct ipath_rwq) + size * sz);
220 if (!wq) { 233 if (!wq) {
221 ret = -ENOMEM; 234 ret = -ENOMEM;
222 goto bail; 235 goto bail;
223 } 236 }
224 237
225 spin_lock_irqsave(&srq->rq.lock, flags); 238 /*
226 if (srq->rq.head < srq->rq.tail) 239 * Return the address of the RWQ as the offset to mmap.
227 n = srq->rq.size + srq->rq.head - srq->rq.tail; 240 * See ipath_mmap() for details.
241 */
242 if (udata && udata->inlen >= sizeof(__u64)) {
243 __u64 offset_addr;
244 __u64 offset = (__u64) wq;
245
246 ret = ib_copy_from_udata(&offset_addr, udata,
247 sizeof(offset_addr));
248 if (ret) {
249 vfree(wq);
250 goto bail;
251 }
252 udata->outbuf = (void __user *) offset_addr;
253 ret = ib_copy_to_udata(udata, &offset,
254 sizeof(offset));
255 if (ret) {
256 vfree(wq);
257 goto bail;
258 }
259 }
260
261 spin_lock_irq(&srq->rq.lock);
262 /*
263 * validate head pointer value and compute
264 * the number of remaining WQEs.
265 */
266 owq = srq->rq.wq;
267 head = owq->head;
268 if (head >= srq->rq.size)
269 head = 0;
270 tail = owq->tail;
271 if (tail >= srq->rq.size)
272 tail = 0;
273 n = head;
274 if (n < tail)
275 n += srq->rq.size - tail;
228 else 276 else
229 n = srq->rq.head - srq->rq.tail; 277 n -= tail;
230 if (size <= n || size <= srq->limit) { 278 if (size <= n) {
231 spin_unlock_irqrestore(&srq->rq.lock, flags); 279 spin_unlock_irq(&srq->rq.lock);
232 vfree(wq); 280 vfree(wq);
233 ret = -EINVAL; 281 ret = -EINVAL;
234 goto bail; 282 goto bail;
235 } 283 }
236 n = 0; 284 n = 0;
237 p = wq; 285 p = wq->wq;
238 while (srq->rq.tail != srq->rq.head) { 286 while (tail != head) {
239 struct ipath_rwqe *wqe; 287 struct ipath_rwqe *wqe;
240 int i; 288 int i;
241 289
242 wqe = get_rwqe_ptr(&srq->rq, srq->rq.tail); 290 wqe = get_rwqe_ptr(&srq->rq, tail);
243 p->wr_id = wqe->wr_id; 291 p->wr_id = wqe->wr_id;
244 p->length = wqe->length;
245 p->num_sge = wqe->num_sge; 292 p->num_sge = wqe->num_sge;
246 for (i = 0; i < wqe->num_sge; i++) 293 for (i = 0; i < wqe->num_sge; i++)
247 p->sg_list[i] = wqe->sg_list[i]; 294 p->sg_list[i] = wqe->sg_list[i];
248 n++; 295 n++;
249 p = (struct ipath_rwqe *)((char *) p + sz); 296 p = (struct ipath_rwqe *)((char *) p + sz);
250 if (++srq->rq.tail >= srq->rq.size) 297 if (++tail >= srq->rq.size)
251 srq->rq.tail = 0; 298 tail = 0;
252 } 299 }
253 vfree(srq->rq.wq);
254 srq->rq.wq = wq; 300 srq->rq.wq = wq;
255 srq->rq.size = size; 301 srq->rq.size = size;
256 srq->rq.head = n; 302 wq->head = n;
257 srq->rq.tail = 0; 303 wq->tail = 0;
258 srq->rq.max_sge = attr->max_sge; 304 if (attr_mask & IB_SRQ_LIMIT)
259 spin_unlock_irqrestore(&srq->rq.lock, flags); 305 srq->limit = attr->srq_limit;
260 } 306 spin_unlock_irq(&srq->rq.lock);
261 307
262 if (attr_mask & IB_SRQ_LIMIT) { 308 vfree(owq);
263 spin_lock_irqsave(&srq->rq.lock, flags); 309
264 srq->limit = attr->srq_limit; 310 if (srq->ip) {
265 spin_unlock_irqrestore(&srq->rq.lock, flags); 311 struct ipath_mmap_info *ip = srq->ip;
312 struct ipath_ibdev *dev = to_idev(srq->ibsrq.device);
313
314 ip->obj = wq;
315 ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) +
316 size * sz);
317 spin_lock_irq(&dev->pending_lock);
318 ip->next = dev->pending_mmaps;
319 dev->pending_mmaps = ip;
320 spin_unlock_irq(&dev->pending_lock);
321 }
322 } else if (attr_mask & IB_SRQ_LIMIT) {
323 spin_lock_irq(&srq->rq.lock);
324 if (attr->srq_limit >= srq->rq.size)
325 ret = -EINVAL;
326 else
327 srq->limit = attr->srq_limit;
328 spin_unlock_irq(&srq->rq.lock);
266 } 329 }
267 ret = 0;
268 330
269bail: 331bail:
270 return ret; 332 return ret;
diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c
index 70351b7e35c0..30a825928fcf 100644
--- a/drivers/infiniband/hw/ipath/ipath_stats.c
+++ b/drivers/infiniband/hw/ipath/ipath_stats.c
@@ -271,33 +271,6 @@ void ipath_get_faststats(unsigned long opaque)
271 } 271 }
272 } 272 }
273 273
274 if (dd->ipath_nosma_bufs) {
275 dd->ipath_nosma_secs += 5;
276 if (dd->ipath_nosma_secs >= 30) {
277 ipath_cdbg(SMA, "No SMA bufs avail %u seconds; "
278 "cancelling pending sends\n",
279 dd->ipath_nosma_secs);
280 /*
281 * issue an abort as well, in case we have a packet
282 * stuck in launch fifo. This could corrupt an
283 * outgoing user packet in the worst case,
284 * but this is a pretty catastrophic, anyway.
285 */
286 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
287 INFINIPATH_S_ABORT);
288 ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
289 dd->ipath_piobcnt2k +
290 dd->ipath_piobcnt4k -
291 dd->ipath_lastport_piobuf);
292 /* start again, if necessary */
293 dd->ipath_nosma_secs = 0;
294 } else
295 ipath_cdbg(SMA, "No SMA bufs avail %u tries, "
296 "after %u seconds\n",
297 dd->ipath_nosma_bufs,
298 dd->ipath_nosma_secs);
299 }
300
301done: 274done:
302 mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5); 275 mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5);
303} 276}
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c
index b98821d7801d..e299148c4b68 100644
--- a/drivers/infiniband/hw/ipath/ipath_sysfs.c
+++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c
@@ -35,7 +35,6 @@
35#include <linux/pci.h> 35#include <linux/pci.h>
36 36
37#include "ipath_kernel.h" 37#include "ipath_kernel.h"
38#include "ipath_layer.h"
39#include "ipath_common.h" 38#include "ipath_common.h"
40 39
41/** 40/**
@@ -76,7 +75,7 @@ bail:
76static ssize_t show_version(struct device_driver *dev, char *buf) 75static ssize_t show_version(struct device_driver *dev, char *buf)
77{ 76{
78 /* The string printed here is already newline-terminated. */ 77 /* The string printed here is already newline-terminated. */
79 return scnprintf(buf, PAGE_SIZE, "%s", ipath_core_version); 78 return scnprintf(buf, PAGE_SIZE, "%s", ib_ipath_version);
80} 79}
81 80
82static ssize_t show_num_units(struct device_driver *dev, char *buf) 81static ssize_t show_num_units(struct device_driver *dev, char *buf)
@@ -108,8 +107,8 @@ static const char *ipath_status_str[] = {
108 "Initted", 107 "Initted",
109 "Disabled", 108 "Disabled",
110 "Admin_Disabled", 109 "Admin_Disabled",
111 "OIB_SMA", 110 "", /* This used to be the old "OIB_SMA" status. */
112 "SMA", 111 "", /* This used to be the old "SMA" status. */
113 "Present", 112 "Present",
114 "IB_link_up", 113 "IB_link_up",
115 "IB_configured", 114 "IB_configured",
@@ -227,7 +226,6 @@ static ssize_t store_mlid(struct device *dev,
227 unit = dd->ipath_unit; 226 unit = dd->ipath_unit;
228 227
229 dd->ipath_mlid = mlid; 228 dd->ipath_mlid = mlid;
230 ipath_layer_intr(dd, IPATH_LAYER_INT_BCAST);
231 229
232 goto bail; 230 goto bail;
233invalid: 231invalid:
@@ -467,7 +465,7 @@ static ssize_t store_link_state(struct device *dev,
467 if (ret < 0) 465 if (ret < 0)
468 goto invalid; 466 goto invalid;
469 467
470 r = ipath_layer_set_linkstate(dd, state); 468 r = ipath_set_linkstate(dd, state);
471 if (r < 0) { 469 if (r < 0) {
472 ret = r; 470 ret = r;
473 goto bail; 471 goto bail;
@@ -502,7 +500,7 @@ static ssize_t store_mtu(struct device *dev,
502 if (ret < 0) 500 if (ret < 0)
503 goto invalid; 501 goto invalid;
504 502
505 r = ipath_layer_set_mtu(dd, mtu); 503 r = ipath_set_mtu(dd, mtu);
506 if (r < 0) 504 if (r < 0)
507 ret = r; 505 ret = r;
508 506
@@ -563,6 +561,33 @@ bail:
563 return ret; 561 return ret;
564} 562}
565 563
564static ssize_t store_rx_pol_inv(struct device *dev,
565 struct device_attribute *attr,
566 const char *buf,
567 size_t count)
568{
569 struct ipath_devdata *dd = dev_get_drvdata(dev);
570 int ret, r;
571 u16 val;
572
573 ret = ipath_parse_ushort(buf, &val);
574 if (ret < 0)
575 goto invalid;
576
577 r = ipath_set_rx_pol_inv(dd, val);
578 if (r < 0) {
579 ret = r;
580 goto bail;
581 }
582
583 goto bail;
584invalid:
585 ipath_dev_err(dd, "attempt to set invalid Rx Polarity invert\n");
586bail:
587 return ret;
588}
589
590
566static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL); 591static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL);
567static DRIVER_ATTR(version, S_IRUGO, show_version, NULL); 592static DRIVER_ATTR(version, S_IRUGO, show_version, NULL);
568 593
@@ -589,6 +614,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
589static DEVICE_ATTR(status_str, S_IRUGO, show_status_str, NULL); 614static DEVICE_ATTR(status_str, S_IRUGO, show_status_str, NULL);
590static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL); 615static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL);
591static DEVICE_ATTR(unit, S_IRUGO, show_unit, NULL); 616static DEVICE_ATTR(unit, S_IRUGO, show_unit, NULL);
617static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv);
592 618
593static struct attribute *dev_attributes[] = { 619static struct attribute *dev_attributes[] = {
594 &dev_attr_guid.attr, 620 &dev_attr_guid.attr,
@@ -603,6 +629,7 @@ static struct attribute *dev_attributes[] = {
603 &dev_attr_boardversion.attr, 629 &dev_attr_boardversion.attr,
604 &dev_attr_unit.attr, 630 &dev_attr_unit.attr,
605 &dev_attr_enabled.attr, 631 &dev_attr_enabled.attr,
632 &dev_attr_rx_pol_inv.attr,
606 NULL 633 NULL
607}; 634};
608 635
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c
index c33abea2d5a7..0fd3cded16ba 100644
--- a/drivers/infiniband/hw/ipath/ipath_uc.c
+++ b/drivers/infiniband/hw/ipath/ipath_uc.c
@@ -32,7 +32,7 @@
32 */ 32 */
33 33
34#include "ipath_verbs.h" 34#include "ipath_verbs.h"
35#include "ipath_common.h" 35#include "ipath_kernel.h"
36 36
37/* cut down ridiculously long IB macro names */ 37/* cut down ridiculously long IB macro names */
38#define OP(x) IB_OPCODE_UC_##x 38#define OP(x) IB_OPCODE_UC_##x
@@ -261,8 +261,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
261 * size to 56 bytes so the last 4 bytes of 261 * size to 56 bytes so the last 4 bytes of
262 * the BTH header (PSN) is in the data buffer. 262 * the BTH header (PSN) is in the data buffer.
263 */ 263 */
264 header_in_data = 264 header_in_data = dev->dd->ipath_rcvhdrentsize == 16;
265 ipath_layer_get_rcvhdrentsize(dev->dd) == 16;
266 if (header_in_data) { 265 if (header_in_data) {
267 psn = be32_to_cpu(((__be32 *) data)[0]); 266 psn = be32_to_cpu(((__be32 *) data)[0]);
268 data += sizeof(__be32); 267 data += sizeof(__be32);
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 3466129af804..6991d1d74e3c 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -34,7 +34,54 @@
34#include <rdma/ib_smi.h> 34#include <rdma/ib_smi.h>
35 35
36#include "ipath_verbs.h" 36#include "ipath_verbs.h"
37#include "ipath_common.h" 37#include "ipath_kernel.h"
38
39static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
40 u32 *lengthp, struct ipath_sge_state *ss)
41{
42 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
43 int user = to_ipd(qp->ibqp.pd)->user;
44 int i, j, ret;
45 struct ib_wc wc;
46
47 *lengthp = 0;
48 for (i = j = 0; i < wqe->num_sge; i++) {
49 if (wqe->sg_list[i].length == 0)
50 continue;
51 /* Check LKEY */
52 if ((user && wqe->sg_list[i].lkey == 0) ||
53 !ipath_lkey_ok(&dev->lk_table,
54 j ? &ss->sg_list[j - 1] : &ss->sge,
55 &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
56 goto bad_lkey;
57 *lengthp += wqe->sg_list[i].length;
58 j++;
59 }
60 ss->num_sge = j;
61 ret = 1;
62 goto bail;
63
64bad_lkey:
65 wc.wr_id = wqe->wr_id;
66 wc.status = IB_WC_LOC_PROT_ERR;
67 wc.opcode = IB_WC_RECV;
68 wc.vendor_err = 0;
69 wc.byte_len = 0;
70 wc.imm_data = 0;
71 wc.qp_num = qp->ibqp.qp_num;
72 wc.src_qp = 0;
73 wc.wc_flags = 0;
74 wc.pkey_index = 0;
75 wc.slid = 0;
76 wc.sl = 0;
77 wc.dlid_path_bits = 0;
78 wc.port_num = 0;
79 /* Signal solicited completion event. */
80 ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
81 ret = 0;
82bail:
83 return ret;
84}
38 85
39/** 86/**
40 * ipath_ud_loopback - handle send on loopback QPs 87 * ipath_ud_loopback - handle send on loopback QPs
@@ -46,6 +93,8 @@
46 * 93 *
47 * This is called from ipath_post_ud_send() to forward a WQE addressed 94 * This is called from ipath_post_ud_send() to forward a WQE addressed
48 * to the same HCA. 95 * to the same HCA.
96 * Note that the receive interrupt handler may be calling ipath_ud_rcv()
97 * while this is being called.
49 */ 98 */
50static void ipath_ud_loopback(struct ipath_qp *sqp, 99static void ipath_ud_loopback(struct ipath_qp *sqp,
51 struct ipath_sge_state *ss, 100 struct ipath_sge_state *ss,
@@ -60,7 +109,11 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
60 struct ipath_srq *srq; 109 struct ipath_srq *srq;
61 struct ipath_sge_state rsge; 110 struct ipath_sge_state rsge;
62 struct ipath_sge *sge; 111 struct ipath_sge *sge;
112 struct ipath_rwq *wq;
63 struct ipath_rwqe *wqe; 113 struct ipath_rwqe *wqe;
114 void (*handler)(struct ib_event *, void *);
115 u32 tail;
116 u32 rlen;
64 117
65 qp = ipath_lookup_qpn(&dev->qp_table, wr->wr.ud.remote_qpn); 118 qp = ipath_lookup_qpn(&dev->qp_table, wr->wr.ud.remote_qpn);
66 if (!qp) 119 if (!qp)
@@ -94,6 +147,13 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
94 wc->imm_data = 0; 147 wc->imm_data = 0;
95 } 148 }
96 149
150 if (wr->num_sge > 1) {
151 rsge.sg_list = kmalloc((wr->num_sge - 1) *
152 sizeof(struct ipath_sge),
153 GFP_ATOMIC);
154 } else
155 rsge.sg_list = NULL;
156
97 /* 157 /*
98 * Get the next work request entry to find where to put the data. 158 * Get the next work request entry to find where to put the data.
99 * Note that it is safe to drop the lock after changing rq->tail 159 * Note that it is safe to drop the lock after changing rq->tail
@@ -101,37 +161,52 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
101 */ 161 */
102 if (qp->ibqp.srq) { 162 if (qp->ibqp.srq) {
103 srq = to_isrq(qp->ibqp.srq); 163 srq = to_isrq(qp->ibqp.srq);
164 handler = srq->ibsrq.event_handler;
104 rq = &srq->rq; 165 rq = &srq->rq;
105 } else { 166 } else {
106 srq = NULL; 167 srq = NULL;
168 handler = NULL;
107 rq = &qp->r_rq; 169 rq = &qp->r_rq;
108 } 170 }
171
109 spin_lock_irqsave(&rq->lock, flags); 172 spin_lock_irqsave(&rq->lock, flags);
110 if (rq->tail == rq->head) { 173 wq = rq->wq;
111 spin_unlock_irqrestore(&rq->lock, flags); 174 tail = wq->tail;
112 dev->n_pkt_drops++; 175 while (1) {
113 goto done; 176 if (unlikely(tail == wq->head)) {
177 spin_unlock_irqrestore(&rq->lock, flags);
178 dev->n_pkt_drops++;
179 goto bail_sge;
180 }
181 wqe = get_rwqe_ptr(rq, tail);
182 if (++tail >= rq->size)
183 tail = 0;
184 if (init_sge(qp, wqe, &rlen, &rsge))
185 break;
186 wq->tail = tail;
114 } 187 }
115 /* Silently drop packets which are too big. */ 188 /* Silently drop packets which are too big. */
116 wqe = get_rwqe_ptr(rq, rq->tail); 189 if (wc->byte_len > rlen) {
117 if (wc->byte_len > wqe->length) {
118 spin_unlock_irqrestore(&rq->lock, flags); 190 spin_unlock_irqrestore(&rq->lock, flags);
119 dev->n_pkt_drops++; 191 dev->n_pkt_drops++;
120 goto done; 192 goto bail_sge;
121 } 193 }
194 wq->tail = tail;
122 wc->wr_id = wqe->wr_id; 195 wc->wr_id = wqe->wr_id;
123 rsge.sge = wqe->sg_list[0]; 196 if (handler) {
124 rsge.sg_list = wqe->sg_list + 1;
125 rsge.num_sge = wqe->num_sge;
126 if (++rq->tail >= rq->size)
127 rq->tail = 0;
128 if (srq && srq->ibsrq.event_handler) {
129 u32 n; 197 u32 n;
130 198
131 if (rq->head < rq->tail) 199 /*
132 n = rq->size + rq->head - rq->tail; 200 * validate head pointer value and compute
201 * the number of remaining WQEs.
202 */
203 n = wq->head;
204 if (n >= rq->size)
205 n = 0;
206 if (n < tail)
207 n += rq->size - tail;
133 else 208 else
134 n = rq->head - rq->tail; 209 n -= tail;
135 if (n < srq->limit) { 210 if (n < srq->limit) {
136 struct ib_event ev; 211 struct ib_event ev;
137 212
@@ -140,12 +215,12 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
140 ev.device = qp->ibqp.device; 215 ev.device = qp->ibqp.device;
141 ev.element.srq = qp->ibqp.srq; 216 ev.element.srq = qp->ibqp.srq;
142 ev.event = IB_EVENT_SRQ_LIMIT_REACHED; 217 ev.event = IB_EVENT_SRQ_LIMIT_REACHED;
143 srq->ibsrq.event_handler(&ev, 218 handler(&ev, srq->ibsrq.srq_context);
144 srq->ibsrq.srq_context);
145 } else 219 } else
146 spin_unlock_irqrestore(&rq->lock, flags); 220 spin_unlock_irqrestore(&rq->lock, flags);
147 } else 221 } else
148 spin_unlock_irqrestore(&rq->lock, flags); 222 spin_unlock_irqrestore(&rq->lock, flags);
223
149 ah_attr = &to_iah(wr->wr.ud.ah)->attr; 224 ah_attr = &to_iah(wr->wr.ud.ah)->attr;
150 if (ah_attr->ah_flags & IB_AH_GRH) { 225 if (ah_attr->ah_flags & IB_AH_GRH) {
151 ipath_copy_sge(&rsge, &ah_attr->grh, sizeof(struct ib_grh)); 226 ipath_copy_sge(&rsge, &ah_attr->grh, sizeof(struct ib_grh));
@@ -186,7 +261,7 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
186 wc->src_qp = sqp->ibqp.qp_num; 261 wc->src_qp = sqp->ibqp.qp_num;
187 /* XXX do we know which pkey matched? Only needed for GSI. */ 262 /* XXX do we know which pkey matched? Only needed for GSI. */
188 wc->pkey_index = 0; 263 wc->pkey_index = 0;
189 wc->slid = ipath_layer_get_lid(dev->dd) | 264 wc->slid = dev->dd->ipath_lid |
190 (ah_attr->src_path_bits & 265 (ah_attr->src_path_bits &
191 ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1)); 266 ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1));
192 wc->sl = ah_attr->sl; 267 wc->sl = ah_attr->sl;
@@ -196,6 +271,8 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
196 ipath_cq_enter(to_icq(qp->ibqp.recv_cq), wc, 271 ipath_cq_enter(to_icq(qp->ibqp.recv_cq), wc,
197 wr->send_flags & IB_SEND_SOLICITED); 272 wr->send_flags & IB_SEND_SOLICITED);
198 273
274bail_sge:
275 kfree(rsge.sg_list);
199done: 276done:
200 if (atomic_dec_and_test(&qp->refcount)) 277 if (atomic_dec_and_test(&qp->refcount))
201 wake_up(&qp->wait); 278 wake_up(&qp->wait);
@@ -276,7 +353,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
276 ss.num_sge++; 353 ss.num_sge++;
277 } 354 }
278 /* Check for invalid packet size. */ 355 /* Check for invalid packet size. */
279 if (len > ipath_layer_get_ibmtu(dev->dd)) { 356 if (len > dev->dd->ipath_ibmtu) {
280 ret = -EINVAL; 357 ret = -EINVAL;
281 goto bail; 358 goto bail;
282 } 359 }
@@ -298,7 +375,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
298 dev->n_unicast_xmit++; 375 dev->n_unicast_xmit++;
299 lid = ah_attr->dlid & 376 lid = ah_attr->dlid &
300 ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); 377 ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1);
301 if (unlikely(lid == ipath_layer_get_lid(dev->dd))) { 378 if (unlikely(lid == dev->dd->ipath_lid)) {
302 /* 379 /*
303 * Pass in an uninitialized ib_wc to save stack 380 * Pass in an uninitialized ib_wc to save stack
304 * space. 381 * space.
@@ -327,7 +404,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
327 qp->s_hdr.u.l.grh.sgid.global.subnet_prefix = 404 qp->s_hdr.u.l.grh.sgid.global.subnet_prefix =
328 dev->gid_prefix; 405 dev->gid_prefix;
329 qp->s_hdr.u.l.grh.sgid.global.interface_id = 406 qp->s_hdr.u.l.grh.sgid.global.interface_id =
330 ipath_layer_get_guid(dev->dd); 407 dev->dd->ipath_guid;
331 qp->s_hdr.u.l.grh.dgid = ah_attr->grh.dgid; 408 qp->s_hdr.u.l.grh.dgid = ah_attr->grh.dgid;
332 /* 409 /*
333 * Don't worry about sending to locally attached multicast 410 * Don't worry about sending to locally attached multicast
@@ -357,7 +434,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
357 qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); 434 qp->s_hdr.lrh[0] = cpu_to_be16(lrh0);
358 qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ 435 qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */
359 qp->s_hdr.lrh[2] = cpu_to_be16(hwords + nwords + SIZE_OF_CRC); 436 qp->s_hdr.lrh[2] = cpu_to_be16(hwords + nwords + SIZE_OF_CRC);
360 lid = ipath_layer_get_lid(dev->dd); 437 lid = dev->dd->ipath_lid;
361 if (lid) { 438 if (lid) {
362 lid |= ah_attr->src_path_bits & 439 lid |= ah_attr->src_path_bits &
363 ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); 440 ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1);
@@ -368,7 +445,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
368 bth0 |= 1 << 23; 445 bth0 |= 1 << 23;
369 bth0 |= extra_bytes << 20; 446 bth0 |= extra_bytes << 20;
370 bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? IPATH_DEFAULT_P_KEY : 447 bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? IPATH_DEFAULT_P_KEY :
371 ipath_layer_get_pkey(dev->dd, qp->s_pkey_index); 448 ipath_get_pkey(dev->dd, qp->s_pkey_index);
372 ohdr->bth[0] = cpu_to_be32(bth0); 449 ohdr->bth[0] = cpu_to_be32(bth0);
373 /* 450 /*
374 * Use the multicast QP if the destination LID is a multicast LID. 451 * Use the multicast QP if the destination LID is a multicast LID.
@@ -433,13 +510,9 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
433 int opcode; 510 int opcode;
434 u32 hdrsize; 511 u32 hdrsize;
435 u32 pad; 512 u32 pad;
436 unsigned long flags;
437 struct ib_wc wc; 513 struct ib_wc wc;
438 u32 qkey; 514 u32 qkey;
439 u32 src_qp; 515 u32 src_qp;
440 struct ipath_rq *rq;
441 struct ipath_srq *srq;
442 struct ipath_rwqe *wqe;
443 u16 dlid; 516 u16 dlid;
444 int header_in_data; 517 int header_in_data;
445 518
@@ -458,8 +531,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
458 * the eager header buffer size to 56 bytes so the last 12 531 * the eager header buffer size to 56 bytes so the last 12
459 * bytes of the IB header is in the data buffer. 532 * bytes of the IB header is in the data buffer.
460 */ 533 */
461 header_in_data = 534 header_in_data = dev->dd->ipath_rcvhdrentsize == 16;
462 ipath_layer_get_rcvhdrentsize(dev->dd) == 16;
463 if (header_in_data) { 535 if (header_in_data) {
464 qkey = be32_to_cpu(((__be32 *) data)[1]); 536 qkey = be32_to_cpu(((__be32 *) data)[1]);
465 src_qp = be32_to_cpu(((__be32 *) data)[2]); 537 src_qp = be32_to_cpu(((__be32 *) data)[2]);
@@ -547,19 +619,10 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
547 619
548 /* 620 /*
549 * Get the next work request entry to find where to put the data. 621 * Get the next work request entry to find where to put the data.
550 * Note that it is safe to drop the lock after changing rq->tail
551 * since ipath_post_receive() won't fill the empty slot.
552 */ 622 */
553 if (qp->ibqp.srq) { 623 if (qp->r_reuse_sge)
554 srq = to_isrq(qp->ibqp.srq); 624 qp->r_reuse_sge = 0;
555 rq = &srq->rq; 625 else if (!ipath_get_rwqe(qp, 0)) {
556 } else {
557 srq = NULL;
558 rq = &qp->r_rq;
559 }
560 spin_lock_irqsave(&rq->lock, flags);
561 if (rq->tail == rq->head) {
562 spin_unlock_irqrestore(&rq->lock, flags);
563 /* 626 /*
564 * Count VL15 packets dropped due to no receive buffer. 627 * Count VL15 packets dropped due to no receive buffer.
565 * Otherwise, count them as buffer overruns since usually, 628 * Otherwise, count them as buffer overruns since usually,
@@ -573,39 +636,11 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
573 goto bail; 636 goto bail;
574 } 637 }
575 /* Silently drop packets which are too big. */ 638 /* Silently drop packets which are too big. */
576 wqe = get_rwqe_ptr(rq, rq->tail); 639 if (wc.byte_len > qp->r_len) {
577 if (wc.byte_len > wqe->length) { 640 qp->r_reuse_sge = 1;
578 spin_unlock_irqrestore(&rq->lock, flags);
579 dev->n_pkt_drops++; 641 dev->n_pkt_drops++;
580 goto bail; 642 goto bail;
581 } 643 }
582 wc.wr_id = wqe->wr_id;
583 qp->r_sge.sge = wqe->sg_list[0];
584 qp->r_sge.sg_list = wqe->sg_list + 1;
585 qp->r_sge.num_sge = wqe->num_sge;
586 if (++rq->tail >= rq->size)
587 rq->tail = 0;
588 if (srq && srq->ibsrq.event_handler) {
589 u32 n;
590
591 if (rq->head < rq->tail)
592 n = rq->size + rq->head - rq->tail;
593 else
594 n = rq->head - rq->tail;
595 if (n < srq->limit) {
596 struct ib_event ev;
597
598 srq->limit = 0;
599 spin_unlock_irqrestore(&rq->lock, flags);
600 ev.device = qp->ibqp.device;
601 ev.element.srq = qp->ibqp.srq;
602 ev.event = IB_EVENT_SRQ_LIMIT_REACHED;
603 srq->ibsrq.event_handler(&ev,
604 srq->ibsrq.srq_context);
605 } else
606 spin_unlock_irqrestore(&rq->lock, flags);
607 } else
608 spin_unlock_irqrestore(&rq->lock, flags);
609 if (has_grh) { 644 if (has_grh) {
610 ipath_copy_sge(&qp->r_sge, &hdr->u.l.grh, 645 ipath_copy_sge(&qp->r_sge, &hdr->u.l.grh,
611 sizeof(struct ib_grh)); 646 sizeof(struct ib_grh));
@@ -614,6 +649,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
614 ipath_skip_sge(&qp->r_sge, sizeof(struct ib_grh)); 649 ipath_skip_sge(&qp->r_sge, sizeof(struct ib_grh));
615 ipath_copy_sge(&qp->r_sge, data, 650 ipath_copy_sge(&qp->r_sge, data,
616 wc.byte_len - sizeof(struct ib_grh)); 651 wc.byte_len - sizeof(struct ib_grh));
652 wc.wr_id = qp->r_wr_id;
617 wc.status = IB_WC_SUCCESS; 653 wc.status = IB_WC_SUCCESS;
618 wc.opcode = IB_WC_RECV; 654 wc.opcode = IB_WC_RECV;
619 wc.vendor_err = 0; 655 wc.vendor_err = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index d70a9b6b5239..b8381c5e72bd 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -33,15 +33,13 @@
33 33
34#include <rdma/ib_mad.h> 34#include <rdma/ib_mad.h>
35#include <rdma/ib_user_verbs.h> 35#include <rdma/ib_user_verbs.h>
36#include <linux/io.h>
36#include <linux/utsname.h> 37#include <linux/utsname.h>
37 38
38#include "ipath_kernel.h" 39#include "ipath_kernel.h"
39#include "ipath_verbs.h" 40#include "ipath_verbs.h"
40#include "ipath_common.h" 41#include "ipath_common.h"
41 42
42/* Not static, because we don't want the compiler removing it */
43const char ipath_verbs_version[] = "ipath_verbs " IPATH_IDSTR;
44
45static unsigned int ib_ipath_qp_table_size = 251; 43static unsigned int ib_ipath_qp_table_size = 251;
46module_param_named(qp_table_size, ib_ipath_qp_table_size, uint, S_IRUGO); 44module_param_named(qp_table_size, ib_ipath_qp_table_size, uint, S_IRUGO);
47MODULE_PARM_DESC(qp_table_size, "QP table size"); 45MODULE_PARM_DESC(qp_table_size, "QP table size");
@@ -52,10 +50,6 @@ module_param_named(lkey_table_size, ib_ipath_lkey_table_size, uint,
52MODULE_PARM_DESC(lkey_table_size, 50MODULE_PARM_DESC(lkey_table_size,
53 "LKEY table size in bits (2^n, 1 <= n <= 23)"); 51 "LKEY table size in bits (2^n, 1 <= n <= 23)");
54 52
55unsigned int ib_ipath_debug; /* debug mask */
56module_param_named(debug, ib_ipath_debug, uint, S_IWUSR | S_IRUGO);
57MODULE_PARM_DESC(debug, "Verbs debug mask");
58
59static unsigned int ib_ipath_max_pds = 0xFFFF; 53static unsigned int ib_ipath_max_pds = 0xFFFF;
60module_param_named(max_pds, ib_ipath_max_pds, uint, S_IWUSR | S_IRUGO); 54module_param_named(max_pds, ib_ipath_max_pds, uint, S_IWUSR | S_IRUGO);
61MODULE_PARM_DESC(max_pds, 55MODULE_PARM_DESC(max_pds,
@@ -79,6 +73,10 @@ module_param_named(max_qp_wrs, ib_ipath_max_qp_wrs, uint,
79 S_IWUSR | S_IRUGO); 73 S_IWUSR | S_IRUGO);
80MODULE_PARM_DESC(max_qp_wrs, "Maximum number of QP WRs to support"); 74MODULE_PARM_DESC(max_qp_wrs, "Maximum number of QP WRs to support");
81 75
76unsigned int ib_ipath_max_qps = 16384;
77module_param_named(max_qps, ib_ipath_max_qps, uint, S_IWUSR | S_IRUGO);
78MODULE_PARM_DESC(max_qps, "Maximum number of QPs to support");
79
82unsigned int ib_ipath_max_sges = 0x60; 80unsigned int ib_ipath_max_sges = 0x60;
83module_param_named(max_sges, ib_ipath_max_sges, uint, S_IWUSR | S_IRUGO); 81module_param_named(max_sges, ib_ipath_max_sges, uint, S_IWUSR | S_IRUGO);
84MODULE_PARM_DESC(max_sges, "Maximum number of SGEs to support"); 82MODULE_PARM_DESC(max_sges, "Maximum number of SGEs to support");
@@ -109,9 +107,9 @@ module_param_named(max_srq_wrs, ib_ipath_max_srq_wrs,
109 uint, S_IWUSR | S_IRUGO); 107 uint, S_IWUSR | S_IRUGO);
110MODULE_PARM_DESC(max_srq_wrs, "Maximum number of SRQ WRs support"); 108MODULE_PARM_DESC(max_srq_wrs, "Maximum number of SRQ WRs support");
111 109
112MODULE_LICENSE("GPL"); 110static unsigned int ib_ipath_disable_sma;
113MODULE_AUTHOR("QLogic <support@pathscale.com>"); 111module_param_named(disable_sma, ib_ipath_disable_sma, uint, S_IWUSR | S_IRUGO);
114MODULE_DESCRIPTION("QLogic InfiniPath driver"); 112MODULE_PARM_DESC(ib_ipath_disable_sma, "Disable the SMA");
115 113
116const int ib_ipath_state_ops[IB_QPS_ERR + 1] = { 114const int ib_ipath_state_ops[IB_QPS_ERR + 1] = {
117 [IB_QPS_RESET] = 0, 115 [IB_QPS_RESET] = 0,
@@ -125,6 +123,16 @@ const int ib_ipath_state_ops[IB_QPS_ERR + 1] = {
125 [IB_QPS_ERR] = 0, 123 [IB_QPS_ERR] = 0,
126}; 124};
127 125
126struct ipath_ucontext {
127 struct ib_ucontext ibucontext;
128};
129
130static inline struct ipath_ucontext *to_iucontext(struct ib_ucontext
131 *ibucontext)
132{
133 return container_of(ibucontext, struct ipath_ucontext, ibucontext);
134}
135
128/* 136/*
129 * Translate ib_wr_opcode into ib_wc_opcode. 137 * Translate ib_wr_opcode into ib_wc_opcode.
130 */ 138 */
@@ -277,11 +285,12 @@ static int ipath_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
277 struct ib_recv_wr **bad_wr) 285 struct ib_recv_wr **bad_wr)
278{ 286{
279 struct ipath_qp *qp = to_iqp(ibqp); 287 struct ipath_qp *qp = to_iqp(ibqp);
288 struct ipath_rwq *wq = qp->r_rq.wq;
280 unsigned long flags; 289 unsigned long flags;
281 int ret; 290 int ret;
282 291
283 /* Check that state is OK to post receive. */ 292 /* Check that state is OK to post receive. */
284 if (!(ib_ipath_state_ops[qp->state] & IPATH_POST_RECV_OK)) { 293 if (!(ib_ipath_state_ops[qp->state] & IPATH_POST_RECV_OK) || !wq) {
285 *bad_wr = wr; 294 *bad_wr = wr;
286 ret = -EINVAL; 295 ret = -EINVAL;
287 goto bail; 296 goto bail;
@@ -290,59 +299,31 @@ static int ipath_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
290 for (; wr; wr = wr->next) { 299 for (; wr; wr = wr->next) {
291 struct ipath_rwqe *wqe; 300 struct ipath_rwqe *wqe;
292 u32 next; 301 u32 next;
293 int i, j; 302 int i;
294 303
295 if (wr->num_sge > qp->r_rq.max_sge) { 304 if ((unsigned) wr->num_sge > qp->r_rq.max_sge) {
296 *bad_wr = wr; 305 *bad_wr = wr;
297 ret = -ENOMEM; 306 ret = -ENOMEM;
298 goto bail; 307 goto bail;
299 } 308 }
300 309
301 spin_lock_irqsave(&qp->r_rq.lock, flags); 310 spin_lock_irqsave(&qp->r_rq.lock, flags);
302 next = qp->r_rq.head + 1; 311 next = wq->head + 1;
303 if (next >= qp->r_rq.size) 312 if (next >= qp->r_rq.size)
304 next = 0; 313 next = 0;
305 if (next == qp->r_rq.tail) { 314 if (next == wq->tail) {
306 spin_unlock_irqrestore(&qp->r_rq.lock, flags); 315 spin_unlock_irqrestore(&qp->r_rq.lock, flags);
307 *bad_wr = wr; 316 *bad_wr = wr;
308 ret = -ENOMEM; 317 ret = -ENOMEM;
309 goto bail; 318 goto bail;
310 } 319 }
311 320
312 wqe = get_rwqe_ptr(&qp->r_rq, qp->r_rq.head); 321 wqe = get_rwqe_ptr(&qp->r_rq, wq->head);
313 wqe->wr_id = wr->wr_id; 322 wqe->wr_id = wr->wr_id;
314 wqe->sg_list[0].mr = NULL; 323 wqe->num_sge = wr->num_sge;
315 wqe->sg_list[0].vaddr = NULL; 324 for (i = 0; i < wr->num_sge; i++)
316 wqe->sg_list[0].length = 0; 325 wqe->sg_list[i] = wr->sg_list[i];
317 wqe->sg_list[0].sge_length = 0; 326 wq->head = next;
318 wqe->length = 0;
319 for (i = 0, j = 0; i < wr->num_sge; i++) {
320 /* Check LKEY */
321 if (to_ipd(qp->ibqp.pd)->user &&
322 wr->sg_list[i].lkey == 0) {
323 spin_unlock_irqrestore(&qp->r_rq.lock,
324 flags);
325 *bad_wr = wr;
326 ret = -EINVAL;
327 goto bail;
328 }
329 if (wr->sg_list[i].length == 0)
330 continue;
331 if (!ipath_lkey_ok(
332 &to_idev(qp->ibqp.device)->lk_table,
333 &wqe->sg_list[j], &wr->sg_list[i],
334 IB_ACCESS_LOCAL_WRITE)) {
335 spin_unlock_irqrestore(&qp->r_rq.lock,
336 flags);
337 *bad_wr = wr;
338 ret = -EINVAL;
339 goto bail;
340 }
341 wqe->length += wr->sg_list[i].length;
342 j++;
343 }
344 wqe->num_sge = j;
345 qp->r_rq.head = next;
346 spin_unlock_irqrestore(&qp->r_rq.lock, flags); 327 spin_unlock_irqrestore(&qp->r_rq.lock, flags);
347 } 328 }
348 ret = 0; 329 ret = 0;
@@ -377,6 +358,9 @@ static void ipath_qp_rcv(struct ipath_ibdev *dev,
377 switch (qp->ibqp.qp_type) { 358 switch (qp->ibqp.qp_type) {
378 case IB_QPT_SMI: 359 case IB_QPT_SMI:
379 case IB_QPT_GSI: 360 case IB_QPT_GSI:
361 if (ib_ipath_disable_sma)
362 break;
363 /* FALLTHROUGH */
380 case IB_QPT_UD: 364 case IB_QPT_UD:
381 ipath_ud_rcv(dev, hdr, has_grh, data, tlen, qp); 365 ipath_ud_rcv(dev, hdr, has_grh, data, tlen, qp);
382 break; 366 break;
@@ -395,7 +379,7 @@ static void ipath_qp_rcv(struct ipath_ibdev *dev,
395} 379}
396 380
397/** 381/**
398 * ipath_ib_rcv - process and incoming packet 382 * ipath_ib_rcv - process an incoming packet
399 * @arg: the device pointer 383 * @arg: the device pointer
400 * @rhdr: the header of the packet 384 * @rhdr: the header of the packet
401 * @data: the packet data 385 * @data: the packet data
@@ -404,9 +388,9 @@ static void ipath_qp_rcv(struct ipath_ibdev *dev,
404 * This is called from ipath_kreceive() to process an incoming packet at 388 * This is called from ipath_kreceive() to process an incoming packet at
405 * interrupt level. Tlen is the length of the header + data + CRC in bytes. 389 * interrupt level. Tlen is the length of the header + data + CRC in bytes.
406 */ 390 */
407static void ipath_ib_rcv(void *arg, void *rhdr, void *data, u32 tlen) 391void ipath_ib_rcv(struct ipath_ibdev *dev, void *rhdr, void *data,
392 u32 tlen)
408{ 393{
409 struct ipath_ibdev *dev = (struct ipath_ibdev *) arg;
410 struct ipath_ib_header *hdr = rhdr; 394 struct ipath_ib_header *hdr = rhdr;
411 struct ipath_other_headers *ohdr; 395 struct ipath_other_headers *ohdr;
412 struct ipath_qp *qp; 396 struct ipath_qp *qp;
@@ -427,7 +411,7 @@ static void ipath_ib_rcv(void *arg, void *rhdr, void *data, u32 tlen)
427 lid = be16_to_cpu(hdr->lrh[1]); 411 lid = be16_to_cpu(hdr->lrh[1]);
428 if (lid < IPATH_MULTICAST_LID_BASE) { 412 if (lid < IPATH_MULTICAST_LID_BASE) {
429 lid &= ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); 413 lid &= ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1);
430 if (unlikely(lid != ipath_layer_get_lid(dev->dd))) { 414 if (unlikely(lid != dev->dd->ipath_lid)) {
431 dev->rcv_errors++; 415 dev->rcv_errors++;
432 goto bail; 416 goto bail;
433 } 417 }
@@ -495,9 +479,8 @@ bail:;
495 * This is called from ipath_do_rcv_timer() at interrupt level to check for 479 * This is called from ipath_do_rcv_timer() at interrupt level to check for
496 * QPs which need retransmits and to collect performance numbers. 480 * QPs which need retransmits and to collect performance numbers.
497 */ 481 */
498static void ipath_ib_timer(void *arg) 482void ipath_ib_timer(struct ipath_ibdev *dev)
499{ 483{
500 struct ipath_ibdev *dev = (struct ipath_ibdev *) arg;
501 struct ipath_qp *resend = NULL; 484 struct ipath_qp *resend = NULL;
502 struct list_head *last; 485 struct list_head *last;
503 struct ipath_qp *qp; 486 struct ipath_qp *qp;
@@ -539,19 +522,19 @@ static void ipath_ib_timer(void *arg)
539 if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_STARTED && 522 if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_STARTED &&
540 --dev->pma_sample_start == 0) { 523 --dev->pma_sample_start == 0) {
541 dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_RUNNING; 524 dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_RUNNING;
542 ipath_layer_snapshot_counters(dev->dd, &dev->ipath_sword, 525 ipath_snapshot_counters(dev->dd, &dev->ipath_sword,
543 &dev->ipath_rword, 526 &dev->ipath_rword,
544 &dev->ipath_spkts, 527 &dev->ipath_spkts,
545 &dev->ipath_rpkts, 528 &dev->ipath_rpkts,
546 &dev->ipath_xmit_wait); 529 &dev->ipath_xmit_wait);
547 } 530 }
548 if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_RUNNING) { 531 if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_RUNNING) {
549 if (dev->pma_sample_interval == 0) { 532 if (dev->pma_sample_interval == 0) {
550 u64 ta, tb, tc, td, te; 533 u64 ta, tb, tc, td, te;
551 534
552 dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_DONE; 535 dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_DONE;
553 ipath_layer_snapshot_counters(dev->dd, &ta, &tb, 536 ipath_snapshot_counters(dev->dd, &ta, &tb,
554 &tc, &td, &te); 537 &tc, &td, &te);
555 538
556 dev->ipath_sword = ta - dev->ipath_sword; 539 dev->ipath_sword = ta - dev->ipath_sword;
557 dev->ipath_rword = tb - dev->ipath_rword; 540 dev->ipath_rword = tb - dev->ipath_rword;
@@ -581,6 +564,362 @@ static void ipath_ib_timer(void *arg)
581 } 564 }
582} 565}
583 566
567static void update_sge(struct ipath_sge_state *ss, u32 length)
568{
569 struct ipath_sge *sge = &ss->sge;
570
571 sge->vaddr += length;
572 sge->length -= length;
573 sge->sge_length -= length;
574 if (sge->sge_length == 0) {
575 if (--ss->num_sge)
576 *sge = *ss->sg_list++;
577 } else if (sge->length == 0 && sge->mr != NULL) {
578 if (++sge->n >= IPATH_SEGSZ) {
579 if (++sge->m >= sge->mr->mapsz)
580 return;
581 sge->n = 0;
582 }
583 sge->vaddr = sge->mr->map[sge->m]->segs[sge->n].vaddr;
584 sge->length = sge->mr->map[sge->m]->segs[sge->n].length;
585 }
586}
587
588#ifdef __LITTLE_ENDIAN
589static inline u32 get_upper_bits(u32 data, u32 shift)
590{
591 return data >> shift;
592}
593
594static inline u32 set_upper_bits(u32 data, u32 shift)
595{
596 return data << shift;
597}
598
599static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off)
600{
601 data <<= ((sizeof(u32) - n) * BITS_PER_BYTE);
602 data >>= ((sizeof(u32) - n - off) * BITS_PER_BYTE);
603 return data;
604}
605#else
606static inline u32 get_upper_bits(u32 data, u32 shift)
607{
608 return data << shift;
609}
610
611static inline u32 set_upper_bits(u32 data, u32 shift)
612{
613 return data >> shift;
614}
615
616static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off)
617{
618 data >>= ((sizeof(u32) - n) * BITS_PER_BYTE);
619 data <<= ((sizeof(u32) - n - off) * BITS_PER_BYTE);
620 return data;
621}
622#endif
623
624static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss,
625 u32 length)
626{
627 u32 extra = 0;
628 u32 data = 0;
629 u32 last;
630
631 while (1) {
632 u32 len = ss->sge.length;
633 u32 off;
634
635 BUG_ON(len == 0);
636 if (len > length)
637 len = length;
638 if (len > ss->sge.sge_length)
639 len = ss->sge.sge_length;
640 /* If the source address is not aligned, try to align it. */
641 off = (unsigned long)ss->sge.vaddr & (sizeof(u32) - 1);
642 if (off) {
643 u32 *addr = (u32 *)((unsigned long)ss->sge.vaddr &
644 ~(sizeof(u32) - 1));
645 u32 v = get_upper_bits(*addr, off * BITS_PER_BYTE);
646 u32 y;
647
648 y = sizeof(u32) - off;
649 if (len > y)
650 len = y;
651 if (len + extra >= sizeof(u32)) {
652 data |= set_upper_bits(v, extra *
653 BITS_PER_BYTE);
654 len = sizeof(u32) - extra;
655 if (len == length) {
656 last = data;
657 break;
658 }
659 __raw_writel(data, piobuf);
660 piobuf++;
661 extra = 0;
662 data = 0;
663 } else {
664 /* Clear unused upper bytes */
665 data |= clear_upper_bytes(v, len, extra);
666 if (len == length) {
667 last = data;
668 break;
669 }
670 extra += len;
671 }
672 } else if (extra) {
673 /* Source address is aligned. */
674 u32 *addr = (u32 *) ss->sge.vaddr;
675 int shift = extra * BITS_PER_BYTE;
676 int ushift = 32 - shift;
677 u32 l = len;
678
679 while (l >= sizeof(u32)) {
680 u32 v = *addr;
681
682 data |= set_upper_bits(v, shift);
683 __raw_writel(data, piobuf);
684 data = get_upper_bits(v, ushift);
685 piobuf++;
686 addr++;
687 l -= sizeof(u32);
688 }
689 /*
690 * We still have 'extra' number of bytes leftover.
691 */
692 if (l) {
693 u32 v = *addr;
694
695 if (l + extra >= sizeof(u32)) {
696 data |= set_upper_bits(v, shift);
697 len -= l + extra - sizeof(u32);
698 if (len == length) {
699 last = data;
700 break;
701 }
702 __raw_writel(data, piobuf);
703 piobuf++;
704 extra = 0;
705 data = 0;
706 } else {
707 /* Clear unused upper bytes */
708 data |= clear_upper_bytes(v, l,
709 extra);
710 if (len == length) {
711 last = data;
712 break;
713 }
714 extra += l;
715 }
716 } else if (len == length) {
717 last = data;
718 break;
719 }
720 } else if (len == length) {
721 u32 w;
722
723 /*
724 * Need to round up for the last dword in the
725 * packet.
726 */
727 w = (len + 3) >> 2;
728 __iowrite32_copy(piobuf, ss->sge.vaddr, w - 1);
729 piobuf += w - 1;
730 last = ((u32 *) ss->sge.vaddr)[w - 1];
731 break;
732 } else {
733 u32 w = len >> 2;
734
735 __iowrite32_copy(piobuf, ss->sge.vaddr, w);
736 piobuf += w;
737
738 extra = len & (sizeof(u32) - 1);
739 if (extra) {
740 u32 v = ((u32 *) ss->sge.vaddr)[w];
741
742 /* Clear unused upper bytes */
743 data = clear_upper_bytes(v, extra, 0);
744 }
745 }
746 update_sge(ss, len);
747 length -= len;
748 }
749 /* Update address before sending packet. */
750 update_sge(ss, length);
751 /* must flush early everything before trigger word */
752 ipath_flush_wc();
753 __raw_writel(last, piobuf);
754 /* be sure trigger word is written */
755 ipath_flush_wc();
756}
757
758/**
759 * ipath_verbs_send - send a packet
760 * @dd: the infinipath device
761 * @hdrwords: the number of words in the header
762 * @hdr: the packet header
763 * @len: the length of the packet in bytes
764 * @ss: the SGE to send
765 */
766int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
767 u32 *hdr, u32 len, struct ipath_sge_state *ss)
768{
769 u32 __iomem *piobuf;
770 u32 plen;
771 int ret;
772
773 /* +1 is for the qword padding of pbc */
774 plen = hdrwords + ((len + 3) >> 2) + 1;
775 if (unlikely((plen << 2) > dd->ipath_ibmaxlen)) {
776 ipath_dbg("packet len 0x%x too long, failing\n", plen);
777 ret = -EINVAL;
778 goto bail;
779 }
780
781 /* Get a PIO buffer to use. */
782 piobuf = ipath_getpiobuf(dd, NULL);
783 if (unlikely(piobuf == NULL)) {
784 ret = -EBUSY;
785 goto bail;
786 }
787
788 /*
789 * Write len to control qword, no flags.
790 * We have to flush after the PBC for correctness on some cpus
791 * or WC buffer can be written out of order.
792 */
793 writeq(plen, piobuf);
794 ipath_flush_wc();
795 piobuf += 2;
796 if (len == 0) {
797 /*
798 * If there is just the header portion, must flush before
799 * writing last word of header for correctness, and after
800 * the last header word (trigger word).
801 */
802 __iowrite32_copy(piobuf, hdr, hdrwords - 1);
803 ipath_flush_wc();
804 __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords - 1);
805 ipath_flush_wc();
806 ret = 0;
807 goto bail;
808 }
809
810 __iowrite32_copy(piobuf, hdr, hdrwords);
811 piobuf += hdrwords;
812
813 /* The common case is aligned and contained in one segment. */
814 if (likely(ss->num_sge == 1 && len <= ss->sge.length &&
815 !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) {
816 u32 w;
817 u32 *addr = (u32 *) ss->sge.vaddr;
818
819 /* Update address before sending packet. */
820 update_sge(ss, len);
821 /* Need to round up for the last dword in the packet. */
822 w = (len + 3) >> 2;
823 __iowrite32_copy(piobuf, addr, w - 1);
824 /* must flush early everything before trigger word */
825 ipath_flush_wc();
826 __raw_writel(addr[w - 1], piobuf + w - 1);
827 /* be sure trigger word is written */
828 ipath_flush_wc();
829 ret = 0;
830 goto bail;
831 }
832 copy_io(piobuf, ss, len);
833 ret = 0;
834
835bail:
836 return ret;
837}
838
839int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords,
840 u64 *rwords, u64 *spkts, u64 *rpkts,
841 u64 *xmit_wait)
842{
843 int ret;
844
845 if (!(dd->ipath_flags & IPATH_INITTED)) {
846 /* no hardware, freeze, etc. */
847 ipath_dbg("unit %u not usable\n", dd->ipath_unit);
848 ret = -EINVAL;
849 goto bail;
850 }
851 *swords = ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt);
852 *rwords = ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt);
853 *spkts = ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt);
854 *rpkts = ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt);
855 *xmit_wait = ipath_snap_cntr(dd, dd->ipath_cregs->cr_sendstallcnt);
856
857 ret = 0;
858
859bail:
860 return ret;
861}
862
863/**
864 * ipath_get_counters - get various chip counters
865 * @dd: the infinipath device
866 * @cntrs: counters are placed here
867 *
868 * Return the counters needed by recv_pma_get_portcounters().
869 */
870int ipath_get_counters(struct ipath_devdata *dd,
871 struct ipath_verbs_counters *cntrs)
872{
873 int ret;
874
875 if (!(dd->ipath_flags & IPATH_INITTED)) {
876 /* no hardware, freeze, etc. */
877 ipath_dbg("unit %u not usable\n", dd->ipath_unit);
878 ret = -EINVAL;
879 goto bail;
880 }
881 cntrs->symbol_error_counter =
882 ipath_snap_cntr(dd, dd->ipath_cregs->cr_ibsymbolerrcnt);
883 cntrs->link_error_recovery_counter =
884 ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt);
885 /*
886 * The link downed counter counts when the other side downs the
887 * connection. We add in the number of times we downed the link
888 * due to local link integrity errors to compensate.
889 */
890 cntrs->link_downed_counter =
891 ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkdowncnt);
892 cntrs->port_rcv_errors =
893 ipath_snap_cntr(dd, dd->ipath_cregs->cr_rxdroppktcnt) +
894 ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvovflcnt) +
895 ipath_snap_cntr(dd, dd->ipath_cregs->cr_portovflcnt) +
896 ipath_snap_cntr(dd, dd->ipath_cregs->cr_err_rlencnt) +
897 ipath_snap_cntr(dd, dd->ipath_cregs->cr_invalidrlencnt) +
898 ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) +
899 ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) +
900 ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) +
901 ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt);
902 cntrs->port_rcv_remphys_errors =
903 ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt);
904 cntrs->port_xmit_discards =
905 ipath_snap_cntr(dd, dd->ipath_cregs->cr_unsupvlcnt);
906 cntrs->port_xmit_data =
907 ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt);
908 cntrs->port_rcv_data =
909 ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt);
910 cntrs->port_xmit_packets =
911 ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt);
912 cntrs->port_rcv_packets =
913 ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt);
914 cntrs->local_link_integrity_errors = dd->ipath_lli_errors;
915 cntrs->excessive_buffer_overrun_errors = 0; /* XXX */
916
917 ret = 0;
918
919bail:
920 return ret;
921}
922
584/** 923/**
585 * ipath_ib_piobufavail - callback when a PIO buffer is available 924 * ipath_ib_piobufavail - callback when a PIO buffer is available
586 * @arg: the device pointer 925 * @arg: the device pointer
@@ -591,9 +930,8 @@ static void ipath_ib_timer(void *arg)
591 * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and 930 * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and
592 * return zero). 931 * return zero).
593 */ 932 */
594static int ipath_ib_piobufavail(void *arg) 933int ipath_ib_piobufavail(struct ipath_ibdev *dev)
595{ 934{
596 struct ipath_ibdev *dev = (struct ipath_ibdev *) arg;
597 struct ipath_qp *qp; 935 struct ipath_qp *qp;
598 unsigned long flags; 936 unsigned long flags;
599 937
@@ -624,14 +962,14 @@ static int ipath_query_device(struct ib_device *ibdev,
624 IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | 962 IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT |
625 IB_DEVICE_SYS_IMAGE_GUID; 963 IB_DEVICE_SYS_IMAGE_GUID;
626 props->page_size_cap = PAGE_SIZE; 964 props->page_size_cap = PAGE_SIZE;
627 props->vendor_id = ipath_layer_get_vendorid(dev->dd); 965 props->vendor_id = dev->dd->ipath_vendorid;
628 props->vendor_part_id = ipath_layer_get_deviceid(dev->dd); 966 props->vendor_part_id = dev->dd->ipath_deviceid;
629 props->hw_ver = ipath_layer_get_pcirev(dev->dd); 967 props->hw_ver = dev->dd->ipath_pcirev;
630 968
631 props->sys_image_guid = dev->sys_image_guid; 969 props->sys_image_guid = dev->sys_image_guid;
632 970
633 props->max_mr_size = ~0ull; 971 props->max_mr_size = ~0ull;
634 props->max_qp = dev->qp_table.max; 972 props->max_qp = ib_ipath_max_qps;
635 props->max_qp_wr = ib_ipath_max_qp_wrs; 973 props->max_qp_wr = ib_ipath_max_qp_wrs;
636 props->max_sge = ib_ipath_max_sges; 974 props->max_sge = ib_ipath_max_sges;
637 props->max_cq = ib_ipath_max_cqs; 975 props->max_cq = ib_ipath_max_cqs;
@@ -647,7 +985,7 @@ static int ipath_query_device(struct ib_device *ibdev,
647 props->max_srq_sge = ib_ipath_max_srq_sges; 985 props->max_srq_sge = ib_ipath_max_srq_sges;
648 /* props->local_ca_ack_delay */ 986 /* props->local_ca_ack_delay */
649 props->atomic_cap = IB_ATOMIC_HCA; 987 props->atomic_cap = IB_ATOMIC_HCA;
650 props->max_pkeys = ipath_layer_get_npkeys(dev->dd); 988 props->max_pkeys = ipath_get_npkeys(dev->dd);
651 props->max_mcast_grp = ib_ipath_max_mcast_grps; 989 props->max_mcast_grp = ib_ipath_max_mcast_grps;
652 props->max_mcast_qp_attach = ib_ipath_max_mcast_qp_attached; 990 props->max_mcast_qp_attach = ib_ipath_max_mcast_qp_attached;
653 props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * 991 props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
@@ -672,12 +1010,17 @@ const u8 ipath_cvt_physportstate[16] = {
672 [INFINIPATH_IBCS_LT_STATE_RECOVERIDLE] = 6, 1010 [INFINIPATH_IBCS_LT_STATE_RECOVERIDLE] = 6,
673}; 1011};
674 1012
1013u32 ipath_get_cr_errpkey(struct ipath_devdata *dd)
1014{
1015 return ipath_read_creg32(dd, dd->ipath_cregs->cr_errpkey);
1016}
1017
675static int ipath_query_port(struct ib_device *ibdev, 1018static int ipath_query_port(struct ib_device *ibdev,
676 u8 port, struct ib_port_attr *props) 1019 u8 port, struct ib_port_attr *props)
677{ 1020{
678 struct ipath_ibdev *dev = to_idev(ibdev); 1021 struct ipath_ibdev *dev = to_idev(ibdev);
679 enum ib_mtu mtu; 1022 enum ib_mtu mtu;
680 u16 lid = ipath_layer_get_lid(dev->dd); 1023 u16 lid = dev->dd->ipath_lid;
681 u64 ibcstat; 1024 u64 ibcstat;
682 1025
683 memset(props, 0, sizeof(*props)); 1026 memset(props, 0, sizeof(*props));
@@ -685,16 +1028,16 @@ static int ipath_query_port(struct ib_device *ibdev,
685 props->lmc = dev->mkeyprot_resv_lmc & 7; 1028 props->lmc = dev->mkeyprot_resv_lmc & 7;
686 props->sm_lid = dev->sm_lid; 1029 props->sm_lid = dev->sm_lid;
687 props->sm_sl = dev->sm_sl; 1030 props->sm_sl = dev->sm_sl;
688 ibcstat = ipath_layer_get_lastibcstat(dev->dd); 1031 ibcstat = dev->dd->ipath_lastibcstat;
689 props->state = ((ibcstat >> 4) & 0x3) + 1; 1032 props->state = ((ibcstat >> 4) & 0x3) + 1;
690 /* See phys_state_show() */ 1033 /* See phys_state_show() */
691 props->phys_state = ipath_cvt_physportstate[ 1034 props->phys_state = ipath_cvt_physportstate[
692 ipath_layer_get_lastibcstat(dev->dd) & 0xf]; 1035 dev->dd->ipath_lastibcstat & 0xf];
693 props->port_cap_flags = dev->port_cap_flags; 1036 props->port_cap_flags = dev->port_cap_flags;
694 props->gid_tbl_len = 1; 1037 props->gid_tbl_len = 1;
695 props->max_msg_sz = 0x80000000; 1038 props->max_msg_sz = 0x80000000;
696 props->pkey_tbl_len = ipath_layer_get_npkeys(dev->dd); 1039 props->pkey_tbl_len = ipath_get_npkeys(dev->dd);
697 props->bad_pkey_cntr = ipath_layer_get_cr_errpkey(dev->dd) - 1040 props->bad_pkey_cntr = ipath_get_cr_errpkey(dev->dd) -
698 dev->z_pkey_violations; 1041 dev->z_pkey_violations;
699 props->qkey_viol_cntr = dev->qkey_violations; 1042 props->qkey_viol_cntr = dev->qkey_violations;
700 props->active_width = IB_WIDTH_4X; 1043 props->active_width = IB_WIDTH_4X;
@@ -704,7 +1047,7 @@ static int ipath_query_port(struct ib_device *ibdev,
704 props->init_type_reply = 0; 1047 props->init_type_reply = 0;
705 1048
706 props->max_mtu = IB_MTU_4096; 1049 props->max_mtu = IB_MTU_4096;
707 switch (ipath_layer_get_ibmtu(dev->dd)) { 1050 switch (dev->dd->ipath_ibmtu) {
708 case 4096: 1051 case 4096:
709 mtu = IB_MTU_4096; 1052 mtu = IB_MTU_4096;
710 break; 1053 break;
@@ -763,7 +1106,7 @@ static int ipath_modify_port(struct ib_device *ibdev,
763 dev->port_cap_flags |= props->set_port_cap_mask; 1106 dev->port_cap_flags |= props->set_port_cap_mask;
764 dev->port_cap_flags &= ~props->clr_port_cap_mask; 1107 dev->port_cap_flags &= ~props->clr_port_cap_mask;
765 if (port_modify_mask & IB_PORT_SHUTDOWN) 1108 if (port_modify_mask & IB_PORT_SHUTDOWN)
766 ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKDOWN); 1109 ipath_set_linkstate(dev->dd, IPATH_IB_LINKDOWN);
767 if (port_modify_mask & IB_PORT_RESET_QKEY_CNTR) 1110 if (port_modify_mask & IB_PORT_RESET_QKEY_CNTR)
768 dev->qkey_violations = 0; 1111 dev->qkey_violations = 0;
769 return 0; 1112 return 0;
@@ -780,7 +1123,7 @@ static int ipath_query_gid(struct ib_device *ibdev, u8 port,
780 goto bail; 1123 goto bail;
781 } 1124 }
782 gid->global.subnet_prefix = dev->gid_prefix; 1125 gid->global.subnet_prefix = dev->gid_prefix;
783 gid->global.interface_id = ipath_layer_get_guid(dev->dd); 1126 gid->global.interface_id = dev->dd->ipath_guid;
784 1127
785 ret = 0; 1128 ret = 0;
786 1129
@@ -803,18 +1146,22 @@ static struct ib_pd *ipath_alloc_pd(struct ib_device *ibdev,
803 * we allow allocations of more than we report for this value. 1146 * we allow allocations of more than we report for this value.
804 */ 1147 */
805 1148
806 if (dev->n_pds_allocated == ib_ipath_max_pds) { 1149 pd = kmalloc(sizeof *pd, GFP_KERNEL);
1150 if (!pd) {
807 ret = ERR_PTR(-ENOMEM); 1151 ret = ERR_PTR(-ENOMEM);
808 goto bail; 1152 goto bail;
809 } 1153 }
810 1154
811 pd = kmalloc(sizeof *pd, GFP_KERNEL); 1155 spin_lock(&dev->n_pds_lock);
812 if (!pd) { 1156 if (dev->n_pds_allocated == ib_ipath_max_pds) {
1157 spin_unlock(&dev->n_pds_lock);
1158 kfree(pd);
813 ret = ERR_PTR(-ENOMEM); 1159 ret = ERR_PTR(-ENOMEM);
814 goto bail; 1160 goto bail;
815 } 1161 }
816 1162
817 dev->n_pds_allocated++; 1163 dev->n_pds_allocated++;
1164 spin_unlock(&dev->n_pds_lock);
818 1165
819 /* ib_alloc_pd() will initialize pd->ibpd. */ 1166 /* ib_alloc_pd() will initialize pd->ibpd. */
820 pd->user = udata != NULL; 1167 pd->user = udata != NULL;
@@ -830,7 +1177,9 @@ static int ipath_dealloc_pd(struct ib_pd *ibpd)
830 struct ipath_pd *pd = to_ipd(ibpd); 1177 struct ipath_pd *pd = to_ipd(ibpd);
831 struct ipath_ibdev *dev = to_idev(ibpd->device); 1178 struct ipath_ibdev *dev = to_idev(ibpd->device);
832 1179
1180 spin_lock(&dev->n_pds_lock);
833 dev->n_pds_allocated--; 1181 dev->n_pds_allocated--;
1182 spin_unlock(&dev->n_pds_lock);
834 1183
835 kfree(pd); 1184 kfree(pd);
836 1185
@@ -851,11 +1200,6 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
851 struct ib_ah *ret; 1200 struct ib_ah *ret;
852 struct ipath_ibdev *dev = to_idev(pd->device); 1201 struct ipath_ibdev *dev = to_idev(pd->device);
853 1202
854 if (dev->n_ahs_allocated == ib_ipath_max_ahs) {
855 ret = ERR_PTR(-ENOMEM);
856 goto bail;
857 }
858
859 /* A multicast address requires a GRH (see ch. 8.4.1). */ 1203 /* A multicast address requires a GRH (see ch. 8.4.1). */
860 if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE && 1204 if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE &&
861 ah_attr->dlid != IPATH_PERMISSIVE_LID && 1205 ah_attr->dlid != IPATH_PERMISSIVE_LID &&
@@ -881,7 +1225,16 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
881 goto bail; 1225 goto bail;
882 } 1226 }
883 1227
1228 spin_lock(&dev->n_ahs_lock);
1229 if (dev->n_ahs_allocated == ib_ipath_max_ahs) {
1230 spin_unlock(&dev->n_ahs_lock);
1231 kfree(ah);
1232 ret = ERR_PTR(-ENOMEM);
1233 goto bail;
1234 }
1235
884 dev->n_ahs_allocated++; 1236 dev->n_ahs_allocated++;
1237 spin_unlock(&dev->n_ahs_lock);
885 1238
886 /* ib_create_ah() will initialize ah->ibah. */ 1239 /* ib_create_ah() will initialize ah->ibah. */
887 ah->attr = *ah_attr; 1240 ah->attr = *ah_attr;
@@ -903,7 +1256,9 @@ static int ipath_destroy_ah(struct ib_ah *ibah)
903 struct ipath_ibdev *dev = to_idev(ibah->device); 1256 struct ipath_ibdev *dev = to_idev(ibah->device);
904 struct ipath_ah *ah = to_iah(ibah); 1257 struct ipath_ah *ah = to_iah(ibah);
905 1258
1259 spin_lock(&dev->n_ahs_lock);
906 dev->n_ahs_allocated--; 1260 dev->n_ahs_allocated--;
1261 spin_unlock(&dev->n_ahs_lock);
907 1262
908 kfree(ah); 1263 kfree(ah);
909 1264
@@ -919,25 +1274,50 @@ static int ipath_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
919 return 0; 1274 return 0;
920} 1275}
921 1276
1277/**
1278 * ipath_get_npkeys - return the size of the PKEY table for port 0
1279 * @dd: the infinipath device
1280 */
1281unsigned ipath_get_npkeys(struct ipath_devdata *dd)
1282{
1283 return ARRAY_SIZE(dd->ipath_pd[0]->port_pkeys);
1284}
1285
1286/**
1287 * ipath_get_pkey - return the indexed PKEY from the port 0 PKEY table
1288 * @dd: the infinipath device
1289 * @index: the PKEY index
1290 */
1291unsigned ipath_get_pkey(struct ipath_devdata *dd, unsigned index)
1292{
1293 unsigned ret;
1294
1295 if (index >= ARRAY_SIZE(dd->ipath_pd[0]->port_pkeys))
1296 ret = 0;
1297 else
1298 ret = dd->ipath_pd[0]->port_pkeys[index];
1299
1300 return ret;
1301}
1302
922static int ipath_query_pkey(struct ib_device *ibdev, u8 port, u16 index, 1303static int ipath_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
923 u16 *pkey) 1304 u16 *pkey)
924{ 1305{
925 struct ipath_ibdev *dev = to_idev(ibdev); 1306 struct ipath_ibdev *dev = to_idev(ibdev);
926 int ret; 1307 int ret;
927 1308
928 if (index >= ipath_layer_get_npkeys(dev->dd)) { 1309 if (index >= ipath_get_npkeys(dev->dd)) {
929 ret = -EINVAL; 1310 ret = -EINVAL;
930 goto bail; 1311 goto bail;
931 } 1312 }
932 1313
933 *pkey = ipath_layer_get_pkey(dev->dd, index); 1314 *pkey = ipath_get_pkey(dev->dd, index);
934 ret = 0; 1315 ret = 0;
935 1316
936bail: 1317bail:
937 return ret; 1318 return ret;
938} 1319}
939 1320
940
941/** 1321/**
942 * ipath_alloc_ucontext - allocate a ucontest 1322 * ipath_alloc_ucontext - allocate a ucontest
943 * @ibdev: the infiniband device 1323 * @ibdev: the infiniband device
@@ -970,26 +1350,91 @@ static int ipath_dealloc_ucontext(struct ib_ucontext *context)
970 1350
971static int ipath_verbs_register_sysfs(struct ib_device *dev); 1351static int ipath_verbs_register_sysfs(struct ib_device *dev);
972 1352
1353static void __verbs_timer(unsigned long arg)
1354{
1355 struct ipath_devdata *dd = (struct ipath_devdata *) arg;
1356
1357 /*
1358 * If port 0 receive packet interrupts are not available, or
1359 * can be missed, poll the receive queue
1360 */
1361 if (dd->ipath_flags & IPATH_POLL_RX_INTR)
1362 ipath_kreceive(dd);
1363
1364 /* Handle verbs layer timeouts. */
1365 ipath_ib_timer(dd->verbs_dev);
1366
1367 mod_timer(&dd->verbs_timer, jiffies + 1);
1368}
1369
1370static int enable_timer(struct ipath_devdata *dd)
1371{
1372 /*
1373 * Early chips had a design flaw where the chip and kernel idea
1374 * of the tail register don't always agree, and therefore we won't
1375 * get an interrupt on the next packet received.
1376 * If the board supports per packet receive interrupts, use it.
1377 * Otherwise, the timer function periodically checks for packets
1378 * to cover this case.
1379 * Either way, the timer is needed for verbs layer related
1380 * processing.
1381 */
1382 if (dd->ipath_flags & IPATH_GPIO_INTR) {
1383 ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect,
1384 0x2074076542310ULL);
1385 /* Enable GPIO bit 2 interrupt */
1386 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask,
1387 (u64) (1 << 2));
1388 }
1389
1390 init_timer(&dd->verbs_timer);
1391 dd->verbs_timer.function = __verbs_timer;
1392 dd->verbs_timer.data = (unsigned long)dd;
1393 dd->verbs_timer.expires = jiffies + 1;
1394 add_timer(&dd->verbs_timer);
1395
1396 return 0;
1397}
1398
1399static int disable_timer(struct ipath_devdata *dd)
1400{
1401 /* Disable GPIO bit 2 interrupt */
1402 if (dd->ipath_flags & IPATH_GPIO_INTR)
1403 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, 0);
1404
1405 del_timer_sync(&dd->verbs_timer);
1406
1407 return 0;
1408}
1409
973/** 1410/**
974 * ipath_register_ib_device - register our device with the infiniband core 1411 * ipath_register_ib_device - register our device with the infiniband core
975 * @unit: the device number to register
976 * @dd: the device data structure 1412 * @dd: the device data structure
977 * Return the allocated ipath_ibdev pointer or NULL on error. 1413 * Return the allocated ipath_ibdev pointer or NULL on error.
978 */ 1414 */
979static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd) 1415int ipath_register_ib_device(struct ipath_devdata *dd)
980{ 1416{
981 struct ipath_layer_counters cntrs; 1417 struct ipath_verbs_counters cntrs;
982 struct ipath_ibdev *idev; 1418 struct ipath_ibdev *idev;
983 struct ib_device *dev; 1419 struct ib_device *dev;
984 int ret; 1420 int ret;
985 1421
986 idev = (struct ipath_ibdev *)ib_alloc_device(sizeof *idev); 1422 idev = (struct ipath_ibdev *)ib_alloc_device(sizeof *idev);
987 if (idev == NULL) 1423 if (idev == NULL) {
1424 ret = -ENOMEM;
988 goto bail; 1425 goto bail;
1426 }
989 1427
990 dev = &idev->ibdev; 1428 dev = &idev->ibdev;
991 1429
992 /* Only need to initialize non-zero fields. */ 1430 /* Only need to initialize non-zero fields. */
1431 spin_lock_init(&idev->n_pds_lock);
1432 spin_lock_init(&idev->n_ahs_lock);
1433 spin_lock_init(&idev->n_cqs_lock);
1434 spin_lock_init(&idev->n_qps_lock);
1435 spin_lock_init(&idev->n_srqs_lock);
1436 spin_lock_init(&idev->n_mcast_grps_lock);
1437
993 spin_lock_init(&idev->qp_table.lock); 1438 spin_lock_init(&idev->qp_table.lock);
994 spin_lock_init(&idev->lk_table.lock); 1439 spin_lock_init(&idev->lk_table.lock);
995 idev->sm_lid = __constant_be16_to_cpu(IB_LID_PERMISSIVE); 1440 idev->sm_lid = __constant_be16_to_cpu(IB_LID_PERMISSIVE);
@@ -1030,7 +1475,7 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd)
1030 idev->link_width_enabled = 3; /* 1x or 4x */ 1475 idev->link_width_enabled = 3; /* 1x or 4x */
1031 1476
1032 /* Snapshot current HW counters to "clear" them. */ 1477 /* Snapshot current HW counters to "clear" them. */
1033 ipath_layer_get_counters(dd, &cntrs); 1478 ipath_get_counters(dd, &cntrs);
1034 idev->z_symbol_error_counter = cntrs.symbol_error_counter; 1479 idev->z_symbol_error_counter = cntrs.symbol_error_counter;
1035 idev->z_link_error_recovery_counter = 1480 idev->z_link_error_recovery_counter =
1036 cntrs.link_error_recovery_counter; 1481 cntrs.link_error_recovery_counter;
@@ -1054,14 +1499,14 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd)
1054 * device types in the system, we can't be sure this is unique. 1499 * device types in the system, we can't be sure this is unique.
1055 */ 1500 */
1056 if (!sys_image_guid) 1501 if (!sys_image_guid)
1057 sys_image_guid = ipath_layer_get_guid(dd); 1502 sys_image_guid = dd->ipath_guid;
1058 idev->sys_image_guid = sys_image_guid; 1503 idev->sys_image_guid = sys_image_guid;
1059 idev->ib_unit = unit; 1504 idev->ib_unit = dd->ipath_unit;
1060 idev->dd = dd; 1505 idev->dd = dd;
1061 1506
1062 strlcpy(dev->name, "ipath%d", IB_DEVICE_NAME_MAX); 1507 strlcpy(dev->name, "ipath%d", IB_DEVICE_NAME_MAX);
1063 dev->owner = THIS_MODULE; 1508 dev->owner = THIS_MODULE;
1064 dev->node_guid = ipath_layer_get_guid(dd); 1509 dev->node_guid = dd->ipath_guid;
1065 dev->uverbs_abi_ver = IPATH_UVERBS_ABI_VERSION; 1510 dev->uverbs_abi_ver = IPATH_UVERBS_ABI_VERSION;
1066 dev->uverbs_cmd_mask = 1511 dev->uverbs_cmd_mask =
1067 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | 1512 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
@@ -1093,9 +1538,9 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd)
1093 (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) | 1538 (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) |
1094 (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) | 1539 (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) |
1095 (1ull << IB_USER_VERBS_CMD_POST_SRQ_RECV); 1540 (1ull << IB_USER_VERBS_CMD_POST_SRQ_RECV);
1096 dev->node_type = IB_NODE_CA; 1541 dev->node_type = RDMA_NODE_IB_CA;
1097 dev->phys_port_cnt = 1; 1542 dev->phys_port_cnt = 1;
1098 dev->dma_device = ipath_layer_get_device(dd); 1543 dev->dma_device = &dd->pcidev->dev;
1099 dev->class_dev.dev = dev->dma_device; 1544 dev->class_dev.dev = dev->dma_device;
1100 dev->query_device = ipath_query_device; 1545 dev->query_device = ipath_query_device;
1101 dev->modify_device = ipath_modify_device; 1546 dev->modify_device = ipath_modify_device;
@@ -1137,9 +1582,10 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd)
1137 dev->attach_mcast = ipath_multicast_attach; 1582 dev->attach_mcast = ipath_multicast_attach;
1138 dev->detach_mcast = ipath_multicast_detach; 1583 dev->detach_mcast = ipath_multicast_detach;
1139 dev->process_mad = ipath_process_mad; 1584 dev->process_mad = ipath_process_mad;
1585 dev->mmap = ipath_mmap;
1140 1586
1141 snprintf(dev->node_desc, sizeof(dev->node_desc), 1587 snprintf(dev->node_desc, sizeof(dev->node_desc),
1142 IPATH_IDSTR " %s kernel_SMA", system_utsname.nodename); 1588 IPATH_IDSTR " %s", system_utsname.nodename);
1143 1589
1144 ret = ib_register_device(dev); 1590 ret = ib_register_device(dev);
1145 if (ret) 1591 if (ret)
@@ -1148,7 +1594,7 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd)
1148 if (ipath_verbs_register_sysfs(dev)) 1594 if (ipath_verbs_register_sysfs(dev))
1149 goto err_class; 1595 goto err_class;
1150 1596
1151 ipath_layer_enable_timer(dd); 1597 enable_timer(dd);
1152 1598
1153 goto bail; 1599 goto bail;
1154 1600
@@ -1160,37 +1606,32 @@ err_lk:
1160 kfree(idev->qp_table.table); 1606 kfree(idev->qp_table.table);
1161err_qp: 1607err_qp:
1162 ib_dealloc_device(dev); 1608 ib_dealloc_device(dev);
1163 _VERBS_ERROR("ib_ipath%d cannot register verbs (%d)!\n", 1609 ipath_dev_err(dd, "cannot register verbs: %d!\n", -ret);
1164 unit, -ret);
1165 idev = NULL; 1610 idev = NULL;
1166 1611
1167bail: 1612bail:
1168 return idev; 1613 dd->verbs_dev = idev;
1614 return ret;
1169} 1615}
1170 1616
1171static void ipath_unregister_ib_device(void *arg) 1617void ipath_unregister_ib_device(struct ipath_ibdev *dev)
1172{ 1618{
1173 struct ipath_ibdev *dev = (struct ipath_ibdev *) arg;
1174 struct ib_device *ibdev = &dev->ibdev; 1619 struct ib_device *ibdev = &dev->ibdev;
1175 1620
1176 ipath_layer_disable_timer(dev->dd); 1621 disable_timer(dev->dd);
1177 1622
1178 ib_unregister_device(ibdev); 1623 ib_unregister_device(ibdev);
1179 1624
1180 if (!list_empty(&dev->pending[0]) || 1625 if (!list_empty(&dev->pending[0]) ||
1181 !list_empty(&dev->pending[1]) || 1626 !list_empty(&dev->pending[1]) ||
1182 !list_empty(&dev->pending[2])) 1627 !list_empty(&dev->pending[2]))
1183 _VERBS_ERROR("ipath%d pending list not empty!\n", 1628 ipath_dev_err(dev->dd, "pending list not empty!\n");
1184 dev->ib_unit);
1185 if (!list_empty(&dev->piowait)) 1629 if (!list_empty(&dev->piowait))
1186 _VERBS_ERROR("ipath%d piowait list not empty!\n", 1630 ipath_dev_err(dev->dd, "piowait list not empty!\n");
1187 dev->ib_unit);
1188 if (!list_empty(&dev->rnrwait)) 1631 if (!list_empty(&dev->rnrwait))
1189 _VERBS_ERROR("ipath%d rnrwait list not empty!\n", 1632 ipath_dev_err(dev->dd, "rnrwait list not empty!\n");
1190 dev->ib_unit);
1191 if (!ipath_mcast_tree_empty()) 1633 if (!ipath_mcast_tree_empty())
1192 _VERBS_ERROR("ipath%d multicast table memory leak!\n", 1634 ipath_dev_err(dev->dd, "multicast table memory leak!\n");
1193 dev->ib_unit);
1194 /* 1635 /*
1195 * Note that ipath_unregister_ib_device() can be called before all 1636 * Note that ipath_unregister_ib_device() can be called before all
1196 * the QPs are destroyed! 1637 * the QPs are destroyed!
@@ -1201,25 +1642,12 @@ static void ipath_unregister_ib_device(void *arg)
1201 ib_dealloc_device(ibdev); 1642 ib_dealloc_device(ibdev);
1202} 1643}
1203 1644
1204static int __init ipath_verbs_init(void)
1205{
1206 return ipath_verbs_register(ipath_register_ib_device,
1207 ipath_unregister_ib_device,
1208 ipath_ib_piobufavail, ipath_ib_rcv,
1209 ipath_ib_timer);
1210}
1211
1212static void __exit ipath_verbs_cleanup(void)
1213{
1214 ipath_verbs_unregister();
1215}
1216
1217static ssize_t show_rev(struct class_device *cdev, char *buf) 1645static ssize_t show_rev(struct class_device *cdev, char *buf)
1218{ 1646{
1219 struct ipath_ibdev *dev = 1647 struct ipath_ibdev *dev =
1220 container_of(cdev, struct ipath_ibdev, ibdev.class_dev); 1648 container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
1221 1649
1222 return sprintf(buf, "%x\n", ipath_layer_get_pcirev(dev->dd)); 1650 return sprintf(buf, "%x\n", dev->dd->ipath_pcirev);
1223} 1651}
1224 1652
1225static ssize_t show_hca(struct class_device *cdev, char *buf) 1653static ssize_t show_hca(struct class_device *cdev, char *buf)
@@ -1228,7 +1656,7 @@ static ssize_t show_hca(struct class_device *cdev, char *buf)
1228 container_of(cdev, struct ipath_ibdev, ibdev.class_dev); 1656 container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
1229 int ret; 1657 int ret;
1230 1658
1231 ret = ipath_layer_get_boardname(dev->dd, buf, 128); 1659 ret = dev->dd->ipath_f_get_boardname(dev->dd, buf, 128);
1232 if (ret < 0) 1660 if (ret < 0)
1233 goto bail; 1661 goto bail;
1234 strcat(buf, "\n"); 1662 strcat(buf, "\n");
@@ -1305,6 +1733,3 @@ static int ipath_verbs_register_sysfs(struct ib_device *dev)
1305bail: 1733bail:
1306 return ret; 1734 return ret;
1307} 1735}
1308
1309module_init(ipath_verbs_init);
1310module_exit(ipath_verbs_cleanup);
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 2df684727dc1..09bbb3f9a217 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -38,10 +38,10 @@
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <linux/kref.h>
41#include <rdma/ib_pack.h> 42#include <rdma/ib_pack.h>
42 43
43#include "ipath_layer.h" 44#include "ipath_layer.h"
44#include "verbs_debug.h"
45 45
46#define QPN_MAX (1 << 24) 46#define QPN_MAX (1 << 24)
47#define QPNMAP_ENTRIES (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE) 47#define QPNMAP_ENTRIES (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE)
@@ -50,7 +50,7 @@
50 * Increment this value if any changes that break userspace ABI 50 * Increment this value if any changes that break userspace ABI
51 * compatibility are made. 51 * compatibility are made.
52 */ 52 */
53#define IPATH_UVERBS_ABI_VERSION 1 53#define IPATH_UVERBS_ABI_VERSION 2
54 54
55/* 55/*
56 * Define an ib_cq_notify value that is not valid so we know when CQ 56 * Define an ib_cq_notify value that is not valid so we know when CQ
@@ -152,19 +152,6 @@ struct ipath_mcast {
152 int n_attached; 152 int n_attached;
153}; 153};
154 154
155/* Memory region */
156struct ipath_mr {
157 struct ib_mr ibmr;
158 struct ipath_mregion mr; /* must be last */
159};
160
161/* Fast memory region */
162struct ipath_fmr {
163 struct ib_fmr ibfmr;
164 u8 page_shift;
165 struct ipath_mregion mr; /* must be last */
166};
167
168/* Protection domain */ 155/* Protection domain */
169struct ipath_pd { 156struct ipath_pd {
170 struct ib_pd ibpd; 157 struct ib_pd ibpd;
@@ -178,58 +165,89 @@ struct ipath_ah {
178}; 165};
179 166
180/* 167/*
181 * Quick description of our CQ/QP locking scheme: 168 * This structure is used by ipath_mmap() to validate an offset
182 * 169 * when an mmap() request is made. The vm_area_struct then uses
183 * We have one global lock that protects dev->cq/qp_table. Each 170 * this as its vm_private_data.
184 * struct ipath_cq/qp also has its own lock. An individual qp lock 171 */
185 * may be taken inside of an individual cq lock. Both cqs attached to 172struct ipath_mmap_info {
186 * a qp may be locked, with the send cq locked first. No other 173 struct ipath_mmap_info *next;
187 * nesting should be done. 174 struct ib_ucontext *context;
188 * 175 void *obj;
189 * Each struct ipath_cq/qp also has an atomic_t ref count. The 176 struct kref ref;
190 * pointer from the cq/qp_table to the struct counts as one reference. 177 unsigned size;
191 * This reference also is good for access through the consumer API, so 178 unsigned mmap_cnt;
192 * modifying the CQ/QP etc doesn't need to take another reference. 179};
193 * Access because of a completion being polled does need a reference. 180
194 * 181/*
195 * Finally, each struct ipath_cq/qp has a wait_queue_head_t for the 182 * This structure is used to contain the head pointer, tail pointer,
196 * destroy function to sleep on. 183 * and completion queue entries as a single memory allocation so
197 * 184 * it can be mmap'ed into user space.
198 * This means that access from the consumer API requires nothing but
199 * taking the struct's lock.
200 *
201 * Access because of a completion event should go as follows:
202 * - lock cq/qp_table and look up struct
203 * - increment ref count in struct
204 * - drop cq/qp_table lock
205 * - lock struct, do your thing, and unlock struct
206 * - decrement ref count; if zero, wake up waiters
207 *
208 * To destroy a CQ/QP, we can do the following:
209 * - lock cq/qp_table, remove pointer, unlock cq/qp_table lock
210 * - decrement ref count
211 * - wait_event until ref count is zero
212 *
213 * It is the consumer's responsibilty to make sure that no QP
214 * operations (WQE posting or state modification) are pending when the
215 * QP is destroyed. Also, the consumer must make sure that calls to
216 * qp_modify are serialized.
217 *
218 * Possible optimizations (wait for profile data to see if/where we
219 * have locks bouncing between CPUs):
220 * - split cq/qp table lock into n separate (cache-aligned) locks,
221 * indexed (say) by the page in the table
222 */ 185 */
186struct ipath_cq_wc {
187 u32 head; /* index of next entry to fill */
188 u32 tail; /* index of next ib_poll_cq() entry */
189 struct ib_wc queue[1]; /* this is actually size ibcq.cqe + 1 */
190};
223 191
192/*
193 * The completion queue structure.
194 */
224struct ipath_cq { 195struct ipath_cq {
225 struct ib_cq ibcq; 196 struct ib_cq ibcq;
226 struct tasklet_struct comptask; 197 struct tasklet_struct comptask;
227 spinlock_t lock; 198 spinlock_t lock;
228 u8 notify; 199 u8 notify;
229 u8 triggered; 200 u8 triggered;
230 u32 head; /* new records added to the head */ 201 struct ipath_cq_wc *queue;
231 u32 tail; /* poll_cq() reads from here. */ 202 struct ipath_mmap_info *ip;
232 struct ib_wc *queue; /* this is actually ibcq.cqe + 1 */ 203};
204
205/*
206 * A segment is a linear region of low physical memory.
207 * XXX Maybe we should use phys addr here and kmap()/kunmap().
208 * Used by the verbs layer.
209 */
210struct ipath_seg {
211 void *vaddr;
212 size_t length;
213};
214
215/* The number of ipath_segs that fit in a page. */
216#define IPATH_SEGSZ (PAGE_SIZE / sizeof (struct ipath_seg))
217
218struct ipath_segarray {
219 struct ipath_seg segs[IPATH_SEGSZ];
220};
221
222struct ipath_mregion {
223 u64 user_base; /* User's address for this region */
224 u64 iova; /* IB start address of this region */
225 size_t length;
226 u32 lkey;
227 u32 offset; /* offset (bytes) to start of region */
228 int access_flags;
229 u32 max_segs; /* number of ipath_segs in all the arrays */
230 u32 mapsz; /* size of the map array */
231 struct ipath_segarray *map[0]; /* the segments */
232};
233
234/*
235 * These keep track of the copy progress within a memory region.
236 * Used by the verbs layer.
237 */
238struct ipath_sge {
239 struct ipath_mregion *mr;
240 void *vaddr; /* current pointer into the segment */
241 u32 sge_length; /* length of the SGE */
242 u32 length; /* remaining length of the segment */
243 u16 m; /* current index: mr->map[m] */
244 u16 n; /* current index: mr->map[m]->segs[n] */
245};
246
247/* Memory region */
248struct ipath_mr {
249 struct ib_mr ibmr;
250 struct ipath_mregion mr; /* must be last */
233}; 251};
234 252
235/* 253/*
@@ -248,32 +266,50 @@ struct ipath_swqe {
248 266
249/* 267/*
250 * Receive work request queue entry. 268 * Receive work request queue entry.
251 * The size of the sg_list is determined when the QP is created and stored 269 * The size of the sg_list is determined when the QP (or SRQ) is created
252 * in qp->r_max_sge. 270 * and stored in qp->r_rq.max_sge (or srq->rq.max_sge).
253 */ 271 */
254struct ipath_rwqe { 272struct ipath_rwqe {
255 u64 wr_id; 273 u64 wr_id;
256 u32 length; /* total length of data in sg_list */
257 u8 num_sge; 274 u8 num_sge;
258 struct ipath_sge sg_list[0]; 275 struct ib_sge sg_list[0];
259}; 276};
260 277
261struct ipath_rq { 278/*
262 spinlock_t lock; 279 * This structure is used to contain the head pointer, tail pointer,
280 * and receive work queue entries as a single memory allocation so
281 * it can be mmap'ed into user space.
282 * Note that the wq array elements are variable size so you can't
283 * just index into the array to get the N'th element;
284 * use get_rwqe_ptr() instead.
285 */
286struct ipath_rwq {
263 u32 head; /* new work requests posted to the head */ 287 u32 head; /* new work requests posted to the head */
264 u32 tail; /* receives pull requests from here. */ 288 u32 tail; /* receives pull requests from here. */
289 struct ipath_rwqe wq[0];
290};
291
292struct ipath_rq {
293 struct ipath_rwq *wq;
294 spinlock_t lock;
265 u32 size; /* size of RWQE array */ 295 u32 size; /* size of RWQE array */
266 u8 max_sge; 296 u8 max_sge;
267 struct ipath_rwqe *wq; /* RWQE array */
268}; 297};
269 298
270struct ipath_srq { 299struct ipath_srq {
271 struct ib_srq ibsrq; 300 struct ib_srq ibsrq;
272 struct ipath_rq rq; 301 struct ipath_rq rq;
302 struct ipath_mmap_info *ip;
273 /* send signal when number of RWQEs < limit */ 303 /* send signal when number of RWQEs < limit */
274 u32 limit; 304 u32 limit;
275}; 305};
276 306
307struct ipath_sge_state {
308 struct ipath_sge *sg_list; /* next SGE to be used if any */
309 struct ipath_sge sge; /* progress state for the current SGE */
310 u8 num_sge;
311};
312
277/* 313/*
278 * Variables prefixed with s_ are for the requester (sender). 314 * Variables prefixed with s_ are for the requester (sender).
279 * Variables prefixed with r_ are for the responder (receiver). 315 * Variables prefixed with r_ are for the responder (receiver).
@@ -293,6 +329,7 @@ struct ipath_qp {
293 atomic_t refcount; 329 atomic_t refcount;
294 wait_queue_head_t wait; 330 wait_queue_head_t wait;
295 struct tasklet_struct s_task; 331 struct tasklet_struct s_task;
332 struct ipath_mmap_info *ip;
296 struct ipath_sge_state *s_cur_sge; 333 struct ipath_sge_state *s_cur_sge;
297 struct ipath_sge_state s_sge; /* current send request data */ 334 struct ipath_sge_state s_sge; /* current send request data */
298 /* current RDMA read send data */ 335 /* current RDMA read send data */
@@ -334,6 +371,7 @@ struct ipath_qp {
334 u8 s_retry; /* requester retry counter */ 371 u8 s_retry; /* requester retry counter */
335 u8 s_rnr_retry; /* requester RNR retry counter */ 372 u8 s_rnr_retry; /* requester RNR retry counter */
336 u8 s_pkey_index; /* PKEY index to use */ 373 u8 s_pkey_index; /* PKEY index to use */
374 u8 timeout; /* Timeout for this QP */
337 enum ib_mtu path_mtu; 375 enum ib_mtu path_mtu;
338 u32 remote_qpn; 376 u32 remote_qpn;
339 u32 qkey; /* QKEY for this QP (for UD or RD) */ 377 u32 qkey; /* QKEY for this QP (for UD or RD) */
@@ -345,7 +383,8 @@ struct ipath_qp {
345 u32 s_ssn; /* SSN of tail entry */ 383 u32 s_ssn; /* SSN of tail entry */
346 u32 s_lsn; /* limit sequence number (credit) */ 384 u32 s_lsn; /* limit sequence number (credit) */
347 struct ipath_swqe *s_wq; /* send work queue */ 385 struct ipath_swqe *s_wq; /* send work queue */
348 struct ipath_rq r_rq; /* receive work queue */ 386 struct ipath_rq r_rq; /* receive work queue */
387 struct ipath_sge r_sg_list[0]; /* verified SGEs */
349}; 388};
350 389
351/* 390/*
@@ -369,15 +408,15 @@ static inline struct ipath_swqe *get_swqe_ptr(struct ipath_qp *qp,
369 408
370/* 409/*
371 * Since struct ipath_rwqe is not a fixed size, we can't simply index into 410 * Since struct ipath_rwqe is not a fixed size, we can't simply index into
372 * struct ipath_rq.wq. This function does the array index computation. 411 * struct ipath_rwq.wq. This function does the array index computation.
373 */ 412 */
374static inline struct ipath_rwqe *get_rwqe_ptr(struct ipath_rq *rq, 413static inline struct ipath_rwqe *get_rwqe_ptr(struct ipath_rq *rq,
375 unsigned n) 414 unsigned n)
376{ 415{
377 return (struct ipath_rwqe *) 416 return (struct ipath_rwqe *)
378 ((char *) rq->wq + 417 ((char *) rq->wq->wq +
379 (sizeof(struct ipath_rwqe) + 418 (sizeof(struct ipath_rwqe) +
380 rq->max_sge * sizeof(struct ipath_sge)) * n); 419 rq->max_sge * sizeof(struct ib_sge)) * n);
381} 420}
382 421
383/* 422/*
@@ -417,6 +456,7 @@ struct ipath_ibdev {
417 struct ib_device ibdev; 456 struct ib_device ibdev;
418 struct list_head dev_list; 457 struct list_head dev_list;
419 struct ipath_devdata *dd; 458 struct ipath_devdata *dd;
459 struct ipath_mmap_info *pending_mmaps;
420 int ib_unit; /* This is the device number */ 460 int ib_unit; /* This is the device number */
421 u16 sm_lid; /* in host order */ 461 u16 sm_lid; /* in host order */
422 u8 sm_sl; 462 u8 sm_sl;
@@ -435,11 +475,20 @@ struct ipath_ibdev {
435 __be64 sys_image_guid; /* in network order */ 475 __be64 sys_image_guid; /* in network order */
436 __be64 gid_prefix; /* in network order */ 476 __be64 gid_prefix; /* in network order */
437 __be64 mkey; 477 __be64 mkey;
478
438 u32 n_pds_allocated; /* number of PDs allocated for device */ 479 u32 n_pds_allocated; /* number of PDs allocated for device */
480 spinlock_t n_pds_lock;
439 u32 n_ahs_allocated; /* number of AHs allocated for device */ 481 u32 n_ahs_allocated; /* number of AHs allocated for device */
482 spinlock_t n_ahs_lock;
440 u32 n_cqs_allocated; /* number of CQs allocated for device */ 483 u32 n_cqs_allocated; /* number of CQs allocated for device */
484 spinlock_t n_cqs_lock;
485 u32 n_qps_allocated; /* number of QPs allocated for device */
486 spinlock_t n_qps_lock;
441 u32 n_srqs_allocated; /* number of SRQs allocated for device */ 487 u32 n_srqs_allocated; /* number of SRQs allocated for device */
488 spinlock_t n_srqs_lock;
442 u32 n_mcast_grps_allocated; /* number of mcast groups allocated */ 489 u32 n_mcast_grps_allocated; /* number of mcast groups allocated */
490 spinlock_t n_mcast_grps_lock;
491
443 u64 ipath_sword; /* total dwords sent (sample result) */ 492 u64 ipath_sword; /* total dwords sent (sample result) */
444 u64 ipath_rword; /* total dwords received (sample result) */ 493 u64 ipath_rword; /* total dwords received (sample result) */
445 u64 ipath_spkts; /* total packets sent (sample result) */ 494 u64 ipath_spkts; /* total packets sent (sample result) */
@@ -494,8 +543,19 @@ struct ipath_ibdev {
494 struct ipath_opcode_stats opstats[128]; 543 struct ipath_opcode_stats opstats[128];
495}; 544};
496 545
497struct ipath_ucontext { 546struct ipath_verbs_counters {
498 struct ib_ucontext ibucontext; 547 u64 symbol_error_counter;
548 u64 link_error_recovery_counter;
549 u64 link_downed_counter;
550 u64 port_rcv_errors;
551 u64 port_rcv_remphys_errors;
552 u64 port_xmit_discards;
553 u64 port_xmit_data;
554 u64 port_rcv_data;
555 u64 port_xmit_packets;
556 u64 port_rcv_packets;
557 u32 local_link_integrity_errors;
558 u32 excessive_buffer_overrun_errors;
499}; 559};
500 560
501static inline struct ipath_mr *to_imr(struct ib_mr *ibmr) 561static inline struct ipath_mr *to_imr(struct ib_mr *ibmr)
@@ -503,11 +563,6 @@ static inline struct ipath_mr *to_imr(struct ib_mr *ibmr)
503 return container_of(ibmr, struct ipath_mr, ibmr); 563 return container_of(ibmr, struct ipath_mr, ibmr);
504} 564}
505 565
506static inline struct ipath_fmr *to_ifmr(struct ib_fmr *ibfmr)
507{
508 return container_of(ibfmr, struct ipath_fmr, ibfmr);
509}
510
511static inline struct ipath_pd *to_ipd(struct ib_pd *ibpd) 566static inline struct ipath_pd *to_ipd(struct ib_pd *ibpd)
512{ 567{
513 return container_of(ibpd, struct ipath_pd, ibpd); 568 return container_of(ibpd, struct ipath_pd, ibpd);
@@ -545,12 +600,6 @@ int ipath_process_mad(struct ib_device *ibdev,
545 struct ib_grh *in_grh, 600 struct ib_grh *in_grh,
546 struct ib_mad *in_mad, struct ib_mad *out_mad); 601 struct ib_mad *in_mad, struct ib_mad *out_mad);
547 602
548static inline struct ipath_ucontext *to_iucontext(struct ib_ucontext
549 *ibucontext)
550{
551 return container_of(ibucontext, struct ipath_ucontext, ibucontext);
552}
553
554/* 603/*
555 * Compare the lower 24 bits of the two values. 604 * Compare the lower 24 bits of the two values.
556 * Returns an integer <, ==, or > than zero. 605 * Returns an integer <, ==, or > than zero.
@@ -562,6 +611,13 @@ static inline int ipath_cmp24(u32 a, u32 b)
562 611
563struct ipath_mcast *ipath_mcast_find(union ib_gid *mgid); 612struct ipath_mcast *ipath_mcast_find(union ib_gid *mgid);
564 613
614int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords,
615 u64 *rwords, u64 *spkts, u64 *rpkts,
616 u64 *xmit_wait);
617
618int ipath_get_counters(struct ipath_devdata *dd,
619 struct ipath_verbs_counters *cntrs);
620
565int ipath_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); 621int ipath_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
566 622
567int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); 623int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
@@ -579,7 +635,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
579int ipath_destroy_qp(struct ib_qp *ibqp); 635int ipath_destroy_qp(struct ib_qp *ibqp);
580 636
581int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, 637int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
582 int attr_mask); 638 int attr_mask, struct ib_udata *udata);
583 639
584int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, 640int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
585 int attr_mask, struct ib_qp_init_attr *init_attr); 641 int attr_mask, struct ib_qp_init_attr *init_attr);
@@ -592,6 +648,9 @@ void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc);
592 648
593void ipath_get_credit(struct ipath_qp *qp, u32 aeth); 649void ipath_get_credit(struct ipath_qp *qp, u32 aeth);
594 650
651int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
652 u32 *hdr, u32 len, struct ipath_sge_state *ss);
653
595void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); 654void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig);
596 655
597int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, 656int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
@@ -638,7 +697,8 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
638 struct ib_udata *udata); 697 struct ib_udata *udata);
639 698
640int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, 699int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
641 enum ib_srq_attr_mask attr_mask); 700 enum ib_srq_attr_mask attr_mask,
701 struct ib_udata *udata);
642 702
643int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr); 703int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr);
644 704
@@ -680,6 +740,10 @@ int ipath_unmap_fmr(struct list_head *fmr_list);
680 740
681int ipath_dealloc_fmr(struct ib_fmr *ibfmr); 741int ipath_dealloc_fmr(struct ib_fmr *ibfmr);
682 742
743void ipath_release_mmap_info(struct kref *ref);
744
745int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
746
683void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev); 747void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev);
684 748
685void ipath_insert_rnr_queue(struct ipath_qp *qp); 749void ipath_insert_rnr_queue(struct ipath_qp *qp);
@@ -700,6 +764,22 @@ int ipath_make_rc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr,
700int ipath_make_uc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr, 764int ipath_make_uc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr,
701 u32 pmtu, u32 *bth0p, u32 *bth2p); 765 u32 pmtu, u32 *bth0p, u32 *bth2p);
702 766
767int ipath_register_ib_device(struct ipath_devdata *);
768
769void ipath_unregister_ib_device(struct ipath_ibdev *);
770
771void ipath_ib_rcv(struct ipath_ibdev *, void *, void *, u32);
772
773int ipath_ib_piobufavail(struct ipath_ibdev *);
774
775void ipath_ib_timer(struct ipath_ibdev *);
776
777unsigned ipath_get_npkeys(struct ipath_devdata *);
778
779u32 ipath_get_cr_errpkey(struct ipath_devdata *);
780
781unsigned ipath_get_pkey(struct ipath_devdata *, unsigned);
782
703extern const enum ib_wc_opcode ib_ipath_wc_opcode[]; 783extern const enum ib_wc_opcode ib_ipath_wc_opcode[];
704 784
705extern const u8 ipath_cvt_physportstate[]; 785extern const u8 ipath_cvt_physportstate[];
@@ -714,6 +794,8 @@ extern unsigned int ib_ipath_max_cqs;
714 794
715extern unsigned int ib_ipath_max_qp_wrs; 795extern unsigned int ib_ipath_max_qp_wrs;
716 796
797extern unsigned int ib_ipath_max_qps;
798
717extern unsigned int ib_ipath_max_sges; 799extern unsigned int ib_ipath_max_sges;
718 800
719extern unsigned int ib_ipath_max_mcast_grps; 801extern unsigned int ib_ipath_max_mcast_grps;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
index ee0e1d96d723..085e28b939ec 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
@@ -207,12 +207,17 @@ static int ipath_mcast_add(struct ipath_ibdev *dev,
207 goto bail; 207 goto bail;
208 } 208 }
209 209
210 spin_lock(&dev->n_mcast_grps_lock);
210 if (dev->n_mcast_grps_allocated == ib_ipath_max_mcast_grps) { 211 if (dev->n_mcast_grps_allocated == ib_ipath_max_mcast_grps) {
212 spin_unlock(&dev->n_mcast_grps_lock);
211 ret = ENOMEM; 213 ret = ENOMEM;
212 goto bail; 214 goto bail;
213 } 215 }
214 216
215 dev->n_mcast_grps_allocated++; 217 dev->n_mcast_grps_allocated++;
218 spin_unlock(&dev->n_mcast_grps_lock);
219
220 mcast->n_attached++;
216 221
217 list_add_tail_rcu(&mqp->list, &mcast->qp_list); 222 list_add_tail_rcu(&mqp->list, &mcast->qp_list);
218 223
@@ -343,7 +348,9 @@ int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
343 atomic_dec(&mcast->refcount); 348 atomic_dec(&mcast->refcount);
344 wait_event(mcast->wait, !atomic_read(&mcast->refcount)); 349 wait_event(mcast->wait, !atomic_read(&mcast->refcount));
345 ipath_mcast_free(mcast); 350 ipath_mcast_free(mcast);
351 spin_lock(&dev->n_mcast_grps_lock);
346 dev->n_mcast_grps_allocated--; 352 dev->n_mcast_grps_allocated--;
353 spin_unlock(&dev->n_mcast_grps_lock);
347 } 354 }
348 355
349 ret = 0; 356 ret = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c b/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
new file mode 100644
index 000000000000..036fde662aa9
--- /dev/null
+++ b/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2006 QLogic, Inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33/*
34 * This file is conditionally built on PowerPC only. Otherwise weak symbol
35 * versions of the functions exported from here are used.
36 */
37
38#include "ipath_kernel.h"
39
40/**
41 * ipath_unordered_wc - indicate whether write combining is ordered
42 *
43 * PowerPC systems (at least those in the 970 processor family)
44 * write partially filled store buffers in address order, but will write
45 * completely filled store buffers in "random" order, and therefore must
46 * have serialization for correctness with current InfiniPath chips.
47 *
48 */
49int ipath_unordered_wc(void)
50{
51 return 1;
52}
diff --git a/drivers/infiniband/hw/ipath/verbs_debug.h b/drivers/infiniband/hw/ipath/verbs_debug.h
deleted file mode 100644
index 6186676f2a16..000000000000
--- a/drivers/infiniband/hw/ipath/verbs_debug.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/*
2 * Copyright (c) 2006 QLogic, Inc. All rights reserved.
3 * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34#ifndef _VERBS_DEBUG_H
35#define _VERBS_DEBUG_H
36
37/*
38 * This file contains tracing code for the ib_ipath kernel module.
39 */
40#ifndef _VERBS_DEBUGGING /* tracing enabled or not */
41#define _VERBS_DEBUGGING 1
42#endif
43
44extern unsigned ib_ipath_debug;
45
46#define _VERBS_ERROR(fmt,...) \
47 do { \
48 printk(KERN_ERR "%s: " fmt, "ib_ipath", ##__VA_ARGS__); \
49 } while(0)
50
51#define _VERBS_UNIT_ERROR(unit,fmt,...) \
52 do { \
53 printk(KERN_ERR "%s: " fmt, "ib_ipath", ##__VA_ARGS__); \
54 } while(0)
55
56#if _VERBS_DEBUGGING
57
58/*
59 * Mask values for debugging. The scheme allows us to compile out any
60 * of the debug tracing stuff, and if compiled in, to enable or
61 * disable dynamically.
62 * This can be set at modprobe time also:
63 * modprobe ib_path ib_ipath_debug=3
64 */
65
66#define __VERBS_INFO 0x1 /* generic low verbosity stuff */
67#define __VERBS_DBG 0x2 /* generic debug */
68#define __VERBS_VDBG 0x4 /* verbose debug */
69#define __VERBS_SMADBG 0x8000 /* sma packet debug */
70
71#define _VERBS_INFO(fmt,...) \
72 do { \
73 if (unlikely(ib_ipath_debug&__VERBS_INFO)) \
74 printk(KERN_INFO "%s: " fmt,"ib_ipath", \
75 ##__VA_ARGS__); \
76 } while(0)
77
78#define _VERBS_DBG(fmt,...) \
79 do { \
80 if (unlikely(ib_ipath_debug&__VERBS_DBG)) \
81 printk(KERN_DEBUG "%s: " fmt, __func__, \
82 ##__VA_ARGS__); \
83 } while(0)
84
85#define _VERBS_VDBG(fmt,...) \
86 do { \
87 if (unlikely(ib_ipath_debug&__VERBS_VDBG)) \
88 printk(KERN_DEBUG "%s: " fmt, __func__, \
89 ##__VA_ARGS__); \
90 } while(0)
91
92#define _VERBS_SMADBG(fmt,...) \
93 do { \
94 if (unlikely(ib_ipath_debug&__VERBS_SMADBG)) \
95 printk(KERN_DEBUG "%s: " fmt, __func__, \
96 ##__VA_ARGS__); \
97 } while(0)
98
99#else /* ! _VERBS_DEBUGGING */
100
101#define _VERBS_INFO(fmt,...)
102#define _VERBS_DBG(fmt,...)
103#define _VERBS_VDBG(fmt,...)
104#define _VERBS_SMADBG(fmt,...)
105
106#endif /* _VERBS_DEBUGGING */
107
108#endif /* _VERBS_DEBUG_H */
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index e215041b2db9..69599455aca2 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -90,7 +90,7 @@ static enum ib_rate tavor_rate_to_ib(u8 mthca_rate, u8 port_rate)
90 case MTHCA_RATE_TAVOR_1X: return IB_RATE_2_5_GBPS; 90 case MTHCA_RATE_TAVOR_1X: return IB_RATE_2_5_GBPS;
91 case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS; 91 case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS;
92 case MTHCA_RATE_TAVOR_4X: return IB_RATE_10_GBPS; 92 case MTHCA_RATE_TAVOR_4X: return IB_RATE_10_GBPS;
93 default: return port_rate; 93 default: return mult_to_ib_rate(port_rate);
94 } 94 }
95} 95}
96 96
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index c3bec7490f52..cd044ea2dfa4 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -34,6 +34,7 @@
34 34
35#include <linux/jiffies.h> 35#include <linux/jiffies.h>
36#include <linux/timer.h> 36#include <linux/timer.h>
37#include <linux/workqueue.h>
37 38
38#include "mthca_dev.h" 39#include "mthca_dev.h"
39 40
@@ -48,9 +49,41 @@ enum {
48 49
49static DEFINE_SPINLOCK(catas_lock); 50static DEFINE_SPINLOCK(catas_lock);
50 51
52static LIST_HEAD(catas_list);
53static struct workqueue_struct *catas_wq;
54static struct work_struct catas_work;
55
56static int catas_reset_disable;
57module_param_named(catas_reset_disable, catas_reset_disable, int, 0644);
58MODULE_PARM_DESC(catas_reset_disable, "disable reset on catastrophic event if nonzero");
59
60static void catas_reset(void *work_ptr)
61{
62 struct mthca_dev *dev, *tmpdev;
63 LIST_HEAD(tlist);
64 int ret;
65
66 mutex_lock(&mthca_device_mutex);
67
68 spin_lock_irq(&catas_lock);
69 list_splice_init(&catas_list, &tlist);
70 spin_unlock_irq(&catas_lock);
71
72 list_for_each_entry_safe(dev, tmpdev, &tlist, catas_err.list) {
73 ret = __mthca_restart_one(dev->pdev);
74 if (ret)
75 mthca_err(dev, "Reset failed (%d)\n", ret);
76 else
77 mthca_dbg(dev, "Reset succeeded\n");
78 }
79
80 mutex_unlock(&mthca_device_mutex);
81}
82
51static void handle_catas(struct mthca_dev *dev) 83static void handle_catas(struct mthca_dev *dev)
52{ 84{
53 struct ib_event event; 85 struct ib_event event;
86 unsigned long flags;
54 const char *type; 87 const char *type;
55 int i; 88 int i;
56 89
@@ -82,6 +115,14 @@ static void handle_catas(struct mthca_dev *dev)
82 for (i = 0; i < dev->catas_err.size; ++i) 115 for (i = 0; i < dev->catas_err.size; ++i)
83 mthca_err(dev, " buf[%02x]: %08x\n", 116 mthca_err(dev, " buf[%02x]: %08x\n",
84 i, swab32(readl(dev->catas_err.map + i))); 117 i, swab32(readl(dev->catas_err.map + i)));
118
119 if (catas_reset_disable)
120 return;
121
122 spin_lock_irqsave(&catas_lock, flags);
123 list_add(&dev->catas_err.list, &catas_list);
124 queue_work(catas_wq, &catas_work);
125 spin_unlock_irqrestore(&catas_lock, flags);
85} 126}
86 127
87static void poll_catas(unsigned long dev_ptr) 128static void poll_catas(unsigned long dev_ptr)
@@ -135,6 +176,7 @@ void mthca_start_catas_poll(struct mthca_dev *dev)
135 dev->catas_err.timer.data = (unsigned long) dev; 176 dev->catas_err.timer.data = (unsigned long) dev;
136 dev->catas_err.timer.function = poll_catas; 177 dev->catas_err.timer.function = poll_catas;
137 dev->catas_err.timer.expires = jiffies + MTHCA_CATAS_POLL_INTERVAL; 178 dev->catas_err.timer.expires = jiffies + MTHCA_CATAS_POLL_INTERVAL;
179 INIT_LIST_HEAD(&dev->catas_err.list);
138 add_timer(&dev->catas_err.timer); 180 add_timer(&dev->catas_err.timer);
139} 181}
140 182
@@ -153,4 +195,24 @@ void mthca_stop_catas_poll(struct mthca_dev *dev)
153 dev->catas_err.addr), 195 dev->catas_err.addr),
154 dev->catas_err.size * 4); 196 dev->catas_err.size * 4);
155 } 197 }
198
199 spin_lock_irq(&catas_lock);
200 list_del(&dev->catas_err.list);
201 spin_unlock_irq(&catas_lock);
202}
203
204int __init mthca_catas_init(void)
205{
206 INIT_WORK(&catas_work, catas_reset, NULL);
207
208 catas_wq = create_singlethread_workqueue("mthca_catas");
209 if (!catas_wq)
210 return -ENOMEM;
211
212 return 0;
213}
214
215void mthca_catas_cleanup(void)
216{
217 destroy_workqueue(catas_wq);
156} 218}
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index deabc14b4ea4..99a94d710935 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -34,7 +34,7 @@
34 * $Id: mthca_cmd.c 1349 2004-12-16 21:09:43Z roland $ 34 * $Id: mthca_cmd.c 1349 2004-12-16 21:09:43Z roland $
35 */ 35 */
36 36
37#include <linux/sched.h> 37#include <linux/completion.h>
38#include <linux/pci.h> 38#include <linux/pci.h>
39#include <linux/errno.h> 39#include <linux/errno.h>
40#include <asm/io.h> 40#include <asm/io.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 3e27a084257e..e393681ba7d4 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -544,11 +544,11 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
544 wq = &(*cur_qp)->rq; 544 wq = &(*cur_qp)->rq;
545 wqe = be32_to_cpu(cqe->wqe); 545 wqe = be32_to_cpu(cqe->wqe);
546 wqe_index = wqe >> wq->wqe_shift; 546 wqe_index = wqe >> wq->wqe_shift;
547 /* 547 /*
548 * WQE addr == base - 1 might be reported in receive completion 548 * WQE addr == base - 1 might be reported in receive completion
549 * with error instead of (rq size - 1) by Sinai FW 1.0.800 and 549 * with error instead of (rq size - 1) by Sinai FW 1.0.800 and
550 * Arbel FW 5.1.400. This bug should be fixed in later FW revs. 550 * Arbel FW 5.1.400. This bug should be fixed in later FW revs.
551 */ 551 */
552 if (unlikely(wqe_index < 0)) 552 if (unlikely(wqe_index < 0))
553 wqe_index = wq->max - 1; 553 wqe_index = wq->max - 1;
554 entry->wr_id = (*cur_qp)->wrid[wqe_index]; 554 entry->wr_id = (*cur_qp)->wrid[wqe_index];
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index f8160b8de090..fe5cecf70fed 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -45,6 +45,7 @@
45#include <linux/dma-mapping.h> 45#include <linux/dma-mapping.h>
46#include <linux/timer.h> 46#include <linux/timer.h>
47#include <linux/mutex.h> 47#include <linux/mutex.h>
48#include <linux/list.h>
48 49
49#include <asm/semaphore.h> 50#include <asm/semaphore.h>
50 51
@@ -283,8 +284,11 @@ struct mthca_catas_err {
283 unsigned long stop; 284 unsigned long stop;
284 u32 size; 285 u32 size;
285 struct timer_list timer; 286 struct timer_list timer;
287 struct list_head list;
286}; 288};
287 289
290extern struct mutex mthca_device_mutex;
291
288struct mthca_dev { 292struct mthca_dev {
289 struct ib_device ib_dev; 293 struct ib_device ib_dev;
290 struct pci_dev *pdev; 294 struct pci_dev *pdev;
@@ -450,6 +454,9 @@ void mthca_unregister_device(struct mthca_dev *dev);
450 454
451void mthca_start_catas_poll(struct mthca_dev *dev); 455void mthca_start_catas_poll(struct mthca_dev *dev);
452void mthca_stop_catas_poll(struct mthca_dev *dev); 456void mthca_stop_catas_poll(struct mthca_dev *dev);
457int __mthca_restart_one(struct pci_dev *pdev);
458int mthca_catas_init(void);
459void mthca_catas_cleanup(void);
453 460
454int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar); 461int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar);
455void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar); 462void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar);
@@ -506,7 +513,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
506 struct ib_srq_attr *attr, struct mthca_srq *srq); 513 struct ib_srq_attr *attr, struct mthca_srq *srq);
507void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq); 514void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
508int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, 515int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
509 enum ib_srq_attr_mask attr_mask); 516 enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
510int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr); 517int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
511int mthca_max_srq_sge(struct mthca_dev *dev); 518int mthca_max_srq_sge(struct mthca_dev *dev);
512void mthca_srq_event(struct mthca_dev *dev, u32 srqn, 519void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
@@ -521,7 +528,8 @@ void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
521 enum ib_event_type event_type); 528 enum ib_event_type event_type);
522int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask, 529int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
523 struct ib_qp_init_attr *qp_init_attr); 530 struct ib_qp_init_attr *qp_init_attr);
524int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask); 531int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
532 struct ib_udata *udata);
525int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, 533int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
526 struct ib_send_wr **bad_wr); 534 struct ib_send_wr **bad_wr);
527int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, 535int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index d9bc030bcccc..45e106f14807 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -119,7 +119,7 @@ static void smp_snoop(struct ib_device *ibdev,
119 119
120 mthca_update_rate(to_mdev(ibdev), port_num); 120 mthca_update_rate(to_mdev(ibdev), port_num);
121 update_sm_ah(to_mdev(ibdev), port_num, 121 update_sm_ah(to_mdev(ibdev), port_num,
122 be16_to_cpu(pinfo->lid), 122 be16_to_cpu(pinfo->sm_lid),
123 pinfo->neighbormtu_mastersmsl & 0xf); 123 pinfo->neighbormtu_mastersmsl & 0xf);
124 124
125 event.device = ibdev; 125 event.device = ibdev;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 7b82c1907f04..47ea02148368 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -80,6 +80,8 @@ static int tune_pci = 0;
80module_param(tune_pci, int, 0444); 80module_param(tune_pci, int, 0444);
81MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero"); 81MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero");
82 82
83struct mutex mthca_device_mutex;
84
83static const char mthca_version[] __devinitdata = 85static const char mthca_version[] __devinitdata =
84 DRV_NAME ": Mellanox InfiniBand HCA driver v" 86 DRV_NAME ": Mellanox InfiniBand HCA driver v"
85 DRV_VERSION " (" DRV_RELDATE ")\n"; 87 DRV_VERSION " (" DRV_RELDATE ")\n";
@@ -978,28 +980,15 @@ static struct {
978 MTHCA_FLAG_SINAI_OPT } 980 MTHCA_FLAG_SINAI_OPT }
979}; 981};
980 982
981static int __devinit mthca_init_one(struct pci_dev *pdev, 983static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
982 const struct pci_device_id *id)
983{ 984{
984 static int mthca_version_printed = 0;
985 int ddr_hidden = 0; 985 int ddr_hidden = 0;
986 int err; 986 int err;
987 struct mthca_dev *mdev; 987 struct mthca_dev *mdev;
988 988
989 if (!mthca_version_printed) {
990 printk(KERN_INFO "%s", mthca_version);
991 ++mthca_version_printed;
992 }
993
994 printk(KERN_INFO PFX "Initializing %s\n", 989 printk(KERN_INFO PFX "Initializing %s\n",
995 pci_name(pdev)); 990 pci_name(pdev));
996 991
997 if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) {
998 printk(KERN_ERR PFX "%s has invalid driver data %lx\n",
999 pci_name(pdev), id->driver_data);
1000 return -ENODEV;
1001 }
1002
1003 err = pci_enable_device(pdev); 992 err = pci_enable_device(pdev);
1004 if (err) { 993 if (err) {
1005 dev_err(&pdev->dev, "Cannot enable PCI device, " 994 dev_err(&pdev->dev, "Cannot enable PCI device, "
@@ -1065,7 +1054,7 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
1065 1054
1066 mdev->pdev = pdev; 1055 mdev->pdev = pdev;
1067 1056
1068 mdev->mthca_flags = mthca_hca_table[id->driver_data].flags; 1057 mdev->mthca_flags = mthca_hca_table[hca_type].flags;
1069 if (ddr_hidden) 1058 if (ddr_hidden)
1070 mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN; 1059 mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN;
1071 1060
@@ -1099,13 +1088,13 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
1099 if (err) 1088 if (err)
1100 goto err_cmd; 1089 goto err_cmd;
1101 1090
1102 if (mdev->fw_ver < mthca_hca_table[id->driver_data].latest_fw) { 1091 if (mdev->fw_ver < mthca_hca_table[hca_type].latest_fw) {
1103 mthca_warn(mdev, "HCA FW version %d.%d.%d is old (%d.%d.%d is current).\n", 1092 mthca_warn(mdev, "HCA FW version %d.%d.%d is old (%d.%d.%d is current).\n",
1104 (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff, 1093 (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff,
1105 (int) (mdev->fw_ver & 0xffff), 1094 (int) (mdev->fw_ver & 0xffff),
1106 (int) (mthca_hca_table[id->driver_data].latest_fw >> 32), 1095 (int) (mthca_hca_table[hca_type].latest_fw >> 32),
1107 (int) (mthca_hca_table[id->driver_data].latest_fw >> 16) & 0xffff, 1096 (int) (mthca_hca_table[hca_type].latest_fw >> 16) & 0xffff,
1108 (int) (mthca_hca_table[id->driver_data].latest_fw & 0xffff)); 1097 (int) (mthca_hca_table[hca_type].latest_fw & 0xffff));
1109 mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n"); 1098 mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n");
1110 } 1099 }
1111 1100
@@ -1122,6 +1111,7 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
1122 goto err_unregister; 1111 goto err_unregister;
1123 1112
1124 pci_set_drvdata(pdev, mdev); 1113 pci_set_drvdata(pdev, mdev);
1114 mdev->hca_type = hca_type;
1125 1115
1126 return 0; 1116 return 0;
1127 1117
@@ -1166,7 +1156,7 @@ err_disable_pdev:
1166 return err; 1156 return err;
1167} 1157}
1168 1158
1169static void __devexit mthca_remove_one(struct pci_dev *pdev) 1159static void __mthca_remove_one(struct pci_dev *pdev)
1170{ 1160{
1171 struct mthca_dev *mdev = pci_get_drvdata(pdev); 1161 struct mthca_dev *mdev = pci_get_drvdata(pdev);
1172 u8 status; 1162 u8 status;
@@ -1211,6 +1201,51 @@ static void __devexit mthca_remove_one(struct pci_dev *pdev)
1211 } 1201 }
1212} 1202}
1213 1203
1204int __mthca_restart_one(struct pci_dev *pdev)
1205{
1206 struct mthca_dev *mdev;
1207
1208 mdev = pci_get_drvdata(pdev);
1209 if (!mdev)
1210 return -ENODEV;
1211 __mthca_remove_one(pdev);
1212 return __mthca_init_one(pdev, mdev->hca_type);
1213}
1214
1215static int __devinit mthca_init_one(struct pci_dev *pdev,
1216 const struct pci_device_id *id)
1217{
1218 static int mthca_version_printed = 0;
1219 int ret;
1220
1221 mutex_lock(&mthca_device_mutex);
1222
1223 if (!mthca_version_printed) {
1224 printk(KERN_INFO "%s", mthca_version);
1225 ++mthca_version_printed;
1226 }
1227
1228 if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) {
1229 printk(KERN_ERR PFX "%s has invalid driver data %lx\n",
1230 pci_name(pdev), id->driver_data);
1231 mutex_unlock(&mthca_device_mutex);
1232 return -ENODEV;
1233 }
1234
1235 ret = __mthca_init_one(pdev, id->driver_data);
1236
1237 mutex_unlock(&mthca_device_mutex);
1238
1239 return ret;
1240}
1241
1242static void __devexit mthca_remove_one(struct pci_dev *pdev)
1243{
1244 mutex_lock(&mthca_device_mutex);
1245 __mthca_remove_one(pdev);
1246 mutex_unlock(&mthca_device_mutex);
1247}
1248
1214static struct pci_device_id mthca_pci_table[] = { 1249static struct pci_device_id mthca_pci_table[] = {
1215 { PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR), 1250 { PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR),
1216 .driver_data = TAVOR }, 1251 .driver_data = TAVOR },
@@ -1248,13 +1283,24 @@ static int __init mthca_init(void)
1248{ 1283{
1249 int ret; 1284 int ret;
1250 1285
1286 mutex_init(&mthca_device_mutex);
1287 ret = mthca_catas_init();
1288 if (ret)
1289 return ret;
1290
1251 ret = pci_register_driver(&mthca_driver); 1291 ret = pci_register_driver(&mthca_driver);
1252 return ret < 0 ? ret : 0; 1292 if (ret < 0) {
1293 mthca_catas_cleanup();
1294 return ret;
1295 }
1296
1297 return 0;
1253} 1298}
1254 1299
1255static void __exit mthca_cleanup(void) 1300static void __exit mthca_cleanup(void)
1256{ 1301{
1257 pci_unregister_driver(&mthca_driver); 1302 pci_unregister_driver(&mthca_driver);
1303 mthca_catas_cleanup();
1258} 1304}
1259 1305
1260module_init(mthca_init); 1306module_init(mthca_init);
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 265b1d1c4a62..981fe2eebdfa 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -1288,7 +1288,7 @@ int mthca_register_device(struct mthca_dev *dev)
1288 (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | 1288 (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
1289 (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) | 1289 (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) |
1290 (1ull << IB_USER_VERBS_CMD_DETACH_MCAST); 1290 (1ull << IB_USER_VERBS_CMD_DETACH_MCAST);
1291 dev->ib_dev.node_type = IB_NODE_CA; 1291 dev->ib_dev.node_type = RDMA_NODE_IB_CA;
1292 dev->ib_dev.phys_port_cnt = dev->limits.num_ports; 1292 dev->ib_dev.phys_port_cnt = dev->limits.num_ports;
1293 dev->ib_dev.dma_device = &dev->pdev->dev; 1293 dev->ib_dev.dma_device = &dev->pdev->dev;
1294 dev->ib_dev.class_dev.dev = &dev->pdev->dev; 1294 dev->ib_dev.class_dev.dev = &dev->pdev->dev;
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 2e8f6f36e0a5..5e5c58b9920b 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -408,7 +408,7 @@ static void to_ib_ah_attr(struct mthca_dev *dev, struct ib_ah_attr *ib_ah_attr,
408 ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28; 408 ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28;
409 ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f; 409 ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f;
410 ib_ah_attr->static_rate = mthca_rate_to_ib(dev, 410 ib_ah_attr->static_rate = mthca_rate_to_ib(dev,
411 path->static_rate & 0x7, 411 path->static_rate & 0xf,
412 ib_ah_attr->port_num); 412 ib_ah_attr->port_num);
413 ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0; 413 ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0;
414 if (ib_ah_attr->ah_flags) { 414 if (ib_ah_attr->ah_flags) {
@@ -472,10 +472,14 @@ int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_m
472 if (qp->transport == RC || qp->transport == UC) { 472 if (qp->transport == RC || qp->transport == UC) {
473 to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path); 473 to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
474 to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path); 474 to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
475 qp_attr->alt_pkey_index =
476 be32_to_cpu(context->alt_path.port_pkey) & 0x7f;
477 qp_attr->alt_port_num = qp_attr->alt_ah_attr.port_num;
475 } 478 }
476 479
477 qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f; 480 qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f;
478 qp_attr->alt_pkey_index = be32_to_cpu(context->alt_path.port_pkey) & 0x7f; 481 qp_attr->port_num =
482 (be32_to_cpu(context->pri_path.port_pkey) >> 24) & 0x3;
479 483
480 /* qp_attr->en_sqd_async_notify is only applicable in modify qp */ 484 /* qp_attr->en_sqd_async_notify is only applicable in modify qp */
481 qp_attr->sq_draining = mthca_state == MTHCA_QP_STATE_DRAINING; 485 qp_attr->sq_draining = mthca_state == MTHCA_QP_STATE_DRAINING;
@@ -486,11 +490,9 @@ int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_m
486 1 << ((be32_to_cpu(context->params2) >> 21) & 0x7); 490 1 << ((be32_to_cpu(context->params2) >> 21) & 0x7);
487 qp_attr->min_rnr_timer = 491 qp_attr->min_rnr_timer =
488 (be32_to_cpu(context->rnr_nextrecvpsn) >> 24) & 0x1f; 492 (be32_to_cpu(context->rnr_nextrecvpsn) >> 24) & 0x1f;
489 qp_attr->port_num = qp_attr->ah_attr.port_num;
490 qp_attr->timeout = context->pri_path.ackto >> 3; 493 qp_attr->timeout = context->pri_path.ackto >> 3;
491 qp_attr->retry_cnt = (be32_to_cpu(context->params1) >> 16) & 0x7; 494 qp_attr->retry_cnt = (be32_to_cpu(context->params1) >> 16) & 0x7;
492 qp_attr->rnr_retry = context->pri_path.rnr_retry >> 5; 495 qp_attr->rnr_retry = context->pri_path.rnr_retry >> 5;
493 qp_attr->alt_port_num = qp_attr->alt_ah_attr.port_num;
494 qp_attr->alt_timeout = context->alt_path.ackto >> 3; 496 qp_attr->alt_timeout = context->alt_path.ackto >> 3;
495 qp_init_attr->cap = qp_attr->cap; 497 qp_init_attr->cap = qp_attr->cap;
496 498
@@ -527,7 +529,8 @@ static int mthca_path_set(struct mthca_dev *dev, struct ib_ah_attr *ah,
527 return 0; 529 return 0;
528} 530}
529 531
530int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) 532int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
533 struct ib_udata *udata)
531{ 534{
532 struct mthca_dev *dev = to_mdev(ibqp->device); 535 struct mthca_dev *dev = to_mdev(ibqp->device);
533 struct mthca_qp *qp = to_mqp(ibqp); 536 struct mthca_qp *qp = to_mqp(ibqp);
@@ -842,11 +845,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
842 * entries and reinitialize the QP. 845 * entries and reinitialize the QP.
843 */ 846 */
844 if (new_state == IB_QPS_RESET && !qp->ibqp.uobject) { 847 if (new_state == IB_QPS_RESET && !qp->ibqp.uobject) {
845 mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn, 848 mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn,
846 qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); 849 qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
847 if (qp->ibqp.send_cq != qp->ibqp.recv_cq) 850 if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
848 mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn, 851 mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn, NULL);
849 qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
850 852
851 mthca_wq_reset(&qp->sq); 853 mthca_wq_reset(&qp->sq);
852 qp->sq.last = get_send_wqe(qp, qp->sq.max - 1); 854 qp->sq.last = get_send_wqe(qp, qp->sq.max - 1);
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index b60a9d79ae54..0f316c87bf64 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -358,7 +358,7 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq)
358} 358}
359 359
360int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, 360int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
361 enum ib_srq_attr_mask attr_mask) 361 enum ib_srq_attr_mask attr_mask, struct ib_udata *udata)
362{ 362{
363 struct mthca_dev *dev = to_mdev(ibsrq->device); 363 struct mthca_dev *dev = to_mdev(ibsrq->device);
364 struct mthca_srq *srq = to_msrq(ibsrq); 364 struct mthca_srq *srq = to_msrq(ibsrq);
diff --git a/drivers/infiniband/hw/mthca/mthca_uar.c b/drivers/infiniband/hw/mthca/mthca_uar.c
index 8e9219842be4..8b728486410d 100644
--- a/drivers/infiniband/hw/mthca/mthca_uar.c
+++ b/drivers/infiniband/hw/mthca/mthca_uar.c
@@ -60,7 +60,7 @@ int mthca_init_uar_table(struct mthca_dev *dev)
60 ret = mthca_alloc_init(&dev->uar_table.alloc, 60 ret = mthca_alloc_init(&dev->uar_table.alloc,
61 dev->limits.num_uars, 61 dev->limits.num_uars,
62 dev->limits.num_uars - 1, 62 dev->limits.num_uars - 1,
63 dev->limits.reserved_uars); 63 dev->limits.reserved_uars + 1);
64 if (ret) 64 if (ret)
65 return ret; 65 return ret;
66 66
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 474aa214ab57..0b8a79d53a00 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -336,6 +336,8 @@ static inline void ipoib_unregister_debugfs(void) { }
336extern int ipoib_sendq_size; 336extern int ipoib_sendq_size;
337extern int ipoib_recvq_size; 337extern int ipoib_recvq_size;
338 338
339extern struct ib_sa_client ipoib_sa_client;
340
339#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 341#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
340extern int ipoib_debug_level; 342extern int ipoib_debug_level;
341 343
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 5033666b1481..f426a69d9a43 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -169,117 +169,129 @@ static int ipoib_ib_post_receives(struct net_device *dev)
169 return 0; 169 return 0;
170} 170}
171 171
172static void ipoib_ib_handle_wc(struct net_device *dev, 172static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
173 struct ib_wc *wc)
174{ 173{
175 struct ipoib_dev_priv *priv = netdev_priv(dev); 174 struct ipoib_dev_priv *priv = netdev_priv(dev);
176 unsigned int wr_id = wc->wr_id; 175 unsigned int wr_id = wc->wr_id & ~IPOIB_OP_RECV;
176 struct sk_buff *skb;
177 dma_addr_t addr;
177 178
178 ipoib_dbg_data(priv, "called: id %d, op %d, status: %d\n", 179 ipoib_dbg_data(priv, "recv completion: id %d, op %d, status: %d\n",
179 wr_id, wc->opcode, wc->status); 180 wr_id, wc->opcode, wc->status);
180 181
181 if (wr_id & IPOIB_OP_RECV) { 182 if (unlikely(wr_id >= ipoib_recvq_size)) {
182 wr_id &= ~IPOIB_OP_RECV; 183 ipoib_warn(priv, "recv completion event with wrid %d (> %d)\n",
183 184 wr_id, ipoib_recvq_size);
184 if (wr_id < ipoib_recvq_size) { 185 return;
185 struct sk_buff *skb = priv->rx_ring[wr_id].skb; 186 }
186 dma_addr_t addr = priv->rx_ring[wr_id].mapping;
187
188 if (unlikely(wc->status != IB_WC_SUCCESS)) {
189 if (wc->status != IB_WC_WR_FLUSH_ERR)
190 ipoib_warn(priv, "failed recv event "
191 "(status=%d, wrid=%d vend_err %x)\n",
192 wc->status, wr_id, wc->vendor_err);
193 dma_unmap_single(priv->ca->dma_device, addr,
194 IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
195 dev_kfree_skb_any(skb);
196 priv->rx_ring[wr_id].skb = NULL;
197 return;
198 }
199 187
200 /* 188 skb = priv->rx_ring[wr_id].skb;
201 * If we can't allocate a new RX buffer, dump 189 addr = priv->rx_ring[wr_id].mapping;
202 * this packet and reuse the old buffer.
203 */
204 if (unlikely(ipoib_alloc_rx_skb(dev, wr_id))) {
205 ++priv->stats.rx_dropped;
206 goto repost;
207 }
208 190
209 ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n", 191 if (unlikely(wc->status != IB_WC_SUCCESS)) {
210 wc->byte_len, wc->slid); 192 if (wc->status != IB_WC_WR_FLUSH_ERR)
193 ipoib_warn(priv, "failed recv event "
194 "(status=%d, wrid=%d vend_err %x)\n",
195 wc->status, wr_id, wc->vendor_err);
196 dma_unmap_single(priv->ca->dma_device, addr,
197 IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
198 dev_kfree_skb_any(skb);
199 priv->rx_ring[wr_id].skb = NULL;
200 return;
201 }
211 202
212 dma_unmap_single(priv->ca->dma_device, addr, 203 /*
213 IPOIB_BUF_SIZE, DMA_FROM_DEVICE); 204 * If we can't allocate a new RX buffer, dump
205 * this packet and reuse the old buffer.
206 */
207 if (unlikely(ipoib_alloc_rx_skb(dev, wr_id))) {
208 ++priv->stats.rx_dropped;
209 goto repost;
210 }
214 211
215 skb_put(skb, wc->byte_len); 212 ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n",
216 skb_pull(skb, IB_GRH_BYTES); 213 wc->byte_len, wc->slid);
217 214
218 if (wc->slid != priv->local_lid || 215 dma_unmap_single(priv->ca->dma_device, addr,
219 wc->src_qp != priv->qp->qp_num) { 216 IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
220 skb->protocol = ((struct ipoib_header *) skb->data)->proto;
221 skb->mac.raw = skb->data;
222 skb_pull(skb, IPOIB_ENCAP_LEN);
223 217
224 dev->last_rx = jiffies; 218 skb_put(skb, wc->byte_len);
225 ++priv->stats.rx_packets; 219 skb_pull(skb, IB_GRH_BYTES);
226 priv->stats.rx_bytes += skb->len;
227 220
228 skb->dev = dev; 221 if (wc->slid != priv->local_lid ||
229 /* XXX get correct PACKET_ type here */ 222 wc->src_qp != priv->qp->qp_num) {
230 skb->pkt_type = PACKET_HOST; 223 skb->protocol = ((struct ipoib_header *) skb->data)->proto;
231 netif_rx_ni(skb); 224 skb->mac.raw = skb->data;
232 } else { 225 skb_pull(skb, IPOIB_ENCAP_LEN);
233 ipoib_dbg_data(priv, "dropping loopback packet\n");
234 dev_kfree_skb_any(skb);
235 }
236 226
237 repost: 227 dev->last_rx = jiffies;
238 if (unlikely(ipoib_ib_post_receive(dev, wr_id))) 228 ++priv->stats.rx_packets;
239 ipoib_warn(priv, "ipoib_ib_post_receive failed " 229 priv->stats.rx_bytes += skb->len;
240 "for buf %d\n", wr_id);
241 } else
242 ipoib_warn(priv, "completion event with wrid %d\n",
243 wr_id);
244 230
231 skb->dev = dev;
232 /* XXX get correct PACKET_ type here */
233 skb->pkt_type = PACKET_HOST;
234 netif_rx_ni(skb);
245 } else { 235 } else {
246 struct ipoib_tx_buf *tx_req; 236 ipoib_dbg_data(priv, "dropping loopback packet\n");
247 unsigned long flags; 237 dev_kfree_skb_any(skb);
238 }
248 239
249 if (wr_id >= ipoib_sendq_size) { 240repost:
250 ipoib_warn(priv, "completion event with wrid %d (> %d)\n", 241 if (unlikely(ipoib_ib_post_receive(dev, wr_id)))
251 wr_id, ipoib_sendq_size); 242 ipoib_warn(priv, "ipoib_ib_post_receive failed "
252 return; 243 "for buf %d\n", wr_id);
253 } 244}
254 245
255 ipoib_dbg_data(priv, "send complete, wrid %d\n", wr_id); 246static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
247{
248 struct ipoib_dev_priv *priv = netdev_priv(dev);
249 unsigned int wr_id = wc->wr_id;
250 struct ipoib_tx_buf *tx_req;
251 unsigned long flags;
256 252
257 tx_req = &priv->tx_ring[wr_id]; 253 ipoib_dbg_data(priv, "send completion: id %d, op %d, status: %d\n",
254 wr_id, wc->opcode, wc->status);
258 255
259 dma_unmap_single(priv->ca->dma_device, 256 if (unlikely(wr_id >= ipoib_sendq_size)) {
260 pci_unmap_addr(tx_req, mapping), 257 ipoib_warn(priv, "send completion event with wrid %d (> %d)\n",
261 tx_req->skb->len, 258 wr_id, ipoib_sendq_size);
262 DMA_TO_DEVICE); 259 return;
260 }
263 261
264 ++priv->stats.tx_packets; 262 tx_req = &priv->tx_ring[wr_id];
265 priv->stats.tx_bytes += tx_req->skb->len;
266 263
267 dev_kfree_skb_any(tx_req->skb); 264 dma_unmap_single(priv->ca->dma_device,
265 pci_unmap_addr(tx_req, mapping),
266 tx_req->skb->len,
267 DMA_TO_DEVICE);
268 268
269 spin_lock_irqsave(&priv->tx_lock, flags); 269 ++priv->stats.tx_packets;
270 ++priv->tx_tail; 270 priv->stats.tx_bytes += tx_req->skb->len;
271 if (netif_queue_stopped(dev) &&
272 test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags) &&
273 priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1)
274 netif_wake_queue(dev);
275 spin_unlock_irqrestore(&priv->tx_lock, flags);
276 271
277 if (wc->status != IB_WC_SUCCESS && 272 dev_kfree_skb_any(tx_req->skb);
278 wc->status != IB_WC_WR_FLUSH_ERR) 273
279 ipoib_warn(priv, "failed send event " 274 spin_lock_irqsave(&priv->tx_lock, flags);
280 "(status=%d, wrid=%d vend_err %x)\n", 275 ++priv->tx_tail;
281 wc->status, wr_id, wc->vendor_err); 276 if (netif_queue_stopped(dev) &&
282 } 277 test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags) &&
278 priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1)
279 netif_wake_queue(dev);
280 spin_unlock_irqrestore(&priv->tx_lock, flags);
281
282 if (wc->status != IB_WC_SUCCESS &&
283 wc->status != IB_WC_WR_FLUSH_ERR)
284 ipoib_warn(priv, "failed send event "
285 "(status=%d, wrid=%d vend_err %x)\n",
286 wc->status, wr_id, wc->vendor_err);
287}
288
289static void ipoib_ib_handle_wc(struct net_device *dev, struct ib_wc *wc)
290{
291 if (wc->wr_id & IPOIB_OP_RECV)
292 ipoib_ib_handle_rx_wc(dev, wc);
293 else
294 ipoib_ib_handle_tx_wc(dev, wc);
283} 295}
284 296
285void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr) 297void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
@@ -320,7 +332,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
320 struct ipoib_tx_buf *tx_req; 332 struct ipoib_tx_buf *tx_req;
321 dma_addr_t addr; 333 dma_addr_t addr;
322 334
323 if (skb->len > dev->mtu + INFINIBAND_ALEN) { 335 if (unlikely(skb->len > dev->mtu + INFINIBAND_ALEN)) {
324 ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", 336 ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
325 skb->len, dev->mtu + INFINIBAND_ALEN); 337 skb->len, dev->mtu + INFINIBAND_ALEN);
326 ++priv->stats.tx_dropped; 338 ++priv->stats.tx_dropped;
@@ -619,8 +631,10 @@ void ipoib_ib_dev_flush(void *_dev)
619 * The device could have been brought down between the start and when 631 * The device could have been brought down between the start and when
620 * we get here, don't bring it back up if it's not configured up 632 * we get here, don't bring it back up if it's not configured up
621 */ 633 */
622 if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) 634 if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) {
623 ipoib_ib_dev_up(dev); 635 ipoib_ib_dev_up(dev);
636 ipoib_mcast_restart_task(dev);
637 }
624 638
625 mutex_lock(&priv->vlan_mutex); 639 mutex_lock(&priv->vlan_mutex);
626 640
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index cf71d2a5515c..1eaf00e9862c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -40,7 +40,6 @@
40 40
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/vmalloc.h>
44#include <linux/kernel.h> 43#include <linux/kernel.h>
45 44
46#include <linux/if_arp.h> /* For ARPHRD_xxx */ 45#include <linux/if_arp.h> /* For ARPHRD_xxx */
@@ -82,6 +81,8 @@ static const u8 ipv4_bcast_addr[] = {
82 81
83struct workqueue_struct *ipoib_workqueue; 82struct workqueue_struct *ipoib_workqueue;
84 83
84struct ib_sa_client ipoib_sa_client;
85
85static void ipoib_add_one(struct ib_device *device); 86static void ipoib_add_one(struct ib_device *device);
86static void ipoib_remove_one(struct ib_device *device); 87static void ipoib_remove_one(struct ib_device *device);
87 88
@@ -336,7 +337,8 @@ void ipoib_flush_paths(struct net_device *dev)
336 struct ipoib_path *path, *tp; 337 struct ipoib_path *path, *tp;
337 LIST_HEAD(remove_list); 338 LIST_HEAD(remove_list);
338 339
339 spin_lock_irq(&priv->lock); 340 spin_lock_irq(&priv->tx_lock);
341 spin_lock(&priv->lock);
340 342
341 list_splice(&priv->path_list, &remove_list); 343 list_splice(&priv->path_list, &remove_list);
342 INIT_LIST_HEAD(&priv->path_list); 344 INIT_LIST_HEAD(&priv->path_list);
@@ -347,12 +349,15 @@ void ipoib_flush_paths(struct net_device *dev)
347 list_for_each_entry_safe(path, tp, &remove_list, list) { 349 list_for_each_entry_safe(path, tp, &remove_list, list) {
348 if (path->query) 350 if (path->query)
349 ib_sa_cancel_query(path->query_id, path->query); 351 ib_sa_cancel_query(path->query_id, path->query);
350 spin_unlock_irq(&priv->lock); 352 spin_unlock(&priv->lock);
353 spin_unlock_irq(&priv->tx_lock);
351 wait_for_completion(&path->done); 354 wait_for_completion(&path->done);
352 path_free(dev, path); 355 path_free(dev, path);
353 spin_lock_irq(&priv->lock); 356 spin_lock_irq(&priv->tx_lock);
357 spin_lock(&priv->lock);
354 } 358 }
355 spin_unlock_irq(&priv->lock); 359 spin_unlock(&priv->lock);
360 spin_unlock_irq(&priv->tx_lock);
356} 361}
357 362
358static void path_rec_completion(int status, 363static void path_rec_completion(int status,
@@ -459,7 +464,7 @@ static int path_rec_start(struct net_device *dev,
459 init_completion(&path->done); 464 init_completion(&path->done);
460 465
461 path->query_id = 466 path->query_id =
462 ib_sa_path_rec_get(priv->ca, priv->port, 467 ib_sa_path_rec_get(&ipoib_sa_client, priv->ca, priv->port,
463 &path->pathrec, 468 &path->pathrec,
464 IB_SA_PATH_REC_DGID | 469 IB_SA_PATH_REC_DGID |
465 IB_SA_PATH_REC_SGID | 470 IB_SA_PATH_REC_SGID |
@@ -615,7 +620,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
615 struct ipoib_neigh *neigh; 620 struct ipoib_neigh *neigh;
616 unsigned long flags; 621 unsigned long flags;
617 622
618 if (!spin_trylock_irqsave(&priv->tx_lock, flags)) 623 if (unlikely(!spin_trylock_irqsave(&priv->tx_lock, flags)))
619 return NETDEV_TX_LOCKED; 624 return NETDEV_TX_LOCKED;
620 625
621 /* 626 /*
@@ -628,7 +633,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
628 return NETDEV_TX_BUSY; 633 return NETDEV_TX_BUSY;
629 } 634 }
630 635
631 if (skb->dst && skb->dst->neighbour) { 636 if (likely(skb->dst && skb->dst->neighbour)) {
632 if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) { 637 if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
633 ipoib_path_lookup(skb, dev); 638 ipoib_path_lookup(skb, dev);
634 goto out; 639 goto out;
@@ -1107,13 +1112,16 @@ static void ipoib_add_one(struct ib_device *device)
1107 struct ipoib_dev_priv *priv; 1112 struct ipoib_dev_priv *priv;
1108 int s, e, p; 1113 int s, e, p;
1109 1114
1115 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
1116 return;
1117
1110 dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); 1118 dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL);
1111 if (!dev_list) 1119 if (!dev_list)
1112 return; 1120 return;
1113 1121
1114 INIT_LIST_HEAD(dev_list); 1122 INIT_LIST_HEAD(dev_list);
1115 1123
1116 if (device->node_type == IB_NODE_SWITCH) { 1124 if (device->node_type == RDMA_NODE_IB_SWITCH) {
1117 s = 0; 1125 s = 0;
1118 e = 0; 1126 e = 0;
1119 } else { 1127 } else {
@@ -1137,6 +1145,9 @@ static void ipoib_remove_one(struct ib_device *device)
1137 struct ipoib_dev_priv *priv, *tmp; 1145 struct ipoib_dev_priv *priv, *tmp;
1138 struct list_head *dev_list; 1146 struct list_head *dev_list;
1139 1147
1148 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
1149 return;
1150
1140 dev_list = ib_get_client_data(device, &ipoib_client); 1151 dev_list = ib_get_client_data(device, &ipoib_client);
1141 1152
1142 list_for_each_entry_safe(priv, tmp, dev_list, list) { 1153 list_for_each_entry_safe(priv, tmp, dev_list, list) {
@@ -1181,13 +1192,16 @@ static int __init ipoib_init_module(void)
1181 goto err_fs; 1192 goto err_fs;
1182 } 1193 }
1183 1194
1195 ib_sa_register_client(&ipoib_sa_client);
1196
1184 ret = ib_register_client(&ipoib_client); 1197 ret = ib_register_client(&ipoib_client);
1185 if (ret) 1198 if (ret)
1186 goto err_wq; 1199 goto err_sa;
1187 1200
1188 return 0; 1201 return 0;
1189 1202
1190err_wq: 1203err_sa:
1204 ib_sa_unregister_client(&ipoib_sa_client);
1191 destroy_workqueue(ipoib_workqueue); 1205 destroy_workqueue(ipoib_workqueue);
1192 1206
1193err_fs: 1207err_fs:
@@ -1199,6 +1213,7 @@ err_fs:
1199static void __exit ipoib_cleanup_module(void) 1213static void __exit ipoib_cleanup_module(void)
1200{ 1214{
1201 ib_unregister_client(&ipoib_client); 1215 ib_unregister_client(&ipoib_client);
1216 ib_sa_unregister_client(&ipoib_sa_client);
1202 ipoib_unregister_debugfs(); 1217 ipoib_unregister_debugfs();
1203 destroy_workqueue(ipoib_workqueue); 1218 destroy_workqueue(ipoib_workqueue);
1204} 1219}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index ec356ce7cdcd..3faa1820f0e9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -361,7 +361,7 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
361 361
362 init_completion(&mcast->done); 362 init_completion(&mcast->done);
363 363
364 ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec, 364 ret = ib_sa_mcmember_rec_set(&ipoib_sa_client, priv->ca, priv->port, &rec,
365 IB_SA_MCMEMBER_REC_MGID | 365 IB_SA_MCMEMBER_REC_MGID |
366 IB_SA_MCMEMBER_REC_PORT_GID | 366 IB_SA_MCMEMBER_REC_PORT_GID |
367 IB_SA_MCMEMBER_REC_PKEY | 367 IB_SA_MCMEMBER_REC_PKEY |
@@ -472,22 +472,32 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
472 472
473 if (create) { 473 if (create) {
474 comp_mask |= 474 comp_mask |=
475 IB_SA_MCMEMBER_REC_QKEY | 475 IB_SA_MCMEMBER_REC_QKEY |
476 IB_SA_MCMEMBER_REC_SL | 476 IB_SA_MCMEMBER_REC_MTU_SELECTOR |
477 IB_SA_MCMEMBER_REC_FLOW_LABEL | 477 IB_SA_MCMEMBER_REC_MTU |
478 IB_SA_MCMEMBER_REC_TRAFFIC_CLASS; 478 IB_SA_MCMEMBER_REC_TRAFFIC_CLASS |
479 IB_SA_MCMEMBER_REC_RATE_SELECTOR |
480 IB_SA_MCMEMBER_REC_RATE |
481 IB_SA_MCMEMBER_REC_SL |
482 IB_SA_MCMEMBER_REC_FLOW_LABEL |
483 IB_SA_MCMEMBER_REC_HOP_LIMIT;
479 484
480 rec.qkey = priv->broadcast->mcmember.qkey; 485 rec.qkey = priv->broadcast->mcmember.qkey;
486 rec.mtu_selector = IB_SA_EQ;
487 rec.mtu = priv->broadcast->mcmember.mtu;
488 rec.traffic_class = priv->broadcast->mcmember.traffic_class;
489 rec.rate_selector = IB_SA_EQ;
490 rec.rate = priv->broadcast->mcmember.rate;
481 rec.sl = priv->broadcast->mcmember.sl; 491 rec.sl = priv->broadcast->mcmember.sl;
482 rec.flow_label = priv->broadcast->mcmember.flow_label; 492 rec.flow_label = priv->broadcast->mcmember.flow_label;
483 rec.traffic_class = priv->broadcast->mcmember.traffic_class; 493 rec.hop_limit = priv->broadcast->mcmember.hop_limit;
484 } 494 }
485 495
486 init_completion(&mcast->done); 496 init_completion(&mcast->done);
487 497
488 ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec, comp_mask, 498 ret = ib_sa_mcmember_rec_set(&ipoib_sa_client, priv->ca, priv->port,
489 mcast->backoff * 1000, GFP_ATOMIC, 499 &rec, comp_mask, mcast->backoff * 1000,
490 ipoib_mcast_join_complete, 500 GFP_ATOMIC, ipoib_mcast_join_complete,
491 mcast, &mcast->query); 501 mcast, &mcast->query);
492 502
493 if (ret < 0) { 503 if (ret < 0) {
@@ -528,7 +538,7 @@ void ipoib_mcast_join_task(void *dev_ptr)
528 priv->local_rate = attr.active_speed * 538 priv->local_rate = attr.active_speed *
529 ib_width_enum_to_int(attr.active_width); 539 ib_width_enum_to_int(attr.active_width);
530 } else 540 } else
531 ipoib_warn(priv, "ib_query_port failed\n"); 541 ipoib_warn(priv, "ib_query_port failed\n");
532 } 542 }
533 543
534 if (!priv->broadcast) { 544 if (!priv->broadcast) {
@@ -681,7 +691,7 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
681 * Just make one shot at leaving and don't wait for a reply; 691 * Just make one shot at leaving and don't wait for a reply;
682 * if we fail, too bad. 692 * if we fail, too bad.
683 */ 693 */
684 ret = ib_sa_mcmember_rec_delete(priv->ca, priv->port, &rec, 694 ret = ib_sa_mcmember_rec_delete(&ipoib_sa_client, priv->ca, priv->port, &rec,
685 IB_SA_MCMEMBER_REC_MGID | 695 IB_SA_MCMEMBER_REC_MGID |
686 IB_SA_MCMEMBER_REC_PORT_GID | 696 IB_SA_MCMEMBER_REC_PORT_GID |
687 IB_SA_MCMEMBER_REC_PKEY | 697 IB_SA_MCMEMBER_REC_PKEY |
@@ -795,7 +805,7 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
795 } 805 }
796 806
797 if (priv->broadcast) { 807 if (priv->broadcast) {
798 rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree); 808 rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree);
799 list_add_tail(&priv->broadcast->list, &remove_list); 809 list_add_tail(&priv->broadcast->list, &remove_list);
800 priv->broadcast = NULL; 810 priv->broadcast = NULL;
801 } 811 }
diff --git a/drivers/infiniband/ulp/iser/Kconfig b/drivers/infiniband/ulp/iser/Kconfig
index fead87d1eff9..365a1b5f19e0 100644
--- a/drivers/infiniband/ulp/iser/Kconfig
+++ b/drivers/infiniband/ulp/iser/Kconfig
@@ -1,6 +1,6 @@
1config INFINIBAND_ISER 1config INFINIBAND_ISER
2 tristate "ISCSI RDMA Protocol" 2 tristate "ISCSI RDMA Protocol"
3 depends on INFINIBAND && SCSI 3 depends on INFINIBAND && SCSI && INET
4 select SCSI_ISCSI_ATTRS 4 select SCSI_ISCSI_ATTRS
5 ---help--- 5 ---help---
6 Support for the ISCSI RDMA Protocol over InfiniBand. This 6 Support for the ISCSI RDMA Protocol over InfiniBand. This
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 1437d7ee3b19..e9cf1a9f1e1c 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -555,6 +555,7 @@ static struct scsi_host_template iscsi_iser_sht = {
555 .queuecommand = iscsi_queuecommand, 555 .queuecommand = iscsi_queuecommand,
556 .can_queue = ISCSI_XMIT_CMDS_MAX - 1, 556 .can_queue = ISCSI_XMIT_CMDS_MAX - 1,
557 .sg_tablesize = ISCSI_ISER_SG_TABLESIZE, 557 .sg_tablesize = ISCSI_ISER_SG_TABLESIZE,
558 .max_sectors = 1024,
558 .cmd_per_lun = ISCSI_MAX_CMD_PER_LUN, 559 .cmd_per_lun = ISCSI_MAX_CMD_PER_LUN,
559 .eh_abort_handler = iscsi_eh_abort, 560 .eh_abort_handler = iscsi_eh_abort,
560 .eh_host_reset_handler = iscsi_eh_host_reset, 561 .eh_host_reset_handler = iscsi_eh_host_reset,
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 3350ba690cfe..7e1a411db2a3 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -82,8 +82,12 @@
82 __func__ , ## arg); \ 82 __func__ , ## arg); \
83 } while (0) 83 } while (0)
84 84
85#define SHIFT_4K 12
86#define SIZE_4K (1UL << SHIFT_4K)
87#define MASK_4K (~(SIZE_4K-1))
88
85 /* support upto 512KB in one RDMA */ 89 /* support upto 512KB in one RDMA */
86#define ISCSI_ISER_SG_TABLESIZE (0x80000 >> PAGE_SHIFT) 90#define ISCSI_ISER_SG_TABLESIZE (0x80000 >> SHIFT_4K)
87#define ISCSI_ISER_MAX_LUN 256 91#define ISCSI_ISER_MAX_LUN 256
88#define ISCSI_ISER_MAX_CMD_LEN 16 92#define ISCSI_ISER_MAX_CMD_LEN 16
89 93
@@ -171,6 +175,7 @@ struct iser_mem_reg {
171 u64 va; 175 u64 va;
172 u64 len; 176 u64 len;
173 void *mem_h; 177 void *mem_h;
178 int is_fmr;
174}; 179};
175 180
176struct iser_regd_buf { 181struct iser_regd_buf {
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 31950a522a1c..d0b03f426581 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -42,6 +42,7 @@
42#include "iscsi_iser.h" 42#include "iscsi_iser.h"
43 43
44#define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */ 44#define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */
45
45/** 46/**
46 * Decrements the reference count for the 47 * Decrements the reference count for the
47 * registered buffer & releases it 48 * registered buffer & releases it
@@ -55,7 +56,7 @@ int iser_regd_buff_release(struct iser_regd_buf *regd_buf)
55 if ((atomic_read(&regd_buf->ref_count) == 0) || 56 if ((atomic_read(&regd_buf->ref_count) == 0) ||
56 atomic_dec_and_test(&regd_buf->ref_count)) { 57 atomic_dec_and_test(&regd_buf->ref_count)) {
57 /* if we used the dma mr, unreg is just NOP */ 58 /* if we used the dma mr, unreg is just NOP */
58 if (regd_buf->reg.rkey != 0) 59 if (regd_buf->reg.is_fmr)
59 iser_unreg_mem(&regd_buf->reg); 60 iser_unreg_mem(&regd_buf->reg);
60 61
61 if (regd_buf->dma_addr) { 62 if (regd_buf->dma_addr) {
@@ -90,9 +91,9 @@ void iser_reg_single(struct iser_device *device,
90 BUG_ON(dma_mapping_error(dma_addr)); 91 BUG_ON(dma_mapping_error(dma_addr));
91 92
92 regd_buf->reg.lkey = device->mr->lkey; 93 regd_buf->reg.lkey = device->mr->lkey;
93 regd_buf->reg.rkey = 0; /* indicate there's no need to unreg */
94 regd_buf->reg.len = regd_buf->data_size; 94 regd_buf->reg.len = regd_buf->data_size;
95 regd_buf->reg.va = dma_addr; 95 regd_buf->reg.va = dma_addr;
96 regd_buf->reg.is_fmr = 0;
96 97
97 regd_buf->dma_addr = dma_addr; 98 regd_buf->dma_addr = dma_addr;
98 regd_buf->direction = direction; 99 regd_buf->direction = direction;
@@ -239,7 +240,7 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
239 int i; 240 int i;
240 241
241 /* compute the offset of first element */ 242 /* compute the offset of first element */
242 page_vec->offset = (u64) sg[0].offset; 243 page_vec->offset = (u64) sg[0].offset & ~MASK_4K;
243 244
244 for (i = 0; i < data->dma_nents; i++) { 245 for (i = 0; i < data->dma_nents; i++) {
245 total_sz += sg_dma_len(&sg[i]); 246 total_sz += sg_dma_len(&sg[i]);
@@ -247,21 +248,30 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
247 first_addr = sg_dma_address(&sg[i]); 248 first_addr = sg_dma_address(&sg[i]);
248 last_addr = first_addr + sg_dma_len(&sg[i]); 249 last_addr = first_addr + sg_dma_len(&sg[i]);
249 250
250 start_aligned = !(first_addr & ~PAGE_MASK); 251 start_aligned = !(first_addr & ~MASK_4K);
251 end_aligned = !(last_addr & ~PAGE_MASK); 252 end_aligned = !(last_addr & ~MASK_4K);
252 253
253 /* continue to collect page fragments till aligned or SG ends */ 254 /* continue to collect page fragments till aligned or SG ends */
254 while (!end_aligned && (i + 1 < data->dma_nents)) { 255 while (!end_aligned && (i + 1 < data->dma_nents)) {
255 i++; 256 i++;
256 total_sz += sg_dma_len(&sg[i]); 257 total_sz += sg_dma_len(&sg[i]);
257 last_addr = sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]); 258 last_addr = sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]);
258 end_aligned = !(last_addr & ~PAGE_MASK); 259 end_aligned = !(last_addr & ~MASK_4K);
259 } 260 }
260 261
261 first_addr = first_addr & PAGE_MASK; 262 /* handle the 1st page in the 1st DMA element */
262 263 if (cur_page == 0) {
263 for (page = first_addr; page < last_addr; page += PAGE_SIZE) 264 page = first_addr & MASK_4K;
264 page_vec->pages[cur_page++] = page; 265 page_vec->pages[cur_page] = page;
266 cur_page++;
267 page += SIZE_4K;
268 } else
269 page = first_addr;
270
271 for (; page < last_addr; page += SIZE_4K) {
272 page_vec->pages[cur_page] = page;
273 cur_page++;
274 }
265 275
266 } 276 }
267 page_vec->data_size = total_sz; 277 page_vec->data_size = total_sz;
@@ -269,8 +279,7 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
269 return cur_page; 279 return cur_page;
270} 280}
271 281
272#define MASK_4K ((1UL << 12) - 1) /* 0xFFF */ 282#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & ~MASK_4K) == 0)
273#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & MASK_4K) == 0)
274 283
275/** 284/**
276 * iser_data_buf_aligned_len - Tries to determine the maximal correctly aligned 285 * iser_data_buf_aligned_len - Tries to determine the maximal correctly aligned
@@ -320,9 +329,9 @@ static void iser_data_buf_dump(struct iser_data_buf *data)
320 struct scatterlist *sg = (struct scatterlist *)data->buf; 329 struct scatterlist *sg = (struct scatterlist *)data->buf;
321 int i; 330 int i;
322 331
323 for (i = 0; i < data->size; i++) 332 for (i = 0; i < data->dma_nents; i++)
324 iser_err("sg[%d] dma_addr:0x%lX page:0x%p " 333 iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
325 "off:%d sz:%d dma_len:%d\n", 334 "off:0x%x sz:0x%x dma_len:0x%x\n",
326 i, (unsigned long)sg_dma_address(&sg[i]), 335 i, (unsigned long)sg_dma_address(&sg[i]),
327 sg[i].page, sg[i].offset, 336 sg[i].page, sg[i].offset,
328 sg[i].length,sg_dma_len(&sg[i])); 337 sg[i].length,sg_dma_len(&sg[i]));
@@ -352,7 +361,7 @@ static void iser_page_vec_build(struct iser_data_buf *data,
352 361
353 page_vec->length = page_vec_len; 362 page_vec->length = page_vec_len;
354 363
355 if (page_vec_len * PAGE_SIZE < page_vec->data_size) { 364 if (page_vec_len * SIZE_4K < page_vec->data_size) {
356 iser_err("page_vec too short to hold this SG\n"); 365 iser_err("page_vec too short to hold this SG\n");
357 iser_data_buf_dump(data); 366 iser_data_buf_dump(data);
358 iser_dump_page_vec(page_vec); 367 iser_dump_page_vec(page_vec);
@@ -370,15 +379,18 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
370 enum iser_data_dir cmd_dir) 379 enum iser_data_dir cmd_dir)
371{ 380{
372 struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn; 381 struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn;
382 struct iser_device *device = ib_conn->device;
373 struct iser_data_buf *mem = &iser_ctask->data[cmd_dir]; 383 struct iser_data_buf *mem = &iser_ctask->data[cmd_dir];
374 struct iser_regd_buf *regd_buf; 384 struct iser_regd_buf *regd_buf;
375 int aligned_len; 385 int aligned_len;
376 int err; 386 int err;
387 int i;
388 struct scatterlist *sg;
377 389
378 regd_buf = &iser_ctask->rdma_regd[cmd_dir]; 390 regd_buf = &iser_ctask->rdma_regd[cmd_dir];
379 391
380 aligned_len = iser_data_buf_aligned_len(mem); 392 aligned_len = iser_data_buf_aligned_len(mem);
381 if (aligned_len != mem->size) { 393 if (aligned_len != mem->dma_nents) {
382 iser_err("rdma alignment violation %d/%d aligned\n", 394 iser_err("rdma alignment violation %d/%d aligned\n",
383 aligned_len, mem->size); 395 aligned_len, mem->size);
384 iser_data_buf_dump(mem); 396 iser_data_buf_dump(mem);
@@ -389,10 +401,38 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
389 mem = &iser_ctask->data_copy[cmd_dir]; 401 mem = &iser_ctask->data_copy[cmd_dir];
390 } 402 }
391 403
392 iser_page_vec_build(mem, ib_conn->page_vec); 404 /* if there a single dma entry, FMR is not needed */
393 err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, &regd_buf->reg); 405 if (mem->dma_nents == 1) {
394 if (err) 406 sg = (struct scatterlist *)mem->buf;
395 return err; 407
408 regd_buf->reg.lkey = device->mr->lkey;
409 regd_buf->reg.rkey = device->mr->rkey;
410 regd_buf->reg.len = sg_dma_len(&sg[0]);
411 regd_buf->reg.va = sg_dma_address(&sg[0]);
412 regd_buf->reg.is_fmr = 0;
413
414 iser_dbg("PHYSICAL Mem.register: lkey: 0x%08X rkey: 0x%08X "
415 "va: 0x%08lX sz: %ld]\n",
416 (unsigned int)regd_buf->reg.lkey,
417 (unsigned int)regd_buf->reg.rkey,
418 (unsigned long)regd_buf->reg.va,
419 (unsigned long)regd_buf->reg.len);
420 } else { /* use FMR for multiple dma entries */
421 iser_page_vec_build(mem, ib_conn->page_vec);
422 err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, &regd_buf->reg);
423 if (err) {
424 iser_data_buf_dump(mem);
425 iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", mem->dma_nents,
426 ntoh24(iser_ctask->desc.iscsi_header.dlength));
427 iser_err("page_vec: data_size = 0x%x, length = %d, offset = 0x%x\n",
428 ib_conn->page_vec->data_size, ib_conn->page_vec->length,
429 ib_conn->page_vec->offset);
430 for (i=0 ; i<ib_conn->page_vec->length ; i++)
431 iser_err("page_vec[%d] = 0x%llx\n", i,
432 (unsigned long long) ib_conn->page_vec->pages[i]);
433 return err;
434 }
435 }
396 436
397 /* take a reference on this regd buf such that it will not be released * 437 /* take a reference on this regd buf such that it will not be released *
398 * (eg in send dto completion) before we get the scsi response */ 438 * (eg in send dto completion) before we get the scsi response */
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 72febf1f8ff8..ecdca7fc1e4c 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -88,8 +88,9 @@ static int iser_create_device_ib_res(struct iser_device *device)
88 iser_cq_tasklet_fn, 88 iser_cq_tasklet_fn,
89 (unsigned long)device); 89 (unsigned long)device);
90 90
91 device->mr = ib_get_dma_mr(device->pd, 91 device->mr = ib_get_dma_mr(device->pd, IB_ACCESS_LOCAL_WRITE |
92 IB_ACCESS_LOCAL_WRITE); 92 IB_ACCESS_REMOTE_WRITE |
93 IB_ACCESS_REMOTE_READ);
93 if (IS_ERR(device->mr)) 94 if (IS_ERR(device->mr))
94 goto dma_mr_err; 95 goto dma_mr_err;
95 96
@@ -150,7 +151,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
150 } 151 }
151 ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1); 152 ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1);
152 153
153 params.page_shift = PAGE_SHIFT; 154 params.page_shift = SHIFT_4K;
154 /* when the first/last SG element are not start/end * 155 /* when the first/last SG element are not start/end *
155 * page aligned, the map whould be of N+1 pages */ 156 * page aligned, the map whould be of N+1 pages */
156 params.max_pages_per_fmr = ISCSI_ISER_SG_TABLESIZE + 1; 157 params.max_pages_per_fmr = ISCSI_ISER_SG_TABLESIZE + 1;
@@ -604,8 +605,9 @@ int iser_reg_page_vec(struct iser_conn *ib_conn,
604 605
605 mem_reg->lkey = mem->fmr->lkey; 606 mem_reg->lkey = mem->fmr->lkey;
606 mem_reg->rkey = mem->fmr->rkey; 607 mem_reg->rkey = mem->fmr->rkey;
607 mem_reg->len = page_vec->length * PAGE_SIZE; 608 mem_reg->len = page_vec->length * SIZE_4K;
608 mem_reg->va = io_addr; 609 mem_reg->va = io_addr;
610 mem_reg->is_fmr = 1;
609 mem_reg->mem_h = (void *)mem; 611 mem_reg->mem_h = (void *)mem;
610 612
611 mem_reg->va += page_vec->offset; 613 mem_reg->va += page_vec->offset;
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index fd8344cdc0db..44b9e5be6687 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -96,6 +96,8 @@ static struct ib_client srp_client = {
96 .remove = srp_remove_one 96 .remove = srp_remove_one
97}; 97};
98 98
99static struct ib_sa_client srp_sa_client;
100
99static inline struct srp_target_port *host_to_target(struct Scsi_Host *host) 101static inline struct srp_target_port *host_to_target(struct Scsi_Host *host)
100{ 102{
101 return (struct srp_target_port *) host->hostdata; 103 return (struct srp_target_port *) host->hostdata;
@@ -267,7 +269,8 @@ static int srp_lookup_path(struct srp_target_port *target)
267 269
268 init_completion(&target->done); 270 init_completion(&target->done);
269 271
270 target->path_query_id = ib_sa_path_rec_get(target->srp_host->dev->dev, 272 target->path_query_id = ib_sa_path_rec_get(&srp_sa_client,
273 target->srp_host->dev->dev,
271 target->srp_host->port, 274 target->srp_host->port,
272 &target->path, 275 &target->path,
273 IB_SA_PATH_REC_DGID | 276 IB_SA_PATH_REC_DGID |
@@ -330,7 +333,7 @@ static int srp_send_req(struct srp_target_port *target)
330 req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | 333 req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
331 SRP_BUF_FORMAT_INDIRECT); 334 SRP_BUF_FORMAT_INDIRECT);
332 /* 335 /*
333 * In the published SRP specification (draft rev. 16a), the 336 * In the published SRP specification (draft rev. 16a), the
334 * port identifier format is 8 bytes of ID extension followed 337 * port identifier format is 8 bytes of ID extension followed
335 * by 8 bytes of GUID. Older drafts put the two halves in the 338 * by 8 bytes of GUID. Older drafts put the two halves in the
336 * opposite order, so that the GUID comes first. 339 * opposite order, so that the GUID comes first.
@@ -1449,12 +1452,28 @@ static ssize_t show_zero_req_lim(struct class_device *cdev, char *buf)
1449 return sprintf(buf, "%d\n", target->zero_req_lim); 1452 return sprintf(buf, "%d\n", target->zero_req_lim);
1450} 1453}
1451 1454
1452static CLASS_DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); 1455static ssize_t show_local_ib_port(struct class_device *cdev, char *buf)
1453static CLASS_DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); 1456{
1454static CLASS_DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); 1457 struct srp_target_port *target = host_to_target(class_to_shost(cdev));
1455static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); 1458
1456static CLASS_DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL); 1459 return sprintf(buf, "%d\n", target->srp_host->port);
1457static CLASS_DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); 1460}
1461
1462static ssize_t show_local_ib_device(struct class_device *cdev, char *buf)
1463{
1464 struct srp_target_port *target = host_to_target(class_to_shost(cdev));
1465
1466 return sprintf(buf, "%s\n", target->srp_host->dev->dev->name);
1467}
1468
1469static CLASS_DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL);
1470static CLASS_DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL);
1471static CLASS_DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL);
1472static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
1473static CLASS_DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL);
1474static CLASS_DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL);
1475static CLASS_DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL);
1476static CLASS_DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
1458 1477
1459static struct class_device_attribute *srp_host_attrs[] = { 1478static struct class_device_attribute *srp_host_attrs[] = {
1460 &class_device_attr_id_ext, 1479 &class_device_attr_id_ext,
@@ -1463,6 +1482,8 @@ static struct class_device_attribute *srp_host_attrs[] = {
1463 &class_device_attr_pkey, 1482 &class_device_attr_pkey,
1464 &class_device_attr_dgid, 1483 &class_device_attr_dgid,
1465 &class_device_attr_zero_req_lim, 1484 &class_device_attr_zero_req_lim,
1485 &class_device_attr_local_ib_port,
1486 &class_device_attr_local_ib_device,
1466 NULL 1487 NULL
1467}; 1488};
1468 1489
@@ -1881,7 +1902,7 @@ static void srp_add_one(struct ib_device *device)
1881 if (IS_ERR(srp_dev->fmr_pool)) 1902 if (IS_ERR(srp_dev->fmr_pool))
1882 srp_dev->fmr_pool = NULL; 1903 srp_dev->fmr_pool = NULL;
1883 1904
1884 if (device->node_type == IB_NODE_SWITCH) { 1905 if (device->node_type == RDMA_NODE_IB_SWITCH) {
1885 s = 0; 1906 s = 0;
1886 e = 0; 1907 e = 0;
1887 } else { 1908 } else {
@@ -1980,9 +2001,12 @@ static int __init srp_init_module(void)
1980 return ret; 2001 return ret;
1981 } 2002 }
1982 2003
2004 ib_sa_register_client(&srp_sa_client);
2005
1983 ret = ib_register_client(&srp_client); 2006 ret = ib_register_client(&srp_client);
1984 if (ret) { 2007 if (ret) {
1985 printk(KERN_ERR PFX "couldn't register IB client\n"); 2008 printk(KERN_ERR PFX "couldn't register IB client\n");
2009 ib_sa_unregister_client(&srp_sa_client);
1986 class_unregister(&srp_class); 2010 class_unregister(&srp_class);
1987 return ret; 2011 return ret;
1988 } 2012 }
@@ -1993,6 +2017,7 @@ static int __init srp_init_module(void)
1993static void __exit srp_cleanup_module(void) 2017static void __exit srp_cleanup_module(void)
1994{ 2018{
1995 ib_unregister_client(&srp_client); 2019 ib_unregister_client(&srp_client);
2020 ib_sa_unregister_client(&srp_sa_client);
1996 class_unregister(&srp_class); 2021 class_unregister(&srp_class);
1997} 2022}
1998 2023
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 82657bc86d19..d56216067549 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -139,7 +139,9 @@ static int macio_uevent(struct device *dev, char **envp, int num_envp,
139{ 139{
140 struct macio_dev * macio_dev; 140 struct macio_dev * macio_dev;
141 struct of_device * of; 141 struct of_device * of;
142 char *scratch, *compat, *compat2; 142 char *scratch;
143 const char *compat, *compat2;
144
143 int i = 0; 145 int i = 0;
144 int length, cplen, cplen2, seen = 0; 146 int length, cplen, cplen2, seen = 0;
145 147
@@ -173,7 +175,7 @@ static int macio_uevent(struct device *dev, char **envp, int num_envp,
173 * it's not really legal to split it out with commas. We split it 175 * it's not really legal to split it out with commas. We split it
174 * up using a number of environment variables instead. */ 176 * up using a number of environment variables instead. */
175 177
176 compat = (char *) get_property(of->node, "compatible", &cplen); 178 compat = get_property(of->node, "compatible", &cplen);
177 compat2 = compat; 179 compat2 = compat;
178 cplen2= cplen; 180 cplen2= cplen;
179 while (compat && cplen > 0) { 181 while (compat && cplen > 0) {
@@ -454,7 +456,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
454 struct resource *parent_res) 456 struct resource *parent_res)
455{ 457{
456 struct macio_dev *dev; 458 struct macio_dev *dev;
457 u32 *reg; 459 const u32 *reg;
458 460
459 if (np == NULL) 461 if (np == NULL)
460 return NULL; 462 return NULL;
@@ -489,7 +491,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
489#endif 491#endif
490 MAX_NODE_NAME_SIZE, np->name); 492 MAX_NODE_NAME_SIZE, np->name);
491 } else { 493 } else {
492 reg = (u32 *)get_property(np, "reg", NULL); 494 reg = get_property(np, "reg", NULL);
493 sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s", 495 sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s",
494 chip->lbus.index, 496 chip->lbus.index,
495 reg ? *reg : 0, MAX_NODE_NAME_SIZE, np->name); 497 reg ? *reg : 0, MAX_NODE_NAME_SIZE, np->name);
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
index cae24a13526a..8566bdfdd4b8 100644
--- a/drivers/macintosh/macio_sysfs.c
+++ b/drivers/macintosh/macio_sysfs.c
@@ -16,12 +16,12 @@ static ssize_t
16compatible_show (struct device *dev, struct device_attribute *attr, char *buf) 16compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
17{ 17{
18 struct of_device *of; 18 struct of_device *of;
19 char *compat; 19 const char *compat;
20 int cplen; 20 int cplen;
21 int length = 0; 21 int length = 0;
22 22
23 of = &to_macio_device (dev)->ofdev; 23 of = &to_macio_device (dev)->ofdev;
24 compat = (char *) get_property(of->node, "compatible", &cplen); 24 compat = get_property(of->node, "compatible", &cplen);
25 if (!compat) { 25 if (!compat) {
26 *buf = '\0'; 26 *buf = '\0';
27 return 0; 27 return 0;
@@ -42,12 +42,12 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
42 char *buf) 42 char *buf)
43{ 43{
44 struct of_device *of; 44 struct of_device *of;
45 char *compat; 45 const char *compat;
46 int cplen; 46 int cplen;
47 int length; 47 int length;
48 48
49 of = &to_macio_device (dev)->ofdev; 49 of = &to_macio_device (dev)->ofdev;
50 compat = (char *) get_property (of->node, "compatible", &cplen); 50 compat = get_property(of->node, "compatible", &cplen);
51 if (!compat) compat = "", cplen = 1; 51 if (!compat) compat = "", cplen = 1;
52 length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type); 52 length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type);
53 buf += length; 53 buf += length;
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 00ef46898147..090e40fc5013 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -454,7 +454,7 @@ EXPORT_SYMBOL(smu_present);
454int __init smu_init (void) 454int __init smu_init (void)
455{ 455{
456 struct device_node *np; 456 struct device_node *np;
457 u32 *data; 457 const u32 *data;
458 458
459 np = of_find_node_by_type(NULL, "smu"); 459 np = of_find_node_by_type(NULL, "smu");
460 if (np == NULL) 460 if (np == NULL)
@@ -490,7 +490,7 @@ int __init smu_init (void)
490 printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); 490 printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n");
491 goto fail; 491 goto fail;
492 } 492 }
493 data = (u32 *)get_property(smu->db_node, "reg", NULL); 493 data = get_property(smu->db_node, "reg", NULL);
494 if (data == NULL) { 494 if (data == NULL) {
495 of_node_put(smu->db_node); 495 of_node_put(smu->db_node);
496 smu->db_node = NULL; 496 smu->db_node = NULL;
@@ -511,7 +511,7 @@ int __init smu_init (void)
511 smu->msg_node = of_find_node_by_name(NULL, "smu-interrupt"); 511 smu->msg_node = of_find_node_by_name(NULL, "smu-interrupt");
512 if (smu->msg_node == NULL) 512 if (smu->msg_node == NULL)
513 break; 513 break;
514 data = (u32 *)get_property(smu->msg_node, "reg", NULL); 514 data = get_property(smu->msg_node, "reg", NULL);
515 if (data == NULL) { 515 if (data == NULL) {
516 of_node_put(smu->msg_node); 516 of_node_put(smu->msg_node);
517 smu->msg_node = NULL; 517 smu->msg_node = NULL;
@@ -982,11 +982,11 @@ static struct smu_sdbp_header *smu_create_sdb_partition(int id)
982/* Note: Only allowed to return error code in pointers (using ERR_PTR) 982/* Note: Only allowed to return error code in pointers (using ERR_PTR)
983 * when interruptible is 1 983 * when interruptible is 1
984 */ 984 */
985struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, 985const struct smu_sdbp_header *__smu_get_sdb_partition(int id,
986 int interruptible) 986 unsigned int *size, int interruptible)
987{ 987{
988 char pname[32]; 988 char pname[32];
989 struct smu_sdbp_header *part; 989 const struct smu_sdbp_header *part;
990 990
991 if (!smu) 991 if (!smu)
992 return NULL; 992 return NULL;
@@ -1003,8 +1003,7 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size,
1003 } else 1003 } else
1004 mutex_lock(&smu_part_access); 1004 mutex_lock(&smu_part_access);
1005 1005
1006 part = (struct smu_sdbp_header *)get_property(smu->of_node, 1006 part = get_property(smu->of_node, pname, size);
1007 pname, size);
1008 if (part == NULL) { 1007 if (part == NULL) {
1009 DPRINTK("trying to extract from SMU ...\n"); 1008 DPRINTK("trying to extract from SMU ...\n");
1010 part = smu_create_sdb_partition(id); 1009 part = smu_create_sdb_partition(id);
@@ -1015,7 +1014,7 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size,
1015 return part; 1014 return part;
1016} 1015}
1017 1016
1018struct smu_sdbp_header *smu_get_sdb_partition(int id, unsigned int *size) 1017const struct smu_sdbp_header *smu_get_sdb_partition(int id, unsigned int *size)
1019{ 1018{
1020 return __smu_get_sdb_partition(id, size, 0); 1019 return __smu_get_sdb_partition(id, size, 0);
1021} 1020}
@@ -1094,7 +1093,7 @@ static ssize_t smu_write(struct file *file, const char __user *buf,
1094 pp->mode = smu_file_events; 1093 pp->mode = smu_file_events;
1095 return 0; 1094 return 0;
1096 } else if (hdr.cmdtype == SMU_CMDTYPE_GET_PARTITION) { 1095 } else if (hdr.cmdtype == SMU_CMDTYPE_GET_PARTITION) {
1097 struct smu_sdbp_header *part; 1096 const struct smu_sdbp_header *part;
1098 part = __smu_get_sdb_partition(hdr.cmd, NULL, 1); 1097 part = __smu_get_sdb_partition(hdr.cmd, NULL, 1);
1099 if (part == NULL) 1098 if (part == NULL)
1100 return -EINVAL; 1099 return -EINVAL;
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 7f86478bdd36..a0f30d0853ea 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -47,7 +47,7 @@ static u8 FAN_SPD_SET[2] = {0x30, 0x31};
47 47
48static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */ 48static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */
49static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */ 49static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */
50static char *sensor_location[3] = {NULL, NULL, NULL}; 50static const char *sensor_location[3] = {NULL, NULL, NULL};
51 51
52static int limit_adjust = 0; 52static int limit_adjust = 0;
53static int fan_speed = -1; 53static int fan_speed = -1;
@@ -553,7 +553,7 @@ static int __init
553thermostat_init(void) 553thermostat_init(void)
554{ 554{
555 struct device_node* np; 555 struct device_node* np;
556 u32 *prop; 556 const u32 *prop;
557 int i = 0, offset = 0; 557 int i = 0, offset = 0;
558 558
559 np = of_find_node_by_name(NULL, "fan"); 559 np = of_find_node_by_name(NULL, "fan");
@@ -566,13 +566,13 @@ thermostat_init(void)
566 else 566 else
567 return -ENODEV; 567 return -ENODEV;
568 568
569 prop = (u32 *)get_property(np, "hwsensor-params-version", NULL); 569 prop = get_property(np, "hwsensor-params-version", NULL);
570 printk(KERN_INFO "adt746x: version %d (%ssupported)\n", *prop, 570 printk(KERN_INFO "adt746x: version %d (%ssupported)\n", *prop,
571 (*prop == 1)?"":"un"); 571 (*prop == 1)?"":"un");
572 if (*prop != 1) 572 if (*prop != 1)
573 return -ENODEV; 573 return -ENODEV;
574 574
575 prop = (u32 *)get_property(np, "reg", NULL); 575 prop = get_property(np, "reg", NULL);
576 if (!prop) 576 if (!prop)
577 return -ENODEV; 577 return -ENODEV;
578 578
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 20bf67244e2c..d00c0c37a12e 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -660,7 +660,7 @@ static int read_eeprom(int cpu, struct mpu_data *out)
660{ 660{
661 struct device_node *np; 661 struct device_node *np;
662 char nodename[64]; 662 char nodename[64];
663 u8 *data; 663 const u8 *data;
664 int len; 664 int len;
665 665
666 /* prom.c routine for finding a node by path is a bit brain dead 666 /* prom.c routine for finding a node by path is a bit brain dead
@@ -673,7 +673,7 @@ static int read_eeprom(int cpu, struct mpu_data *out)
673 printk(KERN_ERR "therm_pm72: Failed to retrieve cpuid node from device-tree\n"); 673 printk(KERN_ERR "therm_pm72: Failed to retrieve cpuid node from device-tree\n");
674 return -ENODEV; 674 return -ENODEV;
675 } 675 }
676 data = (u8 *)get_property(np, "cpuid", &len); 676 data = get_property(np, "cpuid", &len);
677 if (data == NULL) { 677 if (data == NULL) {
678 printk(KERN_ERR "therm_pm72: Failed to retrieve cpuid property from device-tree\n"); 678 printk(KERN_ERR "therm_pm72: Failed to retrieve cpuid property from device-tree\n");
679 of_node_put(np); 679 of_node_put(np);
@@ -1336,7 +1336,7 @@ static int init_backside_state(struct backside_pid_state *state)
1336 */ 1336 */
1337 u3 = of_find_node_by_path("/u3@0,f8000000"); 1337 u3 = of_find_node_by_path("/u3@0,f8000000");
1338 if (u3 != NULL) { 1338 if (u3 != NULL) {
1339 u32 *vers = (u32 *)get_property(u3, "device-rev", NULL); 1339 const u32 *vers = get_property(u3, "device-rev", NULL);
1340 if (vers) 1340 if (vers)
1341 if (((*vers) & 0x3f) < 0x34) 1341 if (((*vers) & 0x3f) < 0x34)
1342 u3h = 0; 1342 u3h = 0;
@@ -2111,8 +2111,8 @@ static void fcu_lookup_fans(struct device_node *fcu_node)
2111 2111
2112 while ((np = of_get_next_child(fcu_node, np)) != NULL) { 2112 while ((np = of_get_next_child(fcu_node, np)) != NULL) {
2113 int type = -1; 2113 int type = -1;
2114 char *loc; 2114 const char *loc;
2115 u32 *reg; 2115 const u32 *reg;
2116 2116
2117 DBG(" control: %s, type: %s\n", np->name, np->type); 2117 DBG(" control: %s, type: %s\n", np->name, np->type);
2118 2118
@@ -2128,8 +2128,8 @@ static void fcu_lookup_fans(struct device_node *fcu_node)
2128 continue; 2128 continue;
2129 2129
2130 /* Lookup for a matching location */ 2130 /* Lookup for a matching location */
2131 loc = (char *)get_property(np, "location", NULL); 2131 loc = get_property(np, "location", NULL);
2132 reg = (u32 *)get_property(np, "reg", NULL); 2132 reg = get_property(np, "reg", NULL);
2133 if (loc == NULL || reg == NULL) 2133 if (loc == NULL || reg == NULL)
2134 continue; 2134 continue;
2135 DBG(" matching location: %s, reg: 0x%08x\n", loc, *reg); 2135 DBG(" matching location: %s, reg: 0x%08x\n", loc, *reg);
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index c7d1c290cb0c..738faab1b22c 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -484,14 +484,14 @@ struct apple_thermal_info {
484static int __init 484static int __init
485g4fan_init( void ) 485g4fan_init( void )
486{ 486{
487 struct apple_thermal_info *info; 487 const struct apple_thermal_info *info;
488 struct device_node *np; 488 struct device_node *np;
489 489
490 init_MUTEX( &x.lock ); 490 init_MUTEX( &x.lock );
491 491
492 if( !(np=of_find_node_by_name(NULL, "power-mgt")) ) 492 if( !(np=of_find_node_by_name(NULL, "power-mgt")) )
493 return -ENODEV; 493 return -ENODEV;
494 info = (struct apple_thermal_info*)get_property(np, "thermal-info", NULL); 494 info = get_property(np, "thermal-info", NULL);
495 of_node_put(np); 495 of_node_put(np);
496 496
497 if( !info || !machine_is_compatible("PowerMac3,6") ) 497 if( !info || !machine_is_compatible("PowerMac3,6") )
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index 69d5452fd22f..7512d1c15207 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -123,7 +123,7 @@ int __init find_via_cuda(void)
123{ 123{
124 struct adb_request req; 124 struct adb_request req;
125 phys_addr_t taddr; 125 phys_addr_t taddr;
126 u32 *reg; 126 const u32 *reg;
127 int err; 127 int err;
128 128
129 if (vias != 0) 129 if (vias != 0)
@@ -132,7 +132,7 @@ int __init find_via_cuda(void)
132 if (vias == 0) 132 if (vias == 0)
133 return 0; 133 return 0;
134 134
135 reg = (u32 *)get_property(vias, "reg", NULL); 135 reg = get_property(vias, "reg", NULL);
136 if (reg == NULL) { 136 if (reg == NULL) {
137 printk(KERN_ERR "via-cuda: No \"reg\" property !\n"); 137 printk(KERN_ERR "via-cuda: No \"reg\" property !\n");
138 goto fail; 138 goto fail;
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c
index 5189d5454b1f..179af10105d9 100644
--- a/drivers/macintosh/via-pmu-led.c
+++ b/drivers/macintosh/via-pmu-led.c
@@ -120,7 +120,7 @@ static int __init via_pmu_led_init(void)
120 dt = of_find_node_by_path("/"); 120 dt = of_find_node_by_path("/");
121 if (dt == NULL) 121 if (dt == NULL)
122 return -ENODEV; 122 return -ENODEV;
123 model = (const char *)get_property(dt, "model", NULL); 123 model = get_property(dt, "model", NULL);
124 if (model == NULL) 124 if (model == NULL)
125 return -ENODEV; 125 return -ENODEV;
126 if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && 126 if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 14610a63f580..dda03985dcf5 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -280,7 +280,7 @@ static char *pbook_type[] = {
280int __init find_via_pmu(void) 280int __init find_via_pmu(void)
281{ 281{
282 u64 taddr; 282 u64 taddr;
283 u32 *reg; 283 const u32 *reg;
284 284
285 if (via != 0) 285 if (via != 0)
286 return 1; 286 return 1;
@@ -288,7 +288,7 @@ int __init find_via_pmu(void)
288 if (vias == NULL) 288 if (vias == NULL)
289 return 0; 289 return 0;
290 290
291 reg = (u32 *)get_property(vias, "reg", NULL); 291 reg = get_property(vias, "reg", NULL);
292 if (reg == NULL) { 292 if (reg == NULL) {
293 printk(KERN_ERR "via-pmu: No \"reg\" property !\n"); 293 printk(KERN_ERR "via-pmu: No \"reg\" property !\n");
294 goto fail; 294 goto fail;
@@ -330,7 +330,7 @@ int __init find_via_pmu(void)
330 330
331 gpiop = of_find_node_by_name(NULL, "gpio"); 331 gpiop = of_find_node_by_name(NULL, "gpio");
332 if (gpiop) { 332 if (gpiop) {
333 reg = (u32 *)get_property(gpiop, "reg", NULL); 333 reg = get_property(gpiop, "reg", NULL);
334 if (reg) 334 if (reg)
335 gaddr = of_translate_address(gpiop, reg); 335 gaddr = of_translate_address(gpiop, reg);
336 if (gaddr != OF_BAD_ADDR) 336 if (gaddr != OF_BAD_ADDR)
@@ -479,9 +479,9 @@ static int __init via_pmu_dev_init(void)
479 pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART; 479 pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
480 } else { 480 } else {
481 struct device_node* prim = find_devices("power-mgt"); 481 struct device_node* prim = find_devices("power-mgt");
482 u32 *prim_info = NULL; 482 const u32 *prim_info = NULL;
483 if (prim) 483 if (prim)
484 prim_info = (u32 *)get_property(prim, "prim-info", NULL); 484 prim_info = get_property(prim, "prim-info", NULL);
485 if (prim_info) { 485 if (prim_info) {
486 /* Other stuffs here yet unknown */ 486 /* Other stuffs here yet unknown */
487 pmu_battery_count = (prim_info[6] >> 16) & 0xff; 487 pmu_battery_count = (prim_info[6] >> 16) & 0xff;
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
index f1df6efcbe68..2ff546e4c92f 100644
--- a/drivers/macintosh/windfarm_pm81.c
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -396,7 +396,7 @@ static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st)
396static void wf_smu_create_cpu_fans(void) 396static void wf_smu_create_cpu_fans(void)
397{ 397{
398 struct wf_cpu_pid_param pid_param; 398 struct wf_cpu_pid_param pid_param;
399 struct smu_sdbp_header *hdr; 399 const struct smu_sdbp_header *hdr;
400 struct smu_sdbp_cpupiddata *piddata; 400 struct smu_sdbp_cpupiddata *piddata;
401 struct smu_sdbp_fvt *fvt; 401 struct smu_sdbp_fvt *fvt;
402 s32 tmax, tdelta, maxpow, powadj; 402 s32 tmax, tdelta, maxpow, powadj;
@@ -702,7 +702,7 @@ static struct notifier_block wf_smu_events = {
702 702
703static int wf_init_pm(void) 703static int wf_init_pm(void)
704{ 704{
705 struct smu_sdbp_header *hdr; 705 const struct smu_sdbp_header *hdr;
706 706
707 hdr = smu_get_sdb_partition(SMU_SDB_SENSORTREE_ID, NULL); 707 hdr = smu_get_sdb_partition(SMU_SDB_SENSORTREE_ID, NULL);
708 if (hdr != 0) { 708 if (hdr != 0) {
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c
index 0d6372e96d32..59e9ffe37c39 100644
--- a/drivers/macintosh/windfarm_pm91.c
+++ b/drivers/macintosh/windfarm_pm91.c
@@ -144,7 +144,7 @@ static struct wf_smu_slots_fans_state *wf_smu_slots_fans;
144static void wf_smu_create_cpu_fans(void) 144static void wf_smu_create_cpu_fans(void)
145{ 145{
146 struct wf_cpu_pid_param pid_param; 146 struct wf_cpu_pid_param pid_param;
147 struct smu_sdbp_header *hdr; 147 const struct smu_sdbp_header *hdr;
148 struct smu_sdbp_cpupiddata *piddata; 148 struct smu_sdbp_cpupiddata *piddata;
149 struct smu_sdbp_fvt *fvt; 149 struct smu_sdbp_fvt *fvt;
150 s32 tmax, tdelta, maxpow, powadj; 150 s32 tmax, tdelta, maxpow, powadj;
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index a9e88edc0c72..bff1f372f188 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -159,14 +159,15 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
159 int pwm_fan) 159 int pwm_fan)
160{ 160{
161 struct smu_fan_control *fct; 161 struct smu_fan_control *fct;
162 s32 *v; u32 *reg; 162 const s32 *v;
163 char *l; 163 const u32 *reg;
164 const char *l;
164 165
165 fct = kmalloc(sizeof(struct smu_fan_control), GFP_KERNEL); 166 fct = kmalloc(sizeof(struct smu_fan_control), GFP_KERNEL);
166 if (fct == NULL) 167 if (fct == NULL)
167 return NULL; 168 return NULL;
168 fct->ctrl.ops = &smu_fan_ops; 169 fct->ctrl.ops = &smu_fan_ops;
169 l = (char *)get_property(node, "location", NULL); 170 l = get_property(node, "location", NULL);
170 if (l == NULL) 171 if (l == NULL)
171 goto fail; 172 goto fail;
172 173
@@ -223,17 +224,17 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
223 goto fail; 224 goto fail;
224 225
225 /* Get min & max values*/ 226 /* Get min & max values*/
226 v = (s32 *)get_property(node, "min-value", NULL); 227 v = get_property(node, "min-value", NULL);
227 if (v == NULL) 228 if (v == NULL)
228 goto fail; 229 goto fail;
229 fct->min = *v; 230 fct->min = *v;
230 v = (s32 *)get_property(node, "max-value", NULL); 231 v = get_property(node, "max-value", NULL);
231 if (v == NULL) 232 if (v == NULL)
232 goto fail; 233 goto fail;
233 fct->max = *v; 234 fct->max = *v;
234 235
235 /* Get "reg" value */ 236 /* Get "reg" value */
236 reg = (u32 *)get_property(node, "reg", NULL); 237 reg = get_property(node, "reg", NULL);
237 if (reg == NULL) 238 if (reg == NULL)
238 goto fail; 239 goto fail;
239 fct->reg = *reg; 240 fct->reg = *reg;
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index e295a07a1ebc..aceb61d9fbc8 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -233,15 +233,15 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
233{ 233{
234 struct wf_sat *sat; 234 struct wf_sat *sat;
235 struct wf_sat_sensor *sens; 235 struct wf_sat_sensor *sens;
236 u32 *reg; 236 const u32 *reg;
237 char *loc, *type; 237 const char *loc, *type;
238 u8 addr, chip, core; 238 u8 addr, chip, core;
239 struct device_node *child; 239 struct device_node *child;
240 int shift, cpu, index; 240 int shift, cpu, index;
241 char *name; 241 char *name;
242 int vsens[2], isens[2]; 242 int vsens[2], isens[2];
243 243
244 reg = (u32 *) get_property(dev, "reg", NULL); 244 reg = get_property(dev, "reg", NULL);
245 if (reg == NULL) 245 if (reg == NULL)
246 return; 246 return;
247 addr = *reg; 247 addr = *reg;
@@ -268,7 +268,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
268 isens[0] = isens[1] = -1; 268 isens[0] = isens[1] = -1;
269 child = NULL; 269 child = NULL;
270 while ((child = of_get_next_child(dev, child)) != NULL) { 270 while ((child = of_get_next_child(dev, child)) != NULL) {
271 reg = (u32 *) get_property(child, "reg", NULL); 271 reg = get_property(child, "reg", NULL);
272 type = get_property(child, "device_type", NULL); 272 type = get_property(child, "device_type", NULL);
273 loc = get_property(child, "location", NULL); 273 loc = get_property(child, "location", NULL);
274 if (reg == NULL || loc == NULL) 274 if (reg == NULL || loc == NULL)
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c
index bed25dcf8a1e..defe9922ebd1 100644
--- a/drivers/macintosh/windfarm_smu_sensors.c
+++ b/drivers/macintosh/windfarm_smu_sensors.c
@@ -198,14 +198,14 @@ static struct wf_sensor_ops smu_slotspow_ops = {
198static struct smu_ad_sensor *smu_ads_create(struct device_node *node) 198static struct smu_ad_sensor *smu_ads_create(struct device_node *node)
199{ 199{
200 struct smu_ad_sensor *ads; 200 struct smu_ad_sensor *ads;
201 char *c, *l; 201 const char *c, *l;
202 u32 *v; 202 const u32 *v;
203 203
204 ads = kmalloc(sizeof(struct smu_ad_sensor), GFP_KERNEL); 204 ads = kmalloc(sizeof(struct smu_ad_sensor), GFP_KERNEL);
205 if (ads == NULL) 205 if (ads == NULL)
206 return NULL; 206 return NULL;
207 c = (char *)get_property(node, "device_type", NULL); 207 c = get_property(node, "device_type", NULL);
208 l = (char *)get_property(node, "location", NULL); 208 l = get_property(node, "location", NULL);
209 if (c == NULL || l == NULL) 209 if (c == NULL || l == NULL)
210 goto fail; 210 goto fail;
211 211
@@ -255,7 +255,7 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node)
255 } else 255 } else
256 goto fail; 256 goto fail;
257 257
258 v = (u32 *)get_property(node, "reg", NULL); 258 v = get_property(node, "reg", NULL);
259 if (v == NULL) 259 if (v == NULL)
260 goto fail; 260 goto fail;
261 ads->reg = *v; 261 ads->reg = *v;
@@ -382,7 +382,7 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps)
382 382
383static void smu_fetch_param_partitions(void) 383static void smu_fetch_param_partitions(void)
384{ 384{
385 struct smu_sdbp_header *hdr; 385 const struct smu_sdbp_header *hdr;
386 386
387 /* Get CPU voltage/current/power calibration data */ 387 /* Get CPU voltage/current/power calibration data */
388 hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); 388 hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 6022ed12a795..bdbd34993a80 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -5,6 +5,7 @@
5 * This file is released under the GPL. 5 * This file is released under the GPL.
6 */ 6 */
7 7
8#include <linux/err.h>
8#include <linux/module.h> 9#include <linux/module.h>
9#include <linux/init.h> 10#include <linux/init.h>
10#include <linux/kernel.h> 11#include <linux/kernel.h>
@@ -78,11 +79,13 @@ struct crypt_config {
78 */ 79 */
79 struct crypt_iv_operations *iv_gen_ops; 80 struct crypt_iv_operations *iv_gen_ops;
80 char *iv_mode; 81 char *iv_mode;
81 void *iv_gen_private; 82 struct crypto_cipher *iv_gen_private;
82 sector_t iv_offset; 83 sector_t iv_offset;
83 unsigned int iv_size; 84 unsigned int iv_size;
84 85
85 struct crypto_tfm *tfm; 86 char cipher[CRYPTO_MAX_ALG_NAME];
87 char chainmode[CRYPTO_MAX_ALG_NAME];
88 struct crypto_blkcipher *tfm;
86 unsigned int key_size; 89 unsigned int key_size;
87 u8 key[0]; 90 u8 key[0];
88}; 91};
@@ -96,12 +99,12 @@ static kmem_cache_t *_crypt_io_pool;
96/* 99/*
97 * Different IV generation algorithms: 100 * Different IV generation algorithms:
98 * 101 *
99 * plain: the initial vector is the 32-bit low-endian version of the sector 102 * plain: the initial vector is the 32-bit little-endian version of the sector
100 * number, padded with zeros if neccessary. 103 * number, padded with zeros if neccessary.
101 * 104 *
102 * ess_iv: "encrypted sector|salt initial vector", the sector number is 105 * essiv: "encrypted sector|salt initial vector", the sector number is
103 * encrypted with the bulk cipher using a salt as key. The salt 106 * encrypted with the bulk cipher using a salt as key. The salt
104 * should be derived from the bulk cipher's key via hashing. 107 * should be derived from the bulk cipher's key via hashing.
105 * 108 *
106 * plumb: unimplemented, see: 109 * plumb: unimplemented, see:
107 * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454 110 * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454
@@ -118,11 +121,13 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
118static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, 121static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
119 const char *opts) 122 const char *opts)
120{ 123{
121 struct crypto_tfm *essiv_tfm; 124 struct crypto_cipher *essiv_tfm;
122 struct crypto_tfm *hash_tfm; 125 struct crypto_hash *hash_tfm;
126 struct hash_desc desc;
123 struct scatterlist sg; 127 struct scatterlist sg;
124 unsigned int saltsize; 128 unsigned int saltsize;
125 u8 *salt; 129 u8 *salt;
130 int err;
126 131
127 if (opts == NULL) { 132 if (opts == NULL) {
128 ti->error = "Digest algorithm missing for ESSIV mode"; 133 ti->error = "Digest algorithm missing for ESSIV mode";
@@ -130,76 +135,70 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
130 } 135 }
131 136
132 /* Hash the cipher key with the given hash algorithm */ 137 /* Hash the cipher key with the given hash algorithm */
133 hash_tfm = crypto_alloc_tfm(opts, CRYPTO_TFM_REQ_MAY_SLEEP); 138 hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC);
134 if (hash_tfm == NULL) { 139 if (IS_ERR(hash_tfm)) {
135 ti->error = "Error initializing ESSIV hash"; 140 ti->error = "Error initializing ESSIV hash";
136 return -EINVAL; 141 return PTR_ERR(hash_tfm);
137 } 142 }
138 143
139 if (crypto_tfm_alg_type(hash_tfm) != CRYPTO_ALG_TYPE_DIGEST) { 144 saltsize = crypto_hash_digestsize(hash_tfm);
140 ti->error = "Expected digest algorithm for ESSIV hash";
141 crypto_free_tfm(hash_tfm);
142 return -EINVAL;
143 }
144
145 saltsize = crypto_tfm_alg_digestsize(hash_tfm);
146 salt = kmalloc(saltsize, GFP_KERNEL); 145 salt = kmalloc(saltsize, GFP_KERNEL);
147 if (salt == NULL) { 146 if (salt == NULL) {
148 ti->error = "Error kmallocing salt storage in ESSIV"; 147 ti->error = "Error kmallocing salt storage in ESSIV";
149 crypto_free_tfm(hash_tfm); 148 crypto_free_hash(hash_tfm);
150 return -ENOMEM; 149 return -ENOMEM;
151 } 150 }
152 151
153 sg_set_buf(&sg, cc->key, cc->key_size); 152 sg_set_buf(&sg, cc->key, cc->key_size);
154 crypto_digest_digest(hash_tfm, &sg, 1, salt); 153 desc.tfm = hash_tfm;
155 crypto_free_tfm(hash_tfm); 154 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
155 err = crypto_hash_digest(&desc, &sg, cc->key_size, salt);
156 crypto_free_hash(hash_tfm);
157
158 if (err) {
159 ti->error = "Error calculating hash in ESSIV";
160 return err;
161 }
156 162
157 /* Setup the essiv_tfm with the given salt */ 163 /* Setup the essiv_tfm with the given salt */
158 essiv_tfm = crypto_alloc_tfm(crypto_tfm_alg_name(cc->tfm), 164 essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);
159 CRYPTO_TFM_MODE_ECB | 165 if (IS_ERR(essiv_tfm)) {
160 CRYPTO_TFM_REQ_MAY_SLEEP);
161 if (essiv_tfm == NULL) {
162 ti->error = "Error allocating crypto tfm for ESSIV"; 166 ti->error = "Error allocating crypto tfm for ESSIV";
163 kfree(salt); 167 kfree(salt);
164 return -EINVAL; 168 return PTR_ERR(essiv_tfm);
165 } 169 }
166 if (crypto_tfm_alg_blocksize(essiv_tfm) 170 if (crypto_cipher_blocksize(essiv_tfm) !=
167 != crypto_tfm_alg_ivsize(cc->tfm)) { 171 crypto_blkcipher_ivsize(cc->tfm)) {
168 ti->error = "Block size of ESSIV cipher does " 172 ti->error = "Block size of ESSIV cipher does "
169 "not match IV size of block cipher"; 173 "not match IV size of block cipher";
170 crypto_free_tfm(essiv_tfm); 174 crypto_free_cipher(essiv_tfm);
171 kfree(salt); 175 kfree(salt);
172 return -EINVAL; 176 return -EINVAL;
173 } 177 }
174 if (crypto_cipher_setkey(essiv_tfm, salt, saltsize) < 0) { 178 err = crypto_cipher_setkey(essiv_tfm, salt, saltsize);
179 if (err) {
175 ti->error = "Failed to set key for ESSIV cipher"; 180 ti->error = "Failed to set key for ESSIV cipher";
176 crypto_free_tfm(essiv_tfm); 181 crypto_free_cipher(essiv_tfm);
177 kfree(salt); 182 kfree(salt);
178 return -EINVAL; 183 return err;
179 } 184 }
180 kfree(salt); 185 kfree(salt);
181 186
182 cc->iv_gen_private = (void *)essiv_tfm; 187 cc->iv_gen_private = essiv_tfm;
183 return 0; 188 return 0;
184} 189}
185 190
186static void crypt_iv_essiv_dtr(struct crypt_config *cc) 191static void crypt_iv_essiv_dtr(struct crypt_config *cc)
187{ 192{
188 crypto_free_tfm((struct crypto_tfm *)cc->iv_gen_private); 193 crypto_free_cipher(cc->iv_gen_private);
189 cc->iv_gen_private = NULL; 194 cc->iv_gen_private = NULL;
190} 195}
191 196
192static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector) 197static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
193{ 198{
194 struct scatterlist sg;
195
196 memset(iv, 0, cc->iv_size); 199 memset(iv, 0, cc->iv_size);
197 *(u64 *)iv = cpu_to_le64(sector); 200 *(u64 *)iv = cpu_to_le64(sector);
198 201 crypto_cipher_encrypt_one(cc->iv_gen_private, iv, iv);
199 sg_set_buf(&sg, iv, cc->iv_size);
200 crypto_cipher_encrypt((struct crypto_tfm *)cc->iv_gen_private,
201 &sg, &sg, cc->iv_size);
202
203 return 0; 202 return 0;
204} 203}
205 204
@@ -220,6 +219,11 @@ crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out,
220 int write, sector_t sector) 219 int write, sector_t sector)
221{ 220{
222 u8 iv[cc->iv_size]; 221 u8 iv[cc->iv_size];
222 struct blkcipher_desc desc = {
223 .tfm = cc->tfm,
224 .info = iv,
225 .flags = CRYPTO_TFM_REQ_MAY_SLEEP,
226 };
223 int r; 227 int r;
224 228
225 if (cc->iv_gen_ops) { 229 if (cc->iv_gen_ops) {
@@ -228,14 +232,14 @@ crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out,
228 return r; 232 return r;
229 233
230 if (write) 234 if (write)
231 r = crypto_cipher_encrypt_iv(cc->tfm, out, in, length, iv); 235 r = crypto_blkcipher_encrypt_iv(&desc, out, in, length);
232 else 236 else
233 r = crypto_cipher_decrypt_iv(cc->tfm, out, in, length, iv); 237 r = crypto_blkcipher_decrypt_iv(&desc, out, in, length);
234 } else { 238 } else {
235 if (write) 239 if (write)
236 r = crypto_cipher_encrypt(cc->tfm, out, in, length); 240 r = crypto_blkcipher_encrypt(&desc, out, in, length);
237 else 241 else
238 r = crypto_cipher_decrypt(cc->tfm, out, in, length); 242 r = crypto_blkcipher_decrypt(&desc, out, in, length);
239 } 243 }
240 244
241 return r; 245 return r;
@@ -510,13 +514,12 @@ static void crypt_encode_key(char *hex, u8 *key, unsigned int size)
510static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) 514static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
511{ 515{
512 struct crypt_config *cc; 516 struct crypt_config *cc;
513 struct crypto_tfm *tfm; 517 struct crypto_blkcipher *tfm;
514 char *tmp; 518 char *tmp;
515 char *cipher; 519 char *cipher;
516 char *chainmode; 520 char *chainmode;
517 char *ivmode; 521 char *ivmode;
518 char *ivopts; 522 char *ivopts;
519 unsigned int crypto_flags;
520 unsigned int key_size; 523 unsigned int key_size;
521 unsigned long long tmpll; 524 unsigned long long tmpll;
522 525
@@ -556,31 +559,25 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
556 ivmode = "plain"; 559 ivmode = "plain";
557 } 560 }
558 561
559 /* Choose crypto_flags according to chainmode */ 562 if (strcmp(chainmode, "ecb") && !ivmode) {
560 if (strcmp(chainmode, "cbc") == 0) 563 ti->error = "This chaining mode requires an IV mechanism";
561 crypto_flags = CRYPTO_TFM_MODE_CBC;
562 else if (strcmp(chainmode, "ecb") == 0)
563 crypto_flags = CRYPTO_TFM_MODE_ECB;
564 else {
565 ti->error = "Unknown chaining mode";
566 goto bad1; 564 goto bad1;
567 } 565 }
568 566
569 if (crypto_flags != CRYPTO_TFM_MODE_ECB && !ivmode) { 567 if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)", chainmode,
570 ti->error = "This chaining mode requires an IV mechanism"; 568 cipher) >= CRYPTO_MAX_ALG_NAME) {
569 ti->error = "Chain mode + cipher name is too long";
571 goto bad1; 570 goto bad1;
572 } 571 }
573 572
574 tfm = crypto_alloc_tfm(cipher, crypto_flags | CRYPTO_TFM_REQ_MAY_SLEEP); 573 tfm = crypto_alloc_blkcipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);
575 if (!tfm) { 574 if (IS_ERR(tfm)) {
576 ti->error = "Error allocating crypto tfm"; 575 ti->error = "Error allocating crypto tfm";
577 goto bad1; 576 goto bad1;
578 } 577 }
579 if (crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER) {
580 ti->error = "Expected cipher algorithm";
581 goto bad2;
582 }
583 578
579 strcpy(cc->cipher, cipher);
580 strcpy(cc->chainmode, chainmode);
584 cc->tfm = tfm; 581 cc->tfm = tfm;
585 582
586 /* 583 /*
@@ -603,12 +600,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
603 cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0) 600 cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0)
604 goto bad2; 601 goto bad2;
605 602
606 if (tfm->crt_cipher.cit_decrypt_iv && tfm->crt_cipher.cit_encrypt_iv) 603 cc->iv_size = crypto_blkcipher_ivsize(tfm);
604 if (cc->iv_size)
607 /* at least a 64 bit sector number should fit in our buffer */ 605 /* at least a 64 bit sector number should fit in our buffer */
608 cc->iv_size = max(crypto_tfm_alg_ivsize(tfm), 606 cc->iv_size = max(cc->iv_size,
609 (unsigned int)(sizeof(u64) / sizeof(u8))); 607 (unsigned int)(sizeof(u64) / sizeof(u8)));
610 else { 608 else {
611 cc->iv_size = 0;
612 if (cc->iv_gen_ops) { 609 if (cc->iv_gen_ops) {
613 DMWARN("Selected cipher does not support IVs"); 610 DMWARN("Selected cipher does not support IVs");
614 if (cc->iv_gen_ops->dtr) 611 if (cc->iv_gen_ops->dtr)
@@ -629,7 +626,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
629 goto bad4; 626 goto bad4;
630 } 627 }
631 628
632 if (tfm->crt_cipher.cit_setkey(tfm, cc->key, key_size) < 0) { 629 if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) {
633 ti->error = "Error setting key"; 630 ti->error = "Error setting key";
634 goto bad5; 631 goto bad5;
635 } 632 }
@@ -675,7 +672,7 @@ bad3:
675 if (cc->iv_gen_ops && cc->iv_gen_ops->dtr) 672 if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
676 cc->iv_gen_ops->dtr(cc); 673 cc->iv_gen_ops->dtr(cc);
677bad2: 674bad2:
678 crypto_free_tfm(tfm); 675 crypto_free_blkcipher(tfm);
679bad1: 676bad1:
680 /* Must zero key material before freeing */ 677 /* Must zero key material before freeing */
681 memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8)); 678 memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
@@ -693,7 +690,7 @@ static void crypt_dtr(struct dm_target *ti)
693 kfree(cc->iv_mode); 690 kfree(cc->iv_mode);
694 if (cc->iv_gen_ops && cc->iv_gen_ops->dtr) 691 if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
695 cc->iv_gen_ops->dtr(cc); 692 cc->iv_gen_ops->dtr(cc);
696 crypto_free_tfm(cc->tfm); 693 crypto_free_blkcipher(cc->tfm);
697 dm_put_device(ti, cc->dev); 694 dm_put_device(ti, cc->dev);
698 695
699 /* Must zero key material before freeing */ 696 /* Must zero key material before freeing */
@@ -858,18 +855,9 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
858 break; 855 break;
859 856
860 case STATUSTYPE_TABLE: 857 case STATUSTYPE_TABLE:
861 cipher = crypto_tfm_alg_name(cc->tfm); 858 cipher = crypto_blkcipher_name(cc->tfm);
862 859
863 switch(cc->tfm->crt_cipher.cit_mode) { 860 chainmode = cc->chainmode;
864 case CRYPTO_TFM_MODE_CBC:
865 chainmode = "cbc";
866 break;
867 case CRYPTO_TFM_MODE_ECB:
868 chainmode = "ecb";
869 break;
870 default:
871 BUG();
872 }
873 861
874 if (cc->iv_mode) 862 if (cc->iv_mode)
875 DMEMIT("%s-%s-%s ", cipher, chainmode, cc->iv_mode); 863 DMEMIT("%s-%s-%s ", cipher, chainmode, cc->iv_mode);
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 1344ad7a4b14..717e90448fc6 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -263,6 +263,14 @@ config RFD_FTL
263 263
264 http://www.gensw.com/pages/prod/bios/rfd.htm 264 http://www.gensw.com/pages/prod/bios/rfd.htm
265 265
266config SSFDC
267 bool "NAND SSFDC (SmartMedia) read only translation layer"
268 depends on MTD
269 default n
270 help
271 This enables read only access to SmartMedia formatted NAND
272 flash. You can mount it with FAT file system.
273
266source "drivers/mtd/chips/Kconfig" 274source "drivers/mtd/chips/Kconfig"
267 275
268source "drivers/mtd/maps/Kconfig" 276source "drivers/mtd/maps/Kconfig"
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index fc9374407c2b..1e36b9aed98b 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
21obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o 21obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
22obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o 22obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_blkdevs.o 23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_blkdevs.o
24obj-$(CONFIG_SSFDC) += ssfdc.o mtd_blkdevs.o
24 25
25nftl-objs := nftlcore.o nftlmount.o 26nftl-objs := nftlcore.o nftlmount.o
26inftl-objs := inftlcore.o inftlmount.o 27inftl-objs := inftlcore.o inftlmount.o
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index a482e8922de1..702ae4cd8691 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -212,6 +212,7 @@ static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param)
212{ 212{
213 mtd->lock = cfi_atmel_lock; 213 mtd->lock = cfi_atmel_lock;
214 mtd->unlock = cfi_atmel_unlock; 214 mtd->unlock = cfi_atmel_unlock;
215 mtd->flags |= MTD_STUPID_LOCK;
215} 216}
216 217
217static struct cfi_fixup cfi_fixup_table[] = { 218static struct cfi_fixup cfi_fixup_table[] = {
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index 2c0149708739..354e1657cc26 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -4,82 +4,82 @@
4 * PMC551 PCI Mezzanine Ram Device 4 * PMC551 PCI Mezzanine Ram Device
5 * 5 *
6 * Author: 6 * Author:
7 * Mark Ferrell <mferrell@mvista.com> 7 * Mark Ferrell <mferrell@mvista.com>
8 * Copyright 1999,2000 Nortel Networks 8 * Copyright 1999,2000 Nortel Networks
9 * 9 *
10 * License: 10 * License:
11 * As part of this driver was derived from the slram.c driver it 11 * As part of this driver was derived from the slram.c driver it
12 * falls under the same license, which is GNU General Public 12 * falls under the same license, which is GNU General Public
13 * License v2 13 * License v2
14 * 14 *
15 * Description: 15 * Description:
16 * This driver is intended to support the PMC551 PCI Ram device 16 * This driver is intended to support the PMC551 PCI Ram device
17 * from Ramix Inc. The PMC551 is a PMC Mezzanine module for 17 * from Ramix Inc. The PMC551 is a PMC Mezzanine module for
18 * cPCI embedded systems. The device contains a single SROM 18 * cPCI embedded systems. The device contains a single SROM
19 * that initially programs the V370PDC chipset onboard the 19 * that initially programs the V370PDC chipset onboard the
20 * device, and various banks of DRAM/SDRAM onboard. This driver 20 * device, and various banks of DRAM/SDRAM onboard. This driver
21 * implements this PCI Ram device as an MTD (Memory Technology 21 * implements this PCI Ram device as an MTD (Memory Technology
22 * Device) so that it can be used to hold a file system, or for 22 * Device) so that it can be used to hold a file system, or for
23 * added swap space in embedded systems. Since the memory on 23 * added swap space in embedded systems. Since the memory on
24 * this board isn't as fast as main memory we do not try to hook 24 * this board isn't as fast as main memory we do not try to hook
25 * it into main memory as that would simply reduce performance 25 * it into main memory as that would simply reduce performance
26 * on the system. Using it as a block device allows us to use 26 * on the system. Using it as a block device allows us to use
27 * it as high speed swap or for a high speed disk device of some 27 * it as high speed swap or for a high speed disk device of some
28 * sort. Which becomes very useful on diskless systems in the 28 * sort. Which becomes very useful on diskless systems in the
29 * embedded market I might add. 29 * embedded market I might add.
30 * 30 *
31 * Notes: 31 * Notes:
32 * Due to what I assume is more buggy SROM, the 64M PMC551 I 32 * Due to what I assume is more buggy SROM, the 64M PMC551 I
33 * have available claims that all 4 of it's DRAM banks have 64M 33 * have available claims that all 4 of it's DRAM banks have 64M
34 * of ram configured (making a grand total of 256M onboard). 34 * of ram configured (making a grand total of 256M onboard).
35 * This is slightly annoying since the BAR0 size reflects the 35 * This is slightly annoying since the BAR0 size reflects the
36 * aperture size, not the dram size, and the V370PDC supplies no 36 * aperture size, not the dram size, and the V370PDC supplies no
37 * other method for memory size discovery. This problem is 37 * other method for memory size discovery. This problem is
38 * mostly only relevant when compiled as a module, as the 38 * mostly only relevant when compiled as a module, as the
39 * unloading of the module with an aperture size smaller then 39 * unloading of the module with an aperture size smaller then
40 * the ram will cause the driver to detect the onboard memory 40 * the ram will cause the driver to detect the onboard memory
41 * size to be equal to the aperture size when the module is 41 * size to be equal to the aperture size when the module is
42 * reloaded. Soooo, to help, the module supports an msize 42 * reloaded. Soooo, to help, the module supports an msize
43 * option to allow the specification of the onboard memory, and 43 * option to allow the specification of the onboard memory, and
44 * an asize option, to allow the specification of the aperture 44 * an asize option, to allow the specification of the aperture
45 * size. The aperture must be equal to or less then the memory 45 * size. The aperture must be equal to or less then the memory
46 * size, the driver will correct this if you screw it up. This 46 * size, the driver will correct this if you screw it up. This
47 * problem is not relevant for compiled in drivers as compiled 47 * problem is not relevant for compiled in drivers as compiled
48 * in drivers only init once. 48 * in drivers only init once.
49 * 49 *
50 * Credits: 50 * Credits:
51 * Saeed Karamooz <saeed@ramix.com> of Ramix INC. for the 51 * Saeed Karamooz <saeed@ramix.com> of Ramix INC. for the
52 * initial example code of how to initialize this device and for 52 * initial example code of how to initialize this device and for
53 * help with questions I had concerning operation of the device. 53 * help with questions I had concerning operation of the device.
54 * 54 *
55 * Most of the MTD code for this driver was originally written 55 * Most of the MTD code for this driver was originally written
56 * for the slram.o module in the MTD drivers package which 56 * for the slram.o module in the MTD drivers package which
57 * allows the mapping of system memory into an MTD device. 57 * allows the mapping of system memory into an MTD device.
58 * Since the PMC551 memory module is accessed in the same 58 * Since the PMC551 memory module is accessed in the same
59 * fashion as system memory, the slram.c code became a very nice 59 * fashion as system memory, the slram.c code became a very nice
60 * fit to the needs of this driver. All we added was PCI 60 * fit to the needs of this driver. All we added was PCI
61 * detection/initialization to the driver and automatically figure 61 * detection/initialization to the driver and automatically figure
62 * out the size via the PCI detection.o, later changes by Corey 62 * out the size via the PCI detection.o, later changes by Corey
63 * Minyard set up the card to utilize a 1M sliding apature. 63 * Minyard set up the card to utilize a 1M sliding apature.
64 * 64 *
65 * Corey Minyard <minyard@nortelnetworks.com> 65 * Corey Minyard <minyard@nortelnetworks.com>
66 * * Modified driver to utilize a sliding aperture instead of 66 * * Modified driver to utilize a sliding aperture instead of
67 * mapping all memory into kernel space which turned out to 67 * mapping all memory into kernel space which turned out to
68 * be very wasteful. 68 * be very wasteful.
69 * * Located a bug in the SROM's initialization sequence that 69 * * Located a bug in the SROM's initialization sequence that
70 * made the memory unusable, added a fix to code to touch up 70 * made the memory unusable, added a fix to code to touch up
71 * the DRAM some. 71 * the DRAM some.
72 * 72 *
73 * Bugs/FIXME's: 73 * Bugs/FIXME's:
74 * * MUST fix the init function to not spin on a register 74 * * MUST fix the init function to not spin on a register
75 * waiting for it to set .. this does not safely handle busted 75 * waiting for it to set .. this does not safely handle busted
76 * devices that never reset the register correctly which will 76 * devices that never reset the register correctly which will
77 * cause the system to hang w/ a reboot being the only chance at 77 * cause the system to hang w/ a reboot being the only chance at
78 * recover. [sort of fixed, could be better] 78 * recover. [sort of fixed, could be better]
79 * * Add I2C handling of the SROM so we can read the SROM's information 79 * * Add I2C handling of the SROM so we can read the SROM's information
80 * about the aperture size. This should always accurately reflect the 80 * about the aperture size. This should always accurately reflect the
81 * onboard memory size. 81 * onboard memory size.
82 * * Comb the init routine. It's still a bit cludgy on a few things. 82 * * Comb the init routine. It's still a bit cludgy on a few things.
83 */ 83 */
84 84
85#include <linux/kernel.h> 85#include <linux/kernel.h>
@@ -105,74 +105,77 @@
105 105
106static struct mtd_info *pmc551list; 106static struct mtd_info *pmc551list;
107 107
108static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr) 108static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
109{ 109{
110 struct mypriv *priv = mtd->priv; 110 struct mypriv *priv = mtd->priv;
111 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 111 u32 soff_hi, soff_lo; /* start address offset hi/lo */
112 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 112 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
113 unsigned long end; 113 unsigned long end;
114 u_char *ptr; 114 u_char *ptr;
115 size_t retlen; 115 size_t retlen;
116 116
117#ifdef CONFIG_MTD_PMC551_DEBUG 117#ifdef CONFIG_MTD_PMC551_DEBUG
118 printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len); 118 printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr,
119 (long)instr->len);
119#endif 120#endif
120 121
121 end = instr->addr + instr->len - 1; 122 end = instr->addr + instr->len - 1;
122 123
123 /* Is it past the end? */ 124 /* Is it past the end? */
124 if ( end > mtd->size ) { 125 if (end > mtd->size) {
125#ifdef CONFIG_MTD_PMC551_DEBUG 126#ifdef CONFIG_MTD_PMC551_DEBUG
126 printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n", (long)end, (long)mtd->size); 127 printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n",
128 (long)end, (long)mtd->size);
127#endif 129#endif
128 return -EINVAL; 130 return -EINVAL;
129 } 131 }
130 132
131 eoff_hi = end & ~(priv->asize - 1); 133 eoff_hi = end & ~(priv->asize - 1);
132 soff_hi = instr->addr & ~(priv->asize - 1); 134 soff_hi = instr->addr & ~(priv->asize - 1);
133 eoff_lo = end & (priv->asize - 1); 135 eoff_lo = end & (priv->asize - 1);
134 soff_lo = instr->addr & (priv->asize - 1); 136 soff_lo = instr->addr & (priv->asize - 1);
135 137
136 pmc551_point (mtd, instr->addr, instr->len, &retlen, &ptr); 138 pmc551_point(mtd, instr->addr, instr->len, &retlen, &ptr);
137 139
138 if ( soff_hi == eoff_hi || mtd->size == priv->asize) { 140 if (soff_hi == eoff_hi || mtd->size == priv->asize) {
139 /* The whole thing fits within one access, so just one shot 141 /* The whole thing fits within one access, so just one shot
140 will do it. */ 142 will do it. */
141 memset(ptr, 0xff, instr->len); 143 memset(ptr, 0xff, instr->len);
142 } else { 144 } else {
143 /* We have to do multiple writes to get all the data 145 /* We have to do multiple writes to get all the data
144 written. */ 146 written. */
145 while (soff_hi != eoff_hi) { 147 while (soff_hi != eoff_hi) {
146#ifdef CONFIG_MTD_PMC551_DEBUG 148#ifdef CONFIG_MTD_PMC551_DEBUG
147 printk( KERN_DEBUG "pmc551_erase() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 149 printk(KERN_DEBUG "pmc551_erase() soff_hi: %ld, "
150 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
148#endif 151#endif
149 memset(ptr, 0xff, priv->asize); 152 memset(ptr, 0xff, priv->asize);
150 if (soff_hi + priv->asize >= mtd->size) { 153 if (soff_hi + priv->asize >= mtd->size) {
151 goto out; 154 goto out;
152 } 155 }
153 soff_hi += priv->asize; 156 soff_hi += priv->asize;
154 pmc551_point (mtd,(priv->base_map0|soff_hi), 157 pmc551_point(mtd, (priv->base_map0 | soff_hi),
155 priv->asize, &retlen, &ptr); 158 priv->asize, &retlen, &ptr);
156 } 159 }
157 memset (ptr, 0xff, eoff_lo); 160 memset(ptr, 0xff, eoff_lo);
158 } 161 }
159 162
160out: 163 out:
161 instr->state = MTD_ERASE_DONE; 164 instr->state = MTD_ERASE_DONE;
162#ifdef CONFIG_MTD_PMC551_DEBUG 165#ifdef CONFIG_MTD_PMC551_DEBUG
163 printk(KERN_DEBUG "pmc551_erase() done\n"); 166 printk(KERN_DEBUG "pmc551_erase() done\n");
164#endif 167#endif
165 168
166 mtd_erase_callback(instr); 169 mtd_erase_callback(instr);
167 return 0; 170 return 0;
168} 171}
169 172
170 173static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
171static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) 174 size_t * retlen, u_char ** mtdbuf)
172{ 175{
173 struct mypriv *priv = mtd->priv; 176 struct mypriv *priv = mtd->priv;
174 u32 soff_hi; 177 u32 soff_hi;
175 u32 soff_lo; 178 u32 soff_lo;
176 179
177#ifdef CONFIG_MTD_PMC551_DEBUG 180#ifdef CONFIG_MTD_PMC551_DEBUG
178 printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len); 181 printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len);
@@ -180,18 +183,19 @@ static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *
180 183
181 if (from + len > mtd->size) { 184 if (from + len > mtd->size) {
182#ifdef CONFIG_MTD_PMC551_DEBUG 185#ifdef CONFIG_MTD_PMC551_DEBUG
183 printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n", (long)from+len, (long)mtd->size); 186 printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n",
187 (long)from + len, (long)mtd->size);
184#endif 188#endif
185 return -EINVAL; 189 return -EINVAL;
186 } 190 }
187 191
188 soff_hi = from & ~(priv->asize - 1); 192 soff_hi = from & ~(priv->asize - 1);
189 soff_lo = from & (priv->asize - 1); 193 soff_lo = from & (priv->asize - 1);
190 194
191 /* Cheap hack optimization */ 195 /* Cheap hack optimization */
192 if( priv->curr_map0 != from ) { 196 if (priv->curr_map0 != from) {
193 pci_write_config_dword ( priv->dev, PMC551_PCI_MEM_MAP0, 197 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0,
194 (priv->base_map0 | soff_hi) ); 198 (priv->base_map0 | soff_hi));
195 priv->curr_map0 = soff_hi; 199 priv->curr_map0 = soff_hi;
196 } 200 }
197 201
@@ -200,137 +204,144 @@ static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *
200 return 0; 204 return 0;
201} 205}
202 206
203 207static void pmc551_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
204static void pmc551_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 208 size_t len)
205{ 209{
206#ifdef CONFIG_MTD_PMC551_DEBUG 210#ifdef CONFIG_MTD_PMC551_DEBUG
207 printk(KERN_DEBUG "pmc551_unpoint()\n"); 211 printk(KERN_DEBUG "pmc551_unpoint()\n");
208#endif 212#endif
209} 213}
210 214
211 215static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
212static int pmc551_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) 216 size_t * retlen, u_char * buf)
213{ 217{
214 struct mypriv *priv = mtd->priv; 218 struct mypriv *priv = mtd->priv;
215 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 219 u32 soff_hi, soff_lo; /* start address offset hi/lo */
216 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 220 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
217 unsigned long end; 221 unsigned long end;
218 u_char *ptr; 222 u_char *ptr;
219 u_char *copyto = buf; 223 u_char *copyto = buf;
220 224
221#ifdef CONFIG_MTD_PMC551_DEBUG 225#ifdef CONFIG_MTD_PMC551_DEBUG
222 printk(KERN_DEBUG "pmc551_read(pos:%ld, len:%ld) asize: %ld\n", (long)from, (long)len, (long)priv->asize); 226 printk(KERN_DEBUG "pmc551_read(pos:%ld, len:%ld) asize: %ld\n",
227 (long)from, (long)len, (long)priv->asize);
223#endif 228#endif
224 229
225 end = from + len - 1; 230 end = from + len - 1;
226 231
227 /* Is it past the end? */ 232 /* Is it past the end? */
228 if (end > mtd->size) { 233 if (end > mtd->size) {
229#ifdef CONFIG_MTD_PMC551_DEBUG 234#ifdef CONFIG_MTD_PMC551_DEBUG
230 printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n", (long) end, (long)mtd->size); 235 printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n",
236 (long)end, (long)mtd->size);
231#endif 237#endif
232 return -EINVAL; 238 return -EINVAL;
233 } 239 }
234 240
235 soff_hi = from & ~(priv->asize - 1); 241 soff_hi = from & ~(priv->asize - 1);
236 eoff_hi = end & ~(priv->asize - 1); 242 eoff_hi = end & ~(priv->asize - 1);
237 soff_lo = from & (priv->asize - 1); 243 soff_lo = from & (priv->asize - 1);
238 eoff_lo = end & (priv->asize - 1); 244 eoff_lo = end & (priv->asize - 1);
239 245
240 pmc551_point (mtd, from, len, retlen, &ptr); 246 pmc551_point(mtd, from, len, retlen, &ptr);
241 247
242 if (soff_hi == eoff_hi) { 248 if (soff_hi == eoff_hi) {
243 /* The whole thing fits within one access, so just one shot 249 /* The whole thing fits within one access, so just one shot
244 will do it. */ 250 will do it. */
245 memcpy(copyto, ptr, len); 251 memcpy(copyto, ptr, len);
246 copyto += len; 252 copyto += len;
247 } else { 253 } else {
248 /* We have to do multiple writes to get all the data 254 /* We have to do multiple writes to get all the data
249 written. */ 255 written. */
250 while (soff_hi != eoff_hi) { 256 while (soff_hi != eoff_hi) {
251#ifdef CONFIG_MTD_PMC551_DEBUG 257#ifdef CONFIG_MTD_PMC551_DEBUG
252 printk( KERN_DEBUG "pmc551_read() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 258 printk(KERN_DEBUG "pmc551_read() soff_hi: %ld, "
259 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
253#endif 260#endif
254 memcpy(copyto, ptr, priv->asize); 261 memcpy(copyto, ptr, priv->asize);
255 copyto += priv->asize; 262 copyto += priv->asize;
256 if (soff_hi + priv->asize >= mtd->size) { 263 if (soff_hi + priv->asize >= mtd->size) {
257 goto out; 264 goto out;
258 } 265 }
259 soff_hi += priv->asize; 266 soff_hi += priv->asize;
260 pmc551_point (mtd, soff_hi, priv->asize, retlen, &ptr); 267 pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
261 } 268 }
262 memcpy(copyto, ptr, eoff_lo); 269 memcpy(copyto, ptr, eoff_lo);
263 copyto += eoff_lo; 270 copyto += eoff_lo;
264 } 271 }
265 272
266out: 273 out:
267#ifdef CONFIG_MTD_PMC551_DEBUG 274#ifdef CONFIG_MTD_PMC551_DEBUG
268 printk(KERN_DEBUG "pmc551_read() done\n"); 275 printk(KERN_DEBUG "pmc551_read() done\n");
269#endif 276#endif
270 *retlen = copyto - buf; 277 *retlen = copyto - buf;
271 return 0; 278 return 0;
272} 279}
273 280
274static int pmc551_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) 281static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
282 size_t * retlen, const u_char * buf)
275{ 283{
276 struct mypriv *priv = mtd->priv; 284 struct mypriv *priv = mtd->priv;
277 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 285 u32 soff_hi, soff_lo; /* start address offset hi/lo */
278 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 286 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
279 unsigned long end; 287 unsigned long end;
280 u_char *ptr; 288 u_char *ptr;
281 const u_char *copyfrom = buf; 289 const u_char *copyfrom = buf;
282
283 290
284#ifdef CONFIG_MTD_PMC551_DEBUG 291#ifdef CONFIG_MTD_PMC551_DEBUG
285 printk(KERN_DEBUG "pmc551_write(pos:%ld, len:%ld) asize:%ld\n", (long)to, (long)len, (long)priv->asize); 292 printk(KERN_DEBUG "pmc551_write(pos:%ld, len:%ld) asize:%ld\n",
293 (long)to, (long)len, (long)priv->asize);
286#endif 294#endif
287 295
288 end = to + len - 1; 296 end = to + len - 1;
289 /* Is it past the end? or did the u32 wrap? */ 297 /* Is it past the end? or did the u32 wrap? */
290 if (end > mtd->size ) { 298 if (end > mtd->size) {
291#ifdef CONFIG_MTD_PMC551_DEBUG 299#ifdef CONFIG_MTD_PMC551_DEBUG
292 printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, size: %ld, to: %ld)\n", (long) end, (long)mtd->size, (long)to); 300 printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, "
301 "size: %ld, to: %ld)\n", (long)end, (long)mtd->size,
302 (long)to);
293#endif 303#endif
294 return -EINVAL; 304 return -EINVAL;
295 } 305 }
296 306
297 soff_hi = to & ~(priv->asize - 1); 307 soff_hi = to & ~(priv->asize - 1);
298 eoff_hi = end & ~(priv->asize - 1); 308 eoff_hi = end & ~(priv->asize - 1);
299 soff_lo = to & (priv->asize - 1); 309 soff_lo = to & (priv->asize - 1);
300 eoff_lo = end & (priv->asize - 1); 310 eoff_lo = end & (priv->asize - 1);
301 311
302 pmc551_point (mtd, to, len, retlen, &ptr); 312 pmc551_point(mtd, to, len, retlen, &ptr);
303 313
304 if (soff_hi == eoff_hi) { 314 if (soff_hi == eoff_hi) {
305 /* The whole thing fits within one access, so just one shot 315 /* The whole thing fits within one access, so just one shot
306 will do it. */ 316 will do it. */
307 memcpy(ptr, copyfrom, len); 317 memcpy(ptr, copyfrom, len);
308 copyfrom += len; 318 copyfrom += len;
309 } else { 319 } else {
310 /* We have to do multiple writes to get all the data 320 /* We have to do multiple writes to get all the data
311 written. */ 321 written. */
312 while (soff_hi != eoff_hi) { 322 while (soff_hi != eoff_hi) {
313#ifdef CONFIG_MTD_PMC551_DEBUG 323#ifdef CONFIG_MTD_PMC551_DEBUG
314 printk( KERN_DEBUG "pmc551_write() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 324 printk(KERN_DEBUG "pmc551_write() soff_hi: %ld, "
325 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
315#endif 326#endif
316 memcpy(ptr, copyfrom, priv->asize); 327 memcpy(ptr, copyfrom, priv->asize);
317 copyfrom += priv->asize; 328 copyfrom += priv->asize;
318 if (soff_hi >= mtd->size) { 329 if (soff_hi >= mtd->size) {
319 goto out; 330 goto out;
320 } 331 }
321 soff_hi += priv->asize; 332 soff_hi += priv->asize;
322 pmc551_point (mtd, soff_hi, priv->asize, retlen, &ptr); 333 pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
323 } 334 }
324 memcpy(ptr, copyfrom, eoff_lo); 335 memcpy(ptr, copyfrom, eoff_lo);
325 copyfrom += eoff_lo; 336 copyfrom += eoff_lo;
326 } 337 }
327 338
328out: 339 out:
329#ifdef CONFIG_MTD_PMC551_DEBUG 340#ifdef CONFIG_MTD_PMC551_DEBUG
330 printk(KERN_DEBUG "pmc551_write() done\n"); 341 printk(KERN_DEBUG "pmc551_write() done\n");
331#endif 342#endif
332 *retlen = copyfrom - buf; 343 *retlen = copyfrom - buf;
333 return 0; 344 return 0;
334} 345}
335 346
336/* 347/*
@@ -345,58 +356,58 @@ out:
345 * mechanism 356 * mechanism
346 * returns the size of the memory region found. 357 * returns the size of the memory region found.
347 */ 358 */
348static u32 fixup_pmc551 (struct pci_dev *dev) 359static u32 fixup_pmc551(struct pci_dev *dev)
349{ 360{
350#ifdef CONFIG_MTD_PMC551_BUGFIX 361#ifdef CONFIG_MTD_PMC551_BUGFIX
351 u32 dram_data; 362 u32 dram_data;
352#endif 363#endif
353 u32 size, dcmd, cfg, dtmp; 364 u32 size, dcmd, cfg, dtmp;
354 u16 cmd, tmp, i; 365 u16 cmd, tmp, i;
355 u8 bcmd, counter; 366 u8 bcmd, counter;
356 367
357 /* Sanity Check */ 368 /* Sanity Check */
358 if(!dev) { 369 if (!dev) {
359 return -ENODEV; 370 return -ENODEV;
360 } 371 }
361 372
362 /* 373 /*
363 * Attempt to reset the card 374 * Attempt to reset the card
364 * FIXME: Stop Spinning registers 375 * FIXME: Stop Spinning registers
365 */ 376 */
366 counter=0; 377 counter = 0;
367 /* unlock registers */ 378 /* unlock registers */
368 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5 ); 379 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5);
369 /* read in old data */ 380 /* read in old data */
370 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd ); 381 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd);
371 /* bang the reset line up and down for a few */ 382 /* bang the reset line up and down for a few */
372 for(i=0;i<10;i++) { 383 for (i = 0; i < 10; i++) {
373 counter=0; 384 counter = 0;
374 bcmd &= ~0x80; 385 bcmd &= ~0x80;
375 while(counter++ < 100) { 386 while (counter++ < 100) {
376 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 387 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
377 } 388 }
378 counter=0; 389 counter = 0;
379 bcmd |= 0x80; 390 bcmd |= 0x80;
380 while(counter++ < 100) { 391 while (counter++ < 100) {
381 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 392 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
382 } 393 }
383 } 394 }
384 bcmd |= (0x40|0x20); 395 bcmd |= (0x40 | 0x20);
385 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 396 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
386 397
387 /* 398 /*
388 * Take care and turn off the memory on the device while we 399 * Take care and turn off the memory on the device while we
389 * tweak the configurations 400 * tweak the configurations
390 */ 401 */
391 pci_read_config_word(dev, PCI_COMMAND, &cmd); 402 pci_read_config_word(dev, PCI_COMMAND, &cmd);
392 tmp = cmd & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY); 403 tmp = cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
393 pci_write_config_word(dev, PCI_COMMAND, tmp); 404 pci_write_config_word(dev, PCI_COMMAND, tmp);
394 405
395 /* 406 /*
396 * Disable existing aperture before probing memory size 407 * Disable existing aperture before probing memory size
397 */ 408 */
398 pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd); 409 pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd);
399 dtmp=(dcmd|PMC551_PCI_MEM_MAP_ENABLE|PMC551_PCI_MEM_MAP_REG_EN); 410 dtmp = (dcmd | PMC551_PCI_MEM_MAP_ENABLE | PMC551_PCI_MEM_MAP_REG_EN);
400 pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp); 411 pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp);
401 /* 412 /*
402 * Grab old BAR0 config so that we can figure out memory size 413 * Grab old BAR0 config so that we can figure out memory size
@@ -407,220 +418,230 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
407 * then write all 1's to the memory space, read back the result into 418 * then write all 1's to the memory space, read back the result into
408 * "size", and then write back all the old config. 419 * "size", and then write back all the old config.
409 */ 420 */
410 pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &cfg ); 421 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &cfg);
411#ifndef CONFIG_MTD_PMC551_BUGFIX 422#ifndef CONFIG_MTD_PMC551_BUGFIX
412 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, ~0 ); 423 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ~0);
413 pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &size ); 424 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &size);
414 size = (size&PCI_BASE_ADDRESS_MEM_MASK); 425 size = (size & PCI_BASE_ADDRESS_MEM_MASK);
415 size &= ~(size-1); 426 size &= ~(size - 1);
416 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg ); 427 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, cfg);
417#else 428#else
418 /* 429 /*
419 * Get the size of the memory by reading all the DRAM size values 430 * Get the size of the memory by reading all the DRAM size values
420 * and adding them up. 431 * and adding them up.
421 * 432 *
422 * KLUDGE ALERT: the boards we are using have invalid column and 433 * KLUDGE ALERT: the boards we are using have invalid column and
423 * row mux values. We fix them here, but this will break other 434 * row mux values. We fix them here, but this will break other
424 * memory configurations. 435 * memory configurations.
425 */ 436 */
426 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data); 437 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data);
427 size = PMC551_DRAM_BLK_GET_SIZE(dram_data); 438 size = PMC551_DRAM_BLK_GET_SIZE(dram_data);
428 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 439 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
429 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 440 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
430 pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data); 441 pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data);
431 442
432 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data); 443 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data);
433 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 444 size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
434 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 445 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
435 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 446 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
436 pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data); 447 pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data);
437 448
438 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data); 449 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data);
439 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 450 size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
440 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 451 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
441 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 452 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
442 pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data); 453 pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data);
443 454
444 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data); 455 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data);
445 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 456 size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
446 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 457 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
447 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 458 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
448 pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data); 459 pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data);
449 460
450 /* 461 /*
451 * Oops .. something went wrong 462 * Oops .. something went wrong
452 */ 463 */
453 if( (size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) { 464 if ((size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) {
454 return -ENODEV; 465 return -ENODEV;
455 } 466 }
456#endif /* CONFIG_MTD_PMC551_BUGFIX */ 467#endif /* CONFIG_MTD_PMC551_BUGFIX */
457 468
458 if ((cfg&PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) { 469 if ((cfg & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
459 return -ENODEV; 470 return -ENODEV;
460 } 471 }
461 472
462 /* 473 /*
463 * Precharge Dram 474 * Precharge Dram
464 */ 475 */
465 pci_write_config_word( dev, PMC551_SDRAM_MA, 0x0400 ); 476 pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0400);
466 pci_write_config_word( dev, PMC551_SDRAM_CMD, 0x00bf ); 477 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x00bf);
467 478
468 /* 479 /*
469 * Wait until command has gone through 480 * Wait until command has gone through
470 * FIXME: register spinning issue 481 * FIXME: register spinning issue
471 */ 482 */
472 do { pci_read_config_word( dev, PMC551_SDRAM_CMD, &cmd ); 483 do {
473 if(counter++ > 100)break; 484 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
474 } while ( (PCI_COMMAND_IO) & cmd ); 485 if (counter++ > 100)
475 486 break;
476 /* 487 } while ((PCI_COMMAND_IO) & cmd);
488
489 /*
477 * Turn on auto refresh 490 * Turn on auto refresh
478 * The loop is taken directly from Ramix's example code. I assume that 491 * The loop is taken directly from Ramix's example code. I assume that
479 * this must be held high for some duration of time, but I can find no 492 * this must be held high for some duration of time, but I can find no
480 * documentation refrencing the reasons why. 493 * documentation refrencing the reasons why.
481 */ 494 */
482 for ( i = 1; i<=8 ; i++) { 495 for (i = 1; i <= 8; i++) {
483 pci_write_config_word (dev, PMC551_SDRAM_CMD, 0x0df); 496 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0df);
484 497
485 /* 498 /*
486 * Make certain command has gone through 499 * Make certain command has gone through
487 * FIXME: register spinning issue 500 * FIXME: register spinning issue
488 */ 501 */
489 counter=0; 502 counter = 0;
490 do { pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd); 503 do {
491 if(counter++ > 100)break; 504 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
492 } while ( (PCI_COMMAND_IO) & cmd ); 505 if (counter++ > 100)
493 } 506 break;
494 507 } while ((PCI_COMMAND_IO) & cmd);
495 pci_write_config_word ( dev, PMC551_SDRAM_MA, 0x0020); 508 }
496 pci_write_config_word ( dev, PMC551_SDRAM_CMD, 0x0ff); 509
497 510 pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0020);
498 /* 511 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0ff);
499 * Wait until command completes 512
500 * FIXME: register spinning issue 513 /*
501 */ 514 * Wait until command completes
502 counter=0; 515 * FIXME: register spinning issue
503 do { pci_read_config_word ( dev, PMC551_SDRAM_CMD, &cmd); 516 */
504 if(counter++ > 100)break; 517 counter = 0;
505 } while ( (PCI_COMMAND_IO) & cmd ); 518 do {
506 519 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
507 pci_read_config_dword ( dev, PMC551_DRAM_CFG, &dcmd); 520 if (counter++ > 100)
508 dcmd |= 0x02000000; 521 break;
509 pci_write_config_dword ( dev, PMC551_DRAM_CFG, dcmd); 522 } while ((PCI_COMMAND_IO) & cmd);
510 523
511 /* 524 pci_read_config_dword(dev, PMC551_DRAM_CFG, &dcmd);
512 * Check to make certain fast back-to-back, if not 525 dcmd |= 0x02000000;
513 * then set it so 526 pci_write_config_dword(dev, PMC551_DRAM_CFG, dcmd);
514 */ 527
515 pci_read_config_word( dev, PCI_STATUS, &cmd); 528 /*
516 if((cmd&PCI_COMMAND_FAST_BACK) == 0) { 529 * Check to make certain fast back-to-back, if not
517 cmd |= PCI_COMMAND_FAST_BACK; 530 * then set it so
518 pci_write_config_word( dev, PCI_STATUS, cmd); 531 */
519 } 532 pci_read_config_word(dev, PCI_STATUS, &cmd);
520 533 if ((cmd & PCI_COMMAND_FAST_BACK) == 0) {
521 /* 534 cmd |= PCI_COMMAND_FAST_BACK;
522 * Check to make certain the DEVSEL is set correctly, this device 535 pci_write_config_word(dev, PCI_STATUS, cmd);
523 * has a tendancy to assert DEVSEL and TRDY when a write is performed 536 }
524 * to the memory when memory is read-only 537
525 */ 538 /*
526 if((cmd&PCI_STATUS_DEVSEL_MASK) != 0x0) { 539 * Check to make certain the DEVSEL is set correctly, this device
527 cmd &= ~PCI_STATUS_DEVSEL_MASK; 540 * has a tendancy to assert DEVSEL and TRDY when a write is performed
528 pci_write_config_word( dev, PCI_STATUS, cmd ); 541 * to the memory when memory is read-only
529 } 542 */
530 /* 543 if ((cmd & PCI_STATUS_DEVSEL_MASK) != 0x0) {
531 * Set to be prefetchable and put everything back based on old cfg. 544 cmd &= ~PCI_STATUS_DEVSEL_MASK;
545 pci_write_config_word(dev, PCI_STATUS, cmd);
546 }
547 /*
548 * Set to be prefetchable and put everything back based on old cfg.
532 * it's possible that the reset of the V370PDC nuked the original 549 * it's possible that the reset of the V370PDC nuked the original
533 * setup 550 * setup
534 */ 551 */
552 /*
553 cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH;
554 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
555 */
556
535 /* 557 /*
536 cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH; 558 * Turn PCI memory and I/O bus access back on
537 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg ); 559 */
538 */ 560 pci_write_config_word(dev, PCI_COMMAND,
539 561 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
540 /*
541 * Turn PCI memory and I/O bus access back on
542 */
543 pci_write_config_word( dev, PCI_COMMAND,
544 PCI_COMMAND_MEMORY | PCI_COMMAND_IO );
545#ifdef CONFIG_MTD_PMC551_DEBUG 562#ifdef CONFIG_MTD_PMC551_DEBUG
546 /* 563 /*
547 * Some screen fun 564 * Some screen fun
548 */ 565 */
549 printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%llx\n", 566 printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at "
550 (size<1024)?size:(size<1048576)?size>>10:size>>20, 567 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ?
551 (size<1024)?'B':(size<1048576)?'K':'M', 568 size >> 10 : size >> 20,
552 size, ((dcmd&(0x1<<3)) == 0)?"non-":"", 569 (size < 1024) ? 'B' : (size < 1048576) ? 'K' : 'M', size,
553 (unsigned long long)((dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK)); 570 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "",
554 571 (unsigned long long)pci_resource_start(dev, 0));
555 /* 572
556 * Check to see the state of the memory 573 /*
557 */ 574 * Check to see the state of the memory
558 pci_read_config_dword( dev, PMC551_DRAM_BLK0, &dcmd ); 575 */
559 printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n" 576 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dcmd);
560 "pmc551: DRAM_BLK0 Size: %d at %d\n" 577 printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n"
561 "pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n", 578 "pmc551: DRAM_BLK0 Size: %d at %d\n"
562 (((0x1<<1)&dcmd) == 0)?"RW":"RO", 579 "pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n",
563 (((0x1<<0)&dcmd) == 0)?"Off":"On", 580 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
564 PMC551_DRAM_BLK_GET_SIZE(dcmd), 581 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
565 ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) ); 582 PMC551_DRAM_BLK_GET_SIZE(dcmd),
566 583 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
567 pci_read_config_dword( dev, PMC551_DRAM_BLK1, &dcmd ); 584 ((dcmd >> 9) & 0xF));
568 printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n" 585
569 "pmc551: DRAM_BLK1 Size: %d at %d\n" 586 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dcmd);
570 "pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n", 587 printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n"
571 (((0x1<<1)&dcmd) == 0)?"RW":"RO", 588 "pmc551: DRAM_BLK1 Size: %d at %d\n"
572 (((0x1<<0)&dcmd) == 0)?"Off":"On", 589 "pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n",
573 PMC551_DRAM_BLK_GET_SIZE(dcmd), 590 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
574 ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) ); 591 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
575 592 PMC551_DRAM_BLK_GET_SIZE(dcmd),
576 pci_read_config_dword( dev, PMC551_DRAM_BLK2, &dcmd ); 593 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
577 printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n" 594 ((dcmd >> 9) & 0xF));
578 "pmc551: DRAM_BLK2 Size: %d at %d\n" 595
579 "pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n", 596 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dcmd);
580 (((0x1<<1)&dcmd) == 0)?"RW":"RO", 597 printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n"
581 (((0x1<<0)&dcmd) == 0)?"Off":"On", 598 "pmc551: DRAM_BLK2 Size: %d at %d\n"
582 PMC551_DRAM_BLK_GET_SIZE(dcmd), 599 "pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n",
583 ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) ); 600 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
584 601 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
585 pci_read_config_dword( dev, PMC551_DRAM_BLK3, &dcmd ); 602 PMC551_DRAM_BLK_GET_SIZE(dcmd),
586 printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n" 603 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
587 "pmc551: DRAM_BLK3 Size: %d at %d\n" 604 ((dcmd >> 9) & 0xF));
588 "pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n", 605
589 (((0x1<<1)&dcmd) == 0)?"RW":"RO", 606 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dcmd);
590 (((0x1<<0)&dcmd) == 0)?"Off":"On", 607 printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n"
591 PMC551_DRAM_BLK_GET_SIZE(dcmd), 608 "pmc551: DRAM_BLK3 Size: %d at %d\n"
592 ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) ); 609 "pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n",
593 610 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
594 pci_read_config_word( dev, PCI_COMMAND, &cmd ); 611 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
595 printk( KERN_DEBUG "pmc551: Memory Access %s\n", 612 PMC551_DRAM_BLK_GET_SIZE(dcmd),
596 (((0x1<<1)&cmd) == 0)?"off":"on" ); 613 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
597 printk( KERN_DEBUG "pmc551: I/O Access %s\n", 614 ((dcmd >> 9) & 0xF));
598 (((0x1<<0)&cmd) == 0)?"off":"on" ); 615
599 616 pci_read_config_word(dev, PCI_COMMAND, &cmd);
600 pci_read_config_word( dev, PCI_STATUS, &cmd ); 617 printk(KERN_DEBUG "pmc551: Memory Access %s\n",
601 printk( KERN_DEBUG "pmc551: Devsel %s\n", 618 (((0x1 << 1) & cmd) == 0) ? "off" : "on");
602 ((PCI_STATUS_DEVSEL_MASK&cmd)==0x000)?"Fast": 619 printk(KERN_DEBUG "pmc551: I/O Access %s\n",
603 ((PCI_STATUS_DEVSEL_MASK&cmd)==0x200)?"Medium": 620 (((0x1 << 0) & cmd) == 0) ? "off" : "on");
604 ((PCI_STATUS_DEVSEL_MASK&cmd)==0x400)?"Slow":"Invalid" ); 621
605 622 pci_read_config_word(dev, PCI_STATUS, &cmd);
606 printk( KERN_DEBUG "pmc551: %sFast Back-to-Back\n", 623 printk(KERN_DEBUG "pmc551: Devsel %s\n",
607 ((PCI_COMMAND_FAST_BACK&cmd) == 0)?"Not ":"" ); 624 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x000) ? "Fast" :
608 625 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x200) ? "Medium" :
609 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd ); 626 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x400) ? "Slow" : "Invalid");
610 printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n" 627
611 "pmc551: System Control Register is %slocked to PCI access\n" 628 printk(KERN_DEBUG "pmc551: %sFast Back-to-Back\n",
612 "pmc551: System Control Register is %slocked to EEPROM access\n", 629 ((PCI_COMMAND_FAST_BACK & cmd) == 0) ? "Not " : "");
613 (bcmd&0x1)?"software":"hardware", 630
614 (bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un"); 631 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd);
632 printk(KERN_DEBUG "pmc551: EEPROM is under %s control\n"
633 "pmc551: System Control Register is %slocked to PCI access\n"
634 "pmc551: System Control Register is %slocked to EEPROM access\n",
635 (bcmd & 0x1) ? "software" : "hardware",
636 (bcmd & 0x20) ? "" : "un", (bcmd & 0x40) ? "" : "un");
615#endif 637#endif
616 return size; 638 return size;
617} 639}
618 640
619/* 641/*
620 * Kernel version specific module stuffages 642 * Kernel version specific module stuffages
621 */ 643 */
622 644
623
624MODULE_LICENSE("GPL"); 645MODULE_LICENSE("GPL");
625MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>"); 646MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>");
626MODULE_DESCRIPTION(PMC551_VERSION); 647MODULE_DESCRIPTION(PMC551_VERSION);
@@ -628,11 +649,11 @@ MODULE_DESCRIPTION(PMC551_VERSION);
628/* 649/*
629 * Stuff these outside the ifdef so as to not bust compiled in driver support 650 * Stuff these outside the ifdef so as to not bust compiled in driver support
630 */ 651 */
631static int msize=0; 652static int msize = 0;
632#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE) 653#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
633static int asize=CONFIG_MTD_PMC551_APERTURE_SIZE 654static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE
634#else 655#else
635static int asize=0; 656static int asize = 0;
636#endif 657#endif
637 658
638module_param(msize, int, 0); 659module_param(msize, int, 0);
@@ -645,164 +666,174 @@ MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
645 */ 666 */
646static int __init init_pmc551(void) 667static int __init init_pmc551(void)
647{ 668{
648 struct pci_dev *PCI_Device = NULL; 669 struct pci_dev *PCI_Device = NULL;
649 struct mypriv *priv; 670 struct mypriv *priv;
650 int count, found=0; 671 int count, found = 0;
651 struct mtd_info *mtd; 672 struct mtd_info *mtd;
652 u32 length = 0; 673 u32 length = 0;
653 674
654 if(msize) { 675 if (msize) {
655 msize = (1 << (ffs(msize) - 1))<<20; 676 msize = (1 << (ffs(msize) - 1)) << 20;
656 if (msize > (1<<30)) { 677 if (msize > (1 << 30)) {
657 printk(KERN_NOTICE "pmc551: Invalid memory size [%d]\n", msize); 678 printk(KERN_NOTICE "pmc551: Invalid memory size [%d]\n",
679 msize);
658 return -EINVAL; 680 return -EINVAL;
659 } 681 }
660 } 682 }
661 683
662 if(asize) { 684 if (asize) {
663 asize = (1 << (ffs(asize) - 1))<<20; 685 asize = (1 << (ffs(asize) - 1)) << 20;
664 if (asize > (1<<30) ) { 686 if (asize > (1 << 30)) {
665 printk(KERN_NOTICE "pmc551: Invalid aperture size [%d]\n", asize); 687 printk(KERN_NOTICE "pmc551: Invalid aperture size "
688 "[%d]\n", asize);
666 return -EINVAL; 689 return -EINVAL;
667 } 690 }
668 } 691 }
669 692
670 printk(KERN_INFO PMC551_VERSION); 693 printk(KERN_INFO PMC551_VERSION);
671 694
672 /* 695 /*
673 * PCU-bus chipset probe. 696 * PCU-bus chipset probe.
674 */ 697 */
675 for( count = 0; count < MAX_MTD_DEVICES; count++ ) { 698 for (count = 0; count < MAX_MTD_DEVICES; count++) {
676 699
677 if ((PCI_Device = pci_find_device(PCI_VENDOR_ID_V3_SEMI, 700 if ((PCI_Device = pci_get_device(PCI_VENDOR_ID_V3_SEMI,
678 PCI_DEVICE_ID_V3_SEMI_V370PDC, 701 PCI_DEVICE_ID_V3_SEMI_V370PDC,
679 PCI_Device ) ) == NULL) { 702 PCI_Device)) == NULL) {
680 break; 703 break;
681 } 704 }
682 705
683 printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n", 706 printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n",
684 (unsigned long long)PCI_Device->resource[0].start); 707 (unsigned long long)pci_resource_start(PCI_Device, 0));
685 708
686 /* 709 /*
687 * The PMC551 device acts VERY weird if you don't init it 710 * The PMC551 device acts VERY weird if you don't init it
688 * first. i.e. it will not correctly report devsel. If for 711 * first. i.e. it will not correctly report devsel. If for
689 * some reason the sdram is in a wrote-protected state the 712 * some reason the sdram is in a wrote-protected state the
690 * device will DEVSEL when it is written to causing problems 713 * device will DEVSEL when it is written to causing problems
691 * with the oldproc.c driver in 714 * with the oldproc.c driver in
692 * some kernels (2.2.*) 715 * some kernels (2.2.*)
693 */ 716 */
694 if((length = fixup_pmc551(PCI_Device)) <= 0) { 717 if ((length = fixup_pmc551(PCI_Device)) <= 0) {
695 printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n"); 718 printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n");
696 break; 719 break;
697 } 720 }
698 721
699 /* 722 /*
700 * This is needed until the driver is capable of reading the 723 * This is needed until the driver is capable of reading the
701 * onboard I2C SROM to discover the "real" memory size. 724 * onboard I2C SROM to discover the "real" memory size.
702 */ 725 */
703 if(msize) { 726 if (msize) {
704 length = msize; 727 length = msize;
705 printk(KERN_NOTICE "pmc551: Using specified memory size 0x%x\n", length); 728 printk(KERN_NOTICE "pmc551: Using specified memory "
729 "size 0x%x\n", length);
706 } else { 730 } else {
707 msize = length; 731 msize = length;
708 } 732 }
709 733
710 mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 734 mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
711 if (!mtd) { 735 if (!mtd) {
712 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD device.\n"); 736 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD "
713 break; 737 "device.\n");
714 } 738 break;
715 739 }
716 memset(mtd, 0, sizeof(struct mtd_info)); 740
717 741 priv = kzalloc(sizeof(struct mypriv), GFP_KERNEL);
718 priv = kmalloc (sizeof(struct mypriv), GFP_KERNEL); 742 if (!priv) {
719 if (!priv) { 743 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD "
720 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD device.\n"); 744 "device.\n");
721 kfree(mtd); 745 kfree(mtd);
722 break; 746 break;
723 } 747 }
724 memset(priv, 0, sizeof(*priv)); 748 mtd->priv = priv;
725 mtd->priv = priv; 749 priv->dev = PCI_Device;
726 priv->dev = PCI_Device; 750
727 751 if (asize > length) {
728 if(asize > length) { 752 printk(KERN_NOTICE "pmc551: reducing aperture size to "
729 printk(KERN_NOTICE "pmc551: reducing aperture size to fit %dM\n",length>>20); 753 "fit %dM\n", length >> 20);
730 priv->asize = asize = length; 754 priv->asize = asize = length;
731 } else if (asize == 0 || asize == length) { 755 } else if (asize == 0 || asize == length) {
732 printk(KERN_NOTICE "pmc551: Using existing aperture size %dM\n", length>>20); 756 printk(KERN_NOTICE "pmc551: Using existing aperture "
757 "size %dM\n", length >> 20);
733 priv->asize = asize = length; 758 priv->asize = asize = length;
734 } else { 759 } else {
735 printk(KERN_NOTICE "pmc551: Using specified aperture size %dM\n", asize>>20); 760 printk(KERN_NOTICE "pmc551: Using specified aperture "
761 "size %dM\n", asize >> 20);
736 priv->asize = asize; 762 priv->asize = asize;
737 } 763 }
738 priv->start = ioremap(((PCI_Device->resource[0].start) 764 priv->start = pci_iomap(PCI_Device, 0, priv->asize);
739 & PCI_BASE_ADDRESS_MEM_MASK),
740 priv->asize);
741 765
742 if (!priv->start) { 766 if (!priv->start) {
743 printk(KERN_NOTICE "pmc551: Unable to map IO space\n"); 767 printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
744 kfree(mtd->priv); 768 kfree(mtd->priv);
745 kfree(mtd); 769 kfree(mtd);
746 break; 770 break;
747 } 771 }
748
749#ifdef CONFIG_MTD_PMC551_DEBUG 772#ifdef CONFIG_MTD_PMC551_DEBUG
750 printk( KERN_DEBUG "pmc551: setting aperture to %d\n", 773 printk(KERN_DEBUG "pmc551: setting aperture to %d\n",
751 ffs(priv->asize>>20)-1); 774 ffs(priv->asize >> 20) - 1);
752#endif 775#endif
753 776
754 priv->base_map0 = ( PMC551_PCI_MEM_MAP_REG_EN 777 priv->base_map0 = (PMC551_PCI_MEM_MAP_REG_EN
755 | PMC551_PCI_MEM_MAP_ENABLE 778 | PMC551_PCI_MEM_MAP_ENABLE
756 | (ffs(priv->asize>>20)-1)<<4 ); 779 | (ffs(priv->asize >> 20) - 1) << 4);
757 priv->curr_map0 = priv->base_map0; 780 priv->curr_map0 = priv->base_map0;
758 pci_write_config_dword ( priv->dev, PMC551_PCI_MEM_MAP0, 781 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0,
759 priv->curr_map0 ); 782 priv->curr_map0);
760 783
761#ifdef CONFIG_MTD_PMC551_DEBUG 784#ifdef CONFIG_MTD_PMC551_DEBUG
762 printk( KERN_DEBUG "pmc551: aperture set to %d\n", 785 printk(KERN_DEBUG "pmc551: aperture set to %d\n",
763 (priv->base_map0 & 0xF0)>>4 ); 786 (priv->base_map0 & 0xF0) >> 4);
764#endif 787#endif
765 788
766 mtd->size = msize; 789 mtd->size = msize;
767 mtd->flags = MTD_CAP_RAM; 790 mtd->flags = MTD_CAP_RAM;
768 mtd->erase = pmc551_erase; 791 mtd->erase = pmc551_erase;
769 mtd->read = pmc551_read; 792 mtd->read = pmc551_read;
770 mtd->write = pmc551_write; 793 mtd->write = pmc551_write;
771 mtd->point = pmc551_point; 794 mtd->point = pmc551_point;
772 mtd->unpoint = pmc551_unpoint; 795 mtd->unpoint = pmc551_unpoint;
773 mtd->type = MTD_RAM; 796 mtd->type = MTD_RAM;
774 mtd->name = "PMC551 RAM board"; 797 mtd->name = "PMC551 RAM board";
775 mtd->erasesize = 0x10000; 798 mtd->erasesize = 0x10000;
776 mtd->writesize = 1; 799 mtd->writesize = 1;
777 mtd->owner = THIS_MODULE; 800 mtd->owner = THIS_MODULE;
778 801
779 if (add_mtd_device(mtd)) { 802 if (add_mtd_device(mtd)) {
780 printk(KERN_NOTICE "pmc551: Failed to register new device\n"); 803 printk(KERN_NOTICE "pmc551: Failed to register new "
781 iounmap(priv->start); 804 "device\n");
782 kfree(mtd->priv); 805 pci_iounmap(PCI_Device, priv->start);
783 kfree(mtd); 806 kfree(mtd->priv);
784 break; 807 kfree(mtd);
785 } 808 break;
786 printk(KERN_NOTICE "Registered pmc551 memory device.\n"); 809 }
787 printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n", 810
788 priv->asize>>20, 811 /* Keep a reference as the add_mtd_device worked */
789 priv->start, 812 pci_dev_get(PCI_Device);
790 priv->start + priv->asize); 813
791 printk(KERN_NOTICE "Total memory is %d%c\n", 814 printk(KERN_NOTICE "Registered pmc551 memory device.\n");
792 (length<1024)?length: 815 printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n",
793 (length<1048576)?length>>10:length>>20, 816 priv->asize >> 20,
794 (length<1024)?'B':(length<1048576)?'K':'M'); 817 priv->start, priv->start + priv->asize);
818 printk(KERN_NOTICE "Total memory is %d%c\n",
819 (length < 1024) ? length :
820 (length < 1048576) ? length >> 10 : length >> 20,
821 (length < 1024) ? 'B' : (length < 1048576) ? 'K' : 'M');
795 priv->nextpmc551 = pmc551list; 822 priv->nextpmc551 = pmc551list;
796 pmc551list = mtd; 823 pmc551list = mtd;
797 found++; 824 found++;
798 } 825 }
826
827 /* Exited early, reference left over */
828 if (PCI_Device)
829 pci_dev_put(PCI_Device);
799 830
800 if( !pmc551list ) { 831 if (!pmc551list) {
801 printk(KERN_NOTICE "pmc551: not detected\n"); 832 printk(KERN_NOTICE "pmc551: not detected\n");
802 return -ENODEV; 833 return -ENODEV;
803 } else { 834 } else {
804 printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found); 835 printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found);
805 return 0; 836 return 0;
806 } 837 }
807} 838}
808 839
@@ -811,23 +842,24 @@ static int __init init_pmc551(void)
811 */ 842 */
812static void __exit cleanup_pmc551(void) 843static void __exit cleanup_pmc551(void)
813{ 844{
814 int found=0; 845 int found = 0;
815 struct mtd_info *mtd; 846 struct mtd_info *mtd;
816 struct mypriv *priv; 847 struct mypriv *priv;
817 848
818 while((mtd=pmc551list)) { 849 while ((mtd = pmc551list)) {
819 priv = mtd->priv; 850 priv = mtd->priv;
820 pmc551list = priv->nextpmc551; 851 pmc551list = priv->nextpmc551;
821 852
822 if(priv->start) { 853 if (priv->start) {
823 printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n", 854 printk(KERN_DEBUG "pmc551: unmapping %dM starting at "
824 priv->asize>>20, priv->start); 855 "0x%p\n", priv->asize >> 20, priv->start);
825 iounmap (priv->start); 856 pci_iounmap(priv->dev, priv->start);
826 } 857 }
858 pci_dev_put(priv->dev);
827 859
828 kfree (mtd->priv); 860 kfree(mtd->priv);
829 del_mtd_device (mtd); 861 del_mtd_device(mtd);
830 kfree (mtd); 862 kfree(mtd);
831 found++; 863 found++;
832 } 864 }
833 865
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 64d1b6a6c920..24747bdc3e19 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -447,14 +447,6 @@ config MTD_DC21285
447 21285 bridge used with Intel's StrongARM processors. More info at 447 21285 bridge used with Intel's StrongARM processors. More info at
448 <http://www.intel.com/design/bridge/docs/21285_documentation.htm>. 448 <http://www.intel.com/design/bridge/docs/21285_documentation.htm>.
449 449
450config MTD_IQ80310
451 tristate "CFI Flash device mapped on the XScale IQ80310 board"
452 depends on MTD_CFI && ARCH_IQ80310
453 help
454 This enables access routines for the flash chips on the Intel XScale
455 IQ80310 evaluation board. If you have one of these boards and would
456 like to use the flash chips on it, say 'Y'.
457
458config MTD_IXP4XX 450config MTD_IXP4XX
459 tristate "CFI Flash device mapped on Intel IXP4xx based systems" 451 tristate "CFI Flash device mapped on Intel IXP4xx based systems"
460 depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX 452 depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index ab71f172eb77..191c1928bbec 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
15obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o 15obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o
16obj-$(CONFIG_MTD_DC21285) += dc21285.o 16obj-$(CONFIG_MTD_DC21285) += dc21285.o
17obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o 17obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o
18obj-$(CONFIG_MTD_IQ80310) += iq80310.o
19obj-$(CONFIG_MTD_L440GX) += l440gx.o 18obj-$(CONFIG_MTD_L440GX) += l440gx.o
20obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o 19obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
21obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o 20obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index 447955be18af..797caffb20b1 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -57,6 +57,7 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window)
57 /* Disable writes through the rom window */ 57 /* Disable writes through the rom window */
58 pci_read_config_byte(window->pdev, 0x40, &byte); 58 pci_read_config_byte(window->pdev, 0x40, &byte);
59 pci_write_config_byte(window->pdev, 0x40, byte & ~1); 59 pci_write_config_byte(window->pdev, 0x40, byte & ~1);
60 pci_dev_put(window->pdev);
60 } 61 }
61 62
62 /* Free all of the mtd devices */ 63 /* Free all of the mtd devices */
@@ -91,7 +92,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
91 struct amd76xrom_map_info *map = NULL; 92 struct amd76xrom_map_info *map = NULL;
92 unsigned long map_top; 93 unsigned long map_top;
93 94
94 /* Remember the pci dev I find the window in */ 95 /* Remember the pci dev I find the window in - already have a ref */
95 window->pdev = pdev; 96 window->pdev = pdev;
96 97
97 /* Assume the rom window is properly setup, and find it's size */ 98 /* Assume the rom window is properly setup, and find it's size */
@@ -302,7 +303,7 @@ static int __init init_amd76xrom(void)
302 struct pci_device_id *id; 303 struct pci_device_id *id;
303 pdev = NULL; 304 pdev = NULL;
304 for(id = amd76xrom_pci_tbl; id->vendor; id++) { 305 for(id = amd76xrom_pci_tbl; id->vendor; id++) {
305 pdev = pci_find_device(id->vendor, id->device, NULL); 306 pdev = pci_get_device(id->vendor, id->device, NULL);
306 if (pdev) { 307 if (pdev) {
307 break; 308 break;
308 } 309 }
diff --git a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c
index d95ae582fbe9..642d96bc8919 100644
--- a/drivers/mtd/maps/arctic-mtd.c
+++ b/drivers/mtd/maps/arctic-mtd.c
@@ -96,6 +96,8 @@ static struct mtd_partition arctic_partitions[PARTITIONS] = {
96static int __init 96static int __init
97init_arctic_mtd(void) 97init_arctic_mtd(void)
98{ 98{
99 int err = 0;
100
99 printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR); 101 printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
100 102
101 arctic_mtd_map.virt = ioremap(PADDR, SIZE); 103 arctic_mtd_map.virt = ioremap(PADDR, SIZE);
@@ -109,12 +111,20 @@ init_arctic_mtd(void)
109 printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8); 111 printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
110 arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map); 112 arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
111 113
112 if (!arctic_mtd) 114 if (!arctic_mtd) {
115 iounmap((void *) arctic_mtd_map.virt);
113 return -ENXIO; 116 return -ENXIO;
117 }
114 118
115 arctic_mtd->owner = THIS_MODULE; 119 arctic_mtd->owner = THIS_MODULE;
116 120
117 return add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS); 121 err = add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
122 if (err) {
123 printk("%s: add_mtd_partitions failed\n", NAME);
124 iounmap((void *) arctic_mtd_map.virt);
125 }
126
127 return err;
118} 128}
119 129
120static void __exit 130static void __exit
diff --git a/drivers/mtd/maps/beech-mtd.c b/drivers/mtd/maps/beech-mtd.c
index 5df7361d1407..a64b1a5ab316 100644
--- a/drivers/mtd/maps/beech-mtd.c
+++ b/drivers/mtd/maps/beech-mtd.c
@@ -72,6 +72,8 @@ static struct mtd_partition beech_partitions[2] = {
72static int __init 72static int __init
73init_beech_mtd(void) 73init_beech_mtd(void)
74{ 74{
75 int err = 0;
76
75 printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR); 77 printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
76 78
77 beech_mtd_map.virt = ioremap(PADDR, SIZE); 79 beech_mtd_map.virt = ioremap(PADDR, SIZE);
@@ -86,12 +88,20 @@ init_beech_mtd(void)
86 printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8); 88 printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
87 beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map); 89 beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
88 90
89 if (!beech_mtd) 91 if (!beech_mtd) {
92 iounmap((void *) beech_mtd_map.virt);
90 return -ENXIO; 93 return -ENXIO;
94 }
91 95
92 beech_mtd->owner = THIS_MODULE; 96 beech_mtd->owner = THIS_MODULE;
93 97
94 return add_mtd_partitions(beech_mtd, beech_partitions, 2); 98 err = add_mtd_partitions(beech_mtd, beech_partitions, 2);
99 if (err) {
100 printk("%s: add_mtd_partitions failed\n", NAME);
101 iounmap((void *) beech_mtd_map.virt);
102 }
103
104 return err;
95} 105}
96 106
97static void __exit 107static void __exit
diff --git a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
index aa56defb94c8..d6bef100d69a 100644
--- a/drivers/mtd/maps/cstm_mips_ixx.c
+++ b/drivers/mtd/maps/cstm_mips_ixx.c
@@ -171,7 +171,14 @@ int __init init_cstm_mips_ixx(void)
171 cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr; 171 cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr;
172 cstm_mips_ixx_map[i].virt = ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size); 172 cstm_mips_ixx_map[i].virt = ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);
173 if (!cstm_mips_ixx_map[i].virt) { 173 if (!cstm_mips_ixx_map[i].virt) {
174 int j = 0;
174 printk(KERN_WARNING "Failed to ioremap\n"); 175 printk(KERN_WARNING "Failed to ioremap\n");
176 for (j = 0; j < i; j++) {
177 if (cstm_mips_ixx_map[j].virt) {
178 iounmap((void *)cstm_mips_ixx_map[j].virt);
179 cstm_mips_ixx_map[j].virt = 0;
180 }
181 }
175 return -EIO; 182 return -EIO;
176 } 183 }
177 cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name; 184 cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name;
@@ -204,8 +211,15 @@ int __init init_cstm_mips_ixx(void)
204 cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd; 211 cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd;
205 add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions); 212 add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions);
206 } 213 }
207 else 214 else {
208 return -ENXIO; 215 for (i = 0; i < PHYSMAP_NUMBER; i++) {
216 if (cstm_mips_ixx_map[i].virt) {
217 iounmap((void *)cstm_mips_ixx_map[i].virt);
218 cstm_mips_ixx_map[i].virt = 0;
219 }
220 }
221 return -ENXIO;
222 }
209 } 223 }
210 return 0; 224 return 0;
211} 225}
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index 641e1dd8479e..1488bb92f26f 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -108,6 +108,7 @@ int __init init_ebony(void)
108 ARRAY_SIZE(ebony_small_partitions)); 108 ARRAY_SIZE(ebony_small_partitions));
109 } else { 109 } else {
110 printk("map probe failed for flash\n"); 110 printk("map probe failed for flash\n");
111 iounmap(ebony_small_map.virt);
111 return -ENXIO; 112 return -ENXIO;
112 } 113 }
113 114
@@ -117,6 +118,7 @@ int __init init_ebony(void)
117 118
118 if (!ebony_large_map.virt) { 119 if (!ebony_large_map.virt) {
119 printk("Failed to ioremap flash\n"); 120 printk("Failed to ioremap flash\n");
121 iounmap(ebony_small_map.virt);
120 return -EIO; 122 return -EIO;
121 } 123 }
122 124
@@ -129,6 +131,8 @@ int __init init_ebony(void)
129 ARRAY_SIZE(ebony_large_partitions)); 131 ARRAY_SIZE(ebony_large_partitions));
130 } else { 132 } else {
131 printk("map probe failed for flash\n"); 133 printk("map probe failed for flash\n");
134 iounmap(ebony_small_map.virt);
135 iounmap(ebony_large_map.virt);
132 return -ENXIO; 136 return -ENXIO;
133 } 137 }
134 138
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
index c6bf4e1219ef..7c50c271651c 100644
--- a/drivers/mtd/maps/fortunet.c
+++ b/drivers/mtd/maps/fortunet.c
@@ -218,8 +218,11 @@ int __init init_fortunet(void)
218 map_regions[ix].map_info.size); 218 map_regions[ix].map_info.size);
219 if(!map_regions[ix].map_info.virt) 219 if(!map_regions[ix].map_info.virt)
220 { 220 {
221 int j = 0;
221 printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n", 222 printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
222 map_regions[ix].map_info.name); 223 map_regions[ix].map_info.name);
224 for (j = 0 ; j < ix; j++)
225 iounmap(map_regions[j].map_info.virt);
223 return -ENXIO; 226 return -ENXIO;
224 } 227 }
225 simple_map_init(&map_regions[ix].map_info); 228 simple_map_init(&map_regions[ix].map_info);
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index db4b570d874a..2bb3e63606e5 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -61,6 +61,7 @@ static void ichxrom_cleanup(struct ichxrom_window *window)
61 /* Disable writes through the rom window */ 61 /* Disable writes through the rom window */
62 pci_read_config_word(window->pdev, BIOS_CNTL, &word); 62 pci_read_config_word(window->pdev, BIOS_CNTL, &word);
63 pci_write_config_word(window->pdev, BIOS_CNTL, word & ~1); 63 pci_write_config_word(window->pdev, BIOS_CNTL, word & ~1);
64 pci_dev_put(window->pdev);
64 65
65 /* Free all of the mtd devices */ 66 /* Free all of the mtd devices */
66 list_for_each_entry_safe(map, scratch, &window->maps, list) { 67 list_for_each_entry_safe(map, scratch, &window->maps, list) {
@@ -355,7 +356,7 @@ static int __init init_ichxrom(void)
355 356
356 pdev = NULL; 357 pdev = NULL;
357 for (id = ichxrom_pci_tbl; id->vendor; id++) { 358 for (id = ichxrom_pci_tbl; id->vendor; id++) {
358 pdev = pci_find_device(id->vendor, id->device, NULL); 359 pdev = pci_get_device(id->vendor, id->device, NULL);
359 if (pdev) { 360 if (pdev) {
360 break; 361 break;
361 } 362 }
diff --git a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c
deleted file mode 100644
index 62d9e87d84e2..000000000000
--- a/drivers/mtd/maps/iq80310.c
+++ /dev/null
@@ -1,118 +0,0 @@
1/*
2 * $Id: iq80310.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
3 *
4 * Mapping for the Intel XScale IQ80310 evaluation board
5 *
6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <asm/io.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h>
23
24
25#define WINDOW_ADDR 0
26#define WINDOW_SIZE 8*1024*1024
27#define BUSWIDTH 1
28
29static struct mtd_info *mymtd;
30
31static struct map_info iq80310_map = {
32 .name = "IQ80310 flash",
33 .size = WINDOW_SIZE,
34 .bankwidth = BUSWIDTH,
35 .phys = WINDOW_ADDR
36};
37
38static struct mtd_partition iq80310_partitions[4] = {
39 {
40 .name = "Firmware",
41 .size = 0x00080000,
42 .offset = 0,
43 .mask_flags = MTD_WRITEABLE /* force read-only */
44 },{
45 .name = "Kernel",
46 .size = 0x000a0000,
47 .offset = 0x00080000,
48 },{
49 .name = "Filesystem",
50 .size = 0x00600000,
51 .offset = 0x00120000
52 },{
53 .name = "RedBoot",
54 .size = 0x000e0000,
55 .offset = 0x00720000,
56 .mask_flags = MTD_WRITEABLE
57 }
58};
59
60static struct mtd_info *mymtd;
61static struct mtd_partition *parsed_parts;
62static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
63
64static int __init init_iq80310(void)
65{
66 struct mtd_partition *parts;
67 int nb_parts = 0;
68 int parsed_nr_parts = 0;
69 int ret;
70
71 iq80310_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
72 if (!iq80310_map.virt) {
73 printk("Failed to ioremap\n");
74 return -EIO;
75 }
76 simple_map_init(&iq80310_map);
77
78 mymtd = do_map_probe("cfi_probe", &iq80310_map);
79 if (!mymtd) {
80 iounmap((void *)iq80310_map.virt);
81 return -ENXIO;
82 }
83 mymtd->owner = THIS_MODULE;
84
85 ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0);
86
87 if (ret > 0)
88 parsed_nr_parts = ret;
89
90 if (parsed_nr_parts > 0) {
91 parts = parsed_parts;
92 nb_parts = parsed_nr_parts;
93 } else {
94 parts = iq80310_partitions;
95 nb_parts = ARRAY_SIZE(iq80310_partitions);
96 }
97 add_mtd_partitions(mymtd, parts, nb_parts);
98 return 0;
99}
100
101static void __exit cleanup_iq80310(void)
102{
103 if (mymtd) {
104 del_mtd_partitions(mymtd);
105 map_destroy(mymtd);
106 kfree(parsed_parts);
107 }
108 if (iq80310_map.virt)
109 iounmap((void *)iq80310_map.virt);
110}
111
112module_init(init_iq80310);
113module_exit(cleanup_iq80310);
114
115
116MODULE_LICENSE("GPL");
117MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
118MODULE_DESCRIPTION("MTD map driver for Intel XScale IQ80310 evaluation board");
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 986c58628390..7a828e3e6446 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -253,7 +253,7 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
253 /* Use the fast version */ 253 /* Use the fast version */
254 info->map.write = ixp4xx_write16, 254 info->map.write = ixp4xx_write16,
255 255
256 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); 256 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, dev->resource->start);
257 if (err > 0) { 257 if (err > 0) {
258 err = add_mtd_partitions(info->mtd, info->partitions, err); 258 err = add_mtd_partitions(info->mtd, info->partitions, err);
259 if(err) 259 if(err)
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c
index 6b784ef5ee70..67620adf4811 100644
--- a/drivers/mtd/maps/l440gx.c
+++ b/drivers/mtd/maps/l440gx.c
@@ -61,14 +61,17 @@ static int __init init_l440gx(void)
61 struct resource *pm_iobase; 61 struct resource *pm_iobase;
62 __u16 word; 62 __u16 word;
63 63
64 dev = pci_find_device(PCI_VENDOR_ID_INTEL, 64 dev = pci_get_device(PCI_VENDOR_ID_INTEL,
65 PCI_DEVICE_ID_INTEL_82371AB_0, NULL); 65 PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
66 66
67 pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, 67 pm_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
68 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 68 PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
69 69
70 pci_dev_put(dev);
71
70 if (!dev || !pm_dev) { 72 if (!dev || !pm_dev) {
71 printk(KERN_NOTICE "L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue\n"); 73 printk(KERN_NOTICE "L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue\n");
74 pci_dev_put(pm_dev);
72 return -ENODEV; 75 return -ENODEV;
73 } 76 }
74 77
@@ -76,6 +79,7 @@ static int __init init_l440gx(void)
76 79
77 if (!l440gx_map.virt) { 80 if (!l440gx_map.virt) {
78 printk(KERN_WARNING "Failed to ioremap L440GX flash region\n"); 81 printk(KERN_WARNING "Failed to ioremap L440GX flash region\n");
82 pci_dev_put(pm_dev);
79 return -ENOMEM; 83 return -ENOMEM;
80 } 84 }
81 simple_map_init(&l440gx_map); 85 simple_map_init(&l440gx_map);
@@ -99,8 +103,12 @@ static int __init init_l440gx(void)
99 pm_iobase->start += iobase & ~1; 103 pm_iobase->start += iobase & ~1;
100 pm_iobase->end += iobase & ~1; 104 pm_iobase->end += iobase & ~1;
101 105
106 pci_dev_put(pm_dev);
107
102 /* Allocate the resource region */ 108 /* Allocate the resource region */
103 if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) { 109 if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) {
110 pci_dev_put(dev);
111 pci_dev_put(pm_dev);
104 printk(KERN_WARNING "Could not allocate pm iobase resource\n"); 112 printk(KERN_WARNING "Could not allocate pm iobase resource\n");
105 iounmap(l440gx_map.virt); 113 iounmap(l440gx_map.virt);
106 return -ENXIO; 114 return -ENXIO;
diff --git a/drivers/mtd/maps/lasat.c b/drivers/mtd/maps/lasat.c
index 1c13d2dc0cdf..e34376321050 100644
--- a/drivers/mtd/maps/lasat.c
+++ b/drivers/mtd/maps/lasat.c
@@ -79,6 +79,7 @@ static int __init init_lasat(void)
79 return 0; 79 return 0;
80 } 80 }
81 81
82 iounmap(lasat_map.virt);
82 return -ENXIO; 83 return -ENXIO;
83} 84}
84 85
@@ -89,6 +90,7 @@ static void __exit cleanup_lasat(void)
89 map_destroy(lasat_mtd); 90 map_destroy(lasat_mtd);
90 } 91 }
91 if (lasat_map.virt) { 92 if (lasat_map.virt) {
93 iounmap(lasat_map.virt);
92 lasat_map.virt = 0; 94 lasat_map.virt = 0;
93 } 95 }
94} 96}
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 0994b5b2e331..198e840ff6db 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -277,6 +277,7 @@ int __init nettel_init(void)
277 nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize); 277 nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize);
278 if (!nettel_amd_map.virt) { 278 if (!nettel_amd_map.virt) {
279 printk("SNAPGEAR: failed to ioremap() BOOTCS\n"); 279 printk("SNAPGEAR: failed to ioremap() BOOTCS\n");
280 iounmap(nettel_mmcrp);
280 return(-EIO); 281 return(-EIO);
281 } 282 }
282 simple_map_init(&nettel_amd_map); 283 simple_map_init(&nettel_amd_map);
@@ -337,7 +338,8 @@ int __init nettel_init(void)
337 nettel_amd_map.virt = NULL; 338 nettel_amd_map.virt = NULL;
338#else 339#else
339 /* Only AMD flash supported */ 340 /* Only AMD flash supported */
340 return(-ENXIO); 341 rc = -ENXIO;
342 goto out_unmap2;
341#endif 343#endif
342 } 344 }
343 345
@@ -361,14 +363,15 @@ int __init nettel_init(void)
361 nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize); 363 nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
362 if (!nettel_intel_map.virt) { 364 if (!nettel_intel_map.virt) {
363 printk("SNAPGEAR: failed to ioremap() ROMCS1\n"); 365 printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
364 return(-EIO); 366 rc = -EIO;
367 goto out_unmap2;
365 } 368 }
366 simple_map_init(&nettel_intel_map); 369 simple_map_init(&nettel_intel_map);
367 370
368 intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); 371 intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
369 if (!intel_mtd) { 372 if (!intel_mtd) {
370 iounmap(nettel_intel_map.virt); 373 rc = -ENXIO;
371 return(-ENXIO); 374 goto out_unmap1;
372 } 375 }
373 376
374 /* Set PAR to the detected size */ 377 /* Set PAR to the detected size */
@@ -394,13 +397,14 @@ int __init nettel_init(void)
394 nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize); 397 nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
395 if (!nettel_intel_map.virt) { 398 if (!nettel_intel_map.virt) {
396 printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n"); 399 printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
397 return(-EIO); 400 rc = -EIO;
401 goto out_unmap2;
398 } 402 }
399 403
400 intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); 404 intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
401 if (! intel_mtd) { 405 if (! intel_mtd) {
402 iounmap((void *) nettel_intel_map.virt); 406 rc = -ENXIO;
403 return(-ENXIO); 407 goto out_unmap1;
404 } 408 }
405 409
406 intel1size = intel_mtd->size - intel0size; 410 intel1size = intel_mtd->size - intel0size;
@@ -456,6 +460,18 @@ int __init nettel_init(void)
456#endif 460#endif
457 461
458 return(rc); 462 return(rc);
463
464#ifdef CONFIG_MTD_CFI_INTELEXT
465out_unmap1:
466 iounmap((void *) nettel_intel_map.virt);
467#endif
468
469out_unmap2:
470 iounmap(nettel_mmcrp);
471 iounmap(nettel_amd_map.virt);
472
473 return(rc);
474
459} 475}
460 476
461/****************************************************************************/ 477/****************************************************************************/
@@ -469,6 +485,10 @@ void __exit nettel_cleanup(void)
469 del_mtd_partitions(amd_mtd); 485 del_mtd_partitions(amd_mtd);
470 map_destroy(amd_mtd); 486 map_destroy(amd_mtd);
471 } 487 }
488 if (nettel_mmcrp) {
489 iounmap(nettel_mmcrp);
490 nettel_mmcrp = NULL;
491 }
472 if (nettel_amd_map.virt) { 492 if (nettel_amd_map.virt) {
473 iounmap(nettel_amd_map.virt); 493 iounmap(nettel_amd_map.virt);
474 nettel_amd_map.virt = NULL; 494 nettel_amd_map.virt = NULL;
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
index 2f07602ba940..5522eac8c980 100644
--- a/drivers/mtd/maps/ocotea.c
+++ b/drivers/mtd/maps/ocotea.c
@@ -97,6 +97,7 @@ int __init init_ocotea(void)
97 ARRAY_SIZE(ocotea_small_partitions)); 97 ARRAY_SIZE(ocotea_small_partitions));
98 } else { 98 } else {
99 printk("map probe failed for flash\n"); 99 printk("map probe failed for flash\n");
100 iounmap(ocotea_small_map.virt);
100 return -ENXIO; 101 return -ENXIO;
101 } 102 }
102 103
@@ -106,6 +107,7 @@ int __init init_ocotea(void)
106 107
107 if (!ocotea_large_map.virt) { 108 if (!ocotea_large_map.virt) {
108 printk("Failed to ioremap flash\n"); 109 printk("Failed to ioremap flash\n");
110 iounmap(ocotea_small_map.virt);
109 return -EIO; 111 return -EIO;
110 } 112 }
111 113
@@ -118,6 +120,8 @@ int __init init_ocotea(void)
118 ARRAY_SIZE(ocotea_large_partitions)); 120 ARRAY_SIZE(ocotea_large_partitions));
119 } else { 121 } else {
120 printk("map probe failed for flash\n"); 122 printk("map probe failed for flash\n");
123 iounmap(ocotea_small_map.virt);
124 iounmap(ocotea_large_map.virt);
121 return -ENXIO; 125 return -ENXIO;
122 } 126 }
123 127
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index c861134cbc48..995347b1beba 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -602,6 +602,10 @@ static int pcmciamtd_config(struct pcmcia_device *link)
602 ret = pcmcia_request_configuration(link, &link->conf); 602 ret = pcmcia_request_configuration(link, &link->conf);
603 if(ret != CS_SUCCESS) { 603 if(ret != CS_SUCCESS) {
604 cs_error(link, RequestConfiguration, ret); 604 cs_error(link, RequestConfiguration, ret);
605 if (dev->win_base) {
606 iounmap(dev->win_base);
607 dev->win_base = NULL;
608 }
605 return -ENODEV; 609 return -ENODEV;
606 } 610 }
607 611
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 7799a25a7f2a..bc7cc71788bc 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -158,9 +158,42 @@ err_out:
158 return err; 158 return err;
159} 159}
160 160
161#ifdef CONFIG_PM
162static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state)
163{
164 struct physmap_flash_info *info = platform_get_drvdata(dev);
165 int ret = 0;
166
167 if (info)
168 ret = info->mtd->suspend(info->mtd);
169
170 return ret;
171}
172
173static int physmap_flash_resume(struct platform_device *dev)
174{
175 struct physmap_flash_info *info = platform_get_drvdata(dev);
176 if (info)
177 info->mtd->resume(info->mtd);
178 return 0;
179}
180
181static void physmap_flash_shutdown(struct platform_device *dev)
182{
183 struct physmap_flash_info *info = platform_get_drvdata(dev);
184 if (info && info->mtd->suspend(info->mtd) == 0)
185 info->mtd->resume(info->mtd);
186}
187#endif
188
161static struct platform_driver physmap_flash_driver = { 189static struct platform_driver physmap_flash_driver = {
162 .probe = physmap_flash_probe, 190 .probe = physmap_flash_probe,
163 .remove = physmap_flash_remove, 191 .remove = physmap_flash_remove,
192#ifdef CONFIG_PM
193 .suspend = physmap_flash_suspend,
194 .resume = physmap_flash_resume,
195 .shutdown = physmap_flash_shutdown,
196#endif
164 .driver = { 197 .driver = {
165 .name = "physmap-flash", 198 .name = "physmap-flash",
166 }, 199 },
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index ec8fdae1dd99..2257d2b500c0 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -126,6 +126,8 @@ static struct mtd_info *redwood_mtd;
126 126
127int __init init_redwood_flash(void) 127int __init init_redwood_flash(void)
128{ 128{
129 int err = 0;
130
129 printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n", 131 printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
130 WINDOW_SIZE, WINDOW_ADDR); 132 WINDOW_SIZE, WINDOW_ADDR);
131 133
@@ -141,11 +143,18 @@ int __init init_redwood_flash(void)
141 143
142 if (redwood_mtd) { 144 if (redwood_mtd) {
143 redwood_mtd->owner = THIS_MODULE; 145 redwood_mtd->owner = THIS_MODULE;
144 return add_mtd_partitions(redwood_mtd, 146 err = add_mtd_partitions(redwood_mtd,
145 redwood_flash_partitions, 147 redwood_flash_partitions,
146 NUM_REDWOOD_FLASH_PARTITIONS); 148 NUM_REDWOOD_FLASH_PARTITIONS);
149 if (err) {
150 printk("init_redwood_flash: add_mtd_partitions failed\n");
151 iounmap(redwood_flash_map.virt);
152 }
153 return err;
154
147 } 155 }
148 156
157 iounmap(redwood_flash_map.virt);
149 return -ENXIO; 158 return -ENXIO;
150} 159}
151 160
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c
index 7d0fcf8f4f33..b8c1331b7a04 100644
--- a/drivers/mtd/maps/sbc8240.c
+++ b/drivers/mtd/maps/sbc8240.c
@@ -156,7 +156,7 @@ int __init init_sbc8240_mtd (void)
156 }; 156 };
157 157
158 int devicesfound = 0; 158 int devicesfound = 0;
159 int i; 159 int i,j;
160 160
161 for (i = 0; i < NUM_FLASH_BANKS; i++) { 161 for (i = 0; i < NUM_FLASH_BANKS; i++) {
162 printk (KERN_NOTICE MSG_PREFIX 162 printk (KERN_NOTICE MSG_PREFIX
@@ -166,6 +166,10 @@ int __init init_sbc8240_mtd (void)
166 (unsigned long) ioremap (pt[i].addr, pt[i].size); 166 (unsigned long) ioremap (pt[i].addr, pt[i].size);
167 if (!sbc8240_map[i].map_priv_1) { 167 if (!sbc8240_map[i].map_priv_1) {
168 printk (MSG_PREFIX "failed to ioremap\n"); 168 printk (MSG_PREFIX "failed to ioremap\n");
169 for (j = 0; j < i; j++) {
170 iounmap((void *) sbc8240_map[j].map_priv_1);
171 sbc8240_map[j].map_priv_1 = 0;
172 }
169 return -EIO; 173 return -EIO;
170 } 174 }
171 simple_map_init(&sbc8240_mtd[i]); 175 simple_map_init(&sbc8240_mtd[i]);
@@ -175,6 +179,11 @@ int __init init_sbc8240_mtd (void)
175 if (sbc8240_mtd[i]) { 179 if (sbc8240_mtd[i]) {
176 sbc8240_mtd[i]->module = THIS_MODULE; 180 sbc8240_mtd[i]->module = THIS_MODULE;
177 devicesfound++; 181 devicesfound++;
182 } else {
183 if (sbc8240_map[i].map_priv_1) {
184 iounmap((void *) sbc8240_map[i].map_priv_1);
185 sbc8240_map[i].map_priv_1 = 0;
186 }
178 } 187 }
179 } 188 }
180 189
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
index 7391fd544e86..5e2bce22f37c 100644
--- a/drivers/mtd/maps/scx200_docflash.c
+++ b/drivers/mtd/maps/scx200_docflash.c
@@ -87,19 +87,23 @@ static int __init init_scx200_docflash(void)
87 87
88 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n"); 88 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n");
89 89
90 if ((bridge = pci_find_device(PCI_VENDOR_ID_NS, 90 if ((bridge = pci_get_device(PCI_VENDOR_ID_NS,
91 PCI_DEVICE_ID_NS_SCx200_BRIDGE, 91 PCI_DEVICE_ID_NS_SCx200_BRIDGE,
92 NULL)) == NULL) 92 NULL)) == NULL)
93 return -ENODEV; 93 return -ENODEV;
94 94
95 /* check that we have found the configuration block */ 95 /* check that we have found the configuration block */
96 if (!scx200_cb_present()) 96 if (!scx200_cb_present()) {
97 pci_dev_put(bridge);
97 return -ENODEV; 98 return -ENODEV;
99 }
98 100
99 if (probe) { 101 if (probe) {
100 /* Try to use the present flash mapping if any */ 102 /* Try to use the present flash mapping if any */
101 pci_read_config_dword(bridge, SCx200_DOCCS_BASE, &base); 103 pci_read_config_dword(bridge, SCx200_DOCCS_BASE, &base);
102 pci_read_config_dword(bridge, SCx200_DOCCS_CTRL, &ctrl); 104 pci_read_config_dword(bridge, SCx200_DOCCS_CTRL, &ctrl);
105 pci_dev_put(bridge);
106
103 pmr = inl(scx200_cb_base + SCx200_PMR); 107 pmr = inl(scx200_cb_base + SCx200_PMR);
104 108
105 if (base == 0 109 if (base == 0
@@ -127,6 +131,7 @@ static int __init init_scx200_docflash(void)
127 return -ENOMEM; 131 return -ENOMEM;
128 } 132 }
129 } else { 133 } else {
134 pci_dev_put(bridge);
130 for (u = size; u > 1; u >>= 1) 135 for (u = size; u > 1; u >>= 1)
131 ; 136 ;
132 if (u != 1) { 137 if (u != 1) {
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
index ec80eec376bf..ca932122fb64 100644
--- a/drivers/mtd/maps/walnut.c
+++ b/drivers/mtd/maps/walnut.c
@@ -68,6 +68,7 @@ int __init init_walnut(void)
68 68
69 if (WALNUT_FLASH_ONBD_N(fpga_brds1)) { 69 if (WALNUT_FLASH_ONBD_N(fpga_brds1)) {
70 printk("The on-board flash is disabled (U79 sw 5)!"); 70 printk("The on-board flash is disabled (U79 sw 5)!");
71 iounmap(fpga_status_adr);
71 return -EIO; 72 return -EIO;
72 } 73 }
73 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1)) 74 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
@@ -81,6 +82,7 @@ int __init init_walnut(void)
81 82
82 if (!walnut_map.virt) { 83 if (!walnut_map.virt) {
83 printk("Failed to ioremap flash.\n"); 84 printk("Failed to ioremap flash.\n");
85 iounmap(fpga_status_adr);
84 return -EIO; 86 return -EIO;
85 } 87 }
86 88
@@ -93,9 +95,11 @@ int __init init_walnut(void)
93 ARRAY_SIZE(walnut_partitions)); 95 ARRAY_SIZE(walnut_partitions));
94 } else { 96 } else {
95 printk("map probe failed for flash\n"); 97 printk("map probe failed for flash\n");
98 iounmap(fpga_status_adr);
96 return -ENXIO; 99 return -ENXIO;
97 } 100 }
98 101
102 iounmap(fpga_status_adr);
99 return 0; 103 return 0;
100} 104}
101 105
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 168d3ba063c3..c4d26de74349 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -57,6 +57,16 @@ int add_mtd_device(struct mtd_info *mtd)
57 mtd->index = i; 57 mtd->index = i;
58 mtd->usecount = 0; 58 mtd->usecount = 0;
59 59
60 /* Some chips always power up locked. Unlock them now */
61 if ((mtd->flags & MTD_WRITEABLE)
62 && (mtd->flags & MTD_STUPID_LOCK) && mtd->unlock) {
63 if (mtd->unlock(mtd, 0, mtd->size))
64 printk(KERN_WARNING
65 "%s: unlock failed, "
66 "writes may not work\n",
67 mtd->name);
68 }
69
60 DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name); 70 DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
61 /* No need to get a refcount on the module containing 71 /* No need to get a refcount on the module containing
62 the notifier, since we hold the mtd_table_mutex */ 72 the notifier, since we hold the mtd_table_mutex */
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 31228334da12..09e421a96893 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -21,18 +21,7 @@
21#include <linux/version.h> 21#include <linux/version.h>
22#include <asm/io.h> 22#include <asm/io.h>
23 23
24/* fixme: this is ugly */
25#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
26#include <asm/mach-au1x00/au1xxx.h> 24#include <asm/mach-au1x00/au1xxx.h>
27#else
28#include <asm/au1000.h>
29#ifdef CONFIG_MIPS_PB1550
30#include <asm/pb1550.h>
31#endif
32#ifdef CONFIG_MIPS_DB1550
33#include <asm/db1x00.h>
34#endif
35#endif
36 25
37/* 26/*
38 * MTD structure for NAND controller 27 * MTD structure for NAND controller
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 516c0e5e564c..12017f3c6bd6 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -198,6 +198,9 @@ static void __exit ep7312_cleanup(void)
198 /* Release resources, unregister device */ 198 /* Release resources, unregister device */
199 nand_release(ap7312_mtd); 199 nand_release(ap7312_mtd);
200 200
201 /* Release io resource */
202 iounmap((void *)this->IO_ADDR_R);
203
201 /* Free the MTD device structure */ 204 /* Free the MTD device structure */
202 kfree(ep7312_mtd); 205 kfree(ep7312_mtd);
203} 206}
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index e5bd88f2d560..039c759cfbfc 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -168,7 +168,7 @@ static void ndfc_chip_init(struct ndfc_nand_mtd *mtd)
168 chip->ecc.mode = NAND_ECC_HW; 168 chip->ecc.mode = NAND_ECC_HW;
169 chip->ecc.size = 256; 169 chip->ecc.size = 256;
170 chip->ecc.bytes = 3; 170 chip->ecc.bytes = 3;
171 chip->ecclayout = mtd->pl_chip->ecclayout; 171 chip->ecclayout = chip->ecc.layout = mtd->pl_chip->ecclayout;
172 mtd->mtd.priv = chip; 172 mtd->mtd.priv = chip;
173 mtd->mtd.owner = THIS_MODULE; 173 mtd->mtd.owner = THIS_MODULE;
174} 174}
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
index 22fa65c12ab9..eb7d4d443deb 100644
--- a/drivers/mtd/nand/ppchameleonevb.c
+++ b/drivers/mtd/nand/ppchameleonevb.c
@@ -276,6 +276,7 @@ static int __init ppchameleonevb_init(void)
276 /* Scan to find existence of the device (it could not be mounted) */ 276 /* Scan to find existence of the device (it could not be mounted) */
277 if (nand_scan(ppchameleon_mtd, 1)) { 277 if (nand_scan(ppchameleon_mtd, 1)) {
278 iounmap((void *)ppchameleon_fio_base); 278 iounmap((void *)ppchameleon_fio_base);
279 ppchameleon_fio_base = NULL;
279 kfree(ppchameleon_mtd); 280 kfree(ppchameleon_mtd);
280 goto nand_evb_init; 281 goto nand_evb_init;
281 } 282 }
@@ -314,6 +315,8 @@ static int __init ppchameleonevb_init(void)
314 ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); 315 ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
315 if (!ppchameleonevb_mtd) { 316 if (!ppchameleonevb_mtd) {
316 printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n"); 317 printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n");
318 if (ppchameleon_fio_base)
319 iounmap(ppchameleon_fio_base);
317 return -ENOMEM; 320 return -ENOMEM;
318 } 321 }
319 322
@@ -322,6 +325,8 @@ static int __init ppchameleonevb_init(void)
322 if (!ppchameleonevb_fio_base) { 325 if (!ppchameleonevb_fio_base) {
323 printk("ioremap PPChameleonEVB NAND flash failed\n"); 326 printk("ioremap PPChameleonEVB NAND flash failed\n");
324 kfree(ppchameleonevb_mtd); 327 kfree(ppchameleonevb_mtd);
328 if (ppchameleon_fio_base)
329 iounmap(ppchameleon_fio_base);
325 return -EIO; 330 return -EIO;
326 } 331 }
327 332
@@ -378,6 +383,8 @@ static int __init ppchameleonevb_init(void)
378 if (nand_scan(ppchameleonevb_mtd, 1)) { 383 if (nand_scan(ppchameleonevb_mtd, 1)) {
379 iounmap((void *)ppchameleonevb_fio_base); 384 iounmap((void *)ppchameleonevb_fio_base);
380 kfree(ppchameleonevb_mtd); 385 kfree(ppchameleonevb_mtd);
386 if (ppchameleon_fio_base)
387 iounmap(ppchameleon_fio_base);
381 return -ENXIO; 388 return -ENXIO;
382 } 389 }
383#ifdef CONFIG_MTD_PARTITIONS 390#ifdef CONFIG_MTD_PARTITIONS
diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
new file mode 100644
index 000000000000..ddbf015f4119
--- /dev/null
+++ b/drivers/mtd/ssfdc.c
@@ -0,0 +1,468 @@
1/*
2 * Linux driver for SSFDC Flash Translation Layer (Read only)
3 * (c) 2005 Eptar srl
4 * Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
5 *
6 * Based on NTFL and MTDBLOCK_RO drivers
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/hdreg.h>
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/nand.h>
21#include <linux/mtd/blktrans.h>
22
23struct ssfdcr_record {
24 struct mtd_blktrans_dev mbd;
25 int usecount;
26 unsigned char heads;
27 unsigned char sectors;
28 unsigned short cylinders;
29 int cis_block; /* block n. containing CIS/IDI */
30 int erase_size; /* phys_block_size */
31 unsigned short *logic_block_map; /* all zones (max 8192 phys blocks on
32 the 128MB) */
33 int map_len; /* n. phys_blocks on the card */
34};
35
36#define SSFDCR_MAJOR 257
37#define SSFDCR_PARTN_BITS 3
38
39#define SECTOR_SIZE 512
40#define SECTOR_SHIFT 9
41#define OOB_SIZE 16
42
43#define MAX_LOGIC_BLK_PER_ZONE 1000
44#define MAX_PHYS_BLK_PER_ZONE 1024
45
46#define KB(x) ( (x) * 1024L )
47#define MB(x) ( KB(x) * 1024L )
48
49/** CHS Table
50 1MB 2MB 4MB 8MB 16MB 32MB 64MB 128MB
51NCylinder 125 125 250 250 500 500 500 500
52NHead 4 4 4 4 4 8 8 16
53NSector 4 8 8 16 16 16 32 32
54SumSector 2,000 4,000 8,000 16,000 32,000 64,000 128,000 256,000
55SectorSize 512 512 512 512 512 512 512 512
56**/
57
58typedef struct {
59 unsigned long size;
60 unsigned short cyl;
61 unsigned char head;
62 unsigned char sec;
63} chs_entry_t;
64
65/* Must be ordered by size */
66static const chs_entry_t chs_table[] = {
67 { MB( 1), 125, 4, 4 },
68 { MB( 2), 125, 4, 8 },
69 { MB( 4), 250, 4, 8 },
70 { MB( 8), 250, 4, 16 },
71 { MB( 16), 500, 4, 16 },
72 { MB( 32), 500, 8, 16 },
73 { MB( 64), 500, 8, 32 },
74 { MB(128), 500, 16, 32 },
75 { 0 },
76};
77
78static int get_chs(unsigned long size, unsigned short *cyl, unsigned char *head,
79 unsigned char *sec)
80{
81 int k;
82 int found = 0;
83
84 k = 0;
85 while (chs_table[k].size > 0 && size > chs_table[k].size)
86 k++;
87
88 if (chs_table[k].size > 0) {
89 if (cyl)
90 *cyl = chs_table[k].cyl;
91 if (head)
92 *head = chs_table[k].head;
93 if (sec)
94 *sec = chs_table[k].sec;
95 found = 1;
96 }
97
98 return found;
99}
100
101/* These bytes are the signature for the CIS/IDI sector */
102static const uint8_t cis_numbers[] = {
103 0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20
104};
105
106/* Read and check for a valid CIS sector */
107static int get_valid_cis_sector(struct mtd_info *mtd)
108{
109 int ret, k, cis_sector;
110 size_t retlen;
111 loff_t offset;
112 uint8_t sect_buf[SECTOR_SIZE];
113
114 /*
115 * Look for CIS/IDI sector on the first GOOD block (give up after 4 bad
116 * blocks). If the first good block doesn't contain CIS number the flash
117 * is not SSFDC formatted
118 */
119 cis_sector = -1;
120 for (k = 0, offset = 0; k < 4; k++, offset += mtd->erasesize) {
121 if (!mtd->block_isbad(mtd, offset)) {
122 ret = mtd->read(mtd, offset, SECTOR_SIZE, &retlen,
123 sect_buf);
124
125 /* CIS pattern match on the sector buffer */
126 if ( ret < 0 || retlen != SECTOR_SIZE ) {
127 printk(KERN_WARNING
128 "SSFDC_RO:can't read CIS/IDI sector\n");
129 } else if ( !memcmp(sect_buf, cis_numbers,
130 sizeof(cis_numbers)) ) {
131 /* Found */
132 cis_sector = (int)(offset >> SECTOR_SHIFT);
133 } else {
134 DEBUG(MTD_DEBUG_LEVEL1,
135 "SSFDC_RO: CIS/IDI sector not found"
136 " on %s (mtd%d)\n", mtd->name,
137 mtd->index);
138 }
139 break;
140 }
141 }
142
143 return cis_sector;
144}
145
146/* Read physical sector (wrapper to MTD_READ) */
147static int read_physical_sector(struct mtd_info *mtd, uint8_t *sect_buf,
148 int sect_no)
149{
150 int ret;
151 size_t retlen;
152 loff_t offset = (loff_t)sect_no << SECTOR_SHIFT;
153
154 ret = mtd->read(mtd, offset, SECTOR_SIZE, &retlen, sect_buf);
155 if (ret < 0 || retlen != SECTOR_SIZE)
156 return -1;
157
158 return 0;
159}
160
161/* Read redundancy area (wrapper to MTD_READ_OOB */
162static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
163{
164 struct mtd_oob_ops ops;
165 int ret;
166
167 ops.mode = MTD_OOB_RAW;
168 ops.ooboffs = 0;
169 ops.ooblen = mtd->oobsize;
170 ops.len = OOB_SIZE;
171 ops.oobbuf = buf;
172 ops.datbuf = NULL;
173
174 ret = mtd->read_oob(mtd, offs, &ops);
175 if (ret < 0 || ops.retlen != OOB_SIZE)
176 return -1;
177
178 return 0;
179}
180
181/* Parity calculator on a word of n bit size */
182static int get_parity(int number, int size)
183{
184 int k;
185 int parity;
186
187 parity = 1;
188 for (k = 0; k < size; k++) {
189 parity += (number >> k);
190 parity &= 1;
191 }
192 return parity;
193}
194
195/* Read and validate the logical block address field stored in the OOB */
196static int get_logical_address(uint8_t *oob_buf)
197{
198 int block_address, parity;
199 int offset[2] = {6, 11}; /* offset of the 2 address fields within OOB */
200 int j;
201 int ok = 0;
202
203 /*
204 * Look for the first valid logical address
205 * Valid address has fixed pattern on most significant bits and
206 * parity check
207 */
208 for (j = 0; j < ARRAY_SIZE(offset); j++) {
209 block_address = ((int)oob_buf[offset[j]] << 8) |
210 oob_buf[offset[j]+1];
211
212 /* Check for the signature bits in the address field (MSBits) */
213 if ((block_address & ~0x7FF) == 0x1000) {
214 parity = block_address & 0x01;
215 block_address &= 0x7FF;
216 block_address >>= 1;
217
218 if (get_parity(block_address, 10) != parity) {
219 DEBUG(MTD_DEBUG_LEVEL0,
220 "SSFDC_RO: logical address field%d"
221 "parity error(0x%04X)\n", j+1,
222 block_address);
223 } else {
224 ok = 1;
225 break;
226 }
227 }
228 }
229
230 if ( !ok )
231 block_address = -2;
232
233 DEBUG(MTD_DEBUG_LEVEL3, "SSFDC_RO: get_logical_address() %d\n",
234 block_address);
235
236 return block_address;
237}
238
239/* Build the logic block map */
240static int build_logical_block_map(struct ssfdcr_record *ssfdc)
241{
242 unsigned long offset;
243 uint8_t oob_buf[OOB_SIZE];
244 int ret, block_address, phys_block;
245 struct mtd_info *mtd = ssfdc->mbd.mtd;
246
247 DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: build_block_map() nblks=%d (%luK)\n",
248 ssfdc->map_len, (unsigned long)ssfdc->map_len *
249 ssfdc->erase_size / 1024 );
250
251 /* Scan every physical block, skip CIS block */
252 for (phys_block = ssfdc->cis_block + 1; phys_block < ssfdc->map_len;
253 phys_block++) {
254 offset = (unsigned long)phys_block * ssfdc->erase_size;
255 if (mtd->block_isbad(mtd, offset))
256 continue; /* skip bad blocks */
257
258 ret = read_raw_oob(mtd, offset, oob_buf);
259 if (ret < 0) {
260 DEBUG(MTD_DEBUG_LEVEL0,
261 "SSFDC_RO: mtd read_oob() failed at %lu\n",
262 offset);
263 return -1;
264 }
265 block_address = get_logical_address(oob_buf);
266
267 /* Skip invalid addresses */
268 if (block_address >= 0 &&
269 block_address < MAX_LOGIC_BLK_PER_ZONE) {
270 int zone_index;
271
272 zone_index = phys_block / MAX_PHYS_BLK_PER_ZONE;
273 block_address += zone_index * MAX_LOGIC_BLK_PER_ZONE;
274 ssfdc->logic_block_map[block_address] =
275 (unsigned short)phys_block;
276
277 DEBUG(MTD_DEBUG_LEVEL2,
278 "SSFDC_RO: build_block_map() phys_block=%d,"
279 "logic_block_addr=%d, zone=%d\n",
280 phys_block, block_address, zone_index);
281 }
282 }
283 return 0;
284}
285
286static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
287{
288 struct ssfdcr_record *ssfdc;
289 int cis_sector;
290
291 /* Check for small page NAND flash */
292 if (mtd->type != MTD_NANDFLASH || mtd->oobsize != OOB_SIZE)
293 return;
294
295 /* Check for SSDFC format by reading CIS/IDI sector */
296 cis_sector = get_valid_cis_sector(mtd);
297 if (cis_sector == -1)
298 return;
299
300 ssfdc = kzalloc(sizeof(struct ssfdcr_record), GFP_KERNEL);
301 if (!ssfdc) {
302 printk(KERN_WARNING
303 "SSFDC_RO: out of memory for data structures\n");
304 return;
305 }
306
307 ssfdc->mbd.mtd = mtd;
308 ssfdc->mbd.devnum = -1;
309 ssfdc->mbd.blksize = SECTOR_SIZE;
310 ssfdc->mbd.tr = tr;
311 ssfdc->mbd.readonly = 1;
312
313 ssfdc->cis_block = cis_sector / (mtd->erasesize >> SECTOR_SHIFT);
314 ssfdc->erase_size = mtd->erasesize;
315 ssfdc->map_len = mtd->size / mtd->erasesize;
316
317 DEBUG(MTD_DEBUG_LEVEL1,
318 "SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n",
319 ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len,
320 (ssfdc->map_len + MAX_PHYS_BLK_PER_ZONE - 1) /
321 MAX_PHYS_BLK_PER_ZONE);
322
323 /* Set geometry */
324 ssfdc->heads = 16;
325 ssfdc->sectors = 32;
326 get_chs( mtd->size, NULL, &ssfdc->heads, &ssfdc->sectors);
327 ssfdc->cylinders = (unsigned short)((mtd->size >> SECTOR_SHIFT) /
328 ((long)ssfdc->sectors * (long)ssfdc->heads));
329
330 DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n",
331 ssfdc->cylinders, ssfdc->heads , ssfdc->sectors,
332 (long)ssfdc->cylinders * (long)ssfdc->heads *
333 (long)ssfdc->sectors );
334
335 ssfdc->mbd.size = (long)ssfdc->heads * (long)ssfdc->cylinders *
336 (long)ssfdc->sectors;
337
338 /* Allocate logical block map */
339 ssfdc->logic_block_map = kmalloc( sizeof(ssfdc->logic_block_map[0]) *
340 ssfdc->map_len, GFP_KERNEL);
341 if (!ssfdc->logic_block_map) {
342 printk(KERN_WARNING
343 "SSFDC_RO: out of memory for data structures\n");
344 goto out_err;
345 }
346 memset(ssfdc->logic_block_map, 0xff, sizeof(ssfdc->logic_block_map[0]) *
347 ssfdc->map_len);
348
349 /* Build logical block map */
350 if (build_logical_block_map(ssfdc) < 0)
351 goto out_err;
352
353 /* Register device + partitions */
354 if (add_mtd_blktrans_dev(&ssfdc->mbd))
355 goto out_err;
356
357 printk(KERN_INFO "SSFDC_RO: Found ssfdc%c on mtd%d (%s)\n",
358 ssfdc->mbd.devnum + 'a', mtd->index, mtd->name);
359 return;
360
361out_err:
362 kfree(ssfdc->logic_block_map);
363 kfree(ssfdc);
364}
365
366static void ssfdcr_remove_dev(struct mtd_blktrans_dev *dev)
367{
368 struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
369
370 DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: remove_dev (i=%d)\n", dev->devnum);
371
372 del_mtd_blktrans_dev(dev);
373 kfree(ssfdc->logic_block_map);
374 kfree(ssfdc);
375}
376
377static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
378 unsigned long logic_sect_no, char *buf)
379{
380 struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
381 int sectors_per_block, offset, block_address;
382
383 sectors_per_block = ssfdc->erase_size >> SECTOR_SHIFT;
384 offset = (int)(logic_sect_no % sectors_per_block);
385 block_address = (int)(logic_sect_no / sectors_per_block);
386
387 DEBUG(MTD_DEBUG_LEVEL3,
388 "SSFDC_RO: ssfdcr_readsect(%lu) sec_per_blk=%d, ofst=%d,"
389 " block_addr=%d\n", logic_sect_no, sectors_per_block, offset,
390 block_address);
391
392 if (block_address >= ssfdc->map_len)
393 BUG();
394
395 block_address = ssfdc->logic_block_map[block_address];
396
397 DEBUG(MTD_DEBUG_LEVEL3,
398 "SSFDC_RO: ssfdcr_readsect() phys_block_addr=%d\n",
399 block_address);
400
401 if (block_address < 0xffff) {
402 unsigned long sect_no;
403
404 sect_no = (unsigned long)block_address * sectors_per_block +
405 offset;
406
407 DEBUG(MTD_DEBUG_LEVEL3,
408 "SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n",
409 sect_no);
410
411 if (read_physical_sector( ssfdc->mbd.mtd, buf, sect_no ) < 0)
412 return -EIO;
413 } else {
414 memset(buf, 0xff, SECTOR_SIZE);
415 }
416
417 return 0;
418}
419
420static int ssfdcr_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
421{
422 struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
423
424 DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: ssfdcr_getgeo() C=%d, H=%d, S=%d\n",
425 ssfdc->cylinders, ssfdc->heads, ssfdc->sectors);
426
427 geo->heads = ssfdc->heads;
428 geo->sectors = ssfdc->sectors;
429 geo->cylinders = ssfdc->cylinders;
430
431 return 0;
432}
433
434/****************************************************************************
435 *
436 * Module stuff
437 *
438 ****************************************************************************/
439
440static struct mtd_blktrans_ops ssfdcr_tr = {
441 .name = "ssfdc",
442 .major = SSFDCR_MAJOR,
443 .part_bits = SSFDCR_PARTN_BITS,
444 .getgeo = ssfdcr_getgeo,
445 .readsect = ssfdcr_readsect,
446 .add_mtd = ssfdcr_add_mtd,
447 .remove_dev = ssfdcr_remove_dev,
448 .owner = THIS_MODULE,
449};
450
451static int __init init_ssfdcr(void)
452{
453 printk(KERN_INFO "SSFDC read-only Flash Translation layer\n");
454
455 return register_mtd_blktrans(&ssfdcr_tr);
456}
457
458static void __exit cleanup_ssfdcr(void)
459{
460 deregister_mtd_blktrans(&ssfdcr_tr);
461}
462
463module_init(init_ssfdcr);
464module_exit(cleanup_ssfdcr);
465
466MODULE_LICENSE("GPL");
467MODULE_AUTHOR("Claudio Lanconelli <lanconelli.claudio@eptar.com>");
468MODULE_DESCRIPTION("Flash Translation Layer for read-only SSFDC SmartMedia card");
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index b0c19292b60d..4adfe7b77031 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1264,7 +1264,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
1264{ 1264{
1265 int j, rev, ret; 1265 int j, rev, ret;
1266 struct bmac_data *bp; 1266 struct bmac_data *bp;
1267 unsigned char *addr; 1267 const unsigned char *prop_addr;
1268 unsigned char addr[6];
1268 struct net_device *dev; 1269 struct net_device *dev;
1269 int is_bmac_plus = ((int)match->data) != 0; 1270 int is_bmac_plus = ((int)match->data) != 0;
1270 1271
@@ -1272,14 +1273,16 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
1272 printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n"); 1273 printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n");
1273 return -ENODEV; 1274 return -ENODEV;
1274 } 1275 }
1275 addr = get_property(macio_get_of_node(mdev), "mac-address", NULL); 1276 prop_addr = get_property(macio_get_of_node(mdev), "mac-address", NULL);
1276 if (addr == NULL) { 1277 if (prop_addr == NULL) {
1277 addr = get_property(macio_get_of_node(mdev), "local-mac-address", NULL); 1278 prop_addr = get_property(macio_get_of_node(mdev),
1278 if (addr == NULL) { 1279 "local-mac-address", NULL);
1280 if (prop_addr == NULL) {
1279 printk(KERN_ERR "BMAC: Can't get mac-address\n"); 1281 printk(KERN_ERR "BMAC: Can't get mac-address\n");
1280 return -ENODEV; 1282 return -ENODEV;
1281 } 1283 }
1282 } 1284 }
1285 memcpy(addr, prop_addr, sizeof(addr));
1283 1286
1284 dev = alloc_etherdev(PRIV_BYTES); 1287 dev = alloc_etherdev(PRIV_BYTES);
1285 if (!dev) { 1288 if (!dev) {
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 48e68f5d1651..767203d35bc2 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -702,7 +702,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
702 desc[3].desc, 702 desc[3].desc,
703 desc[4].desc, 703 desc[4].desc,
704 desc[5].desc, 704 desc[5].desc,
705 correlator); 705 correlator,
706 &correlator);
706 } while ((lpar_rc == H_BUSY) && (retry_count--)); 707 } while ((lpar_rc == H_BUSY) && (retry_count--));
707 708
708 if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { 709 if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) {
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index 8385bf836507..f5b25bff1540 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -41,16 +41,6 @@
41#define IbmVethMcastRemoveFilter 0x2UL 41#define IbmVethMcastRemoveFilter 0x2UL
42#define IbmVethMcastClearFilterTable 0x3UL 42#define IbmVethMcastClearFilterTable 0x3UL
43 43
44/* hcall numbers */
45#define H_VIO_SIGNAL 0x104
46#define H_REGISTER_LOGICAL_LAN 0x114
47#define H_FREE_LOGICAL_LAN 0x118
48#define H_ADD_LOGICAL_LAN_BUFFER 0x11C
49#define H_SEND_LOGICAL_LAN 0x120
50#define H_MULTICAST_CTRL 0x130
51#define H_CHANGE_LOGICAL_LAN_MAC 0x14C
52#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
53
54/* hcall macros */ 44/* hcall macros */
55#define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \ 45#define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
56 plpar_hcall_norets(H_REGISTER_LOGICAL_LAN, ua, buflst, rxq, fltlst, mac) 46 plpar_hcall_norets(H_REGISTER_LOGICAL_LAN, ua, buflst, rxq, fltlst, mac)
@@ -61,8 +51,21 @@
61#define h_add_logical_lan_buffer(ua, buf) \ 51#define h_add_logical_lan_buffer(ua, buf) \
62 plpar_hcall_norets(H_ADD_LOGICAL_LAN_BUFFER, ua, buf) 52 plpar_hcall_norets(H_ADD_LOGICAL_LAN_BUFFER, ua, buf)
63 53
64#define h_send_logical_lan(ua, buf1, buf2, buf3, buf4, buf5, buf6, correlator) \ 54static inline long h_send_logical_lan(unsigned long unit_address,
65 plpar_hcall_8arg_2ret(H_SEND_LOGICAL_LAN, ua, buf1, buf2, buf3, buf4, buf5, buf6, correlator, &correlator) 55 unsigned long desc1, unsigned long desc2, unsigned long desc3,
56 unsigned long desc4, unsigned long desc5, unsigned long desc6,
57 unsigned long corellator_in, unsigned long *corellator_out)
58{
59 long rc;
60 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
61
62 rc = plpar_hcall9(H_SEND_LOGICAL_LAN, retbuf, unit_address, desc1,
63 desc2, desc3, desc4, desc5, desc6, corellator_in);
64
65 *corellator_out = retbuf[0];
66
67 return rc;
68}
66 69
67#define h_multicast_ctrl(ua, cmd, mac) \ 70#define h_multicast_ctrl(ua, cmd, mac) \
68 plpar_hcall_norets(H_MULTICAST_CTRL, ua, cmd, mac) 71 plpar_hcall_norets(H_MULTICAST_CTRL, ua, cmd, mac)
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 47d7850da47b..27c24eaa2414 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -113,7 +113,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
113 struct device_node *mace = macio_get_of_node(mdev); 113 struct device_node *mace = macio_get_of_node(mdev);
114 struct net_device *dev; 114 struct net_device *dev;
115 struct mace_data *mp; 115 struct mace_data *mp;
116 unsigned char *addr; 116 const unsigned char *addr;
117 int j, rev, rc = -EBUSY; 117 int j, rev, rc = -EBUSY;
118 118
119 if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) { 119 if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) {
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index 51ff9a9d1bb5..f3655fd772f5 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -43,6 +43,7 @@
43 * deprecated in 2.6 43 * deprecated in 2.6
44 */ 44 */
45 45
46#include <linux/err.h>
46#include <linux/module.h> 47#include <linux/module.h>
47#include <linux/kernel.h> 48#include <linux/kernel.h>
48#include <linux/version.h> 49#include <linux/version.h>
@@ -64,12 +65,13 @@ MODULE_LICENSE("Dual BSD/GPL");
64MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE)); 65MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
65MODULE_VERSION("1.0.2"); 66MODULE_VERSION("1.0.2");
66 67
67static void 68static unsigned int
68setup_sg(struct scatterlist *sg, const void *address, unsigned int length) 69setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
69{ 70{
70 sg[0].page = virt_to_page(address); 71 sg[0].page = virt_to_page(address);
71 sg[0].offset = offset_in_page(address); 72 sg[0].offset = offset_in_page(address);
72 sg[0].length = length; 73 sg[0].length = length;
74 return length;
73} 75}
74 76
75#define SHA1_PAD_SIZE 40 77#define SHA1_PAD_SIZE 40
@@ -95,8 +97,8 @@ static inline void sha_pad_init(struct sha_pad *shapad)
95 * State for an MPPE (de)compressor. 97 * State for an MPPE (de)compressor.
96 */ 98 */
97struct ppp_mppe_state { 99struct ppp_mppe_state {
98 struct crypto_tfm *arc4; 100 struct crypto_blkcipher *arc4;
99 struct crypto_tfm *sha1; 101 struct crypto_hash *sha1;
100 unsigned char *sha1_digest; 102 unsigned char *sha1_digest;
101 unsigned char master_key[MPPE_MAX_KEY_LEN]; 103 unsigned char master_key[MPPE_MAX_KEY_LEN];
102 unsigned char session_key[MPPE_MAX_KEY_LEN]; 104 unsigned char session_key[MPPE_MAX_KEY_LEN];
@@ -136,14 +138,21 @@ struct ppp_mppe_state {
136 */ 138 */
137static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey) 139static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
138{ 140{
141 struct hash_desc desc;
139 struct scatterlist sg[4]; 142 struct scatterlist sg[4];
143 unsigned int nbytes;
140 144
141 setup_sg(&sg[0], state->master_key, state->keylen); 145 nbytes = setup_sg(&sg[0], state->master_key, state->keylen);
142 setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1)); 146 nbytes += setup_sg(&sg[1], sha_pad->sha_pad1,
143 setup_sg(&sg[2], state->session_key, state->keylen); 147 sizeof(sha_pad->sha_pad1));
144 setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2)); 148 nbytes += setup_sg(&sg[2], state->session_key, state->keylen);
149 nbytes += setup_sg(&sg[3], sha_pad->sha_pad2,
150 sizeof(sha_pad->sha_pad2));
145 151
146 crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest); 152 desc.tfm = state->sha1;
153 desc.flags = 0;
154
155 crypto_hash_digest(&desc, sg, nbytes, state->sha1_digest);
147 156
148 memcpy(InterimKey, state->sha1_digest, state->keylen); 157 memcpy(InterimKey, state->sha1_digest, state->keylen);
149} 158}
@@ -156,14 +165,15 @@ static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
156{ 165{
157 unsigned char InterimKey[MPPE_MAX_KEY_LEN]; 166 unsigned char InterimKey[MPPE_MAX_KEY_LEN];
158 struct scatterlist sg_in[1], sg_out[1]; 167 struct scatterlist sg_in[1], sg_out[1];
168 struct blkcipher_desc desc = { .tfm = state->arc4 };
159 169
160 get_new_key_from_sha(state, InterimKey); 170 get_new_key_from_sha(state, InterimKey);
161 if (!initial_key) { 171 if (!initial_key) {
162 crypto_cipher_setkey(state->arc4, InterimKey, state->keylen); 172 crypto_blkcipher_setkey(state->arc4, InterimKey, state->keylen);
163 setup_sg(sg_in, InterimKey, state->keylen); 173 setup_sg(sg_in, InterimKey, state->keylen);
164 setup_sg(sg_out, state->session_key, state->keylen); 174 setup_sg(sg_out, state->session_key, state->keylen);
165 if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, 175 if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
166 state->keylen) != 0) { 176 state->keylen) != 0) {
167 printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n"); 177 printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n");
168 } 178 }
169 } else { 179 } else {
@@ -175,7 +185,7 @@ static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
175 state->session_key[1] = 0x26; 185 state->session_key[1] = 0x26;
176 state->session_key[2] = 0x9e; 186 state->session_key[2] = 0x9e;
177 } 187 }
178 crypto_cipher_setkey(state->arc4, state->session_key, state->keylen); 188 crypto_blkcipher_setkey(state->arc4, state->session_key, state->keylen);
179} 189}
180 190
181/* 191/*
@@ -196,15 +206,19 @@ static void *mppe_alloc(unsigned char *options, int optlen)
196 206
197 memset(state, 0, sizeof(*state)); 207 memset(state, 0, sizeof(*state));
198 208
199 state->arc4 = crypto_alloc_tfm("arc4", 0); 209 state->arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
200 if (!state->arc4) 210 if (IS_ERR(state->arc4)) {
211 state->arc4 = NULL;
201 goto out_free; 212 goto out_free;
213 }
202 214
203 state->sha1 = crypto_alloc_tfm("sha1", 0); 215 state->sha1 = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
204 if (!state->sha1) 216 if (IS_ERR(state->sha1)) {
217 state->sha1 = NULL;
205 goto out_free; 218 goto out_free;
219 }
206 220
207 digestsize = crypto_tfm_alg_digestsize(state->sha1); 221 digestsize = crypto_hash_digestsize(state->sha1);
208 if (digestsize < MPPE_MAX_KEY_LEN) 222 if (digestsize < MPPE_MAX_KEY_LEN)
209 goto out_free; 223 goto out_free;
210 224
@@ -229,9 +243,9 @@ static void *mppe_alloc(unsigned char *options, int optlen)
229 if (state->sha1_digest) 243 if (state->sha1_digest)
230 kfree(state->sha1_digest); 244 kfree(state->sha1_digest);
231 if (state->sha1) 245 if (state->sha1)
232 crypto_free_tfm(state->sha1); 246 crypto_free_hash(state->sha1);
233 if (state->arc4) 247 if (state->arc4)
234 crypto_free_tfm(state->arc4); 248 crypto_free_blkcipher(state->arc4);
235 kfree(state); 249 kfree(state);
236 out: 250 out:
237 return NULL; 251 return NULL;
@@ -247,9 +261,9 @@ static void mppe_free(void *arg)
247 if (state->sha1_digest) 261 if (state->sha1_digest)
248 kfree(state->sha1_digest); 262 kfree(state->sha1_digest);
249 if (state->sha1) 263 if (state->sha1)
250 crypto_free_tfm(state->sha1); 264 crypto_free_hash(state->sha1);
251 if (state->arc4) 265 if (state->arc4)
252 crypto_free_tfm(state->arc4); 266 crypto_free_blkcipher(state->arc4);
253 kfree(state); 267 kfree(state);
254 } 268 }
255} 269}
@@ -356,6 +370,7 @@ mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
356 int isize, int osize) 370 int isize, int osize)
357{ 371{
358 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; 372 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
373 struct blkcipher_desc desc = { .tfm = state->arc4 };
359 int proto; 374 int proto;
360 struct scatterlist sg_in[1], sg_out[1]; 375 struct scatterlist sg_in[1], sg_out[1];
361 376
@@ -413,7 +428,7 @@ mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
413 /* Encrypt packet */ 428 /* Encrypt packet */
414 setup_sg(sg_in, ibuf, isize); 429 setup_sg(sg_in, ibuf, isize);
415 setup_sg(sg_out, obuf, osize); 430 setup_sg(sg_out, obuf, osize);
416 if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize) != 0) { 431 if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in, isize) != 0) {
417 printk(KERN_DEBUG "crypto_cypher_encrypt failed\n"); 432 printk(KERN_DEBUG "crypto_cypher_encrypt failed\n");
418 return -1; 433 return -1;
419 } 434 }
@@ -462,6 +477,7 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
462 int osize) 477 int osize)
463{ 478{
464 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; 479 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
480 struct blkcipher_desc desc = { .tfm = state->arc4 };
465 unsigned ccount; 481 unsigned ccount;
466 int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED; 482 int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
467 int sanity = 0; 483 int sanity = 0;
@@ -599,7 +615,7 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
599 */ 615 */
600 setup_sg(sg_in, ibuf, 1); 616 setup_sg(sg_in, ibuf, 1);
601 setup_sg(sg_out, obuf, 1); 617 setup_sg(sg_out, obuf, 1);
602 if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1) != 0) { 618 if (crypto_blkcipher_decrypt(&desc, sg_out, sg_in, 1) != 0) {
603 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); 619 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
604 return DECOMP_ERROR; 620 return DECOMP_ERROR;
605 } 621 }
@@ -619,7 +635,7 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
619 /* And finally, decrypt the rest of the packet. */ 635 /* And finally, decrypt the rest of the packet. */
620 setup_sg(sg_in, ibuf + 1, isize - 1); 636 setup_sg(sg_in, ibuf + 1, isize - 1);
621 setup_sg(sg_out, obuf + 1, osize - 1); 637 setup_sg(sg_out, obuf + 1, osize - 1);
622 if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1) != 0) { 638 if (crypto_blkcipher_decrypt(&desc, sg_out, sg_in, isize - 1)) {
623 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); 639 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
624 return DECOMP_ERROR; 640 return DECOMP_ERROR;
625 } 641 }
@@ -694,8 +710,8 @@ static struct compressor ppp_mppe = {
694static int __init ppp_mppe_init(void) 710static int __init ppp_mppe_init(void)
695{ 711{
696 int answer; 712 int answer;
697 if (!(crypto_alg_available("arc4", 0) && 713 if (!(crypto_has_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC) &&
698 crypto_alg_available("sha1", 0))) 714 crypto_has_hash("sha1", 0, CRYPTO_ALG_ASYNC)))
699 return -ENODEV; 715 return -ENODEV;
700 716
701 sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL); 717 sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 88907218457a..d64e718afbd2 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1697,10 +1697,10 @@ spider_net_setup_phy(struct spider_net_card *card)
1697 */ 1697 */
1698static int 1698static int
1699spider_net_download_firmware(struct spider_net_card *card, 1699spider_net_download_firmware(struct spider_net_card *card,
1700 u8 *firmware_ptr) 1700 const void *firmware_ptr)
1701{ 1701{
1702 int sequencer, i; 1702 int sequencer, i;
1703 u32 *fw_ptr = (u32 *)firmware_ptr; 1703 const u32 *fw_ptr = firmware_ptr;
1704 1704
1705 /* stop sequencers */ 1705 /* stop sequencers */
1706 spider_net_write_reg(card, SPIDER_NET_GSINIT, 1706 spider_net_write_reg(card, SPIDER_NET_GSINIT,
@@ -1757,7 +1757,7 @@ spider_net_init_firmware(struct spider_net_card *card)
1757{ 1757{
1758 struct firmware *firmware = NULL; 1758 struct firmware *firmware = NULL;
1759 struct device_node *dn; 1759 struct device_node *dn;
1760 u8 *fw_prop = NULL; 1760 const u8 *fw_prop = NULL;
1761 int err = -ENOENT; 1761 int err = -ENOENT;
1762 int fw_size; 1762 int fw_size;
1763 1763
@@ -1783,7 +1783,7 @@ try_host_fw:
1783 if (!dn) 1783 if (!dn)
1784 goto out_err; 1784 goto out_err;
1785 1785
1786 fw_prop = (u8 *)get_property(dn, "firmware", &fw_size); 1786 fw_prop = get_property(dn, "firmware", &fw_size);
1787 if (!fw_prop) 1787 if (!fw_prop)
1788 goto out_err; 1788 goto out_err;
1789 1789
@@ -1986,7 +1986,7 @@ spider_net_setup_netdev(struct spider_net_card *card)
1986 struct net_device *netdev = card->netdev; 1986 struct net_device *netdev = card->netdev;
1987 struct device_node *dn; 1987 struct device_node *dn;
1988 struct sockaddr addr; 1988 struct sockaddr addr;
1989 u8 *mac; 1989 const u8 *mac;
1990 1990
1991 SET_MODULE_OWNER(netdev); 1991 SET_MODULE_OWNER(netdev);
1992 SET_NETDEV_DEV(netdev, &card->pdev->dev); 1992 SET_NETDEV_DEV(netdev, &card->pdev->dev);
@@ -2019,7 +2019,7 @@ spider_net_setup_netdev(struct spider_net_card *card)
2019 if (!dn) 2019 if (!dn)
2020 return -EIO; 2020 return -EIO;
2021 2021
2022 mac = (u8 *)get_property(dn, "local-mac-address", NULL); 2022 mac = get_property(dn, "local-mac-address", NULL);
2023 if (!mac) 2023 if (!mac)
2024 return -EIO; 2024 return -EIO;
2025 memcpy(addr.sa_data, mac, ETH_ALEN); 2025 memcpy(addr.sa_data, mac, ETH_ALEN);
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index e567d0ae77ee..e06c59d4dd62 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2896,7 +2896,7 @@ static int __devinit gem_get_device_address(struct gem *gp)
2896 if (use_idprom) 2896 if (use_idprom)
2897 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 2897 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
2898#elif defined(CONFIG_PPC_PMAC) 2898#elif defined(CONFIG_PPC_PMAC)
2899 unsigned char *addr; 2899 const unsigned char *addr;
2900 2900
2901 addr = get_property(gp->of_node, "local-mac-address", NULL); 2901 addr = get_property(gp->of_node, "local-mac-address", NULL);
2902 if (addr == NULL) { 2902 if (addr == NULL) {
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index e088ceefb4a3..bff04cba3fed 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -19,6 +19,7 @@
19 19
20======================================================================*/ 20======================================================================*/
21 21
22#include <linux/err.h>
22#include <linux/init.h> 23#include <linux/init.h>
23 24
24#include <linux/kernel.h> 25#include <linux/kernel.h>
@@ -1203,7 +1204,7 @@ struct airo_info {
1203 struct iw_spy_data spy_data; 1204 struct iw_spy_data spy_data;
1204 struct iw_public_data wireless_data; 1205 struct iw_public_data wireless_data;
1205 /* MIC stuff */ 1206 /* MIC stuff */
1206 struct crypto_tfm *tfm; 1207 struct crypto_cipher *tfm;
1207 mic_module mod[2]; 1208 mic_module mod[2];
1208 mic_statistics micstats; 1209 mic_statistics micstats;
1209 HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors 1210 HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
@@ -1271,7 +1272,8 @@ static int flashrestart(struct airo_info *ai,struct net_device *dev);
1271 1272
1272static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq); 1273static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);
1273static void MoveWindow(miccntx *context, u32 micSeq); 1274static void MoveWindow(miccntx *context, u32 micSeq);
1274static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *); 1275static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1276 struct crypto_cipher *tfm);
1275static void emmh32_init(emmh32_context *context); 1277static void emmh32_init(emmh32_context *context);
1276static void emmh32_update(emmh32_context *context, u8 *pOctets, int len); 1278static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
1277static void emmh32_final(emmh32_context *context, u8 digest[4]); 1279static void emmh32_final(emmh32_context *context, u8 digest[4]);
@@ -1339,10 +1341,11 @@ static int micsetup(struct airo_info *ai) {
1339 int i; 1341 int i;
1340 1342
1341 if (ai->tfm == NULL) 1343 if (ai->tfm == NULL)
1342 ai->tfm = crypto_alloc_tfm("aes", CRYPTO_TFM_REQ_MAY_SLEEP); 1344 ai->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
1343 1345
1344 if (ai->tfm == NULL) { 1346 if (IS_ERR(ai->tfm)) {
1345 airo_print_err(ai->dev->name, "failed to load transform for AES"); 1347 airo_print_err(ai->dev->name, "failed to load transform for AES");
1348 ai->tfm = NULL;
1346 return ERROR; 1349 return ERROR;
1347 } 1350 }
1348 1351
@@ -1608,7 +1611,8 @@ static void MoveWindow(miccntx *context, u32 micSeq)
1608static unsigned char aes_counter[16]; 1611static unsigned char aes_counter[16];
1609 1612
1610/* expand the key to fill the MMH coefficient array */ 1613/* expand the key to fill the MMH coefficient array */
1611static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm) 1614static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1615 struct crypto_cipher *tfm)
1612{ 1616{
1613 /* take the keying material, expand if necessary, truncate at 16-bytes */ 1617 /* take the keying material, expand if necessary, truncate at 16-bytes */
1614 /* run through AES counter mode to generate context->coeff[] */ 1618 /* run through AES counter mode to generate context->coeff[] */
@@ -1616,7 +1620,6 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct
1616 int i,j; 1620 int i,j;
1617 u32 counter; 1621 u32 counter;
1618 u8 *cipher, plain[16]; 1622 u8 *cipher, plain[16];
1619 struct scatterlist sg[1];
1620 1623
1621 crypto_cipher_setkey(tfm, pkey, 16); 1624 crypto_cipher_setkey(tfm, pkey, 16);
1622 counter = 0; 1625 counter = 0;
@@ -1627,9 +1630,8 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct
1627 aes_counter[12] = (u8)(counter >> 24); 1630 aes_counter[12] = (u8)(counter >> 24);
1628 counter++; 1631 counter++;
1629 memcpy (plain, aes_counter, 16); 1632 memcpy (plain, aes_counter, 16);
1630 sg_set_buf(sg, plain, 16); 1633 crypto_cipher_encrypt_one(tfm, plain, plain);
1631 crypto_cipher_encrypt(tfm, sg, sg, 16); 1634 cipher = plain;
1632 cipher = kmap(sg->page) + sg->offset;
1633 for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) { 1635 for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {
1634 context->coeff[i++] = ntohl(*(u32 *)&cipher[j]); 1636 context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
1635 j += 4; 1637 j += 4;
@@ -2431,7 +2433,7 @@ void stop_airo_card( struct net_device *dev, int freeres )
2431 ai->shared, ai->shared_dma); 2433 ai->shared, ai->shared_dma);
2432 } 2434 }
2433 } 2435 }
2434 crypto_free_tfm(ai->tfm); 2436 crypto_free_cipher(ai->tfm);
2435 del_airo_dev( dev ); 2437 del_airo_dev( dev );
2436 free_netdev( dev ); 2438 free_netdev( dev );
2437} 2439}
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 076bd6dcafae..7288a3eccfb3 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -176,16 +176,16 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
176 return 0; 176 return 0;
177} 177}
178 178
179static int get_children_props(struct device_node *dn, int **drc_indexes, 179static int get_children_props(struct device_node *dn, const int **drc_indexes,
180 int **drc_names, int **drc_types, int **drc_power_domains) 180 const int **drc_names, const int **drc_types,
181 const int **drc_power_domains)
181{ 182{
182 int *indexes, *names; 183 const int *indexes, *names, *types, *domains;
183 int *types, *domains;
184 184
185 indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL); 185 indexes = get_property(dn, "ibm,drc-indexes", NULL);
186 names = (int *) get_property(dn, "ibm,drc-names", NULL); 186 names = get_property(dn, "ibm,drc-names", NULL);
187 types = (int *) get_property(dn, "ibm,drc-types", NULL); 187 types = get_property(dn, "ibm,drc-types", NULL);
188 domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL); 188 domains = get_property(dn, "ibm,drc-power-domains", NULL);
189 189
190 if (!indexes || !names || !types || !domains) { 190 if (!indexes || !names || !types || !domains) {
191 /* Slot does not have dynamically-removable children */ 191 /* Slot does not have dynamically-removable children */
@@ -212,13 +212,13 @@ static int get_children_props(struct device_node *dn, int **drc_indexes,
212int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, 212int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
213 char **drc_name, char **drc_type, int *drc_power_domain) 213 char **drc_name, char **drc_type, int *drc_power_domain)
214{ 214{
215 int *indexes, *names; 215 const int *indexes, *names;
216 int *types, *domains; 216 const int *types, *domains;
217 unsigned int *my_index; 217 const unsigned int *my_index;
218 char *name_tmp, *type_tmp; 218 char *name_tmp, *type_tmp;
219 int i, rc; 219 int i, rc;
220 220
221 my_index = (int *) get_property(dn, "ibm,my-drc-index", NULL); 221 my_index = get_property(dn, "ibm,my-drc-index", NULL);
222 if (!my_index) { 222 if (!my_index) {
223 /* Node isn't DLPAR/hotplug capable */ 223 /* Node isn't DLPAR/hotplug capable */
224 return -EINVAL; 224 return -EINVAL;
@@ -265,10 +265,10 @@ static int is_php_type(char *drc_type)
265 return 1; 265 return 1;
266} 266}
267 267
268static int is_php_dn(struct device_node *dn, int **indexes, int **names, 268static int is_php_dn(struct device_node *dn, const int **indexes,
269 int **types, int **power_domains) 269 const int **names, const int **types, const int **power_domains)
270{ 270{
271 int *drc_types; 271 const int *drc_types;
272 int rc; 272 int rc;
273 273
274 rc = get_children_props(dn, indexes, names, &drc_types, power_domains); 274 rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
@@ -296,7 +296,7 @@ int rpaphp_add_slot(struct device_node *dn)
296 struct slot *slot; 296 struct slot *slot;
297 int retval = 0; 297 int retval = 0;
298 int i; 298 int i;
299 int *indexes, *names, *types, *power_domains; 299 const int *indexes, *names, *types, *power_domains;
300 char *name, *type; 300 char *name, *type;
301 301
302 dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name); 302 dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name);
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig
index 4d36208ff8de..ae89b9b88743 100644
--- a/drivers/s390/Kconfig
+++ b/drivers/s390/Kconfig
@@ -213,17 +213,35 @@ config MONREADER
213 help 213 help
214 Character device driver for reading z/VM monitor service records 214 Character device driver for reading z/VM monitor service records
215 215
216config MONWRITER
217 tristate "API for writing z/VM monitor service records"
218 default "m"
219 help
220 Character device driver for writing z/VM monitor service records
221
216endmenu 222endmenu
217 223
218menu "Cryptographic devices" 224menu "Cryptographic devices"
219 225
220config Z90CRYPT 226config ZCRYPT
221 tristate "Support for PCI-attached cryptographic adapters" 227 tristate "Support for PCI-attached cryptographic adapters"
222 default "m" 228 select ZCRYPT_MONOLITHIC if ZCRYPT="y"
223 help 229 default "m"
230 help
224 Select this option if you want to use a PCI-attached cryptographic 231 Select this option if you want to use a PCI-attached cryptographic
225 adapter like the PCI Cryptographic Accelerator (PCICA) or the PCI 232 adapter like:
226 Cryptographic Coprocessor (PCICC). This option is also available 233 + PCI Cryptographic Accelerator (PCICA)
227 as a module called z90crypt.ko. 234 + PCI Cryptographic Coprocessor (PCICC)
235 + PCI-X Cryptographic Coprocessor (PCIXCC)
236 + Crypto Express2 Coprocessor (CEX2C)
237 + Crypto Express2 Accelerator (CEX2A)
238
239config ZCRYPT_MONOLITHIC
240 bool "Monolithic zcrypt module"
241 depends on ZCRYPT="m"
242 help
243 Select this option if you want to have a single module z90crypt.ko
244 that contains all parts of the crypto device driver (ap bus,
245 request router and all the card drivers).
228 246
229endmenu 247endmenu
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 25c1ef6dfd44..d0647d116eaa 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -184,7 +184,7 @@ dasd_state_known_to_basic(struct dasd_device * device)
184 device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2, 184 device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2,
185 8 * sizeof (long)); 185 8 * sizeof (long));
186 debug_register_view(device->debug_area, &debug_sprintf_view); 186 debug_register_view(device->debug_area, &debug_sprintf_view);
187 debug_set_level(device->debug_area, DBF_EMERG); 187 debug_set_level(device->debug_area, DBF_WARNING);
188 DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created"); 188 DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created");
189 189
190 device->state = DASD_STATE_BASIC; 190 device->state = DASD_STATE_BASIC;
@@ -893,7 +893,7 @@ dasd_handle_killed_request(struct ccw_device *cdev, unsigned long intparm)
893 893
894 device = (struct dasd_device *) cqr->device; 894 device = (struct dasd_device *) cqr->device;
895 if (device == NULL || 895 if (device == NULL ||
896 device != dasd_device_from_cdev(cdev) || 896 device != dasd_device_from_cdev_locked(cdev) ||
897 strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { 897 strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
898 MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s", 898 MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
899 cdev->dev.bus_id); 899 cdev->dev.bus_id);
@@ -970,7 +970,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
970 /* first of all check for state change pending interrupt */ 970 /* first of all check for state change pending interrupt */
971 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; 971 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
972 if ((irb->scsw.dstat & mask) == mask) { 972 if ((irb->scsw.dstat & mask) == mask) {
973 device = dasd_device_from_cdev(cdev); 973 device = dasd_device_from_cdev_locked(cdev);
974 if (!IS_ERR(device)) { 974 if (!IS_ERR(device)) {
975 dasd_handle_state_change_pending(device); 975 dasd_handle_state_change_pending(device);
976 dasd_put_device(device); 976 dasd_put_device(device);
@@ -2169,7 +2169,7 @@ dasd_init(void)
2169 goto failed; 2169 goto failed;
2170 } 2170 }
2171 debug_register_view(dasd_debug_area, &debug_sprintf_view); 2171 debug_register_view(dasd_debug_area, &debug_sprintf_view);
2172 debug_set_level(dasd_debug_area, DBF_EMERG); 2172 debug_set_level(dasd_debug_area, DBF_WARNING);
2173 2173
2174 DBF_EVENT(DBF_EMERG, "%s", "debug area created"); 2174 DBF_EVENT(DBF_EMERG, "%s", "debug area created");
2175 2175
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 9af02c79ce8a..91cf971f0652 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -258,8 +258,12 @@ dasd_parse_keyword( char *parsestring ) {
258 return residual_str; 258 return residual_str;
259 } 259 }
260 if (strncmp("nopav", parsestring, length) == 0) { 260 if (strncmp("nopav", parsestring, length) == 0) {
261 dasd_nopav = 1; 261 if (MACHINE_IS_VM)
262 MESSAGE(KERN_INFO, "%s", "disable PAV mode"); 262 MESSAGE(KERN_INFO, "%s", "'nopav' not supported on VM");
263 else {
264 dasd_nopav = 1;
265 MESSAGE(KERN_INFO, "%s", "disable PAV mode");
266 }
263 return residual_str; 267 return residual_str;
264 } 268 }
265 if (strncmp("fixedbuffers", parsestring, length) == 0) { 269 if (strncmp("fixedbuffers", parsestring, length) == 0) {
@@ -523,17 +527,17 @@ dasd_create_device(struct ccw_device *cdev)
523{ 527{
524 struct dasd_devmap *devmap; 528 struct dasd_devmap *devmap;
525 struct dasd_device *device; 529 struct dasd_device *device;
530 unsigned long flags;
526 int rc; 531 int rc;
527 532
528 devmap = dasd_devmap_from_cdev(cdev); 533 devmap = dasd_devmap_from_cdev(cdev);
529 if (IS_ERR(devmap)) 534 if (IS_ERR(devmap))
530 return (void *) devmap; 535 return (void *) devmap;
531 cdev->dev.driver_data = devmap;
532 536
533 device = dasd_alloc_device(); 537 device = dasd_alloc_device();
534 if (IS_ERR(device)) 538 if (IS_ERR(device))
535 return device; 539 return device;
536 atomic_set(&device->ref_count, 2); 540 atomic_set(&device->ref_count, 3);
537 541
538 spin_lock(&dasd_devmap_lock); 542 spin_lock(&dasd_devmap_lock);
539 if (!devmap->device) { 543 if (!devmap->device) {
@@ -552,6 +556,11 @@ dasd_create_device(struct ccw_device *cdev)
552 dasd_free_device(device); 556 dasd_free_device(device);
553 return ERR_PTR(rc); 557 return ERR_PTR(rc);
554 } 558 }
559
560 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
561 cdev->dev.driver_data = device;
562 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
563
555 return device; 564 return device;
556} 565}
557 566
@@ -569,6 +578,7 @@ dasd_delete_device(struct dasd_device *device)
569{ 578{
570 struct ccw_device *cdev; 579 struct ccw_device *cdev;
571 struct dasd_devmap *devmap; 580 struct dasd_devmap *devmap;
581 unsigned long flags;
572 582
573 /* First remove device pointer from devmap. */ 583 /* First remove device pointer from devmap. */
574 devmap = dasd_find_busid(device->cdev->dev.bus_id); 584 devmap = dasd_find_busid(device->cdev->dev.bus_id);
@@ -582,9 +592,16 @@ dasd_delete_device(struct dasd_device *device)
582 devmap->device = NULL; 592 devmap->device = NULL;
583 spin_unlock(&dasd_devmap_lock); 593 spin_unlock(&dasd_devmap_lock);
584 594
585 /* Drop ref_count by 2, one for the devmap reference and 595 /* Disconnect dasd_device structure from ccw_device structure. */
586 * one for the passed reference. */ 596 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
587 atomic_sub(2, &device->ref_count); 597 device->cdev->dev.driver_data = NULL;
598 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
599
600 /*
601 * Drop ref_count by 3, one for the devmap reference, one for
602 * the cdev reference and one for the passed reference.
603 */
604 atomic_sub(3, &device->ref_count);
588 605
589 /* Wait for reference counter to drop to zero. */ 606 /* Wait for reference counter to drop to zero. */
590 wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0); 607 wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0);
@@ -593,9 +610,6 @@ dasd_delete_device(struct dasd_device *device)
593 cdev = device->cdev; 610 cdev = device->cdev;
594 device->cdev = NULL; 611 device->cdev = NULL;
595 612
596 /* Disconnect dasd_devmap structure from ccw_device structure. */
597 cdev->dev.driver_data = NULL;
598
599 /* Put ccw_device structure. */ 613 /* Put ccw_device structure. */
600 put_device(&cdev->dev); 614 put_device(&cdev->dev);
601 615
@@ -615,21 +629,32 @@ dasd_put_device_wake(struct dasd_device *device)
615 629
616/* 630/*
617 * Return dasd_device structure associated with cdev. 631 * Return dasd_device structure associated with cdev.
632 * This function needs to be called with the ccw device
633 * lock held. It can be used from interrupt context.
634 */
635struct dasd_device *
636dasd_device_from_cdev_locked(struct ccw_device *cdev)
637{
638 struct dasd_device *device = cdev->dev.driver_data;
639
640 if (!device)
641 return ERR_PTR(-ENODEV);
642 dasd_get_device(device);
643 return device;
644}
645
646/*
647 * Return dasd_device structure associated with cdev.
618 */ 648 */
619struct dasd_device * 649struct dasd_device *
620dasd_device_from_cdev(struct ccw_device *cdev) 650dasd_device_from_cdev(struct ccw_device *cdev)
621{ 651{
622 struct dasd_devmap *devmap;
623 struct dasd_device *device; 652 struct dasd_device *device;
653 unsigned long flags;
624 654
625 device = ERR_PTR(-ENODEV); 655 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
626 spin_lock(&dasd_devmap_lock); 656 device = dasd_device_from_cdev_locked(cdev);
627 devmap = cdev->dev.driver_data; 657 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
628 if (devmap && devmap->device) {
629 device = devmap->device;
630 dasd_get_device(device);
631 }
632 spin_unlock(&dasd_devmap_lock);
633 return device; 658 return device;
634} 659}
635 660
@@ -730,16 +755,17 @@ static ssize_t
730dasd_discipline_show(struct device *dev, struct device_attribute *attr, 755dasd_discipline_show(struct device *dev, struct device_attribute *attr,
731 char *buf) 756 char *buf)
732{ 757{
733 struct dasd_devmap *devmap; 758 struct dasd_device *device;
734 char *dname; 759 ssize_t len;
735 760
736 spin_lock(&dasd_devmap_lock); 761 device = dasd_device_from_cdev(to_ccwdev(dev));
737 dname = "none"; 762 if (!IS_ERR(device) && device->discipline) {
738 devmap = dev->driver_data; 763 len = snprintf(buf, PAGE_SIZE, "%s\n",
739 if (devmap && devmap->device && devmap->device->discipline) 764 device->discipline->name);
740 dname = devmap->device->discipline->name; 765 dasd_put_device(device);
741 spin_unlock(&dasd_devmap_lock); 766 } else
742 return snprintf(buf, PAGE_SIZE, "%s\n", dname); 767 len = snprintf(buf, PAGE_SIZE, "none\n");
768 return len;
743} 769}
744 770
745static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); 771static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index da65f1b032f5..e0bf30ebb215 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -678,7 +678,7 @@ int __init dasd_eer_init(void)
678 return 0; 678 return 0;
679} 679}
680 680
681void __exit dasd_eer_exit(void) 681void dasd_eer_exit(void)
682{ 682{
683 WARN_ON(misc_deregister(&dasd_eer_dev) != 0); 683 WARN_ON(misc_deregister(&dasd_eer_dev) != 0);
684} 684}
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 3ccf06d28ba1..9f52004f6fc2 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -534,6 +534,7 @@ int dasd_add_sysfs_files(struct ccw_device *);
534void dasd_remove_sysfs_files(struct ccw_device *); 534void dasd_remove_sysfs_files(struct ccw_device *);
535 535
536struct dasd_device *dasd_device_from_cdev(struct ccw_device *); 536struct dasd_device *dasd_device_from_cdev(struct ccw_device *);
537struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *);
537struct dasd_device *dasd_device_from_devindex(int); 538struct dasd_device *dasd_device_from_devindex(int);
538 539
539int dasd_parse(void); 540int dasd_parse(void);
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index ca7d51f7eccc..cab2c736683a 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -453,7 +453,7 @@ static int __init xpram_init(void)
453 PRINT_WARN("No expanded memory available\n"); 453 PRINT_WARN("No expanded memory available\n");
454 return -ENODEV; 454 return -ENODEV;
455 } 455 }
456 xpram_pages = xpram_highest_page_index(); 456 xpram_pages = xpram_highest_page_index() + 1;
457 PRINT_INFO(" %u pages expanded memory found (%lu KB).\n", 457 PRINT_INFO(" %u pages expanded memory found (%lu KB).\n",
458 xpram_pages, (unsigned long) xpram_pages*4); 458 xpram_pages, (unsigned long) xpram_pages*4);
459 rc = xpram_setup_sizes(xpram_pages); 459 rc = xpram_setup_sizes(xpram_pages);
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index 0c0162ff6c0c..c3e97b4fc186 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_S390_TAPE) += tape.o tape_class.o
28obj-$(CONFIG_S390_TAPE_34XX) += tape_34xx.o 28obj-$(CONFIG_S390_TAPE_34XX) += tape_34xx.o
29obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o 29obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o
30obj-$(CONFIG_MONREADER) += monreader.o 30obj-$(CONFIG_MONREADER) += monreader.o
31obj-$(CONFIG_MONWRITER) += monwriter.o
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
new file mode 100644
index 000000000000..1e3939aeb8ab
--- /dev/null
+++ b/drivers/s390/char/monwriter.c
@@ -0,0 +1,292 @@
1/*
2 * drivers/s390/char/monwriter.c
3 *
4 * Character device driver for writing z/VM *MONITOR service records.
5 *
6 * Copyright (C) IBM Corp. 2006
7 *
8 * Author(s): Melissa Howland <Melissa.Howland@us.ibm.com>
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/init.h>
14#include <linux/errno.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/miscdevice.h>
18#include <linux/ctype.h>
19#include <linux/poll.h>
20#include <asm/uaccess.h>
21#include <asm/ebcdic.h>
22#include <asm/io.h>
23#include <asm/appldata.h>
24#include <asm/monwriter.h>
25
26#define MONWRITE_MAX_DATALEN 4024
27
28static int mon_max_bufs = 255;
29
30struct mon_buf {
31 struct list_head list;
32 struct monwrite_hdr hdr;
33 int diag_done;
34 char *data;
35};
36
37struct mon_private {
38 struct list_head list;
39 struct monwrite_hdr hdr;
40 size_t hdr_to_read;
41 size_t data_to_read;
42 struct mon_buf *current_buf;
43 int mon_buf_count;
44};
45
46/*
47 * helper functions
48 */
49
50static int monwrite_diag(struct monwrite_hdr *myhdr, char *buffer, int fcn)
51{
52 struct appldata_product_id id;
53 int rc;
54
55 strcpy(id.prod_nr, "LNXAPPL");
56 id.prod_fn = myhdr->applid;
57 id.record_nr = myhdr->record_num;
58 id.version_nr = myhdr->version;
59 id.release_nr = myhdr->release;
60 id.mod_lvl = myhdr->mod_level;
61 rc = appldata_asm(&id, fcn, (void *) buffer, myhdr->datalen);
62 if (rc <= 0)
63 return rc;
64 if (rc == 5)
65 return -EPERM;
66 printk("DIAG X'DC' error with return code: %i\n", rc);
67 return -EINVAL;
68}
69
70static inline struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv,
71 struct monwrite_hdr *monhdr)
72{
73 struct mon_buf *entry, *next;
74
75 list_for_each_entry_safe(entry, next, &monpriv->list, list)
76 if (entry->hdr.applid == monhdr->applid &&
77 entry->hdr.record_num == monhdr->record_num &&
78 entry->hdr.version == monhdr->version &&
79 entry->hdr.release == monhdr->release &&
80 entry->hdr.mod_level == monhdr->mod_level)
81 return entry;
82 return NULL;
83}
84
85static int monwrite_new_hdr(struct mon_private *monpriv)
86{
87 struct monwrite_hdr *monhdr = &monpriv->hdr;
88 struct mon_buf *monbuf;
89 int rc;
90
91 if (monhdr->datalen > MONWRITE_MAX_DATALEN ||
92 monhdr->mon_function > MONWRITE_START_CONFIG ||
93 monhdr->hdrlen != sizeof(struct monwrite_hdr))
94 return -EINVAL;
95 monbuf = monwrite_find_hdr(monpriv, monhdr);
96 if (monbuf) {
97 if (monhdr->mon_function == MONWRITE_STOP_INTERVAL) {
98 monhdr->datalen = monbuf->hdr.datalen;
99 rc = monwrite_diag(monhdr, monbuf->data,
100 APPLDATA_STOP_REC);
101 list_del(&monbuf->list);
102 monpriv->mon_buf_count--;
103 kfree(monbuf->data);
104 kfree(monbuf);
105 monbuf = NULL;
106 }
107 } else {
108 if (monpriv->mon_buf_count >= mon_max_bufs)
109 return -ENOSPC;
110 monbuf = kzalloc(sizeof(struct mon_buf), GFP_KERNEL);
111 if (!monbuf)
112 return -ENOMEM;
113 monbuf->data = kzalloc(monbuf->hdr.datalen,
114 GFP_KERNEL | GFP_DMA);
115 if (!monbuf->data) {
116 kfree(monbuf);
117 return -ENOMEM;
118 }
119 monbuf->hdr = *monhdr;
120 list_add_tail(&monbuf->list, &monpriv->list);
121 monpriv->mon_buf_count++;
122 }
123 monpriv->current_buf = monbuf;
124 return 0;
125}
126
127static int monwrite_new_data(struct mon_private *monpriv)
128{
129 struct monwrite_hdr *monhdr = &monpriv->hdr;
130 struct mon_buf *monbuf = monpriv->current_buf;
131 int rc = 0;
132
133 switch (monhdr->mon_function) {
134 case MONWRITE_START_INTERVAL:
135 if (!monbuf->diag_done) {
136 rc = monwrite_diag(monhdr, monbuf->data,
137 APPLDATA_START_INTERVAL_REC);
138 monbuf->diag_done = 1;
139 }
140 break;
141 case MONWRITE_START_CONFIG:
142 if (!monbuf->diag_done) {
143 rc = monwrite_diag(monhdr, monbuf->data,
144 APPLDATA_START_CONFIG_REC);
145 monbuf->diag_done = 1;
146 }
147 break;
148 case MONWRITE_GEN_EVENT:
149 rc = monwrite_diag(monhdr, monbuf->data,
150 APPLDATA_GEN_EVENT_REC);
151 list_del(&monpriv->current_buf->list);
152 kfree(monpriv->current_buf->data);
153 kfree(monpriv->current_buf);
154 monpriv->current_buf = NULL;
155 break;
156 default:
157 /* monhdr->mon_function is checked in monwrite_new_hdr */
158 BUG();
159 }
160 return rc;
161}
162
163/*
164 * file operations
165 */
166
167static int monwrite_open(struct inode *inode, struct file *filp)
168{
169 struct mon_private *monpriv;
170
171 monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
172 if (!monpriv)
173 return -ENOMEM;
174 INIT_LIST_HEAD(&monpriv->list);
175 monpriv->hdr_to_read = sizeof(monpriv->hdr);
176 filp->private_data = monpriv;
177 return nonseekable_open(inode, filp);
178}
179
180static int monwrite_close(struct inode *inode, struct file *filp)
181{
182 struct mon_private *monpriv = filp->private_data;
183 struct mon_buf *entry, *next;
184
185 list_for_each_entry_safe(entry, next, &monpriv->list, list) {
186 if (entry->hdr.mon_function != MONWRITE_GEN_EVENT)
187 monwrite_diag(&entry->hdr, entry->data,
188 APPLDATA_STOP_REC);
189 monpriv->mon_buf_count--;
190 list_del(&entry->list);
191 kfree(entry->data);
192 kfree(entry);
193 }
194 kfree(monpriv);
195 return 0;
196}
197
198static ssize_t monwrite_write(struct file *filp, const char __user *data,
199 size_t count, loff_t *ppos)
200{
201 struct mon_private *monpriv = filp->private_data;
202 size_t len, written;
203 void *to;
204 int rc;
205
206 for (written = 0; written < count; ) {
207 if (monpriv->hdr_to_read) {
208 len = min(count - written, monpriv->hdr_to_read);
209 to = (char *) &monpriv->hdr +
210 sizeof(monpriv->hdr) - monpriv->hdr_to_read;
211 if (copy_from_user(to, data + written, len)) {
212 rc = -EFAULT;
213 goto out_error;
214 }
215 monpriv->hdr_to_read -= len;
216 written += len;
217 if (monpriv->hdr_to_read > 0)
218 continue;
219 rc = monwrite_new_hdr(monpriv);
220 if (rc)
221 goto out_error;
222 monpriv->data_to_read = monpriv->current_buf ?
223 monpriv->current_buf->hdr.datalen : 0;
224 }
225
226 if (monpriv->data_to_read) {
227 len = min(count - written, monpriv->data_to_read);
228 to = monpriv->current_buf->data +
229 monpriv->hdr.datalen - monpriv->data_to_read;
230 if (copy_from_user(to, data + written, len)) {
231 rc = -EFAULT;
232 goto out_error;
233 }
234 monpriv->data_to_read -= len;
235 written += len;
236 if (monpriv->data_to_read > 0)
237 continue;
238 rc = monwrite_new_data(monpriv);
239 if (rc)
240 goto out_error;
241 }
242 monpriv->hdr_to_read = sizeof(monpriv->hdr);
243 }
244 return written;
245
246out_error:
247 monpriv->data_to_read = 0;
248 monpriv->hdr_to_read = sizeof(struct monwrite_hdr);
249 return rc;
250}
251
252static struct file_operations monwrite_fops = {
253 .owner = THIS_MODULE,
254 .open = &monwrite_open,
255 .release = &monwrite_close,
256 .write = &monwrite_write,
257};
258
259static struct miscdevice mon_dev = {
260 .name = "monwriter",
261 .fops = &monwrite_fops,
262 .minor = MISC_DYNAMIC_MINOR,
263};
264
265/*
266 * module init/exit
267 */
268
269static int __init mon_init(void)
270{
271 if (MACHINE_IS_VM)
272 return misc_register(&mon_dev);
273 else
274 return -ENODEV;
275}
276
277static void __exit mon_exit(void)
278{
279 WARN_ON(misc_deregister(&mon_dev) != 0);
280}
281
282module_init(mon_init);
283module_exit(mon_exit);
284
285module_param_named(max_bufs, mon_max_bufs, int, 0644);
286MODULE_PARM_DESC(max_bufs, "Maximum number of sample monitor data buffers"
287 "that can be active at one time");
288
289MODULE_AUTHOR("Melissa Howland <Melissa.Howland@us.ibm.com>");
290MODULE_DESCRIPTION("Character device driver for writing z/VM "
291 "APPLDATA monitor records.");
292MODULE_LICENSE("GPL");
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 19762f3476aa..1678b6c757ec 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2004,2005 IBM Corporation 2 * Copyright (C) 2004,2005 IBM Corporation
3 * Interface implementation for communication with the v/VM control program 3 * Interface implementation for communication with the z/VM control program
4 * Author(s): Christian Borntraeger <cborntra@de.ibm.com> 4 * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
5 * 5 *
6 * 6 *
diff --git a/drivers/s390/char/vmcp.h b/drivers/s390/char/vmcp.h
index 87389e730465..8a5975f3dad7 100644
--- a/drivers/s390/char/vmcp.h
+++ b/drivers/s390/char/vmcp.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2004, 2005 IBM Corporation 2 * Copyright (C) 2004, 2005 IBM Corporation
3 * Interface implementation for communication with the v/VM control program 3 * Interface implementation for communication with the z/VM control program
4 * Version 1.0 4 * Version 1.0
5 * Author(s): Christian Borntraeger <cborntra@de.ibm.com> 5 * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
6 * 6 *
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index c28444af0919..3bb4e472d73d 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -256,7 +256,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
256 /* trigger path verification. */ 256 /* trigger path verification. */
257 if (sch->driver && sch->driver->verify) 257 if (sch->driver && sch->driver->verify)
258 sch->driver->verify(&sch->dev); 258 sch->driver->verify(&sch->dev);
259 else if (sch->vpm == mask) 259 else if (sch->lpm == mask)
260 goto out_unreg; 260 goto out_unreg;
261out_unlock: 261out_unlock:
262 spin_unlock_irq(&sch->lock); 262 spin_unlock_irq(&sch->lock);
@@ -378,6 +378,7 @@ __s390_process_res_acc(struct subchannel_id schid, void *data)
378 378
379 if (chp_mask == 0) { 379 if (chp_mask == 0) {
380 spin_unlock_irq(&sch->lock); 380 spin_unlock_irq(&sch->lock);
381 put_device(&sch->dev);
381 return 0; 382 return 0;
382 } 383 }
383 old_lpm = sch->lpm; 384 old_lpm = sch->lpm;
@@ -392,7 +393,7 @@ __s390_process_res_acc(struct subchannel_id schid, void *data)
392 393
393 spin_unlock_irq(&sch->lock); 394 spin_unlock_irq(&sch->lock);
394 put_device(&sch->dev); 395 put_device(&sch->dev);
395 return (res_data->fla_mask == 0xffff) ? -ENODEV : 0; 396 return 0;
396} 397}
397 398
398 399
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 89320c1ad825..2e2882daefbb 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -16,11 +16,10 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19
20#include <asm/cio.h> 19#include <asm/cio.h>
21#include <asm/delay.h> 20#include <asm/delay.h>
22#include <asm/irq.h> 21#include <asm/irq.h>
23 22#include <asm/setup.h>
24#include "airq.h" 23#include "airq.h"
25#include "cio.h" 24#include "cio.h"
26#include "css.h" 25#include "css.h"
@@ -192,7 +191,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
192 sch->orb.pfch = sch->options.prefetch == 0; 191 sch->orb.pfch = sch->options.prefetch == 0;
193 sch->orb.spnd = sch->options.suspend; 192 sch->orb.spnd = sch->options.suspend;
194 sch->orb.ssic = sch->options.suspend && sch->options.inter; 193 sch->orb.ssic = sch->options.suspend && sch->options.inter;
195 sch->orb.lpm = (lpm != 0) ? (lpm & sch->opm) : sch->lpm; 194 sch->orb.lpm = (lpm != 0) ? lpm : sch->lpm;
196#ifdef CONFIG_64BIT 195#ifdef CONFIG_64BIT
197 /* 196 /*
198 * for 64 bit we always support 64 bit IDAWs with 4k page size only 197 * for 64 bit we always support 64 bit IDAWs with 4k page size only
@@ -570,10 +569,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
570 sch->opm = 0xff; 569 sch->opm = 0xff;
571 if (!cio_is_console(sch->schid)) 570 if (!cio_is_console(sch->schid))
572 chsc_validate_chpids(sch); 571 chsc_validate_chpids(sch);
573 sch->lpm = sch->schib.pmcw.pim & 572 sch->lpm = sch->schib.pmcw.pam & sch->opm;
574 sch->schib.pmcw.pam &
575 sch->schib.pmcw.pom &
576 sch->opm;
577 573
578 CIO_DEBUG(KERN_INFO, 0, 574 CIO_DEBUG(KERN_INFO, 0,
579 "Detected device %04x on subchannel 0.%x.%04X" 575 "Detected device %04x on subchannel 0.%x.%04X"
@@ -841,14 +837,26 @@ __clear_subchannel_easy(struct subchannel_id schid)
841 return -EBUSY; 837 return -EBUSY;
842} 838}
843 839
844extern void do_reipl(unsigned long devno); 840struct sch_match_id {
845static int 841 struct subchannel_id schid;
846__shutdown_subchannel_easy(struct subchannel_id schid, void *data) 842 struct ccw_dev_id devid;
843 int rc;
844};
845
846static int __shutdown_subchannel_easy_and_match(struct subchannel_id schid,
847 void *data)
847{ 848{
848 struct schib schib; 849 struct schib schib;
850 struct sch_match_id *match_id = data;
849 851
850 if (stsch_err(schid, &schib)) 852 if (stsch_err(schid, &schib))
851 return -ENXIO; 853 return -ENXIO;
854 if (match_id && schib.pmcw.dnv &&
855 (schib.pmcw.dev == match_id->devid.devno) &&
856 (schid.ssid == match_id->devid.ssid)) {
857 match_id->schid = schid;
858 match_id->rc = 0;
859 }
852 if (!schib.pmcw.ena) 860 if (!schib.pmcw.ena)
853 return 0; 861 return 0;
854 switch(__disable_subchannel_easy(schid, &schib)) { 862 switch(__disable_subchannel_easy(schid, &schib)) {
@@ -864,18 +872,71 @@ __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
864 return 0; 872 return 0;
865} 873}
866 874
867void 875static int clear_all_subchannels_and_match(struct ccw_dev_id *devid,
868clear_all_subchannels(void) 876 struct subchannel_id *schid)
869{ 877{
878 struct sch_match_id match_id;
879
880 match_id.devid = *devid;
881 match_id.rc = -ENODEV;
870 local_irq_disable(); 882 local_irq_disable();
871 for_each_subchannel(__shutdown_subchannel_easy, NULL); 883 for_each_subchannel(__shutdown_subchannel_easy_and_match, &match_id);
884 if (match_id.rc == 0)
885 *schid = match_id.schid;
886 return match_id.rc;
872} 887}
873 888
889
890void clear_all_subchannels(void)
891{
892 local_irq_disable();
893 for_each_subchannel(__shutdown_subchannel_easy_and_match, NULL);
894}
895
896extern void do_reipl_asm(__u32 schid);
897
874/* Make sure all subchannels are quiet before we re-ipl an lpar. */ 898/* Make sure all subchannels are quiet before we re-ipl an lpar. */
875void 899void reipl_ccw_dev(struct ccw_dev_id *devid)
876reipl(unsigned long devno)
877{ 900{
878 clear_all_subchannels(); 901 struct subchannel_id schid;
902
903 if (clear_all_subchannels_and_match(devid, &schid))
904 panic("IPL Device not found\n");
879 cio_reset_channel_paths(); 905 cio_reset_channel_paths();
880 do_reipl(devno); 906 do_reipl_asm(*((__u32*)&schid));
907}
908
909extern struct schib ipl_schib;
910
911/*
912 * ipl_save_parameters gets called very early. It is not allowed to access
913 * anything in the bss section at all. The bss section is not cleared yet,
914 * but may contain some ipl parameters written by the firmware.
915 * These parameters (if present) are copied to 0x2000.
916 * To avoid corruption of the ipl parameters, all variables used by this
917 * function must reside on the stack or in the data section.
918 */
919void ipl_save_parameters(void)
920{
921 struct subchannel_id schid;
922 unsigned int *ipl_ptr;
923 void *src, *dst;
924
925 schid = *(struct subchannel_id *)__LC_SUBCHANNEL_ID;
926 if (!schid.one)
927 return;
928 if (stsch(schid, &ipl_schib))
929 return;
930 if (!ipl_schib.pmcw.dnv)
931 return;
932 ipl_devno = ipl_schib.pmcw.dev;
933 ipl_flags |= IPL_DEVNO_VALID;
934 if (!ipl_schib.pmcw.qf)
935 return;
936 ipl_flags |= IPL_PARMBLOCK_VALID;
937 ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR;
938 src = (void *)(unsigned long)*ipl_ptr;
939 dst = (void *)IPL_PARMBLOCK_ORIGIN;
940 memmove(dst, src, PAGE_SIZE);
941 *ipl_ptr = IPL_PARMBLOCK_ORIGIN;
881} 942}
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 13eeea3d547f..7086a74e9871 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -182,136 +182,141 @@ get_subchannel_by_schid(struct subchannel_id schid)
182 return dev ? to_subchannel(dev) : NULL; 182 return dev ? to_subchannel(dev) : NULL;
183} 183}
184 184
185 185static inline int css_get_subchannel_status(struct subchannel *sch)
186static inline int
187css_get_subchannel_status(struct subchannel *sch, struct subchannel_id schid)
188{ 186{
189 struct schib schib; 187 struct schib schib;
190 int cc;
191 188
192 cc = stsch(schid, &schib); 189 if (stsch(sch->schid, &schib) || !schib.pmcw.dnv)
193 if (cc)
194 return CIO_GONE;
195 if (!schib.pmcw.dnv)
196 return CIO_GONE; 190 return CIO_GONE;
197 if (sch && sch->schib.pmcw.dnv && 191 if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev))
198 (schib.pmcw.dev != sch->schib.pmcw.dev))
199 return CIO_REVALIDATE; 192 return CIO_REVALIDATE;
200 if (sch && !sch->lpm) 193 if (!sch->lpm)
201 return CIO_NO_PATH; 194 return CIO_NO_PATH;
202 return CIO_OPER; 195 return CIO_OPER;
203} 196}
204 197
205static int 198static int css_evaluate_known_subchannel(struct subchannel *sch, int slow)
206css_evaluate_subchannel(struct subchannel_id schid, int slow)
207{ 199{
208 int event, ret, disc; 200 int event, ret, disc;
209 struct subchannel *sch;
210 unsigned long flags; 201 unsigned long flags;
202 enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE } action;
211 203
212 sch = get_subchannel_by_schid(schid); 204 spin_lock_irqsave(&sch->lock, flags);
213 disc = sch ? device_is_disconnected(sch) : 0; 205 disc = device_is_disconnected(sch);
214 if (disc && slow) { 206 if (disc && slow) {
215 if (sch) 207 /* Disconnected devices are evaluated directly only.*/
216 put_device(&sch->dev); 208 spin_unlock_irqrestore(&sch->lock, flags);
217 return 0; /* Already processed. */ 209 return 0;
218 } 210 }
219 /* 211 /* No interrupt after machine check - kill pending timers. */
220 * We've got a machine check, so running I/O won't get an interrupt. 212 device_kill_pending_timer(sch);
221 * Kill any pending timers.
222 */
223 if (sch)
224 device_kill_pending_timer(sch);
225 if (!disc && !slow) { 213 if (!disc && !slow) {
226 if (sch) 214 /* Non-disconnected devices are evaluated on the slow path. */
227 put_device(&sch->dev); 215 spin_unlock_irqrestore(&sch->lock, flags);
228 return -EAGAIN; /* Will be done on the slow path. */ 216 return -EAGAIN;
229 } 217 }
230 event = css_get_subchannel_status(sch, schid); 218 event = css_get_subchannel_status(sch);
231 CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n", 219 CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n",
232 schid.ssid, schid.sch_no, event, 220 sch->schid.ssid, sch->schid.sch_no, event,
233 sch?(disc?"disconnected":"normal"):"unknown", 221 disc ? "disconnected" : "normal",
234 slow?"slow":"fast"); 222 slow ? "slow" : "fast");
223 /* Analyze subchannel status. */
224 action = NONE;
235 switch (event) { 225 switch (event) {
236 case CIO_NO_PATH: 226 case CIO_NO_PATH:
237 case CIO_GONE: 227 if (disc) {
238 if (!sch) { 228 /* Check if paths have become available. */
239 /* Never used this subchannel. Ignore. */ 229 action = REPROBE;
240 ret = 0;
241 break; 230 break;
242 } 231 }
243 if (disc && (event == CIO_NO_PATH)) { 232 /* fall through */
244 /* 233 case CIO_GONE:
245 * Uargh, hack again. Because we don't get a machine 234 /* Prevent unwanted effects when opening lock. */
246 * check on configure on, our path bookkeeping can 235 cio_disable_subchannel(sch);
247 * be out of date here (it's fine while we only do 236 device_set_disconnected(sch);
248 * logical varying or get chsc machine checks). We 237 /* Ask driver what to do with device. */
249 * need to force reprobing or we might miss devices 238 action = UNREGISTER;
250 * coming operational again. It won't do harm in real 239 if (sch->driver && sch->driver->notify) {
251 * no path situations.
252 */
253 spin_lock_irqsave(&sch->lock, flags);
254 device_trigger_reprobe(sch);
255 spin_unlock_irqrestore(&sch->lock, flags); 240 spin_unlock_irqrestore(&sch->lock, flags);
256 ret = 0; 241 ret = sch->driver->notify(&sch->dev, event);
257 break; 242 spin_lock_irqsave(&sch->lock, flags);
258 } 243 if (ret)
259 if (sch->driver && sch->driver->notify && 244 action = NONE;
260 sch->driver->notify(&sch->dev, event)) {
261 cio_disable_subchannel(sch);
262 device_set_disconnected(sch);
263 ret = 0;
264 break;
265 } 245 }
266 /*
267 * Unregister subchannel.
268 * The device will be killed automatically.
269 */
270 cio_disable_subchannel(sch);
271 css_sch_device_unregister(sch);
272 /* Reset intparm to zeroes. */
273 sch->schib.pmcw.intparm = 0;
274 cio_modify(sch);
275 put_device(&sch->dev);
276 ret = 0;
277 break; 246 break;
278 case CIO_REVALIDATE: 247 case CIO_REVALIDATE:
279 /* 248 /* Device will be removed, so no notify necessary. */
280 * Revalidation machine check. Sick. 249 if (disc)
281 * We don't notify the driver since we have to throw the device 250 /* Reprobe because immediate unregister might block. */
282 * away in any case. 251 action = REPROBE;
283 */ 252 else
284 if (!disc) { 253 action = UNREGISTER_PROBE;
285 css_sch_device_unregister(sch);
286 /* Reset intparm to zeroes. */
287 sch->schib.pmcw.intparm = 0;
288 cio_modify(sch);
289 put_device(&sch->dev);
290 ret = css_probe_device(schid);
291 } else {
292 /*
293 * We can't immediately deregister the disconnected
294 * device since it might block.
295 */
296 spin_lock_irqsave(&sch->lock, flags);
297 device_trigger_reprobe(sch);
298 spin_unlock_irqrestore(&sch->lock, flags);
299 ret = 0;
300 }
301 break; 254 break;
302 case CIO_OPER: 255 case CIO_OPER:
303 if (disc) { 256 if (disc)
304 spin_lock_irqsave(&sch->lock, flags);
305 /* Get device operational again. */ 257 /* Get device operational again. */
306 device_trigger_reprobe(sch); 258 action = REPROBE;
307 spin_unlock_irqrestore(&sch->lock, flags); 259 break;
308 } 260 }
309 ret = sch ? 0 : css_probe_device(schid); 261 /* Perform action. */
262 ret = 0;
263 switch (action) {
264 case UNREGISTER:
265 case UNREGISTER_PROBE:
266 /* Unregister device (will use subchannel lock). */
267 spin_unlock_irqrestore(&sch->lock, flags);
268 css_sch_device_unregister(sch);
269 spin_lock_irqsave(&sch->lock, flags);
270
271 /* Reset intparm to zeroes. */
272 sch->schib.pmcw.intparm = 0;
273 cio_modify(sch);
274
275 /* Probe if necessary. */
276 if (action == UNREGISTER_PROBE)
277 ret = css_probe_device(sch->schid);
278 break;
279 case REPROBE:
280 device_trigger_reprobe(sch);
310 break; 281 break;
311 default: 282 default:
312 BUG(); 283 break;
313 ret = 0; 284 }
285 spin_unlock_irqrestore(&sch->lock, flags);
286
287 return ret;
288}
289
290static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow)
291{
292 struct schib schib;
293
294 if (!slow) {
295 /* Will be done on the slow path. */
296 return -EAGAIN;
314 } 297 }
298 if (stsch(schid, &schib) || !schib.pmcw.dnv) {
299 /* Unusable - ignore. */
300 return 0;
301 }
302 CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, unknown, "
303 "slow path.\n", schid.ssid, schid.sch_no, CIO_OPER);
304
305 return css_probe_device(schid);
306}
307
308static int css_evaluate_subchannel(struct subchannel_id schid, int slow)
309{
310 struct subchannel *sch;
311 int ret;
312
313 sch = get_subchannel_by_schid(schid);
314 if (sch) {
315 ret = css_evaluate_known_subchannel(sch, slow);
316 put_device(&sch->dev);
317 } else
318 ret = css_evaluate_new_subchannel(schid, slow);
319
315 return ret; 320 return ret;
316} 321}
317 322
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 646da5640401..688945662c15 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -52,53 +52,81 @@ ccw_bus_match (struct device * dev, struct device_driver * drv)
52 return 1; 52 return 1;
53} 53}
54 54
55/* 55/* Store modalias string delimited by prefix/suffix string into buffer with
56 * Hotplugging interface for ccw devices. 56 * specified size. Return length of resulting string (excluding trailing '\0')
57 * Heavily modeled on pci and usb hotplug. 57 * even if string doesn't fit buffer (snprintf semantics). */
58 */ 58static int snprint_alias(char *buf, size_t size, const char *prefix,
59static int 59 struct ccw_device_id *id, const char *suffix)
60ccw_uevent (struct device *dev, char **envp, int num_envp,
61 char *buffer, int buffer_size)
62{ 60{
63 struct ccw_device *cdev = to_ccwdev(dev); 61 int len;
64 int i = 0;
65 int length = 0;
66 62
67 if (!cdev) 63 len = snprintf(buf, size, "%sccw:t%04Xm%02X", prefix, id->cu_type,
68 return -ENODEV; 64 id->cu_model);
65 if (len > size)
66 return len;
67 buf += len;
68 size -= len;
69 69
70 /* what we want to pass to /sbin/hotplug */ 70 if (id->dev_type != 0)
71 len += snprintf(buf, size, "dt%04Xdm%02X%s", id->dev_type,
72 id->dev_model, suffix);
73 else
74 len += snprintf(buf, size, "dtdm%s", suffix);
71 75
72 envp[i++] = buffer; 76 return len;
73 length += scnprintf(buffer, buffer_size - length, "CU_TYPE=%04X", 77}
74 cdev->id.cu_type);
75 if ((buffer_size - length <= 0) || (i >= num_envp))
76 return -ENOMEM;
77 ++length;
78 buffer += length;
79 78
79/* Set up environment variables for ccw device uevent. Return 0 on success,
80 * non-zero otherwise. */
81static int ccw_uevent(struct device *dev, char **envp, int num_envp,
82 char *buffer, int buffer_size)
83{
84 struct ccw_device *cdev = to_ccwdev(dev);
85 struct ccw_device_id *id = &(cdev->id);
86 int i = 0;
87 int len;
88
89 /* CU_TYPE= */
90 len = snprintf(buffer, buffer_size, "CU_TYPE=%04X", id->cu_type) + 1;
91 if (len > buffer_size || i >= num_envp)
92 return -ENOMEM;
80 envp[i++] = buffer; 93 envp[i++] = buffer;
81 length += scnprintf(buffer, buffer_size - length, "CU_MODEL=%02X", 94 buffer += len;
82 cdev->id.cu_model); 95 buffer_size -= len;
83 if ((buffer_size - length <= 0) || (i >= num_envp)) 96
97 /* CU_MODEL= */
98 len = snprintf(buffer, buffer_size, "CU_MODEL=%02X", id->cu_model) + 1;
99 if (len > buffer_size || i >= num_envp)
84 return -ENOMEM; 100 return -ENOMEM;
85 ++length; 101 envp[i++] = buffer;
86 buffer += length; 102 buffer += len;
103 buffer_size -= len;
87 104
88 /* The next two can be zero, that's ok for us */ 105 /* The next two can be zero, that's ok for us */
89 envp[i++] = buffer; 106 /* DEV_TYPE= */
90 length += scnprintf(buffer, buffer_size - length, "DEV_TYPE=%04X", 107 len = snprintf(buffer, buffer_size, "DEV_TYPE=%04X", id->dev_type) + 1;
91 cdev->id.dev_type); 108 if (len > buffer_size || i >= num_envp)
92 if ((buffer_size - length <= 0) || (i >= num_envp))
93 return -ENOMEM; 109 return -ENOMEM;
94 ++length; 110 envp[i++] = buffer;
95 buffer += length; 111 buffer += len;
112 buffer_size -= len;
96 113
114 /* DEV_MODEL= */
115 len = snprintf(buffer, buffer_size, "DEV_MODEL=%02X",
116 (unsigned char) id->dev_model) + 1;
117 if (len > buffer_size || i >= num_envp)
118 return -ENOMEM;
97 envp[i++] = buffer; 119 envp[i++] = buffer;
98 length += scnprintf(buffer, buffer_size - length, "DEV_MODEL=%02X", 120 buffer += len;
99 cdev->id.dev_model); 121 buffer_size -= len;
100 if ((buffer_size - length <= 0) || (i >= num_envp)) 122
123 /* MODALIAS= */
124 len = snprint_alias(buffer, buffer_size, "MODALIAS=", id, "") + 1;
125 if (len > buffer_size || i >= num_envp)
101 return -ENOMEM; 126 return -ENOMEM;
127 envp[i++] = buffer;
128 buffer += len;
129 buffer_size -= len;
102 130
103 envp[i] = NULL; 131 envp[i] = NULL;
104 132
@@ -251,16 +279,11 @@ modalias_show (struct device *dev, struct device_attribute *attr, char *buf)
251{ 279{
252 struct ccw_device *cdev = to_ccwdev(dev); 280 struct ccw_device *cdev = to_ccwdev(dev);
253 struct ccw_device_id *id = &(cdev->id); 281 struct ccw_device_id *id = &(cdev->id);
254 int ret; 282 int len;
255 283
256 ret = sprintf(buf, "ccw:t%04Xm%02X", 284 len = snprint_alias(buf, PAGE_SIZE, "", id, "\n") + 1;
257 id->cu_type, id->cu_model); 285
258 if (id->dev_type != 0) 286 return len > PAGE_SIZE ? PAGE_SIZE : len;
259 ret += sprintf(buf + ret, "dt%04Xdm%02X\n",
260 id->dev_type, id->dev_model);
261 else
262 ret += sprintf(buf + ret, "dtdm\n");
263 return ret;
264} 287}
265 288
266static ssize_t 289static ssize_t
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 35e162ba6d54..dace46fc32e8 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -232,10 +232,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
232 */ 232 */
233 old_lpm = sch->lpm; 233 old_lpm = sch->lpm;
234 stsch(sch->schid, &sch->schib); 234 stsch(sch->schid, &sch->schib);
235 sch->lpm = sch->schib.pmcw.pim & 235 sch->lpm = sch->schib.pmcw.pam & sch->opm;
236 sch->schib.pmcw.pam &
237 sch->schib.pmcw.pom &
238 sch->opm;
239 /* Check since device may again have become not operational. */ 236 /* Check since device may again have become not operational. */
240 if (!sch->schib.pmcw.dnv) 237 if (!sch->schib.pmcw.dnv)
241 state = DEV_STATE_NOT_OPER; 238 state = DEV_STATE_NOT_OPER;
@@ -267,6 +264,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
267 notify = 1; 264 notify = 1;
268 } 265 }
269 /* fill out sense information */ 266 /* fill out sense information */
267 memset(&cdev->id, 0, sizeof(cdev->id));
270 cdev->id.cu_type = cdev->private->senseid.cu_type; 268 cdev->id.cu_type = cdev->private->senseid.cu_type;
271 cdev->id.cu_model = cdev->private->senseid.cu_model; 269 cdev->id.cu_model = cdev->private->senseid.cu_model;
272 cdev->id.dev_type = cdev->private->senseid.dev_type; 270 cdev->id.dev_type = cdev->private->senseid.dev_type;
@@ -454,8 +452,8 @@ ccw_device_sense_pgid_done(struct ccw_device *cdev, int err)
454 return; 452 return;
455 } 453 }
456 /* Start Path Group verification. */ 454 /* Start Path Group verification. */
457 sch->vpm = 0; /* Start with no path groups set. */
458 cdev->private->state = DEV_STATE_VERIFY; 455 cdev->private->state = DEV_STATE_VERIFY;
456 cdev->private->flags.doverify = 0;
459 ccw_device_verify_start(cdev); 457 ccw_device_verify_start(cdev);
460} 458}
461 459
@@ -555,7 +553,19 @@ ccw_device_nopath_notify(void *data)
555void 553void
556ccw_device_verify_done(struct ccw_device *cdev, int err) 554ccw_device_verify_done(struct ccw_device *cdev, int err)
557{ 555{
558 cdev->private->flags.doverify = 0; 556 struct subchannel *sch;
557
558 sch = to_subchannel(cdev->dev.parent);
559 /* Update schib - pom may have changed. */
560 stsch(sch->schid, &sch->schib);
561 /* Update lpm with verified path mask. */
562 sch->lpm = sch->vpm;
563 /* Repeat path verification? */
564 if (cdev->private->flags.doverify) {
565 cdev->private->flags.doverify = 0;
566 ccw_device_verify_start(cdev);
567 return;
568 }
559 switch (err) { 569 switch (err) {
560 case -EOPNOTSUPP: /* path grouping not supported, just set online. */ 570 case -EOPNOTSUPP: /* path grouping not supported, just set online. */
561 cdev->private->options.pgroup = 0; 571 cdev->private->options.pgroup = 0;
@@ -613,6 +623,7 @@ ccw_device_online(struct ccw_device *cdev)
613 if (!cdev->private->options.pgroup) { 623 if (!cdev->private->options.pgroup) {
614 /* Start initial path verification. */ 624 /* Start initial path verification. */
615 cdev->private->state = DEV_STATE_VERIFY; 625 cdev->private->state = DEV_STATE_VERIFY;
626 cdev->private->flags.doverify = 0;
616 ccw_device_verify_start(cdev); 627 ccw_device_verify_start(cdev);
617 return 0; 628 return 0;
618 } 629 }
@@ -659,7 +670,6 @@ ccw_device_offline(struct ccw_device *cdev)
659 /* Are we doing path grouping? */ 670 /* Are we doing path grouping? */
660 if (!cdev->private->options.pgroup) { 671 if (!cdev->private->options.pgroup) {
661 /* No, set state offline immediately. */ 672 /* No, set state offline immediately. */
662 sch->vpm = 0;
663 ccw_device_done(cdev, DEV_STATE_OFFLINE); 673 ccw_device_done(cdev, DEV_STATE_OFFLINE);
664 return 0; 674 return 0;
665 } 675 }
@@ -780,6 +790,7 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event)
780 } 790 }
781 /* Device is idle, we can do the path verification. */ 791 /* Device is idle, we can do the path verification. */
782 cdev->private->state = DEV_STATE_VERIFY; 792 cdev->private->state = DEV_STATE_VERIFY;
793 cdev->private->flags.doverify = 0;
783 ccw_device_verify_start(cdev); 794 ccw_device_verify_start(cdev);
784} 795}
785 796
@@ -1042,9 +1053,9 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event)
1042} 1053}
1043 1054
1044static void 1055static void
1045ccw_device_wait4io_verify(struct ccw_device *cdev, enum dev_event dev_event) 1056ccw_device_delay_verify(struct ccw_device *cdev, enum dev_event dev_event)
1046{ 1057{
1047 /* When the I/O has terminated, we have to start verification. */ 1058 /* Start verification after current task finished. */
1048 cdev->private->flags.doverify = 1; 1059 cdev->private->flags.doverify = 1;
1049} 1060}
1050 1061
@@ -1110,10 +1121,7 @@ device_trigger_reprobe(struct subchannel *sch)
1110 * The pim, pam, pom values may not be accurate, but they are the best 1121 * The pim, pam, pom values may not be accurate, but they are the best
1111 * we have before performing device selection :/ 1122 * we have before performing device selection :/
1112 */ 1123 */
1113 sch->lpm = sch->schib.pmcw.pim & 1124 sch->lpm = sch->schib.pmcw.pam & sch->opm;
1114 sch->schib.pmcw.pam &
1115 sch->schib.pmcw.pom &
1116 sch->opm;
1117 /* Re-set some bits in the pmcw that were lost. */ 1125 /* Re-set some bits in the pmcw that were lost. */
1118 sch->schib.pmcw.isc = 3; 1126 sch->schib.pmcw.isc = 3;
1119 sch->schib.pmcw.csense = 1; 1127 sch->schib.pmcw.csense = 1;
@@ -1237,7 +1245,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
1237 [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, 1245 [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
1238 [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, 1246 [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq,
1239 [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, 1247 [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout,
1240 [DEV_EVENT_VERIFY] = ccw_device_nop, 1248 [DEV_EVENT_VERIFY] = ccw_device_delay_verify,
1241 }, 1249 },
1242 [DEV_STATE_ONLINE] = { 1250 [DEV_STATE_ONLINE] = {
1243 [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, 1251 [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
@@ -1280,7 +1288,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
1280 [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, 1288 [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
1281 [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, 1289 [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq,
1282 [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, 1290 [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout,
1283 [DEV_EVENT_VERIFY] = ccw_device_wait4io_verify, 1291 [DEV_EVENT_VERIFY] = ccw_device_delay_verify,
1284 }, 1292 },
1285 [DEV_STATE_QUIESCE] = { 1293 [DEV_STATE_QUIESCE] = {
1286 [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, 1294 [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done,
@@ -1293,7 +1301,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
1293 [DEV_EVENT_NOTOPER] = ccw_device_nop, 1301 [DEV_EVENT_NOTOPER] = ccw_device_nop,
1294 [DEV_EVENT_INTERRUPT] = ccw_device_start_id, 1302 [DEV_EVENT_INTERRUPT] = ccw_device_start_id,
1295 [DEV_EVENT_TIMEOUT] = ccw_device_bug, 1303 [DEV_EVENT_TIMEOUT] = ccw_device_bug,
1296 [DEV_EVENT_VERIFY] = ccw_device_nop, 1304 [DEV_EVENT_VERIFY] = ccw_device_start_id,
1297 }, 1305 },
1298 [DEV_STATE_DISCONNECTED_SENSE_ID] = { 1306 [DEV_STATE_DISCONNECTED_SENSE_ID] = {
1299 [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, 1307 [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper,
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 9e3de0bd59b5..93a897eebfff 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -96,6 +96,12 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
96 ret = cio_set_options (sch, flags); 96 ret = cio_set_options (sch, flags);
97 if (ret) 97 if (ret)
98 return ret; 98 return ret;
99 /* Adjust requested path mask to excluded varied off paths. */
100 if (lpm) {
101 lpm &= sch->opm;
102 if (lpm == 0)
103 return -EACCES;
104 }
99 ret = cio_start_key (sch, cpa, lpm, key); 105 ret = cio_start_key (sch, cpa, lpm, key);
100 if (ret == 0) 106 if (ret == 0)
101 cdev->private->intparm = intparm; 107 cdev->private->intparm = intparm;
@@ -250,7 +256,7 @@ ccw_device_get_path_mask(struct ccw_device *cdev)
250 if (!sch) 256 if (!sch)
251 return 0; 257 return 0;
252 else 258 else
253 return sch->vpm; 259 return sch->lpm;
254} 260}
255 261
256static void 262static void
@@ -304,7 +310,7 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, _
304 sch = to_subchannel(cdev->dev.parent); 310 sch = to_subchannel(cdev->dev.parent);
305 do { 311 do {
306 ret = cio_start (sch, ccw, lpm); 312 ret = cio_start (sch, ccw, lpm);
307 if ((ret == -EBUSY) || (ret == -EACCES)) { 313 if (ret == -EBUSY) {
308 /* Try again later. */ 314 /* Try again later. */
309 spin_unlock_irq(&sch->lock); 315 spin_unlock_irq(&sch->lock);
310 msleep(10); 316 msleep(10);
@@ -433,6 +439,13 @@ read_conf_data_lpm (struct ccw_device *cdev, void **buffer, int *length, __u8 lp
433 if (!ciw || ciw->cmd == 0) 439 if (!ciw || ciw->cmd == 0)
434 return -EOPNOTSUPP; 440 return -EOPNOTSUPP;
435 441
442 /* Adjust requested path mask to excluded varied off paths. */
443 if (lpm) {
444 lpm &= sch->opm;
445 if (lpm == 0)
446 return -EACCES;
447 }
448
436 rcd_ccw = kzalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); 449 rcd_ccw = kzalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
437 if (!rcd_ccw) 450 if (!rcd_ccw)
438 return -ENOMEM; 451 return -ENOMEM;
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 1693a102dcfe..8ca2d078848c 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -245,18 +245,17 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
245 memset(&cdev->private->irb, 0, sizeof(struct irb)); 245 memset(&cdev->private->irb, 0, sizeof(struct irb));
246 246
247 /* Try multiple times. */ 247 /* Try multiple times. */
248 ret = -ENODEV; 248 ret = -EACCES;
249 if (cdev->private->iretry > 0) { 249 if (cdev->private->iretry > 0) {
250 cdev->private->iretry--; 250 cdev->private->iretry--;
251 ret = cio_start (sch, cdev->private->iccws, 251 ret = cio_start (sch, cdev->private->iccws,
252 cdev->private->imask); 252 cdev->private->imask);
253 /* ret is 0, -EBUSY, -EACCES or -ENODEV */ 253 /* We expect an interrupt in case of success or busy
254 if ((ret != -EACCES) && (ret != -ENODEV)) 254 * indication. */
255 if ((ret == 0) || (ret == -EBUSY))
255 return ret; 256 return ret;
256 } 257 }
257 /* PGID command failed on this path. Switch it off. */ 258 /* PGID command failed on this path. */
258 sch->lpm &= ~cdev->private->imask;
259 sch->vpm &= ~cdev->private->imask;
260 CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " 259 CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
261 "0.%x.%04x, lpm %02X, became 'not operational'\n", 260 "0.%x.%04x, lpm %02X, became 'not operational'\n",
262 cdev->private->devno, sch->schid.ssid, 261 cdev->private->devno, sch->schid.ssid,
@@ -286,18 +285,17 @@ static int __ccw_device_do_nop(struct ccw_device *cdev)
286 memset(&cdev->private->irb, 0, sizeof(struct irb)); 285 memset(&cdev->private->irb, 0, sizeof(struct irb));
287 286
288 /* Try multiple times. */ 287 /* Try multiple times. */
289 ret = -ENODEV; 288 ret = -EACCES;
290 if (cdev->private->iretry > 0) { 289 if (cdev->private->iretry > 0) {
291 cdev->private->iretry--; 290 cdev->private->iretry--;
292 ret = cio_start (sch, cdev->private->iccws, 291 ret = cio_start (sch, cdev->private->iccws,
293 cdev->private->imask); 292 cdev->private->imask);
294 /* ret is 0, -EBUSY, -EACCES or -ENODEV */ 293 /* We expect an interrupt in case of success or busy
295 if ((ret != -EACCES) && (ret != -ENODEV)) 294 * indication. */
295 if ((ret == 0) || (ret == -EBUSY))
296 return ret; 296 return ret;
297 } 297 }
298 /* nop command failed on this path. Switch it off. */ 298 /* nop command failed on this path. */
299 sch->lpm &= ~cdev->private->imask;
300 sch->vpm &= ~cdev->private->imask;
301 CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel " 299 CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel "
302 "0.%x.%04x, lpm %02X, became 'not operational'\n", 300 "0.%x.%04x, lpm %02X, became 'not operational'\n",
303 cdev->private->devno, sch->schid.ssid, 301 cdev->private->devno, sch->schid.ssid,
@@ -372,27 +370,32 @@ static void
372__ccw_device_verify_start(struct ccw_device *cdev) 370__ccw_device_verify_start(struct ccw_device *cdev)
373{ 371{
374 struct subchannel *sch; 372 struct subchannel *sch;
375 __u8 imask, func; 373 __u8 func;
376 int ret; 374 int ret;
377 375
378 sch = to_subchannel(cdev->dev.parent); 376 sch = to_subchannel(cdev->dev.parent);
379 while (sch->vpm != sch->lpm) { 377 /* Repeat for all paths. */
380 /* Find first unequal bit in vpm vs. lpm */ 378 for (; cdev->private->imask; cdev->private->imask >>= 1,
381 for (imask = 0x80; imask != 0; imask >>= 1) 379 cdev->private->iretry = 5) {
382 if ((sch->vpm & imask) != (sch->lpm & imask)) 380 if ((cdev->private->imask & sch->schib.pmcw.pam) == 0)
383 break; 381 /* Path not available, try next. */
384 cdev->private->imask = imask; 382 continue;
385 if (cdev->private->options.pgroup) { 383 if (cdev->private->options.pgroup) {
386 func = (sch->vpm & imask) ? 384 if (sch->opm & cdev->private->imask)
387 SPID_FUNC_RESIGN : SPID_FUNC_ESTABLISH; 385 func = SPID_FUNC_ESTABLISH;
386 else
387 func = SPID_FUNC_RESIGN;
388 ret = __ccw_device_do_pgid(cdev, func); 388 ret = __ccw_device_do_pgid(cdev, func);
389 } else 389 } else
390 ret = __ccw_device_do_nop(cdev); 390 ret = __ccw_device_do_nop(cdev);
391 /* We expect an interrupt in case of success or busy
392 * indication. */
391 if (ret == 0 || ret == -EBUSY) 393 if (ret == 0 || ret == -EBUSY)
392 return; 394 return;
393 cdev->private->iretry = 5; 395 /* Permanent path failure, try next. */
394 } 396 }
395 ccw_device_verify_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV); 397 /* Done with all paths. */
398 ccw_device_verify_done(cdev, (sch->vpm != 0) ? 0 : -ENODEV);
396} 399}
397 400
398/* 401/*
@@ -421,14 +424,14 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
421 else 424 else
422 ret = __ccw_device_check_nop(cdev); 425 ret = __ccw_device_check_nop(cdev);
423 memset(&cdev->private->irb, 0, sizeof(struct irb)); 426 memset(&cdev->private->irb, 0, sizeof(struct irb));
427
424 switch (ret) { 428 switch (ret) {
425 /* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */ 429 /* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
426 case 0: 430 case 0:
427 /* Establish or Resign Path Group done. Update vpm. */ 431 /* Path verification ccw finished successfully, update lpm. */
428 if ((sch->lpm & cdev->private->imask) != 0) 432 sch->vpm |= sch->opm & cdev->private->imask;
429 sch->vpm |= cdev->private->imask; 433 /* Go on with next path. */
430 else 434 cdev->private->imask >>= 1;
431 sch->vpm &= ~cdev->private->imask;
432 cdev->private->iretry = 5; 435 cdev->private->iretry = 5;
433 __ccw_device_verify_start(cdev); 436 __ccw_device_verify_start(cdev);
434 break; 437 break;
@@ -441,6 +444,10 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
441 cdev->private->options.pgroup = 0; 444 cdev->private->options.pgroup = 0;
442 else 445 else
443 cdev->private->flags.pgid_single = 1; 446 cdev->private->flags.pgid_single = 1;
447 /* Retry */
448 sch->vpm = 0;
449 cdev->private->imask = 0x80;
450 cdev->private->iretry = 5;
444 /* fall through. */ 451 /* fall through. */
445 case -EAGAIN: /* Try again. */ 452 case -EAGAIN: /* Try again. */
446 __ccw_device_verify_start(cdev); 453 __ccw_device_verify_start(cdev);
@@ -449,8 +456,7 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
449 ccw_device_verify_done(cdev, -ETIME); 456 ccw_device_verify_done(cdev, -ETIME);
450 break; 457 break;
451 case -EACCES: /* channel is not operational. */ 458 case -EACCES: /* channel is not operational. */
452 sch->lpm &= ~cdev->private->imask; 459 cdev->private->imask >>= 1;
453 sch->vpm &= ~cdev->private->imask;
454 cdev->private->iretry = 5; 460 cdev->private->iretry = 5;
455 __ccw_device_verify_start(cdev); 461 __ccw_device_verify_start(cdev);
456 break; 462 break;
@@ -463,19 +469,17 @@ ccw_device_verify_start(struct ccw_device *cdev)
463 struct subchannel *sch = to_subchannel(cdev->dev.parent); 469 struct subchannel *sch = to_subchannel(cdev->dev.parent);
464 470
465 cdev->private->flags.pgid_single = 0; 471 cdev->private->flags.pgid_single = 0;
472 cdev->private->imask = 0x80;
466 cdev->private->iretry = 5; 473 cdev->private->iretry = 5;
467 /* 474
468 * Update sch->lpm with current values to catch paths becoming 475 /* Start with empty vpm. */
469 * available again. 476 sch->vpm = 0;
470 */ 477
478 /* Get current pam. */
471 if (stsch(sch->schid, &sch->schib)) { 479 if (stsch(sch->schid, &sch->schib)) {
472 ccw_device_verify_done(cdev, -ENODEV); 480 ccw_device_verify_done(cdev, -ENODEV);
473 return; 481 return;
474 } 482 }
475 sch->lpm = sch->schib.pmcw.pim &
476 sch->schib.pmcw.pam &
477 sch->schib.pmcw.pom &
478 sch->opm;
479 __ccw_device_verify_start(cdev); 483 __ccw_device_verify_start(cdev);
480} 484}
481 485
@@ -524,7 +528,6 @@ ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event)
524 switch (ret) { 528 switch (ret) {
525 /* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */ 529 /* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
526 case 0: /* disband successful. */ 530 case 0: /* disband successful. */
527 sch->vpm = 0;
528 ccw_device_disband_done(cdev, ret); 531 ccw_device_disband_done(cdev, ret);
529 break; 532 break;
530 case -EOPNOTSUPP: 533 case -EOPNOTSUPP:
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 7c93a8798d23..cde822d8b5c8 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -115,7 +115,7 @@ qdio_min(int a,int b)
115static inline __u64 115static inline __u64
116qdio_get_micros(void) 116qdio_get_micros(void)
117{ 117{
118 return (get_clock() >> 10); /* time>>12 is microseconds */ 118 return (get_clock() >> 12); /* time>>12 is microseconds */
119} 119}
120 120
121/* 121/*
@@ -1129,7 +1129,7 @@ out:
1129 1129
1130#ifdef QDIO_USE_PROCESSING_STATE 1130#ifdef QDIO_USE_PROCESSING_STATE
1131 if (last_position>=0) 1131 if (last_position>=0)
1132 set_slsb(q, &last_position, SLSB_P_INPUT_NOT_INIT, &count); 1132 set_slsb(q, &last_position, SLSB_P_INPUT_PROCESSING, &count);
1133#endif /* QDIO_USE_PROCESSING_STATE */ 1133#endif /* QDIO_USE_PROCESSING_STATE */
1134 1134
1135 QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); 1135 QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index ceb3ab31ee08..124569362f02 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -191,49 +191,49 @@ enum qdio_irq_states {
191#if QDIO_VERBOSE_LEVEL>8 191#if QDIO_VERBOSE_LEVEL>8
192#define QDIO_PRINT_STUPID(x...) printk( KERN_DEBUG QDIO_PRINTK_HEADER x) 192#define QDIO_PRINT_STUPID(x...) printk( KERN_DEBUG QDIO_PRINTK_HEADER x)
193#else 193#else
194#define QDIO_PRINT_STUPID(x...) 194#define QDIO_PRINT_STUPID(x...) do { } while (0)
195#endif 195#endif
196 196
197#if QDIO_VERBOSE_LEVEL>7 197#if QDIO_VERBOSE_LEVEL>7
198#define QDIO_PRINT_ALL(x...) printk( QDIO_PRINTK_HEADER x) 198#define QDIO_PRINT_ALL(x...) printk( QDIO_PRINTK_HEADER x)
199#else 199#else
200#define QDIO_PRINT_ALL(x...) 200#define QDIO_PRINT_ALL(x...) do { } while (0)
201#endif 201#endif
202 202
203#if QDIO_VERBOSE_LEVEL>6 203#if QDIO_VERBOSE_LEVEL>6
204#define QDIO_PRINT_INFO(x...) printk( QDIO_PRINTK_HEADER x) 204#define QDIO_PRINT_INFO(x...) printk( QDIO_PRINTK_HEADER x)
205#else 205#else
206#define QDIO_PRINT_INFO(x...) 206#define QDIO_PRINT_INFO(x...) do { } while (0)
207#endif 207#endif
208 208
209#if QDIO_VERBOSE_LEVEL>5 209#if QDIO_VERBOSE_LEVEL>5
210#define QDIO_PRINT_WARN(x...) printk( QDIO_PRINTK_HEADER x) 210#define QDIO_PRINT_WARN(x...) printk( QDIO_PRINTK_HEADER x)
211#else 211#else
212#define QDIO_PRINT_WARN(x...) 212#define QDIO_PRINT_WARN(x...) do { } while (0)
213#endif 213#endif
214 214
215#if QDIO_VERBOSE_LEVEL>4 215#if QDIO_VERBOSE_LEVEL>4
216#define QDIO_PRINT_ERR(x...) printk( QDIO_PRINTK_HEADER x) 216#define QDIO_PRINT_ERR(x...) printk( QDIO_PRINTK_HEADER x)
217#else 217#else
218#define QDIO_PRINT_ERR(x...) 218#define QDIO_PRINT_ERR(x...) do { } while (0)
219#endif 219#endif
220 220
221#if QDIO_VERBOSE_LEVEL>3 221#if QDIO_VERBOSE_LEVEL>3
222#define QDIO_PRINT_CRIT(x...) printk( QDIO_PRINTK_HEADER x) 222#define QDIO_PRINT_CRIT(x...) printk( QDIO_PRINTK_HEADER x)
223#else 223#else
224#define QDIO_PRINT_CRIT(x...) 224#define QDIO_PRINT_CRIT(x...) do { } while (0)
225#endif 225#endif
226 226
227#if QDIO_VERBOSE_LEVEL>2 227#if QDIO_VERBOSE_LEVEL>2
228#define QDIO_PRINT_ALERT(x...) printk( QDIO_PRINTK_HEADER x) 228#define QDIO_PRINT_ALERT(x...) printk( QDIO_PRINTK_HEADER x)
229#else 229#else
230#define QDIO_PRINT_ALERT(x...) 230#define QDIO_PRINT_ALERT(x...) do { } while (0)
231#endif 231#endif
232 232
233#if QDIO_VERBOSE_LEVEL>1 233#if QDIO_VERBOSE_LEVEL>1
234#define QDIO_PRINT_EMERG(x...) printk( QDIO_PRINTK_HEADER x) 234#define QDIO_PRINT_EMERG(x...) printk( QDIO_PRINTK_HEADER x)
235#else 235#else
236#define QDIO_PRINT_EMERG(x...) 236#define QDIO_PRINT_EMERG(x...) do { } while (0)
237#endif 237#endif
238 238
239#define HEXDUMP16(importance,header,ptr) \ 239#define HEXDUMP16(importance,header,ptr) \
diff --git a/drivers/s390/crypto/Makefile b/drivers/s390/crypto/Makefile
index 15edebbead7f..f0a12d2eb780 100644
--- a/drivers/s390/crypto/Makefile
+++ b/drivers/s390/crypto/Makefile
@@ -2,5 +2,16 @@
2# S/390 crypto devices 2# S/390 crypto devices
3# 3#
4 4
5z90crypt-objs := z90main.o z90hardware.o 5ifdef CONFIG_ZCRYPT_MONOLITHIC
6obj-$(CONFIG_Z90CRYPT) += z90crypt.o 6
7z90crypt-objs := zcrypt_mono.o ap_bus.o zcrypt_api.o \
8 zcrypt_pcica.o zcrypt_pcicc.o zcrypt_pcixcc.o zcrypt_cex2a.o
9obj-$(CONFIG_ZCRYPT) += z90crypt.o
10
11else
12
13ap-objs := ap_bus.o
14obj-$(CONFIG_ZCRYPT) += ap.o zcrypt_api.o zcrypt_pcicc.o zcrypt_pcixcc.o
15obj-$(CONFIG_ZCRYPT) += zcrypt_pcica.o zcrypt_cex2a.o
16
17endif
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
new file mode 100644
index 000000000000..6ed0985c0c91
--- /dev/null
+++ b/drivers/s390/crypto/ap_bus.c
@@ -0,0 +1,1221 @@
1/*
2 * linux/drivers/s390/crypto/ap_bus.c
3 *
4 * Copyright (C) 2006 IBM Corporation
5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Ralph Wuerthner <rwuerthn@de.ibm.com>
8 *
9 * Adjunct processor bus.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/err.h>
30#include <linux/interrupt.h>
31#include <linux/workqueue.h>
32#include <linux/notifier.h>
33#include <linux/kthread.h>
34#include <linux/mutex.h>
35#include <asm/s390_rdev.h>
36
37#include "ap_bus.h"
38
39/* Some prototypes. */
40static void ap_scan_bus(void *);
41static void ap_poll_all(unsigned long);
42static void ap_poll_timeout(unsigned long);
43static int ap_poll_thread_start(void);
44static void ap_poll_thread_stop(void);
45
46/**
47 * Module description.
48 */
49MODULE_AUTHOR("IBM Corporation");
50MODULE_DESCRIPTION("Adjunct Processor Bus driver, "
51 "Copyright 2006 IBM Corporation");
52MODULE_LICENSE("GPL");
53
54/**
55 * Module parameter
56 */
57int ap_domain_index = -1; /* Adjunct Processor Domain Index */
58module_param_named(domain, ap_domain_index, int, 0000);
59MODULE_PARM_DESC(domain, "domain index for ap devices");
60EXPORT_SYMBOL(ap_domain_index);
61
62static int ap_thread_flag = 1;
63module_param_named(poll_thread, ap_thread_flag, int, 0000);
64MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 1 (on).");
65
66static struct device *ap_root_device = NULL;
67
68/**
69 * Workqueue & timer for bus rescan.
70 */
71static struct workqueue_struct *ap_work_queue;
72static struct timer_list ap_config_timer;
73static int ap_config_time = AP_CONFIG_TIME;
74static DECLARE_WORK(ap_config_work, ap_scan_bus, NULL);
75
76/**
77 * Tasklet & timer for AP request polling.
78 */
79static struct timer_list ap_poll_timer = TIMER_INITIALIZER(ap_poll_timeout,0,0);
80static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
81static atomic_t ap_poll_requests = ATOMIC_INIT(0);
82static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
83static struct task_struct *ap_poll_kthread = NULL;
84static DEFINE_MUTEX(ap_poll_thread_mutex);
85
86/**
87 * Test if ap instructions are available.
88 *
89 * Returns 0 if the ap instructions are installed.
90 */
91static inline int ap_instructions_available(void)
92{
93 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
94 register unsigned long reg1 asm ("1") = -ENODEV;
95 register unsigned long reg2 asm ("2") = 0UL;
96
97 asm volatile(
98 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
99 "0: la %1,0\n"
100 "1:\n"
101 EX_TABLE(0b, 1b)
102 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
103 return reg1;
104}
105
106/**
107 * Test adjunct processor queue.
108 * @qid: the ap queue number
109 * @queue_depth: pointer to queue depth value
110 * @device_type: pointer to device type value
111 *
112 * Returns ap queue status structure.
113 */
114static inline struct ap_queue_status
115ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
116{
117 register unsigned long reg0 asm ("0") = qid;
118 register struct ap_queue_status reg1 asm ("1");
119 register unsigned long reg2 asm ("2") = 0UL;
120
121 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
122 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
123 *device_type = (int) (reg2 >> 24);
124 *queue_depth = (int) (reg2 & 0xff);
125 return reg1;
126}
127
128/**
129 * Reset adjunct processor queue.
130 * @qid: the ap queue number
131 *
132 * Returns ap queue status structure.
133 */
134static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
135{
136 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
137 register struct ap_queue_status reg1 asm ("1");
138 register unsigned long reg2 asm ("2") = 0UL;
139
140 asm volatile(
141 ".long 0xb2af0000" /* PQAP(RAPQ) */
142 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
143 return reg1;
144}
145
146/**
147 * Send message to adjunct processor queue.
148 * @qid: the ap queue number
149 * @psmid: the program supplied message identifier
150 * @msg: the message text
151 * @length: the message length
152 *
153 * Returns ap queue status structure.
154 *
155 * Condition code 1 on NQAP can't happen because the L bit is 1.
156 *
157 * Condition code 2 on NQAP also means the send is incomplete,
158 * because a segment boundary was reached. The NQAP is repeated.
159 */
160static inline struct ap_queue_status
161__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
162{
163 typedef struct { char _[length]; } msgblock;
164 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
165 register struct ap_queue_status reg1 asm ("1");
166 register unsigned long reg2 asm ("2") = (unsigned long) msg;
167 register unsigned long reg3 asm ("3") = (unsigned long) length;
168 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
169 register unsigned long reg5 asm ("5") = (unsigned int) psmid;
170
171 asm volatile (
172 "0: .long 0xb2ad0042\n" /* DQAP */
173 " brc 2,0b"
174 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
175 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
176 : "cc" );
177 return reg1;
178}
179
180int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
181{
182 struct ap_queue_status status;
183
184 status = __ap_send(qid, psmid, msg, length);
185 switch (status.response_code) {
186 case AP_RESPONSE_NORMAL:
187 return 0;
188 case AP_RESPONSE_Q_FULL:
189 return -EBUSY;
190 default: /* Device is gone. */
191 return -ENODEV;
192 }
193}
194EXPORT_SYMBOL(ap_send);
195
196/*
197 * Receive message from adjunct processor queue.
198 * @qid: the ap queue number
199 * @psmid: pointer to program supplied message identifier
200 * @msg: the message text
201 * @length: the message length
202 *
203 * Returns ap queue status structure.
204 *
205 * Condition code 1 on DQAP means the receive has taken place
206 * but only partially. The response is incomplete, hence the
207 * DQAP is repeated.
208 *
209 * Condition code 2 on DQAP also means the receive is incomplete,
210 * this time because a segment boundary was reached. Again, the
211 * DQAP is repeated.
212 *
213 * Note that gpr2 is used by the DQAP instruction to keep track of
214 * any 'residual' length, in case the instruction gets interrupted.
215 * Hence it gets zeroed before the instruction.
216 */
217static inline struct ap_queue_status
218__ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
219{
220 typedef struct { char _[length]; } msgblock;
221 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
222 register struct ap_queue_status reg1 asm ("1");
223 register unsigned long reg2 asm("2") = 0UL;
224 register unsigned long reg4 asm("4") = (unsigned long) msg;
225 register unsigned long reg5 asm("5") = (unsigned long) length;
226 register unsigned long reg6 asm("6") = 0UL;
227 register unsigned long reg7 asm("7") = 0UL;
228
229
230 asm volatile(
231 "0: .long 0xb2ae0064\n"
232 " brc 6,0b\n"
233 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
234 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
235 "=m" (*(msgblock *) msg) : : "cc" );
236 *psmid = (((unsigned long long) reg6) << 32) + reg7;
237 return reg1;
238}
239
240int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
241{
242 struct ap_queue_status status;
243
244 status = __ap_recv(qid, psmid, msg, length);
245 switch (status.response_code) {
246 case AP_RESPONSE_NORMAL:
247 return 0;
248 case AP_RESPONSE_NO_PENDING_REPLY:
249 if (status.queue_empty)
250 return -ENOENT;
251 return -EBUSY;
252 default:
253 return -ENODEV;
254 }
255}
256EXPORT_SYMBOL(ap_recv);
257
258/**
259 * Check if an AP queue is available. The test is repeated for
260 * AP_MAX_RESET times.
261 * @qid: the ap queue number
262 * @queue_depth: pointer to queue depth value
263 * @device_type: pointer to device type value
264 */
265static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
266{
267 struct ap_queue_status status;
268 int t_depth, t_device_type, rc, i;
269
270 rc = -EBUSY;
271 for (i = 0; i < AP_MAX_RESET; i++) {
272 status = ap_test_queue(qid, &t_depth, &t_device_type);
273 switch (status.response_code) {
274 case AP_RESPONSE_NORMAL:
275 *queue_depth = t_depth + 1;
276 *device_type = t_device_type;
277 rc = 0;
278 break;
279 case AP_RESPONSE_Q_NOT_AVAIL:
280 rc = -ENODEV;
281 break;
282 case AP_RESPONSE_RESET_IN_PROGRESS:
283 break;
284 case AP_RESPONSE_DECONFIGURED:
285 rc = -ENODEV;
286 break;
287 case AP_RESPONSE_CHECKSTOPPED:
288 rc = -ENODEV;
289 break;
290 case AP_RESPONSE_BUSY:
291 break;
292 default:
293 BUG();
294 }
295 if (rc != -EBUSY)
296 break;
297 if (i < AP_MAX_RESET - 1)
298 udelay(5);
299 }
300 return rc;
301}
302
303/**
304 * Reset an AP queue and wait for it to become available again.
305 * @qid: the ap queue number
306 */
307static int ap_init_queue(ap_qid_t qid)
308{
309 struct ap_queue_status status;
310 int rc, dummy, i;
311
312 rc = -ENODEV;
313 status = ap_reset_queue(qid);
314 for (i = 0; i < AP_MAX_RESET; i++) {
315 switch (status.response_code) {
316 case AP_RESPONSE_NORMAL:
317 if (status.queue_empty)
318 rc = 0;
319 break;
320 case AP_RESPONSE_Q_NOT_AVAIL:
321 case AP_RESPONSE_DECONFIGURED:
322 case AP_RESPONSE_CHECKSTOPPED:
323 i = AP_MAX_RESET; /* return with -ENODEV */
324 break;
325 case AP_RESPONSE_RESET_IN_PROGRESS:
326 case AP_RESPONSE_BUSY:
327 default:
328 break;
329 }
330 if (rc != -ENODEV)
331 break;
332 if (i < AP_MAX_RESET - 1) {
333 udelay(5);
334 status = ap_test_queue(qid, &dummy, &dummy);
335 }
336 }
337 return rc;
338}
339
340/**
341 * AP device related attributes.
342 */
343static ssize_t ap_hwtype_show(struct device *dev,
344 struct device_attribute *attr, char *buf)
345{
346 struct ap_device *ap_dev = to_ap_dev(dev);
347 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
348}
349static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
350
351static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
352 char *buf)
353{
354 struct ap_device *ap_dev = to_ap_dev(dev);
355 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
356}
357static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
358
359static ssize_t ap_request_count_show(struct device *dev,
360 struct device_attribute *attr,
361 char *buf)
362{
363 struct ap_device *ap_dev = to_ap_dev(dev);
364 int rc;
365
366 spin_lock_bh(&ap_dev->lock);
367 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
368 spin_unlock_bh(&ap_dev->lock);
369 return rc;
370}
371
372static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
373
374static ssize_t ap_modalias_show(struct device *dev,
375 struct device_attribute *attr, char *buf)
376{
377 return sprintf(buf, "ap:t%02X", to_ap_dev(dev)->device_type);
378}
379
380static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
381
382static struct attribute *ap_dev_attrs[] = {
383 &dev_attr_hwtype.attr,
384 &dev_attr_depth.attr,
385 &dev_attr_request_count.attr,
386 &dev_attr_modalias.attr,
387 NULL
388};
389static struct attribute_group ap_dev_attr_group = {
390 .attrs = ap_dev_attrs
391};
392
393/**
394 * AP bus driver registration/unregistration.
395 */
396static int ap_bus_match(struct device *dev, struct device_driver *drv)
397{
398 struct ap_device *ap_dev = to_ap_dev(dev);
399 struct ap_driver *ap_drv = to_ap_drv(drv);
400 struct ap_device_id *id;
401
402 /**
403 * Compare device type of the device with the list of
404 * supported types of the device_driver.
405 */
406 for (id = ap_drv->ids; id->match_flags; id++) {
407 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
408 (id->dev_type != ap_dev->device_type))
409 continue;
410 return 1;
411 }
412 return 0;
413}
414
415/**
416 * uevent function for AP devices. It sets up a single environment
417 * variable DEV_TYPE which contains the hardware device type.
418 */
419static int ap_uevent (struct device *dev, char **envp, int num_envp,
420 char *buffer, int buffer_size)
421{
422 struct ap_device *ap_dev = to_ap_dev(dev);
423 int length;
424
425 if (!ap_dev)
426 return -ENODEV;
427
428 /* Set up DEV_TYPE environment variable. */
429 envp[0] = buffer;
430 length = scnprintf(buffer, buffer_size, "DEV_TYPE=%04X",
431 ap_dev->device_type);
432 if (buffer_size - length <= 0)
433 return -ENOMEM;
434 envp[1] = 0;
435 return 0;
436}
437
438static struct bus_type ap_bus_type = {
439 .name = "ap",
440 .match = &ap_bus_match,
441 .uevent = &ap_uevent,
442};
443
444static int ap_device_probe(struct device *dev)
445{
446 struct ap_device *ap_dev = to_ap_dev(dev);
447 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
448 int rc;
449
450 ap_dev->drv = ap_drv;
451 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
452 if (rc)
453 ap_dev->unregistered = 1;
454 return rc;
455}
456
457/**
458 * Flush all requests from the request/pending queue of an AP device.
459 * @ap_dev: pointer to the AP device.
460 */
461static inline void __ap_flush_queue(struct ap_device *ap_dev)
462{
463 struct ap_message *ap_msg, *next;
464
465 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
466 list_del_init(&ap_msg->list);
467 ap_dev->pendingq_count--;
468 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
469 }
470 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
471 list_del_init(&ap_msg->list);
472 ap_dev->requestq_count--;
473 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
474 }
475}
476
477void ap_flush_queue(struct ap_device *ap_dev)
478{
479 spin_lock_bh(&ap_dev->lock);
480 __ap_flush_queue(ap_dev);
481 spin_unlock_bh(&ap_dev->lock);
482}
483EXPORT_SYMBOL(ap_flush_queue);
484
485static int ap_device_remove(struct device *dev)
486{
487 struct ap_device *ap_dev = to_ap_dev(dev);
488 struct ap_driver *ap_drv = ap_dev->drv;
489
490 spin_lock_bh(&ap_dev->lock);
491 __ap_flush_queue(ap_dev);
492 /**
493 * set ->unregistered to 1 while holding the lock. This prevents
494 * new messages to be put on the queue from now on.
495 */
496 ap_dev->unregistered = 1;
497 spin_unlock_bh(&ap_dev->lock);
498 if (ap_drv->remove)
499 ap_drv->remove(ap_dev);
500 return 0;
501}
502
503int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
504 char *name)
505{
506 struct device_driver *drv = &ap_drv->driver;
507
508 drv->bus = &ap_bus_type;
509 drv->probe = ap_device_probe;
510 drv->remove = ap_device_remove;
511 drv->owner = owner;
512 drv->name = name;
513 return driver_register(drv);
514}
515EXPORT_SYMBOL(ap_driver_register);
516
517void ap_driver_unregister(struct ap_driver *ap_drv)
518{
519 driver_unregister(&ap_drv->driver);
520}
521EXPORT_SYMBOL(ap_driver_unregister);
522
523/**
524 * AP bus attributes.
525 */
526static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
527{
528 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
529}
530
531static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
532
533static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
534{
535 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
536}
537
538static ssize_t ap_config_time_store(struct bus_type *bus,
539 const char *buf, size_t count)
540{
541 int time;
542
543 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
544 return -EINVAL;
545 ap_config_time = time;
546 if (!timer_pending(&ap_config_timer) ||
547 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
548 ap_config_timer.expires = jiffies + ap_config_time * HZ;
549 add_timer(&ap_config_timer);
550 }
551 return count;
552}
553
554static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
555
556static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
557{
558 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
559}
560
561static ssize_t ap_poll_thread_store(struct bus_type *bus,
562 const char *buf, size_t count)
563{
564 int flag, rc;
565
566 if (sscanf(buf, "%d\n", &flag) != 1)
567 return -EINVAL;
568 if (flag) {
569 rc = ap_poll_thread_start();
570 if (rc)
571 return rc;
572 }
573 else
574 ap_poll_thread_stop();
575 return count;
576}
577
578static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
579
580static struct bus_attribute *const ap_bus_attrs[] = {
581 &bus_attr_ap_domain,
582 &bus_attr_config_time,
583 &bus_attr_poll_thread,
584 NULL
585};
586
587/**
588 * Pick one of the 16 ap domains.
589 */
590static inline int ap_select_domain(void)
591{
592 int queue_depth, device_type, count, max_count, best_domain;
593 int rc, i, j;
594
595 /**
596 * We want to use a single domain. Either the one specified with
597 * the "domain=" parameter or the domain with the maximum number
598 * of devices.
599 */
600 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
601 /* Domain has already been selected. */
602 return 0;
603 best_domain = -1;
604 max_count = 0;
605 for (i = 0; i < AP_DOMAINS; i++) {
606 count = 0;
607 for (j = 0; j < AP_DEVICES; j++) {
608 ap_qid_t qid = AP_MKQID(j, i);
609 rc = ap_query_queue(qid, &queue_depth, &device_type);
610 if (rc)
611 continue;
612 count++;
613 }
614 if (count > max_count) {
615 max_count = count;
616 best_domain = i;
617 }
618 }
619 if (best_domain >= 0){
620 ap_domain_index = best_domain;
621 return 0;
622 }
623 return -ENODEV;
624}
625
626/**
627 * Find the device type if query queue returned a device type of 0.
628 * @ap_dev: pointer to the AP device.
629 */
630static int ap_probe_device_type(struct ap_device *ap_dev)
631{
632 static unsigned char msg[] = {
633 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
634 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
635 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
636 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
637 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
638 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
639 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
640 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
641 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
642 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
643 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
644 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
645 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
646 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
647 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
648 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
649 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
650 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
651 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
652 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
653 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
654 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
655 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
656 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
657 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
658 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
659 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
660 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
661 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
662 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
663 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
664 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
665 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
666 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
667 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
668 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
669 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
670 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
671 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
672 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
673 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
674 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
675 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
676 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
677 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
678 };
679 struct ap_queue_status status;
680 unsigned long long psmid;
681 char *reply;
682 int rc, i;
683
684 reply = (void *) get_zeroed_page(GFP_KERNEL);
685 if (!reply) {
686 rc = -ENOMEM;
687 goto out;
688 }
689
690 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
691 msg, sizeof(msg));
692 if (status.response_code != AP_RESPONSE_NORMAL) {
693 rc = -ENODEV;
694 goto out_free;
695 }
696
697 /* Wait for the test message to complete. */
698 for (i = 0; i < 6; i++) {
699 mdelay(300);
700 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
701 if (status.response_code == AP_RESPONSE_NORMAL &&
702 psmid == 0x0102030405060708ULL)
703 break;
704 }
705 if (i < 6) {
706 /* Got an answer. */
707 if (reply[0] == 0x00 && reply[1] == 0x86)
708 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
709 else
710 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
711 rc = 0;
712 } else
713 rc = -ENODEV;
714
715out_free:
716 free_page((unsigned long) reply);
717out:
718 return rc;
719}
720
721/**
722 * Scan the ap bus for new devices.
723 */
724static int __ap_scan_bus(struct device *dev, void *data)
725{
726 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
727}
728
729static void ap_device_release(struct device *dev)
730{
731 struct ap_device *ap_dev = to_ap_dev(dev);
732
733 kfree(ap_dev);
734}
735
736static void ap_scan_bus(void *data)
737{
738 struct ap_device *ap_dev;
739 struct device *dev;
740 ap_qid_t qid;
741 int queue_depth, device_type;
742 int rc, i;
743
744 if (ap_select_domain() != 0)
745 return;
746 for (i = 0; i < AP_DEVICES; i++) {
747 qid = AP_MKQID(i, ap_domain_index);
748 dev = bus_find_device(&ap_bus_type, NULL,
749 (void *)(unsigned long)qid,
750 __ap_scan_bus);
751 if (dev) {
752 put_device(dev);
753 continue;
754 }
755 rc = ap_query_queue(qid, &queue_depth, &device_type);
756 if (rc)
757 continue;
758 rc = ap_init_queue(qid);
759 if (rc)
760 continue;
761 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
762 if (!ap_dev)
763 break;
764 ap_dev->qid = qid;
765 ap_dev->queue_depth = queue_depth;
766 spin_lock_init(&ap_dev->lock);
767 INIT_LIST_HEAD(&ap_dev->pendingq);
768 INIT_LIST_HEAD(&ap_dev->requestq);
769 if (device_type == 0)
770 ap_probe_device_type(ap_dev);
771 else
772 ap_dev->device_type = device_type;
773
774 ap_dev->device.bus = &ap_bus_type;
775 ap_dev->device.parent = ap_root_device;
776 snprintf(ap_dev->device.bus_id, BUS_ID_SIZE, "card%02x",
777 AP_QID_DEVICE(ap_dev->qid));
778 ap_dev->device.release = ap_device_release;
779 rc = device_register(&ap_dev->device);
780 if (rc) {
781 kfree(ap_dev);
782 continue;
783 }
784 /* Add device attributes. */
785 rc = sysfs_create_group(&ap_dev->device.kobj,
786 &ap_dev_attr_group);
787 if (rc)
788 device_unregister(&ap_dev->device);
789 }
790}
791
792static void
793ap_config_timeout(unsigned long ptr)
794{
795 queue_work(ap_work_queue, &ap_config_work);
796 ap_config_timer.expires = jiffies + ap_config_time * HZ;
797 add_timer(&ap_config_timer);
798}
799
800/**
801 * Set up the timer to run the poll tasklet
802 */
803static inline void ap_schedule_poll_timer(void)
804{
805 if (timer_pending(&ap_poll_timer))
806 return;
807 mod_timer(&ap_poll_timer, jiffies + AP_POLL_TIME);
808}
809
810/**
811 * Receive pending reply messages from an AP device.
812 * @ap_dev: pointer to the AP device
813 * @flags: pointer to control flags, bit 2^0 is set if another poll is
814 * required, bit 2^1 is set if the poll timer needs to get armed
815 * Returns 0 if the device is still present, -ENODEV if not.
816 */
817static inline int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
818{
819 struct ap_queue_status status;
820 struct ap_message *ap_msg;
821
822 if (ap_dev->queue_count <= 0)
823 return 0;
824 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
825 ap_dev->reply->message, ap_dev->reply->length);
826 switch (status.response_code) {
827 case AP_RESPONSE_NORMAL:
828 atomic_dec(&ap_poll_requests);
829 ap_dev->queue_count--;
830 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
831 if (ap_msg->psmid != ap_dev->reply->psmid)
832 continue;
833 list_del_init(&ap_msg->list);
834 ap_dev->pendingq_count--;
835 ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply);
836 break;
837 }
838 if (ap_dev->queue_count > 0)
839 *flags |= 1;
840 break;
841 case AP_RESPONSE_NO_PENDING_REPLY:
842 if (status.queue_empty) {
843 /* The card shouldn't forget requests but who knows. */
844 ap_dev->queue_count = 0;
845 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
846 ap_dev->requestq_count += ap_dev->pendingq_count;
847 ap_dev->pendingq_count = 0;
848 } else
849 *flags |= 2;
850 break;
851 default:
852 return -ENODEV;
853 }
854 return 0;
855}
856
857/**
858 * Send messages from the request queue to an AP device.
859 * @ap_dev: pointer to the AP device
860 * @flags: pointer to control flags, bit 2^0 is set if another poll is
861 * required, bit 2^1 is set if the poll timer needs to get armed
862 * Returns 0 if the device is still present, -ENODEV if not.
863 */
864static inline int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
865{
866 struct ap_queue_status status;
867 struct ap_message *ap_msg;
868
869 if (ap_dev->requestq_count <= 0 ||
870 ap_dev->queue_count >= ap_dev->queue_depth)
871 return 0;
872 /* Start the next request on the queue. */
873 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
874 status = __ap_send(ap_dev->qid, ap_msg->psmid,
875 ap_msg->message, ap_msg->length);
876 switch (status.response_code) {
877 case AP_RESPONSE_NORMAL:
878 atomic_inc(&ap_poll_requests);
879 ap_dev->queue_count++;
880 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
881 ap_dev->requestq_count--;
882 ap_dev->pendingq_count++;
883 if (ap_dev->queue_count < ap_dev->queue_depth &&
884 ap_dev->requestq_count > 0)
885 *flags |= 1;
886 *flags |= 2;
887 break;
888 case AP_RESPONSE_Q_FULL:
889 *flags |= 2;
890 break;
891 case AP_RESPONSE_MESSAGE_TOO_BIG:
892 return -EINVAL;
893 default:
894 return -ENODEV;
895 }
896 return 0;
897}
898
899/**
900 * Poll AP device for pending replies and send new messages. If either
901 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
902 * @ap_dev: pointer to the bus device
903 * @flags: pointer to control flags, bit 2^0 is set if another poll is
904 * required, bit 2^1 is set if the poll timer needs to get armed
905 * Returns 0.
906 */
907static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
908{
909 int rc;
910
911 rc = ap_poll_read(ap_dev, flags);
912 if (rc)
913 return rc;
914 return ap_poll_write(ap_dev, flags);
915}
916
917/**
918 * Queue a message to a device.
919 * @ap_dev: pointer to the AP device
920 * @ap_msg: the message to be queued
921 */
922static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
923{
924 struct ap_queue_status status;
925
926 if (list_empty(&ap_dev->requestq) &&
927 ap_dev->queue_count < ap_dev->queue_depth) {
928 status = __ap_send(ap_dev->qid, ap_msg->psmid,
929 ap_msg->message, ap_msg->length);
930 switch (status.response_code) {
931 case AP_RESPONSE_NORMAL:
932 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
933 atomic_inc(&ap_poll_requests);
934 ap_dev->pendingq_count++;
935 ap_dev->queue_count++;
936 ap_dev->total_request_count++;
937 break;
938 case AP_RESPONSE_Q_FULL:
939 list_add_tail(&ap_msg->list, &ap_dev->requestq);
940 ap_dev->requestq_count++;
941 ap_dev->total_request_count++;
942 return -EBUSY;
943 case AP_RESPONSE_MESSAGE_TOO_BIG:
944 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
945 return -EINVAL;
946 default: /* Device is gone. */
947 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
948 return -ENODEV;
949 }
950 } else {
951 list_add_tail(&ap_msg->list, &ap_dev->requestq);
952 ap_dev->requestq_count++;
953 ap_dev->total_request_count++;
954 return -EBUSY;
955 }
956 ap_schedule_poll_timer();
957 return 0;
958}
959
960void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
961{
962 unsigned long flags;
963 int rc;
964
965 spin_lock_bh(&ap_dev->lock);
966 if (!ap_dev->unregistered) {
967 /* Make room on the queue by polling for finished requests. */
968 rc = ap_poll_queue(ap_dev, &flags);
969 if (!rc)
970 rc = __ap_queue_message(ap_dev, ap_msg);
971 if (!rc)
972 wake_up(&ap_poll_wait);
973 } else {
974 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
975 rc = 0;
976 }
977 spin_unlock_bh(&ap_dev->lock);
978 if (rc == -ENODEV)
979 device_unregister(&ap_dev->device);
980}
981EXPORT_SYMBOL(ap_queue_message);
982
983/**
984 * Cancel a crypto request. This is done by removing the request
985 * from the devive pendingq or requestq queue. Note that the
986 * request stays on the AP queue. When it finishes the message
987 * reply will be discarded because the psmid can't be found.
988 * @ap_dev: AP device that has the message queued
989 * @ap_msg: the message that is to be removed
990 */
991void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
992{
993 struct ap_message *tmp;
994
995 spin_lock_bh(&ap_dev->lock);
996 if (!list_empty(&ap_msg->list)) {
997 list_for_each_entry(tmp, &ap_dev->pendingq, list)
998 if (tmp->psmid == ap_msg->psmid) {
999 ap_dev->pendingq_count--;
1000 goto found;
1001 }
1002 ap_dev->requestq_count--;
1003 found:
1004 list_del_init(&ap_msg->list);
1005 }
1006 spin_unlock_bh(&ap_dev->lock);
1007}
1008EXPORT_SYMBOL(ap_cancel_message);
1009
1010/**
1011 * AP receive polling for finished AP requests
1012 */
1013static void ap_poll_timeout(unsigned long unused)
1014{
1015 tasklet_schedule(&ap_tasklet);
1016}
1017
1018/**
1019 * Poll all AP devices on the bus in a round robin fashion. Continue
1020 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1021 * of the control flags has been set arm the poll timer.
1022 */
1023static int __ap_poll_all(struct device *dev, void *data)
1024{
1025 struct ap_device *ap_dev = to_ap_dev(dev);
1026 int rc;
1027
1028 spin_lock(&ap_dev->lock);
1029 if (!ap_dev->unregistered) {
1030 rc = ap_poll_queue(to_ap_dev(dev), (unsigned long *) data);
1031 } else
1032 rc = 0;
1033 spin_unlock(&ap_dev->lock);
1034 if (rc)
1035 device_unregister(&ap_dev->device);
1036 return 0;
1037}
1038
1039static void ap_poll_all(unsigned long dummy)
1040{
1041 unsigned long flags;
1042
1043 do {
1044 flags = 0;
1045 bus_for_each_dev(&ap_bus_type, NULL, &flags, __ap_poll_all);
1046 } while (flags & 1);
1047 if (flags & 2)
1048 ap_schedule_poll_timer();
1049}
1050
1051/**
1052 * AP bus poll thread. The purpose of this thread is to poll for
1053 * finished requests in a loop if there is a "free" cpu - that is
1054 * a cpu that doesn't have anything better to do. The polling stops
1055 * as soon as there is another task or if all messages have been
1056 * delivered.
1057 */
1058static int ap_poll_thread(void *data)
1059{
1060 DECLARE_WAITQUEUE(wait, current);
1061 unsigned long flags;
1062 int requests;
1063
1064 set_user_nice(current, -20);
1065 while (1) {
1066 if (need_resched()) {
1067 schedule();
1068 continue;
1069 }
1070 add_wait_queue(&ap_poll_wait, &wait);
1071 set_current_state(TASK_INTERRUPTIBLE);
1072 if (kthread_should_stop())
1073 break;
1074 requests = atomic_read(&ap_poll_requests);
1075 if (requests <= 0)
1076 schedule();
1077 set_current_state(TASK_RUNNING);
1078 remove_wait_queue(&ap_poll_wait, &wait);
1079
1080 local_bh_disable();
1081 flags = 0;
1082 bus_for_each_dev(&ap_bus_type, NULL, &flags, __ap_poll_all);
1083 local_bh_enable();
1084 }
1085 set_current_state(TASK_RUNNING);
1086 remove_wait_queue(&ap_poll_wait, &wait);
1087 return 0;
1088}
1089
1090static int ap_poll_thread_start(void)
1091{
1092 int rc;
1093
1094 mutex_lock(&ap_poll_thread_mutex);
1095 if (!ap_poll_kthread) {
1096 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
1097 rc = IS_ERR(ap_poll_kthread) ? PTR_ERR(ap_poll_kthread) : 0;
1098 if (rc)
1099 ap_poll_kthread = NULL;
1100 }
1101 else
1102 rc = 0;
1103 mutex_unlock(&ap_poll_thread_mutex);
1104 return rc;
1105}
1106
1107static void ap_poll_thread_stop(void)
1108{
1109 mutex_lock(&ap_poll_thread_mutex);
1110 if (ap_poll_kthread) {
1111 kthread_stop(ap_poll_kthread);
1112 ap_poll_kthread = NULL;
1113 }
1114 mutex_unlock(&ap_poll_thread_mutex);
1115}
1116
1117/**
1118 * The module initialization code.
1119 */
1120int __init ap_module_init(void)
1121{
1122 int rc, i;
1123
1124 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
1125 printk(KERN_WARNING "Invalid param: domain = %d. "
1126 " Not loading.\n", ap_domain_index);
1127 return -EINVAL;
1128 }
1129 if (ap_instructions_available() != 0) {
1130 printk(KERN_WARNING "AP instructions not installed.\n");
1131 return -ENODEV;
1132 }
1133
1134 /* Create /sys/bus/ap. */
1135 rc = bus_register(&ap_bus_type);
1136 if (rc)
1137 goto out;
1138 for (i = 0; ap_bus_attrs[i]; i++) {
1139 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1140 if (rc)
1141 goto out_bus;
1142 }
1143
1144 /* Create /sys/devices/ap. */
1145 ap_root_device = s390_root_dev_register("ap");
1146 rc = IS_ERR(ap_root_device) ? PTR_ERR(ap_root_device) : 0;
1147 if (rc)
1148 goto out_bus;
1149
1150 ap_work_queue = create_singlethread_workqueue("kapwork");
1151 if (!ap_work_queue) {
1152 rc = -ENOMEM;
1153 goto out_root;
1154 }
1155
1156 if (ap_select_domain() == 0)
1157 ap_scan_bus(NULL);
1158
1159 /* Setup the ap bus rescan timer. */
1160 init_timer(&ap_config_timer);
1161 ap_config_timer.function = ap_config_timeout;
1162 ap_config_timer.data = 0;
1163 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1164 add_timer(&ap_config_timer);
1165
1166 /* Start the low priority AP bus poll thread. */
1167 if (ap_thread_flag) {
1168 rc = ap_poll_thread_start();
1169 if (rc)
1170 goto out_work;
1171 }
1172
1173 return 0;
1174
1175out_work:
1176 del_timer_sync(&ap_config_timer);
1177 del_timer_sync(&ap_poll_timer);
1178 destroy_workqueue(ap_work_queue);
1179out_root:
1180 s390_root_dev_unregister(ap_root_device);
1181out_bus:
1182 while (i--)
1183 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1184 bus_unregister(&ap_bus_type);
1185out:
1186 return rc;
1187}
1188
1189static int __ap_match_all(struct device *dev, void *data)
1190{
1191 return 1;
1192}
1193
1194/**
1195 * The module termination code
1196 */
1197void ap_module_exit(void)
1198{
1199 int i;
1200 struct device *dev;
1201
1202 ap_poll_thread_stop();
1203 del_timer_sync(&ap_config_timer);
1204 del_timer_sync(&ap_poll_timer);
1205 destroy_workqueue(ap_work_queue);
1206 s390_root_dev_unregister(ap_root_device);
1207 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
1208 __ap_match_all)))
1209 {
1210 device_unregister(dev);
1211 put_device(dev);
1212 }
1213 for (i = 0; ap_bus_attrs[i]; i++)
1214 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1215 bus_unregister(&ap_bus_type);
1216}
1217
1218#ifndef CONFIG_ZCRYPT_MONOLITHIC
1219module_init(ap_module_init);
1220module_exit(ap_module_exit);
1221#endif
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
new file mode 100644
index 000000000000..83b69c01cd6e
--- /dev/null
+++ b/drivers/s390/crypto/ap_bus.h
@@ -0,0 +1,158 @@
1/*
2 * linux/drivers/s390/crypto/ap_bus.h
3 *
4 * Copyright (C) 2006 IBM Corporation
5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Ralph Wuerthner <rwuerthn@de.ibm.com>
8 *
9 * Adjunct processor bus header file.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef _AP_BUS_H_
27#define _AP_BUS_H_
28
29#include <linux/device.h>
30#include <linux/mod_devicetable.h>
31#include <linux/types.h>
32
33#define AP_DEVICES 64 /* Number of AP devices. */
34#define AP_DOMAINS 16 /* Number of AP domains. */
35#define AP_MAX_RESET 90 /* Maximum number of resets. */
36#define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */
37#define AP_POLL_TIME 1 /* Time in ticks between receive polls. */
38
39extern int ap_domain_index;
40
41/**
42 * The ap_qid_t identifier of an ap queue. It contains a
43 * 6 bit device index and a 4 bit queue index (domain).
44 */
45typedef unsigned int ap_qid_t;
46
47#define AP_MKQID(_device,_queue) (((_device) & 63) << 8 | ((_queue) & 15))
48#define AP_QID_DEVICE(_qid) (((_qid) >> 8) & 63)
49#define AP_QID_QUEUE(_qid) ((_qid) & 15)
50
51/**
52 * The ap queue status word is returned by all three AP functions
53 * (PQAP, NQAP and DQAP). There's a set of flags in the first
54 * byte, followed by a 1 byte response code.
55 */
56struct ap_queue_status {
57 unsigned int queue_empty : 1;
58 unsigned int replies_waiting : 1;
59 unsigned int queue_full : 1;
60 unsigned int pad1 : 5;
61 unsigned int response_code : 8;
62 unsigned int pad2 : 16;
63};
64
65#define AP_RESPONSE_NORMAL 0x00
66#define AP_RESPONSE_Q_NOT_AVAIL 0x01
67#define AP_RESPONSE_RESET_IN_PROGRESS 0x02
68#define AP_RESPONSE_DECONFIGURED 0x03
69#define AP_RESPONSE_CHECKSTOPPED 0x04
70#define AP_RESPONSE_BUSY 0x05
71#define AP_RESPONSE_Q_FULL 0x10
72#define AP_RESPONSE_NO_PENDING_REPLY 0x10
73#define AP_RESPONSE_INDEX_TOO_BIG 0x11
74#define AP_RESPONSE_NO_FIRST_PART 0x13
75#define AP_RESPONSE_MESSAGE_TOO_BIG 0x15
76
77/**
78 * Known device types
79 */
80#define AP_DEVICE_TYPE_PCICC 3
81#define AP_DEVICE_TYPE_PCICA 4
82#define AP_DEVICE_TYPE_PCIXCC 5
83#define AP_DEVICE_TYPE_CEX2A 6
84#define AP_DEVICE_TYPE_CEX2C 7
85
86struct ap_device;
87struct ap_message;
88
89struct ap_driver {
90 struct device_driver driver;
91 struct ap_device_id *ids;
92
93 int (*probe)(struct ap_device *);
94 void (*remove)(struct ap_device *);
95 /* receive is called from tasklet context */
96 void (*receive)(struct ap_device *, struct ap_message *,
97 struct ap_message *);
98};
99
100#define to_ap_drv(x) container_of((x), struct ap_driver, driver)
101
102int ap_driver_register(struct ap_driver *, struct module *, char *);
103void ap_driver_unregister(struct ap_driver *);
104
105struct ap_device {
106 struct device device;
107 struct ap_driver *drv; /* Pointer to AP device driver. */
108 spinlock_t lock; /* Per device lock. */
109
110 ap_qid_t qid; /* AP queue id. */
111 int queue_depth; /* AP queue depth.*/
112 int device_type; /* AP device type. */
113 int unregistered; /* marks AP device as unregistered */
114
115 int queue_count; /* # messages currently on AP queue. */
116
117 struct list_head pendingq; /* List of message sent to AP queue. */
118 int pendingq_count; /* # requests on pendingq list. */
119 struct list_head requestq; /* List of message yet to be sent. */
120 int requestq_count; /* # requests on requestq list. */
121 int total_request_count; /* # requests ever for this AP device. */
122
123 struct ap_message *reply; /* Per device reply message. */
124
125 void *private; /* ap driver private pointer. */
126};
127
128#define to_ap_dev(x) container_of((x), struct ap_device, device)
129
130struct ap_message {
131 struct list_head list; /* Request queueing. */
132 unsigned long long psmid; /* Message id. */
133 void *message; /* Pointer to message buffer. */
134 size_t length; /* Message length. */
135
136 void *private; /* ap driver private pointer. */
137};
138
139#define AP_DEVICE(dt) \
140 .dev_type=(dt), \
141 .match_flags=AP_DEVICE_ID_MATCH_DEVICE_TYPE,
142
143/**
144 * Note: don't use ap_send/ap_recv after using ap_queue_message
145 * for the first time. Otherwise the ap message queue will get
146 * confused.
147 */
148int ap_send(ap_qid_t, unsigned long long, void *, size_t);
149int ap_recv(ap_qid_t, unsigned long long *, void *, size_t);
150
151void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg);
152void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg);
153void ap_flush_queue(struct ap_device *ap_dev);
154
155int ap_module_init(void);
156void ap_module_exit(void);
157
158#endif /* _AP_BUS_H_ */
diff --git a/drivers/s390/crypto/z90common.h b/drivers/s390/crypto/z90common.h
deleted file mode 100644
index dbbcda3c846a..000000000000
--- a/drivers/s390/crypto/z90common.h
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2 * linux/drivers/s390/crypto/z90common.h
3 *
4 * z90crypt 1.3.3
5 *
6 * Copyright (C) 2001, 2005 IBM Corporation
7 * Author(s): Robert Burroughs (burrough@us.ibm.com)
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#ifndef _Z90COMMON_H_
28#define _Z90COMMON_H_
29
30
31#define RESPBUFFSIZE 256
32#define PCI_FUNC_KEY_DECRYPT 0x5044
33#define PCI_FUNC_KEY_ENCRYPT 0x504B
34extern int ext_bitlens;
35
36enum devstat {
37 DEV_GONE,
38 DEV_ONLINE,
39 DEV_QUEUE_FULL,
40 DEV_EMPTY,
41 DEV_NO_WORK,
42 DEV_BAD_MESSAGE,
43 DEV_TSQ_EXCEPTION,
44 DEV_RSQ_EXCEPTION,
45 DEV_SEN_EXCEPTION,
46 DEV_REC_EXCEPTION
47};
48
49enum hdstat {
50 HD_NOT_THERE,
51 HD_BUSY,
52 HD_DECONFIGURED,
53 HD_CHECKSTOPPED,
54 HD_ONLINE,
55 HD_TSQ_EXCEPTION
56};
57
58#define Z90C_NO_DEVICES 1
59#define Z90C_AMBIGUOUS_DOMAIN 2
60#define Z90C_INCORRECT_DOMAIN 3
61#define ENOTINIT 4
62
63#define SEN_BUSY 7
64#define SEN_USER_ERROR 8
65#define SEN_QUEUE_FULL 11
66#define SEN_NOT_AVAIL 16
67#define SEN_PAD_ERROR 17
68#define SEN_RETRY 18
69#define SEN_RELEASED 24
70
71#define REC_EMPTY 4
72#define REC_BUSY 6
73#define REC_OPERAND_INV 8
74#define REC_OPERAND_SIZE 9
75#define REC_EVEN_MOD 10
76#define REC_NO_WORK 11
77#define REC_HARDWAR_ERR 12
78#define REC_NO_RESPONSE 13
79#define REC_RETRY_DEV 14
80#define REC_USER_GONE 15
81#define REC_BAD_MESSAGE 16
82#define REC_INVALID_PAD 17
83#define REC_USE_PCICA 18
84
85#define WRONG_DEVICE_TYPE 20
86
87#define REC_FATAL_ERROR 32
88#define SEN_FATAL_ERROR 33
89#define TSQ_FATAL_ERROR 34
90#define RSQ_FATAL_ERROR 35
91
92#define Z90CRYPT_NUM_TYPES 6
93#define PCICA 0
94#define PCICC 1
95#define PCIXCC_MCL2 2
96#define PCIXCC_MCL3 3
97#define CEX2C 4
98#define CEX2A 5
99#define NILDEV -1
100#define ANYDEV -1
101#define PCIXCC_UNK -2
102
103enum hdevice_type {
104 PCICC_HW = 3,
105 PCICA_HW = 4,
106 PCIXCC_HW = 5,
107 CEX2A_HW = 6,
108 CEX2C_HW = 7
109};
110
111struct CPRBX {
112 unsigned short cprb_len;
113 unsigned char cprb_ver_id;
114 unsigned char pad_000[3];
115 unsigned char func_id[2];
116 unsigned char cprb_flags[4];
117 unsigned int req_parml;
118 unsigned int req_datal;
119 unsigned int rpl_msgbl;
120 unsigned int rpld_parml;
121 unsigned int rpl_datal;
122 unsigned int rpld_datal;
123 unsigned int req_extbl;
124 unsigned char pad_001[4];
125 unsigned int rpld_extbl;
126 unsigned char req_parmb[16];
127 unsigned char req_datab[16];
128 unsigned char rpl_parmb[16];
129 unsigned char rpl_datab[16];
130 unsigned char req_extb[16];
131 unsigned char rpl_extb[16];
132 unsigned short ccp_rtcode;
133 unsigned short ccp_rscode;
134 unsigned int mac_data_len;
135 unsigned char logon_id[8];
136 unsigned char mac_value[8];
137 unsigned char mac_content_flgs;
138 unsigned char pad_002;
139 unsigned short domain;
140 unsigned char pad_003[12];
141 unsigned char pad_004[36];
142};
143
144#ifndef DEV_NAME
145#define DEV_NAME "z90crypt"
146#endif
147#define PRINTK(fmt, args...) \
148 printk(KERN_DEBUG DEV_NAME ": %s -> " fmt, __FUNCTION__ , ## args)
149#define PRINTKN(fmt, args...) \
150 printk(KERN_DEBUG DEV_NAME ": " fmt, ## args)
151#define PRINTKW(fmt, args...) \
152 printk(KERN_WARNING DEV_NAME ": %s -> " fmt, __FUNCTION__ , ## args)
153#define PRINTKC(fmt, args...) \
154 printk(KERN_CRIT DEV_NAME ": %s -> " fmt, __FUNCTION__ , ## args)
155
156#ifdef Z90CRYPT_DEBUG
157#define PDEBUG(fmt, args...) \
158 printk(KERN_DEBUG DEV_NAME ": %s -> " fmt, __FUNCTION__ , ## args)
159#else
160#define PDEBUG(fmt, args...) do {} while (0)
161#endif
162
163#define UMIN(a,b) ((a) < (b) ? (a) : (b))
164#define IS_EVEN(x) ((x) == (2 * ((x) / 2)))
165
166#endif
diff --git a/drivers/s390/crypto/z90crypt.h b/drivers/s390/crypto/z90crypt.h
deleted file mode 100644
index 0ca1d126ccb6..000000000000
--- a/drivers/s390/crypto/z90crypt.h
+++ /dev/null
@@ -1,71 +0,0 @@
1/*
2 * linux/drivers/s390/crypto/z90crypt.h
3 *
4 * z90crypt 1.3.3 (kernel-private header)
5 *
6 * Copyright (C) 2001, 2005 IBM Corporation
7 * Author(s): Robert Burroughs (burrough@us.ibm.com)
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#ifndef _Z90CRYPT_H_
28#define _Z90CRYPT_H_
29
30#include <asm/z90crypt.h>
31
32/**
33 * local errno definitions
34 */
35#define ENOBUFF 129 // filp->private_data->...>work_elem_p->buffer is NULL
36#define EWORKPEND 130 // user issues ioctl while another pending
37#define ERELEASED 131 // user released while ioctl pending
38#define EQUIESCE 132 // z90crypt quiescing (no more work allowed)
39#define ETIMEOUT 133 // request timed out
40#define EUNKNOWN 134 // some unrecognized error occured (retry may succeed)
41#define EGETBUFF 135 // Error getting buffer or hardware lacks capability
42 // (retry in software)
43
44/**
45 * DEPRECATED STRUCTURES
46 */
47
48/**
49 * This structure is DEPRECATED and the corresponding ioctl() has been
50 * replaced with individual ioctl()s for each piece of data!
51 * This structure will NOT survive past version 1.3.1, so switch to the
52 * new ioctl()s.
53 */
54#define MASK_LENGTH 64 // mask length
55struct ica_z90_status {
56 int totalcount;
57 int leedslitecount; // PCICA
58 int leeds2count; // PCICC
59 // int PCIXCCCount; is not in struct for backward compatibility
60 int requestqWaitCount;
61 int pendingqWaitCount;
62 int totalOpenCount;
63 int cryptoDomain;
64 // status: 0=not there, 1=PCICA, 2=PCICC, 3=PCIXCC_MCL2, 4=PCIXCC_MCL3,
65 // 5=CEX2C
66 unsigned char status[MASK_LENGTH];
67 // qdepth: # work elements waiting for each device
68 unsigned char qdepth[MASK_LENGTH];
69};
70
71#endif /* _Z90CRYPT_H_ */
diff --git a/drivers/s390/crypto/z90hardware.c b/drivers/s390/crypto/z90hardware.c
deleted file mode 100644
index be60795f4a74..000000000000
--- a/drivers/s390/crypto/z90hardware.c
+++ /dev/null
@@ -1,2531 +0,0 @@
1/*
2 * linux/drivers/s390/crypto/z90hardware.c
3 *
4 * z90crypt 1.3.3
5 *
6 * Copyright (C) 2001, 2005 IBM Corporation
7 * Author(s): Robert Burroughs (burrough@us.ibm.com)
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <asm/uaccess.h>
28#include <linux/compiler.h>
29#include <linux/delay.h>
30#include <linux/init.h>
31#include <linux/module.h>
32#include "z90crypt.h"
33#include "z90common.h"
34
35struct cca_token_hdr {
36 unsigned char token_identifier;
37 unsigned char version;
38 unsigned short token_length;
39 unsigned char reserved[4];
40};
41
42#define CCA_TKN_HDR_ID_EXT 0x1E
43
44struct cca_private_ext_ME_sec {
45 unsigned char section_identifier;
46 unsigned char version;
47 unsigned short section_length;
48 unsigned char private_key_hash[20];
49 unsigned char reserved1[4];
50 unsigned char key_format;
51 unsigned char reserved2;
52 unsigned char key_name_hash[20];
53 unsigned char key_use_flags[4];
54 unsigned char reserved3[6];
55 unsigned char reserved4[24];
56 unsigned char confounder[24];
57 unsigned char exponent[128];
58 unsigned char modulus[128];
59};
60
61#define CCA_PVT_USAGE_ALL 0x80
62
63struct cca_public_sec {
64 unsigned char section_identifier;
65 unsigned char version;
66 unsigned short section_length;
67 unsigned char reserved[2];
68 unsigned short exponent_len;
69 unsigned short modulus_bit_len;
70 unsigned short modulus_byte_len;
71 unsigned char exponent[3];
72};
73
74struct cca_private_ext_ME {
75 struct cca_token_hdr pvtMEHdr;
76 struct cca_private_ext_ME_sec pvtMESec;
77 struct cca_public_sec pubMESec;
78};
79
80struct cca_public_key {
81 struct cca_token_hdr pubHdr;
82 struct cca_public_sec pubSec;
83};
84
85struct cca_pvt_ext_CRT_sec {
86 unsigned char section_identifier;
87 unsigned char version;
88 unsigned short section_length;
89 unsigned char private_key_hash[20];
90 unsigned char reserved1[4];
91 unsigned char key_format;
92 unsigned char reserved2;
93 unsigned char key_name_hash[20];
94 unsigned char key_use_flags[4];
95 unsigned short p_len;
96 unsigned short q_len;
97 unsigned short dp_len;
98 unsigned short dq_len;
99 unsigned short u_len;
100 unsigned short mod_len;
101 unsigned char reserved3[4];
102 unsigned short pad_len;
103 unsigned char reserved4[52];
104 unsigned char confounder[8];
105};
106
107#define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
108#define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
109
110struct cca_private_ext_CRT {
111 struct cca_token_hdr pvtCrtHdr;
112 struct cca_pvt_ext_CRT_sec pvtCrtSec;
113 struct cca_public_sec pubCrtSec;
114};
115
116struct ap_status_word {
117 unsigned char q_stat_flags;
118 unsigned char response_code;
119 unsigned char reserved[2];
120};
121
122#define AP_Q_STATUS_EMPTY 0x80
123#define AP_Q_STATUS_REPLIES_WAITING 0x40
124#define AP_Q_STATUS_ARRAY_FULL 0x20
125
126#define AP_RESPONSE_NORMAL 0x00
127#define AP_RESPONSE_Q_NOT_AVAIL 0x01
128#define AP_RESPONSE_RESET_IN_PROGRESS 0x02
129#define AP_RESPONSE_DECONFIGURED 0x03
130#define AP_RESPONSE_CHECKSTOPPED 0x04
131#define AP_RESPONSE_BUSY 0x05
132#define AP_RESPONSE_Q_FULL 0x10
133#define AP_RESPONSE_NO_PENDING_REPLY 0x10
134#define AP_RESPONSE_INDEX_TOO_BIG 0x11
135#define AP_RESPONSE_NO_FIRST_PART 0x13
136#define AP_RESPONSE_MESSAGE_TOO_BIG 0x15
137
138#define AP_MAX_CDX_BITL 4
139#define AP_RQID_RESERVED_BITL 4
140#define SKIP_BITL (AP_MAX_CDX_BITL + AP_RQID_RESERVED_BITL)
141
142struct type4_hdr {
143 unsigned char reserved1;
144 unsigned char msg_type_code;
145 unsigned short msg_len;
146 unsigned char request_code;
147 unsigned char msg_fmt;
148 unsigned short reserved2;
149};
150
151#define TYPE4_TYPE_CODE 0x04
152#define TYPE4_REQU_CODE 0x40
153
154#define TYPE4_SME_LEN 0x0188
155#define TYPE4_LME_LEN 0x0308
156#define TYPE4_SCR_LEN 0x01E0
157#define TYPE4_LCR_LEN 0x03A0
158
159#define TYPE4_SME_FMT 0x00
160#define TYPE4_LME_FMT 0x10
161#define TYPE4_SCR_FMT 0x40
162#define TYPE4_LCR_FMT 0x50
163
164struct type4_sme {
165 struct type4_hdr header;
166 unsigned char message[128];
167 unsigned char exponent[128];
168 unsigned char modulus[128];
169};
170
171struct type4_lme {
172 struct type4_hdr header;
173 unsigned char message[256];
174 unsigned char exponent[256];
175 unsigned char modulus[256];
176};
177
178struct type4_scr {
179 struct type4_hdr header;
180 unsigned char message[128];
181 unsigned char dp[72];
182 unsigned char dq[64];
183 unsigned char p[72];
184 unsigned char q[64];
185 unsigned char u[72];
186};
187
188struct type4_lcr {
189 struct type4_hdr header;
190 unsigned char message[256];
191 unsigned char dp[136];
192 unsigned char dq[128];
193 unsigned char p[136];
194 unsigned char q[128];
195 unsigned char u[136];
196};
197
198union type4_msg {
199 struct type4_sme sme;
200 struct type4_lme lme;
201 struct type4_scr scr;
202 struct type4_lcr lcr;
203};
204
205struct type84_hdr {
206 unsigned char reserved1;
207 unsigned char code;
208 unsigned short len;
209 unsigned char reserved2[4];
210};
211
212#define TYPE84_RSP_CODE 0x84
213
214struct type6_hdr {
215 unsigned char reserved1;
216 unsigned char type;
217 unsigned char reserved2[2];
218 unsigned char right[4];
219 unsigned char reserved3[2];
220 unsigned char reserved4[2];
221 unsigned char apfs[4];
222 unsigned int offset1;
223 unsigned int offset2;
224 unsigned int offset3;
225 unsigned int offset4;
226 unsigned char agent_id[16];
227 unsigned char rqid[2];
228 unsigned char reserved5[2];
229 unsigned char function_code[2];
230 unsigned char reserved6[2];
231 unsigned int ToCardLen1;
232 unsigned int ToCardLen2;
233 unsigned int ToCardLen3;
234 unsigned int ToCardLen4;
235 unsigned int FromCardLen1;
236 unsigned int FromCardLen2;
237 unsigned int FromCardLen3;
238 unsigned int FromCardLen4;
239};
240
241struct CPRB {
242 unsigned char cprb_len[2];
243 unsigned char cprb_ver_id;
244 unsigned char pad_000;
245 unsigned char srpi_rtcode[4];
246 unsigned char srpi_verb;
247 unsigned char flags;
248 unsigned char func_id[2];
249 unsigned char checkpoint_flag;
250 unsigned char resv2;
251 unsigned char req_parml[2];
252 unsigned char req_parmp[4];
253 unsigned char req_datal[4];
254 unsigned char req_datap[4];
255 unsigned char rpl_parml[2];
256 unsigned char pad_001[2];
257 unsigned char rpl_parmp[4];
258 unsigned char rpl_datal[4];
259 unsigned char rpl_datap[4];
260 unsigned char ccp_rscode[2];
261 unsigned char ccp_rtcode[2];
262 unsigned char repd_parml[2];
263 unsigned char mac_data_len[2];
264 unsigned char repd_datal[4];
265 unsigned char req_pc[2];
266 unsigned char res_origin[8];
267 unsigned char mac_value[8];
268 unsigned char logon_id[8];
269 unsigned char usage_domain[2];
270 unsigned char resv3[18];
271 unsigned char svr_namel[2];
272 unsigned char svr_name[8];
273};
274
275struct type6_msg {
276 struct type6_hdr header;
277 struct CPRB CPRB;
278};
279
280struct type86_hdr {
281 unsigned char reserved1;
282 unsigned char type;
283 unsigned char format;
284 unsigned char reserved2;
285 unsigned char reply_code;
286 unsigned char reserved3[3];
287};
288
289#define TYPE86_RSP_CODE 0x86
290#define TYPE86_FMT2 0x02
291
292struct type86_fmt2_msg {
293 struct type86_hdr header;
294 unsigned char reserved[4];
295 unsigned char apfs[4];
296 unsigned int count1;
297 unsigned int offset1;
298 unsigned int count2;
299 unsigned int offset2;
300 unsigned int count3;
301 unsigned int offset3;
302 unsigned int count4;
303 unsigned int offset4;
304};
305
306static struct type6_hdr static_type6_hdr = {
307 0x00,
308 0x06,
309 {0x00,0x00},
310 {0x00,0x00,0x00,0x00},
311 {0x00,0x00},
312 {0x00,0x00},
313 {0x00,0x00,0x00,0x00},
314 0x00000058,
315 0x00000000,
316 0x00000000,
317 0x00000000,
318 {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
319 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
320 {0x00,0x00},
321 {0x00,0x00},
322 {0x50,0x44},
323 {0x00,0x00},
324 0x00000000,
325 0x00000000,
326 0x00000000,
327 0x00000000,
328 0x00000000,
329 0x00000000,
330 0x00000000,
331 0x00000000
332};
333
334static struct type6_hdr static_type6_hdrX = {
335 0x00,
336 0x06,
337 {0x00,0x00},
338 {0x00,0x00,0x00,0x00},
339 {0x00,0x00},
340 {0x00,0x00},
341 {0x00,0x00,0x00,0x00},
342 0x00000058,
343 0x00000000,
344 0x00000000,
345 0x00000000,
346 {0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
347 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
348 {0x00,0x00},
349 {0x00,0x00},
350 {0x50,0x44},
351 {0x00,0x00},
352 0x00000000,
353 0x00000000,
354 0x00000000,
355 0x00000000,
356 0x00000000,
357 0x00000000,
358 0x00000000,
359 0x00000000
360};
361
362static struct CPRB static_cprb = {
363 {0x70,0x00},
364 0x41,
365 0x00,
366 {0x00,0x00,0x00,0x00},
367 0x00,
368 0x00,
369 {0x54,0x32},
370 0x01,
371 0x00,
372 {0x00,0x00},
373 {0x00,0x00,0x00,0x00},
374 {0x00,0x00,0x00,0x00},
375 {0x00,0x00,0x00,0x00},
376 {0x00,0x00},
377 {0x00,0x00},
378 {0x00,0x00,0x00,0x00},
379 {0x00,0x00,0x00,0x00},
380 {0x00,0x00,0x00,0x00},
381 {0x00,0x00},
382 {0x00,0x00},
383 {0x00,0x00},
384 {0x00,0x00},
385 {0x00,0x00,0x00,0x00},
386 {0x00,0x00},
387 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
388 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
389 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
390 {0x00,0x00},
391 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
392 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
393 0x00,0x00},
394 {0x08,0x00},
395 {0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20}
396};
397
398struct function_and_rules_block {
399 unsigned char function_code[2];
400 unsigned char ulen[2];
401 unsigned char only_rule[8];
402};
403
404static struct function_and_rules_block static_pkd_function_and_rules = {
405 {0x50,0x44},
406 {0x0A,0x00},
407 {'P','K','C','S','-','1','.','2'}
408};
409
410static struct function_and_rules_block static_pke_function_and_rules = {
411 {0x50,0x4B},
412 {0x0A,0x00},
413 {'P','K','C','S','-','1','.','2'}
414};
415
416struct T6_keyBlock_hdr {
417 unsigned char blen[2];
418 unsigned char ulen[2];
419 unsigned char flags[2];
420};
421
422static struct T6_keyBlock_hdr static_T6_keyBlock_hdr = {
423 {0x89,0x01},
424 {0x87,0x01},
425 {0x00}
426};
427
428static struct CPRBX static_cprbx = {
429 0x00DC,
430 0x02,
431 {0x00,0x00,0x00},
432 {0x54,0x32},
433 {0x00,0x00,0x00,0x00},
434 0x00000000,
435 0x00000000,
436 0x00000000,
437 0x00000000,
438 0x00000000,
439 0x00000000,
440 0x00000000,
441 {0x00,0x00,0x00,0x00},
442 0x00000000,
443 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
444 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
445 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
446 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
447 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
448 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
449 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
450 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
451 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
452 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
453 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
454 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
455 0x0000,
456 0x0000,
457 0x00000000,
458 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
459 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
460 0x00,
461 0x00,
462 0x0000,
463 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
464 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
465 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
466 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
467};
468
469static struct function_and_rules_block static_pkd_function_and_rulesX_MCL2 = {
470 {0x50,0x44},
471 {0x00,0x0A},
472 {'P','K','C','S','-','1','.','2'}
473};
474
475static struct function_and_rules_block static_pke_function_and_rulesX_MCL2 = {
476 {0x50,0x4B},
477 {0x00,0x0A},
478 {'Z','E','R','O','-','P','A','D'}
479};
480
481static struct function_and_rules_block static_pkd_function_and_rulesX = {
482 {0x50,0x44},
483 {0x00,0x0A},
484 {'Z','E','R','O','-','P','A','D'}
485};
486
487static struct function_and_rules_block static_pke_function_and_rulesX = {
488 {0x50,0x4B},
489 {0x00,0x0A},
490 {'M','R','P',' ',' ',' ',' ',' '}
491};
492
493static unsigned char static_PKE_function_code[2] = {0x50, 0x4B};
494
495struct T6_keyBlock_hdrX {
496 unsigned short blen;
497 unsigned short ulen;
498 unsigned char flags[2];
499};
500
501static unsigned char static_pad[256] = {
5020x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
5030x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
5040xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
5050x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
5060x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
5070x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
5080x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
5090xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
5100x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
5110x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
5120x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
5130x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
5140x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
5150x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
5160x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
5170x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
518};
519
520static struct cca_private_ext_ME static_pvt_me_key = {
521 {
522 0x1E,
523 0x00,
524 0x0183,
525 {0x00,0x00,0x00,0x00}
526 },
527
528 {
529 0x02,
530 0x00,
531 0x016C,
532 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
533 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
534 0x00,0x00,0x00,0x00},
535 {0x00,0x00,0x00,0x00},
536 0x00,
537 0x00,
538 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
539 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
540 0x00,0x00,0x00,0x00},
541 {0x80,0x00,0x00,0x00},
542 {0x00,0x00,0x00,0x00,0x00,0x00},
543 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
544 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
545 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
546 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
547 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
548 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
549 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
550 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
551 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
552 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
553 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
554 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
555 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
556 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
557 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
558 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
560 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
561 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
562 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
563 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
564 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
565 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
566 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
567 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
568 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
569 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
570 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
571 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
572 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
574 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
575 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
576 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
577 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
578 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
579 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
580 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
581 },
582
583 {
584 0x04,
585 0x00,
586 0x000F,
587 {0x00,0x00},
588 0x0003,
589 0x0000,
590 0x0000,
591 {0x01,0x00,0x01}
592 }
593};
594
595static struct cca_public_key static_public_key = {
596 {
597 0x1E,
598 0x00,
599 0x0000,
600 {0x00,0x00,0x00,0x00}
601 },
602
603 {
604 0x04,
605 0x00,
606 0x0000,
607 {0x00,0x00},
608 0x0000,
609 0x0000,
610 0x0000,
611 {0x01,0x00,0x01}
612 }
613};
614
615#define FIXED_TYPE6_ME_LEN 0x0000025F
616
617#define FIXED_TYPE6_ME_EN_LEN 0x000000F0
618
619#define FIXED_TYPE6_ME_LENX 0x000002CB
620
621#define FIXED_TYPE6_ME_EN_LENX 0x0000015C
622
623static struct cca_public_sec static_cca_pub_sec = {
624 0x04,
625 0x00,
626 0x000f,
627 {0x00,0x00},
628 0x0003,
629 0x0000,
630 0x0000,
631 {0x01,0x00,0x01}
632};
633
634#define FIXED_TYPE6_CR_LEN 0x00000177
635
636#define FIXED_TYPE6_CR_LENX 0x000001E3
637
638#define MAX_RESPONSE_SIZE 0x00000710
639
640#define MAX_RESPONSEX_SIZE 0x0000077C
641
642#define RESPONSE_CPRB_SIZE 0x000006B8
643#define RESPONSE_CPRBX_SIZE 0x00000724
644
645struct type50_hdr {
646 u8 reserved1;
647 u8 msg_type_code;
648 u16 msg_len;
649 u8 reserved2;
650 u8 ignored;
651 u16 reserved3;
652};
653
654#define TYPE50_TYPE_CODE 0x50
655
656#define TYPE50_MEB1_LEN (sizeof(struct type50_meb1_msg))
657#define TYPE50_MEB2_LEN (sizeof(struct type50_meb2_msg))
658#define TYPE50_CRB1_LEN (sizeof(struct type50_crb1_msg))
659#define TYPE50_CRB2_LEN (sizeof(struct type50_crb2_msg))
660
661#define TYPE50_MEB1_FMT 0x0001
662#define TYPE50_MEB2_FMT 0x0002
663#define TYPE50_CRB1_FMT 0x0011
664#define TYPE50_CRB2_FMT 0x0012
665
666struct type50_meb1_msg {
667 struct type50_hdr header;
668 u16 keyblock_type;
669 u8 reserved[6];
670 u8 exponent[128];
671 u8 modulus[128];
672 u8 message[128];
673};
674
675struct type50_meb2_msg {
676 struct type50_hdr header;
677 u16 keyblock_type;
678 u8 reserved[6];
679 u8 exponent[256];
680 u8 modulus[256];
681 u8 message[256];
682};
683
684struct type50_crb1_msg {
685 struct type50_hdr header;
686 u16 keyblock_type;
687 u8 reserved[6];
688 u8 p[64];
689 u8 q[64];
690 u8 dp[64];
691 u8 dq[64];
692 u8 u[64];
693 u8 message[128];
694};
695
696struct type50_crb2_msg {
697 struct type50_hdr header;
698 u16 keyblock_type;
699 u8 reserved[6];
700 u8 p[128];
701 u8 q[128];
702 u8 dp[128];
703 u8 dq[128];
704 u8 u[128];
705 u8 message[256];
706};
707
708union type50_msg {
709 struct type50_meb1_msg meb1;
710 struct type50_meb2_msg meb2;
711 struct type50_crb1_msg crb1;
712 struct type50_crb2_msg crb2;
713};
714
715struct type80_hdr {
716 u8 reserved1;
717 u8 type;
718 u16 len;
719 u8 code;
720 u8 reserved2[3];
721 u8 reserved3[8];
722};
723
724#define TYPE80_RSP_CODE 0x80
725
726struct error_hdr {
727 unsigned char reserved1;
728 unsigned char type;
729 unsigned char reserved2[2];
730 unsigned char reply_code;
731 unsigned char reserved3[3];
732};
733
734#define TYPE82_RSP_CODE 0x82
735#define TYPE88_RSP_CODE 0x88
736
737#define REP82_ERROR_MACHINE_FAILURE 0x10
738#define REP82_ERROR_PREEMPT_FAILURE 0x12
739#define REP82_ERROR_CHECKPT_FAILURE 0x14
740#define REP82_ERROR_MESSAGE_TYPE 0x20
741#define REP82_ERROR_INVALID_COMM_CD 0x21
742#define REP82_ERROR_INVALID_MSG_LEN 0x23
743#define REP82_ERROR_RESERVD_FIELD 0x24
744#define REP82_ERROR_FORMAT_FIELD 0x29
745#define REP82_ERROR_INVALID_COMMAND 0x30
746#define REP82_ERROR_MALFORMED_MSG 0x40
747#define REP82_ERROR_RESERVED_FIELDO 0x50
748#define REP82_ERROR_WORD_ALIGNMENT 0x60
749#define REP82_ERROR_MESSAGE_LENGTH 0x80
750#define REP82_ERROR_OPERAND_INVALID 0x82
751#define REP82_ERROR_OPERAND_SIZE 0x84
752#define REP82_ERROR_EVEN_MOD_IN_OPND 0x85
753#define REP82_ERROR_RESERVED_FIELD 0x88
754#define REP82_ERROR_TRANSPORT_FAIL 0x90
755#define REP82_ERROR_PACKET_TRUNCATED 0xA0
756#define REP82_ERROR_ZERO_BUFFER_LEN 0xB0
757
758#define REP88_ERROR_MODULE_FAILURE 0x10
759#define REP88_ERROR_MODULE_TIMEOUT 0x11
760#define REP88_ERROR_MODULE_NOTINIT 0x13
761#define REP88_ERROR_MODULE_NOTAVAIL 0x14
762#define REP88_ERROR_MODULE_DISABLED 0x15
763#define REP88_ERROR_MODULE_IN_DIAGN 0x17
764#define REP88_ERROR_FASTPATH_DISABLD 0x19
765#define REP88_ERROR_MESSAGE_TYPE 0x20
766#define REP88_ERROR_MESSAGE_MALFORMD 0x22
767#define REP88_ERROR_MESSAGE_LENGTH 0x23
768#define REP88_ERROR_RESERVED_FIELD 0x24
769#define REP88_ERROR_KEY_TYPE 0x34
770#define REP88_ERROR_INVALID_KEY 0x82
771#define REP88_ERROR_OPERAND 0x84
772#define REP88_ERROR_OPERAND_EVEN_MOD 0x85
773
774#define CALLER_HEADER 12
775
776static inline int
777testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat)
778{
779 int ccode;
780
781 asm volatile
782#ifdef CONFIG_64BIT
783 (" llgfr 0,%4 \n"
784 " slgr 1,1 \n"
785 " lgr 2,1 \n"
786 "0: .long 0xb2af0000 \n"
787 "1: ipm %0 \n"
788 " srl %0,28 \n"
789 " iihh %0,0 \n"
790 " iihl %0,0 \n"
791 " lgr %1,1 \n"
792 " lgr %3,2 \n"
793 " srl %3,24 \n"
794 " sll 2,24 \n"
795 " srl 2,24 \n"
796 " lgr %2,2 \n"
797 "2: \n"
798 ".section .fixup,\"ax\" \n"
799 "3: \n"
800 " lhi %0,%h5 \n"
801 " jg 2b \n"
802 ".previous \n"
803 ".section __ex_table,\"a\" \n"
804 " .align 8 \n"
805 " .quad 0b,3b \n"
806 " .quad 1b,3b \n"
807 ".previous"
808 :"=d" (ccode),"=d" (*stat),"=d" (*q_depth), "=d" (*dev_type)
809 :"d" (q_nr), "K" (DEV_TSQ_EXCEPTION)
810 :"cc","0","1","2","memory");
811#else
812 (" lr 0,%4 \n"
813 " slr 1,1 \n"
814 " lr 2,1 \n"
815 "0: .long 0xb2af0000 \n"
816 "1: ipm %0 \n"
817 " srl %0,28 \n"
818 " lr %1,1 \n"
819 " lr %3,2 \n"
820 " srl %3,24 \n"
821 " sll 2,24 \n"
822 " srl 2,24 \n"
823 " lr %2,2 \n"
824 "2: \n"
825 ".section .fixup,\"ax\" \n"
826 "3: \n"
827 " lhi %0,%h5 \n"
828 " bras 1,4f \n"
829 " .long 2b \n"
830 "4: \n"
831 " l 1,0(1) \n"
832 " br 1 \n"
833 ".previous \n"
834 ".section __ex_table,\"a\" \n"
835 " .align 4 \n"
836 " .long 0b,3b \n"
837 " .long 1b,3b \n"
838 ".previous"
839 :"=d" (ccode),"=d" (*stat),"=d" (*q_depth), "=d" (*dev_type)
840 :"d" (q_nr), "K" (DEV_TSQ_EXCEPTION)
841 :"cc","0","1","2","memory");
842#endif
843 return ccode;
844}
845
846static inline int
847resetq(int q_nr, struct ap_status_word *stat_p)
848{
849 int ccode;
850
851 asm volatile
852#ifdef CONFIG_64BIT
853 (" llgfr 0,%2 \n"
854 " lghi 1,1 \n"
855 " sll 1,24 \n"
856 " or 0,1 \n"
857 " slgr 1,1 \n"
858 " lgr 2,1 \n"
859 "0: .long 0xb2af0000 \n"
860 "1: ipm %0 \n"
861 " srl %0,28 \n"
862 " iihh %0,0 \n"
863 " iihl %0,0 \n"
864 " lgr %1,1 \n"
865 "2: \n"
866 ".section .fixup,\"ax\" \n"
867 "3: \n"
868 " lhi %0,%h3 \n"
869 " jg 2b \n"
870 ".previous \n"
871 ".section __ex_table,\"a\" \n"
872 " .align 8 \n"
873 " .quad 0b,3b \n"
874 " .quad 1b,3b \n"
875 ".previous"
876 :"=d" (ccode),"=d" (*stat_p)
877 :"d" (q_nr), "K" (DEV_RSQ_EXCEPTION)
878 :"cc","0","1","2","memory");
879#else
880 (" lr 0,%2 \n"
881 " lhi 1,1 \n"
882 " sll 1,24 \n"
883 " or 0,1 \n"
884 " slr 1,1 \n"
885 " lr 2,1 \n"
886 "0: .long 0xb2af0000 \n"
887 "1: ipm %0 \n"
888 " srl %0,28 \n"
889 " lr %1,1 \n"
890 "2: \n"
891 ".section .fixup,\"ax\" \n"
892 "3: \n"
893 " lhi %0,%h3 \n"
894 " bras 1,4f \n"
895 " .long 2b \n"
896 "4: \n"
897 " l 1,0(1) \n"
898 " br 1 \n"
899 ".previous \n"
900 ".section __ex_table,\"a\" \n"
901 " .align 4 \n"
902 " .long 0b,3b \n"
903 " .long 1b,3b \n"
904 ".previous"
905 :"=d" (ccode),"=d" (*stat_p)
906 :"d" (q_nr), "K" (DEV_RSQ_EXCEPTION)
907 :"cc","0","1","2","memory");
908#endif
909 return ccode;
910}
911
912static inline int
913sen(int msg_len, unsigned char *msg_ext, struct ap_status_word *stat)
914{
915 int ccode;
916
917 asm volatile
918#ifdef CONFIG_64BIT
919 (" lgr 6,%3 \n"
920 " llgfr 7,%2 \n"
921 " llgt 0,0(6) \n"
922 " lghi 1,64 \n"
923 " sll 1,24 \n"
924 " or 0,1 \n"
925 " la 6,4(6) \n"
926 " llgt 2,0(6) \n"
927 " llgt 3,4(6) \n"
928 " la 6,8(6) \n"
929 " slr 1,1 \n"
930 "0: .long 0xb2ad0026 \n"
931 "1: brc 2,0b \n"
932 " ipm %0 \n"
933 " srl %0,28 \n"
934 " iihh %0,0 \n"
935 " iihl %0,0 \n"
936 " lgr %1,1 \n"
937 "2: \n"
938 ".section .fixup,\"ax\" \n"
939 "3: \n"
940 " lhi %0,%h4 \n"
941 " jg 2b \n"
942 ".previous \n"
943 ".section __ex_table,\"a\" \n"
944 " .align 8 \n"
945 " .quad 0b,3b \n"
946 " .quad 1b,3b \n"
947 ".previous"
948 :"=d" (ccode),"=d" (*stat)
949 :"d" (msg_len),"a" (msg_ext), "K" (DEV_SEN_EXCEPTION)
950 :"cc","0","1","2","3","6","7","memory");
951#else
952 (" lr 6,%3 \n"
953 " lr 7,%2 \n"
954 " l 0,0(6) \n"
955 " lhi 1,64 \n"
956 " sll 1,24 \n"
957 " or 0,1 \n"
958 " la 6,4(6) \n"
959 " l 2,0(6) \n"
960 " l 3,4(6) \n"
961 " la 6,8(6) \n"
962 " slr 1,1 \n"
963 "0: .long 0xb2ad0026 \n"
964 "1: brc 2,0b \n"
965 " ipm %0 \n"
966 " srl %0,28 \n"
967 " lr %1,1 \n"
968 "2: \n"
969 ".section .fixup,\"ax\" \n"
970 "3: \n"
971 " lhi %0,%h4 \n"
972 " bras 1,4f \n"
973 " .long 2b \n"
974 "4: \n"
975 " l 1,0(1) \n"
976 " br 1 \n"
977 ".previous \n"
978 ".section __ex_table,\"a\" \n"
979 " .align 4 \n"
980 " .long 0b,3b \n"
981 " .long 1b,3b \n"
982 ".previous"
983 :"=d" (ccode),"=d" (*stat)
984 :"d" (msg_len),"a" (msg_ext), "K" (DEV_SEN_EXCEPTION)
985 :"cc","0","1","2","3","6","7","memory");
986#endif
987 return ccode;
988}
989
990static inline int
991rec(int q_nr, int buff_l, unsigned char *rsp, unsigned char *id,
992 struct ap_status_word *st)
993{
994 int ccode;
995
996 asm volatile
997#ifdef CONFIG_64BIT
998 (" llgfr 0,%2 \n"
999 " lgr 3,%4 \n"
1000 " lgr 6,%3 \n"
1001 " llgfr 7,%5 \n"
1002 " lghi 1,128 \n"
1003 " sll 1,24 \n"
1004 " or 0,1 \n"
1005 " slgr 1,1 \n"
1006 " lgr 2,1 \n"
1007 " lgr 4,1 \n"
1008 " lgr 5,1 \n"
1009 "0: .long 0xb2ae0046 \n"
1010 "1: brc 2,0b \n"
1011 " brc 4,0b \n"
1012 " ipm %0 \n"
1013 " srl %0,28 \n"
1014 " iihh %0,0 \n"
1015 " iihl %0,0 \n"
1016 " lgr %1,1 \n"
1017 " st 4,0(3) \n"
1018 " st 5,4(3) \n"
1019 "2: \n"
1020 ".section .fixup,\"ax\" \n"
1021 "3: \n"
1022 " lhi %0,%h6 \n"
1023 " jg 2b \n"
1024 ".previous \n"
1025 ".section __ex_table,\"a\" \n"
1026 " .align 8 \n"
1027 " .quad 0b,3b \n"
1028 " .quad 1b,3b \n"
1029 ".previous"
1030 :"=d"(ccode),"=d"(*st)
1031 :"d" (q_nr), "d" (rsp), "d" (id), "d" (buff_l), "K" (DEV_REC_EXCEPTION)
1032 :"cc","0","1","2","3","4","5","6","7","memory");
1033#else
1034 (" lr 0,%2 \n"
1035 " lr 3,%4 \n"
1036 " lr 6,%3 \n"
1037 " lr 7,%5 \n"
1038 " lhi 1,128 \n"
1039 " sll 1,24 \n"
1040 " or 0,1 \n"
1041 " slr 1,1 \n"
1042 " lr 2,1 \n"
1043 " lr 4,1 \n"
1044 " lr 5,1 \n"
1045 "0: .long 0xb2ae0046 \n"
1046 "1: brc 2,0b \n"
1047 " brc 4,0b \n"
1048 " ipm %0 \n"
1049 " srl %0,28 \n"
1050 " lr %1,1 \n"
1051 " st 4,0(3) \n"
1052 " st 5,4(3) \n"
1053 "2: \n"
1054 ".section .fixup,\"ax\" \n"
1055 "3: \n"
1056 " lhi %0,%h6 \n"
1057 " bras 1,4f \n"
1058 " .long 2b \n"
1059 "4: \n"
1060 " l 1,0(1) \n"
1061 " br 1 \n"
1062 ".previous \n"
1063 ".section __ex_table,\"a\" \n"
1064 " .align 4 \n"
1065 " .long 0b,3b \n"
1066 " .long 1b,3b \n"
1067 ".previous"
1068 :"=d"(ccode),"=d"(*st)
1069 :"d" (q_nr), "d" (rsp), "d" (id), "d" (buff_l), "K" (DEV_REC_EXCEPTION)
1070 :"cc","0","1","2","3","4","5","6","7","memory");
1071#endif
1072 return ccode;
1073}
1074
1075static inline void
1076itoLe2(int *i_p, unsigned char *lechars)
1077{
1078 *lechars = *((unsigned char *) i_p + sizeof(int) - 1);
1079 *(lechars + 1) = *((unsigned char *) i_p + sizeof(int) - 2);
1080}
1081
1082static inline void
1083le2toI(unsigned char *lechars, int *i_p)
1084{
1085 unsigned char *ic_p;
1086 *i_p = 0;
1087 ic_p = (unsigned char *) i_p;
1088 *(ic_p + 2) = *(lechars + 1);
1089 *(ic_p + 3) = *(lechars);
1090}
1091
1092static inline int
1093is_empty(unsigned char *ptr, int len)
1094{
1095 return !memcmp(ptr, (unsigned char *) &static_pvt_me_key+60, len);
1096}
1097
1098enum hdstat
1099query_online(int deviceNr, int cdx, int resetNr, int *q_depth, int *dev_type)
1100{
1101 int q_nr, i, t_depth, t_dev_type;
1102 enum devstat ccode;
1103 struct ap_status_word stat_word;
1104 enum hdstat stat;
1105 int break_out;
1106
1107 q_nr = (deviceNr << SKIP_BITL) + cdx;
1108 stat = HD_BUSY;
1109 ccode = testq(q_nr, &t_depth, &t_dev_type, &stat_word);
1110 PDEBUG("ccode %d response_code %02X\n", ccode, stat_word.response_code);
1111 break_out = 0;
1112 for (i = 0; i < resetNr; i++) {
1113 if (ccode > 3) {
1114 PRINTKC("Exception testing device %d\n", i);
1115 return HD_TSQ_EXCEPTION;
1116 }
1117 switch (ccode) {
1118 case 0:
1119 PDEBUG("t_dev_type %d\n", t_dev_type);
1120 break_out = 1;
1121 stat = HD_ONLINE;
1122 *q_depth = t_depth + 1;
1123 switch (t_dev_type) {
1124 case PCICA_HW:
1125 *dev_type = PCICA;
1126 break;
1127 case PCICC_HW:
1128 *dev_type = PCICC;
1129 break;
1130 case PCIXCC_HW:
1131 *dev_type = PCIXCC_UNK;
1132 break;
1133 case CEX2C_HW:
1134 *dev_type = CEX2C;
1135 break;
1136 case CEX2A_HW:
1137 *dev_type = CEX2A;
1138 break;
1139 default:
1140 *dev_type = NILDEV;
1141 break;
1142 }
1143 PDEBUG("available device %d: Q depth = %d, dev "
1144 "type = %d, stat = %02X%02X%02X%02X\n",
1145 deviceNr, *q_depth, *dev_type,
1146 stat_word.q_stat_flags,
1147 stat_word.response_code,
1148 stat_word.reserved[0],
1149 stat_word.reserved[1]);
1150 break;
1151 case 3:
1152 switch (stat_word.response_code) {
1153 case AP_RESPONSE_NORMAL:
1154 stat = HD_ONLINE;
1155 break_out = 1;
1156 *q_depth = t_depth + 1;
1157 *dev_type = t_dev_type;
1158 PDEBUG("cc3, available device "
1159 "%d: Q depth = %d, dev "
1160 "type = %d, stat = "
1161 "%02X%02X%02X%02X\n",
1162 deviceNr, *q_depth,
1163 *dev_type,
1164 stat_word.q_stat_flags,
1165 stat_word.response_code,
1166 stat_word.reserved[0],
1167 stat_word.reserved[1]);
1168 break;
1169 case AP_RESPONSE_Q_NOT_AVAIL:
1170 stat = HD_NOT_THERE;
1171 break_out = 1;
1172 break;
1173 case AP_RESPONSE_RESET_IN_PROGRESS:
1174 PDEBUG("device %d in reset\n",
1175 deviceNr);
1176 break;
1177 case AP_RESPONSE_DECONFIGURED:
1178 stat = HD_DECONFIGURED;
1179 break_out = 1;
1180 break;
1181 case AP_RESPONSE_CHECKSTOPPED:
1182 stat = HD_CHECKSTOPPED;
1183 break_out = 1;
1184 break;
1185 case AP_RESPONSE_BUSY:
1186 PDEBUG("device %d busy\n",
1187 deviceNr);
1188 break;
1189 default:
1190 break;
1191 }
1192 break;
1193 default:
1194 stat = HD_NOT_THERE;
1195 break_out = 1;
1196 break;
1197 }
1198 if (break_out)
1199 break;
1200
1201 udelay(5);
1202
1203 ccode = testq(q_nr, &t_depth, &t_dev_type, &stat_word);
1204 }
1205 return stat;
1206}
1207
1208enum devstat
1209reset_device(int deviceNr, int cdx, int resetNr)
1210{
1211 int q_nr, ccode = 0, dummy_qdepth, dummy_devType, i;
1212 struct ap_status_word stat_word;
1213 enum devstat stat;
1214 int break_out;
1215
1216 q_nr = (deviceNr << SKIP_BITL) + cdx;
1217 stat = DEV_GONE;
1218 ccode = resetq(q_nr, &stat_word);
1219 if (ccode > 3)
1220 return DEV_RSQ_EXCEPTION;
1221
1222 break_out = 0;
1223 for (i = 0; i < resetNr; i++) {
1224 switch (ccode) {
1225 case 0:
1226 stat = DEV_ONLINE;
1227 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1228 break_out = 1;
1229 break;
1230 case 3:
1231 switch (stat_word.response_code) {
1232 case AP_RESPONSE_NORMAL:
1233 stat = DEV_ONLINE;
1234 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1235 break_out = 1;
1236 break;
1237 case AP_RESPONSE_Q_NOT_AVAIL:
1238 case AP_RESPONSE_DECONFIGURED:
1239 case AP_RESPONSE_CHECKSTOPPED:
1240 stat = DEV_GONE;
1241 break_out = 1;
1242 break;
1243 case AP_RESPONSE_RESET_IN_PROGRESS:
1244 case AP_RESPONSE_BUSY:
1245 default:
1246 break;
1247 }
1248 break;
1249 default:
1250 stat = DEV_GONE;
1251 break_out = 1;
1252 break;
1253 }
1254 if (break_out == 1)
1255 break;
1256 udelay(5);
1257
1258 ccode = testq(q_nr, &dummy_qdepth, &dummy_devType, &stat_word);
1259 if (ccode > 3) {
1260 stat = DEV_TSQ_EXCEPTION;
1261 break;
1262 }
1263 }
1264 PDEBUG("Number of testq's needed for reset: %d\n", i);
1265
1266 if (i >= resetNr) {
1267 stat = DEV_GONE;
1268 }
1269
1270 return stat;
1271}
1272
1273#ifdef DEBUG_HYDRA_MSGS
1274static inline void
1275print_buffer(unsigned char *buffer, int bufflen)
1276{
1277 int i;
1278 for (i = 0; i < bufflen; i += 16) {
1279 PRINTK("%04X: %02X%02X%02X%02X %02X%02X%02X%02X "
1280 "%02X%02X%02X%02X %02X%02X%02X%02X\n", i,
1281 buffer[i+0], buffer[i+1], buffer[i+2], buffer[i+3],
1282 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
1283 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
1284 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
1285 }
1286}
1287#endif
1288
1289enum devstat
1290send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext)
1291{
1292 struct ap_status_word stat_word;
1293 enum devstat stat;
1294 int ccode;
1295 u32 *q_nr_p = (u32 *)msg_ext;
1296
1297 *q_nr_p = (dev_nr << SKIP_BITL) + cdx;
1298 PDEBUG("msg_len passed to sen: %d\n", msg_len);
1299 PDEBUG("q number passed to sen: %02x%02x%02x%02x\n",
1300 msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]);
1301 stat = DEV_GONE;
1302
1303#ifdef DEBUG_HYDRA_MSGS
1304 PRINTK("Request header: %02X%02X%02X%02X %02X%02X%02X%02X "
1305 "%02X%02X%02X%02X\n",
1306 msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3],
1307 msg_ext[4], msg_ext[5], msg_ext[6], msg_ext[7],
1308 msg_ext[8], msg_ext[9], msg_ext[10], msg_ext[11]);
1309 print_buffer(msg_ext+CALLER_HEADER, msg_len);
1310#endif
1311
1312 ccode = sen(msg_len, msg_ext, &stat_word);
1313 if (ccode > 3)
1314 return DEV_SEN_EXCEPTION;
1315
1316 PDEBUG("nq cc: %u, st: %02x%02x%02x%02x\n",
1317 ccode, stat_word.q_stat_flags, stat_word.response_code,
1318 stat_word.reserved[0], stat_word.reserved[1]);
1319 switch (ccode) {
1320 case 0:
1321 stat = DEV_ONLINE;
1322 break;
1323 case 1:
1324 stat = DEV_GONE;
1325 break;
1326 case 3:
1327 switch (stat_word.response_code) {
1328 case AP_RESPONSE_NORMAL:
1329 stat = DEV_ONLINE;
1330 break;
1331 case AP_RESPONSE_Q_FULL:
1332 stat = DEV_QUEUE_FULL;
1333 break;
1334 default:
1335 stat = DEV_GONE;
1336 break;
1337 }
1338 break;
1339 default:
1340 stat = DEV_GONE;
1341 break;
1342 }
1343
1344 return stat;
1345}
1346
1347enum devstat
1348receive_from_AP(int dev_nr, int cdx, int resplen, unsigned char *resp,
1349 unsigned char *psmid)
1350{
1351 int ccode;
1352 struct ap_status_word stat_word;
1353 enum devstat stat;
1354
1355 memset(resp, 0x00, 8);
1356
1357 ccode = rec((dev_nr << SKIP_BITL) + cdx, resplen, resp, psmid,
1358 &stat_word);
1359 if (ccode > 3)
1360 return DEV_REC_EXCEPTION;
1361
1362 PDEBUG("dq cc: %u, st: %02x%02x%02x%02x\n",
1363 ccode, stat_word.q_stat_flags, stat_word.response_code,
1364 stat_word.reserved[0], stat_word.reserved[1]);
1365
1366 stat = DEV_GONE;
1367 switch (ccode) {
1368 case 0:
1369 stat = DEV_ONLINE;
1370#ifdef DEBUG_HYDRA_MSGS
1371 print_buffer(resp, resplen);
1372#endif
1373 break;
1374 case 3:
1375 switch (stat_word.response_code) {
1376 case AP_RESPONSE_NORMAL:
1377 stat = DEV_ONLINE;
1378 break;
1379 case AP_RESPONSE_NO_PENDING_REPLY:
1380 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1381 stat = DEV_EMPTY;
1382 else
1383 stat = DEV_NO_WORK;
1384 break;
1385 case AP_RESPONSE_INDEX_TOO_BIG:
1386 case AP_RESPONSE_NO_FIRST_PART:
1387 case AP_RESPONSE_MESSAGE_TOO_BIG:
1388 stat = DEV_BAD_MESSAGE;
1389 break;
1390 default:
1391 break;
1392 }
1393 break;
1394 default:
1395 break;
1396 }
1397
1398 return stat;
1399}
1400
1401static inline int
1402pad_msg(unsigned char *buffer, int totalLength, int msgLength)
1403{
1404 int pad_len;
1405
1406 for (pad_len = 0; pad_len < (totalLength - msgLength); pad_len++)
1407 if (buffer[pad_len] != 0x00)
1408 break;
1409 pad_len -= 3;
1410 if (pad_len < 8)
1411 return SEN_PAD_ERROR;
1412
1413 buffer[0] = 0x00;
1414 buffer[1] = 0x02;
1415
1416 memcpy(buffer+2, static_pad, pad_len);
1417
1418 buffer[pad_len + 2] = 0x00;
1419
1420 return 0;
1421}
1422
1423static inline int
1424is_common_public_key(unsigned char *key, int len)
1425{
1426 int i;
1427
1428 for (i = 0; i < len; i++)
1429 if (key[i])
1430 break;
1431 key += i;
1432 len -= i;
1433 if (((len == 1) && (key[0] == 3)) ||
1434 ((len == 3) && (key[0] == 1) && (key[1] == 0) && (key[2] == 1)))
1435 return 1;
1436
1437 return 0;
1438}
1439
1440static int
1441ICAMEX_msg_to_type4MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p,
1442 union type4_msg *z90cMsg_p)
1443{
1444 int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len;
1445 unsigned char *mod_tgt, *exp_tgt, *inp_tgt;
1446 union type4_msg *tmp_type4_msg;
1447
1448 mod_len = icaMex_p->inputdatalength;
1449
1450 msg_size = ((mod_len <= 128) ? TYPE4_SME_LEN : TYPE4_LME_LEN) +
1451 CALLER_HEADER;
1452
1453 memset(z90cMsg_p, 0, msg_size);
1454
1455 tmp_type4_msg = (union type4_msg *)
1456 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
1457
1458 tmp_type4_msg->sme.header.msg_type_code = TYPE4_TYPE_CODE;
1459 tmp_type4_msg->sme.header.request_code = TYPE4_REQU_CODE;
1460
1461 if (mod_len <= 128) {
1462 tmp_type4_msg->sme.header.msg_fmt = TYPE4_SME_FMT;
1463 tmp_type4_msg->sme.header.msg_len = TYPE4_SME_LEN;
1464 mod_tgt = tmp_type4_msg->sme.modulus;
1465 mod_tgt_len = sizeof(tmp_type4_msg->sme.modulus);
1466 exp_tgt = tmp_type4_msg->sme.exponent;
1467 exp_tgt_len = sizeof(tmp_type4_msg->sme.exponent);
1468 inp_tgt = tmp_type4_msg->sme.message;
1469 inp_tgt_len = sizeof(tmp_type4_msg->sme.message);
1470 } else {
1471 tmp_type4_msg->lme.header.msg_fmt = TYPE4_LME_FMT;
1472 tmp_type4_msg->lme.header.msg_len = TYPE4_LME_LEN;
1473 mod_tgt = tmp_type4_msg->lme.modulus;
1474 mod_tgt_len = sizeof(tmp_type4_msg->lme.modulus);
1475 exp_tgt = tmp_type4_msg->lme.exponent;
1476 exp_tgt_len = sizeof(tmp_type4_msg->lme.exponent);
1477 inp_tgt = tmp_type4_msg->lme.message;
1478 inp_tgt_len = sizeof(tmp_type4_msg->lme.message);
1479 }
1480
1481 mod_tgt += (mod_tgt_len - mod_len);
1482 if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len))
1483 return SEN_RELEASED;
1484 if (is_empty(mod_tgt, mod_len))
1485 return SEN_USER_ERROR;
1486 exp_tgt += (exp_tgt_len - mod_len);
1487 if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len))
1488 return SEN_RELEASED;
1489 if (is_empty(exp_tgt, mod_len))
1490 return SEN_USER_ERROR;
1491 inp_tgt += (inp_tgt_len - mod_len);
1492 if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len))
1493 return SEN_RELEASED;
1494 if (is_empty(inp_tgt, mod_len))
1495 return SEN_USER_ERROR;
1496
1497 *z90cMsg_l_p = msg_size - CALLER_HEADER;
1498
1499 return 0;
1500}
1501
1502static int
1503ICACRT_msg_to_type4CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p,
1504 int *z90cMsg_l_p, union type4_msg *z90cMsg_p)
1505{
1506 int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len,
1507 dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len;
1508 unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt;
1509 union type4_msg *tmp_type4_msg;
1510
1511 mod_len = icaMsg_p->inputdatalength;
1512 short_len = mod_len / 2;
1513 long_len = mod_len / 2 + 8;
1514
1515 tmp_size = ((mod_len <= 128) ? TYPE4_SCR_LEN : TYPE4_LCR_LEN) +
1516 CALLER_HEADER;
1517
1518 memset(z90cMsg_p, 0, tmp_size);
1519
1520 tmp_type4_msg = (union type4_msg *)
1521 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
1522
1523 tmp_type4_msg->scr.header.msg_type_code = TYPE4_TYPE_CODE;
1524 tmp_type4_msg->scr.header.request_code = TYPE4_REQU_CODE;
1525 if (mod_len <= 128) {
1526 tmp_type4_msg->scr.header.msg_fmt = TYPE4_SCR_FMT;
1527 tmp_type4_msg->scr.header.msg_len = TYPE4_SCR_LEN;
1528 p_tgt = tmp_type4_msg->scr.p;
1529 p_tgt_len = sizeof(tmp_type4_msg->scr.p);
1530 q_tgt = tmp_type4_msg->scr.q;
1531 q_tgt_len = sizeof(tmp_type4_msg->scr.q);
1532 dp_tgt = tmp_type4_msg->scr.dp;
1533 dp_tgt_len = sizeof(tmp_type4_msg->scr.dp);
1534 dq_tgt = tmp_type4_msg->scr.dq;
1535 dq_tgt_len = sizeof(tmp_type4_msg->scr.dq);
1536 u_tgt = tmp_type4_msg->scr.u;
1537 u_tgt_len = sizeof(tmp_type4_msg->scr.u);
1538 inp_tgt = tmp_type4_msg->scr.message;
1539 inp_tgt_len = sizeof(tmp_type4_msg->scr.message);
1540 } else {
1541 tmp_type4_msg->lcr.header.msg_fmt = TYPE4_LCR_FMT;
1542 tmp_type4_msg->lcr.header.msg_len = TYPE4_LCR_LEN;
1543 p_tgt = tmp_type4_msg->lcr.p;
1544 p_tgt_len = sizeof(tmp_type4_msg->lcr.p);
1545 q_tgt = tmp_type4_msg->lcr.q;
1546 q_tgt_len = sizeof(tmp_type4_msg->lcr.q);
1547 dp_tgt = tmp_type4_msg->lcr.dp;
1548 dp_tgt_len = sizeof(tmp_type4_msg->lcr.dp);
1549 dq_tgt = tmp_type4_msg->lcr.dq;
1550 dq_tgt_len = sizeof(tmp_type4_msg->lcr.dq);
1551 u_tgt = tmp_type4_msg->lcr.u;
1552 u_tgt_len = sizeof(tmp_type4_msg->lcr.u);
1553 inp_tgt = tmp_type4_msg->lcr.message;
1554 inp_tgt_len = sizeof(tmp_type4_msg->lcr.message);
1555 }
1556
1557 p_tgt += (p_tgt_len - long_len);
1558 if (copy_from_user(p_tgt, icaMsg_p->np_prime, long_len))
1559 return SEN_RELEASED;
1560 if (is_empty(p_tgt, long_len))
1561 return SEN_USER_ERROR;
1562 q_tgt += (q_tgt_len - short_len);
1563 if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len))
1564 return SEN_RELEASED;
1565 if (is_empty(q_tgt, short_len))
1566 return SEN_USER_ERROR;
1567 dp_tgt += (dp_tgt_len - long_len);
1568 if (copy_from_user(dp_tgt, icaMsg_p->bp_key, long_len))
1569 return SEN_RELEASED;
1570 if (is_empty(dp_tgt, long_len))
1571 return SEN_USER_ERROR;
1572 dq_tgt += (dq_tgt_len - short_len);
1573 if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len))
1574 return SEN_RELEASED;
1575 if (is_empty(dq_tgt, short_len))
1576 return SEN_USER_ERROR;
1577 u_tgt += (u_tgt_len - long_len);
1578 if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv, long_len))
1579 return SEN_RELEASED;
1580 if (is_empty(u_tgt, long_len))
1581 return SEN_USER_ERROR;
1582 inp_tgt += (inp_tgt_len - mod_len);
1583 if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len))
1584 return SEN_RELEASED;
1585 if (is_empty(inp_tgt, mod_len))
1586 return SEN_USER_ERROR;
1587
1588 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1589
1590 return 0;
1591}
1592
1593static int
1594ICAMEX_msg_to_type6MEX_de_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1595 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1596{
1597 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l;
1598 unsigned char *temp;
1599 struct type6_hdr *tp6Hdr_p;
1600 struct CPRB *cprb_p;
1601 struct cca_private_ext_ME *key_p;
1602 static int deprecated_msg_count = 0;
1603
1604 mod_len = icaMsg_p->inputdatalength;
1605 tmp_size = FIXED_TYPE6_ME_LEN + mod_len;
1606 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1607 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1608 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1609
1610 memset(z90cMsg_p, 0, tmp_size);
1611
1612 temp = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1613 memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr));
1614 tp6Hdr_p = (struct type6_hdr *)temp;
1615 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1616 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1617
1618 temp += sizeof(struct type6_hdr);
1619 memcpy(temp, &static_cprb, sizeof(struct CPRB));
1620 cprb_p = (struct CPRB *) temp;
1621 cprb_p->usage_domain[0]= (unsigned char)cdx;
1622 itoLe2(&parmBlock_l, cprb_p->req_parml);
1623 itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml);
1624
1625 temp += sizeof(struct CPRB);
1626 memcpy(temp, &static_pkd_function_and_rules,
1627 sizeof(struct function_and_rules_block));
1628
1629 temp += sizeof(struct function_and_rules_block);
1630 vud_len = 2 + icaMsg_p->inputdatalength;
1631 itoLe2(&vud_len, temp);
1632
1633 temp += 2;
1634 if (copy_from_user(temp, icaMsg_p->inputdata, mod_len))
1635 return SEN_RELEASED;
1636 if (is_empty(temp, mod_len))
1637 return SEN_USER_ERROR;
1638
1639 temp += mod_len;
1640 memcpy(temp, &static_T6_keyBlock_hdr, sizeof(struct T6_keyBlock_hdr));
1641
1642 temp += sizeof(struct T6_keyBlock_hdr);
1643 memcpy(temp, &static_pvt_me_key, sizeof(struct cca_private_ext_ME));
1644 key_p = (struct cca_private_ext_ME *)temp;
1645 temp = key_p->pvtMESec.exponent + sizeof(key_p->pvtMESec.exponent)
1646 - mod_len;
1647 if (copy_from_user(temp, icaMsg_p->b_key, mod_len))
1648 return SEN_RELEASED;
1649 if (is_empty(temp, mod_len))
1650 return SEN_USER_ERROR;
1651
1652 if (is_common_public_key(temp, mod_len)) {
1653 if (deprecated_msg_count < 20) {
1654 PRINTK("Common public key used for modex decrypt\n");
1655 deprecated_msg_count++;
1656 if (deprecated_msg_count == 20)
1657 PRINTK("No longer issuing messages about common"
1658 " public key for modex decrypt.\n");
1659 }
1660 return SEN_NOT_AVAIL;
1661 }
1662
1663 temp = key_p->pvtMESec.modulus + sizeof(key_p->pvtMESec.modulus)
1664 - mod_len;
1665 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1666 return SEN_RELEASED;
1667 if (is_empty(temp, mod_len))
1668 return SEN_USER_ERROR;
1669
1670 key_p->pubMESec.modulus_bit_len = 8 * mod_len;
1671
1672 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1673
1674 return 0;
1675}
1676
1677static int
1678ICAMEX_msg_to_type6MEX_en_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1679 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1680{
1681 int mod_len, vud_len, exp_len, key_len;
1682 int pad_len, tmp_size, total_CPRB_len, parmBlock_l, i;
1683 unsigned char *temp_exp, *exp_p, *temp;
1684 struct type6_hdr *tp6Hdr_p;
1685 struct CPRB *cprb_p;
1686 struct cca_public_key *key_p;
1687 struct T6_keyBlock_hdr *keyb_p;
1688
1689 temp_exp = kmalloc(256, GFP_KERNEL);
1690 if (!temp_exp)
1691 return EGETBUFF;
1692 mod_len = icaMsg_p->inputdatalength;
1693 if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len)) {
1694 kfree(temp_exp);
1695 return SEN_RELEASED;
1696 }
1697 if (is_empty(temp_exp, mod_len)) {
1698 kfree(temp_exp);
1699 return SEN_USER_ERROR;
1700 }
1701
1702 exp_p = temp_exp;
1703 for (i = 0; i < mod_len; i++)
1704 if (exp_p[i])
1705 break;
1706 if (i >= mod_len) {
1707 kfree(temp_exp);
1708 return SEN_USER_ERROR;
1709 }
1710
1711 exp_len = mod_len - i;
1712 exp_p += i;
1713
1714 PDEBUG("exp_len after computation: %08x\n", exp_len);
1715 tmp_size = FIXED_TYPE6_ME_EN_LEN + 2 * mod_len + exp_len;
1716 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1717 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1718 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1719
1720 vud_len = 2 + mod_len;
1721 memset(z90cMsg_p, 0, tmp_size);
1722
1723 temp = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1724 memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr));
1725 tp6Hdr_p = (struct type6_hdr *)temp;
1726 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1727 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1728 memcpy(tp6Hdr_p->function_code, static_PKE_function_code,
1729 sizeof(static_PKE_function_code));
1730 temp += sizeof(struct type6_hdr);
1731 memcpy(temp, &static_cprb, sizeof(struct CPRB));
1732 cprb_p = (struct CPRB *) temp;
1733 cprb_p->usage_domain[0]= (unsigned char)cdx;
1734 itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml);
1735 temp += sizeof(struct CPRB);
1736 memcpy(temp, &static_pke_function_and_rules,
1737 sizeof(struct function_and_rules_block));
1738 temp += sizeof(struct function_and_rules_block);
1739 temp += 2;
1740 if (copy_from_user(temp, icaMsg_p->inputdata, mod_len)) {
1741 kfree(temp_exp);
1742 return SEN_RELEASED;
1743 }
1744 if (is_empty(temp, mod_len)) {
1745 kfree(temp_exp);
1746 return SEN_USER_ERROR;
1747 }
1748 if ((temp[0] != 0x00) || (temp[1] != 0x02)) {
1749 kfree(temp_exp);
1750 return SEN_NOT_AVAIL;
1751 }
1752 for (i = 2; i < mod_len; i++)
1753 if (temp[i] == 0x00)
1754 break;
1755 if ((i < 9) || (i > (mod_len - 2))) {
1756 kfree(temp_exp);
1757 return SEN_NOT_AVAIL;
1758 }
1759 pad_len = i + 1;
1760 vud_len = mod_len - pad_len;
1761 memmove(temp, temp+pad_len, vud_len);
1762 temp -= 2;
1763 vud_len += 2;
1764 itoLe2(&vud_len, temp);
1765 temp += (vud_len);
1766 keyb_p = (struct T6_keyBlock_hdr *)temp;
1767 temp += sizeof(struct T6_keyBlock_hdr);
1768 memcpy(temp, &static_public_key, sizeof(static_public_key));
1769 key_p = (struct cca_public_key *)temp;
1770 temp = key_p->pubSec.exponent;
1771 memcpy(temp, exp_p, exp_len);
1772 kfree(temp_exp);
1773 temp += exp_len;
1774 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1775 return SEN_RELEASED;
1776 if (is_empty(temp, mod_len))
1777 return SEN_USER_ERROR;
1778 key_p->pubSec.modulus_bit_len = 8 * mod_len;
1779 key_p->pubSec.modulus_byte_len = mod_len;
1780 key_p->pubSec.exponent_len = exp_len;
1781 key_p->pubSec.section_length = CALLER_HEADER + mod_len + exp_len;
1782 key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr);
1783 key_p->pubHdr.token_length = key_len;
1784 key_len += 4;
1785 itoLe2(&key_len, keyb_p->ulen);
1786 key_len += 2;
1787 itoLe2(&key_len, keyb_p->blen);
1788 parmBlock_l -= pad_len;
1789 itoLe2(&parmBlock_l, cprb_p->req_parml);
1790 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1791
1792 return 0;
1793}
1794
1795static int
1796ICACRT_msg_to_type6CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx,
1797 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1798{
1799 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len;
1800 int long_len, pad_len, keyPartsLen, tmp_l;
1801 unsigned char *tgt_p, *temp;
1802 struct type6_hdr *tp6Hdr_p;
1803 struct CPRB *cprb_p;
1804 struct cca_token_hdr *keyHdr_p;
1805 struct cca_pvt_ext_CRT_sec *pvtSec_p;
1806 struct cca_public_sec *pubSec_p;
1807
1808 mod_len = icaMsg_p->inputdatalength;
1809 short_len = mod_len / 2;
1810 long_len = 8 + short_len;
1811 keyPartsLen = 3 * long_len + 2 * short_len;
1812 pad_len = (8 - (keyPartsLen % 8)) % 8;
1813 keyPartsLen += pad_len + mod_len;
1814 tmp_size = FIXED_TYPE6_CR_LEN + keyPartsLen + mod_len;
1815 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1816 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1817 vud_len = 2 + mod_len;
1818 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1819
1820 memset(z90cMsg_p, 0, tmp_size);
1821 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1822 memcpy(tgt_p, &static_type6_hdr, sizeof(struct type6_hdr));
1823 tp6Hdr_p = (struct type6_hdr *)tgt_p;
1824 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1825 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1826 tgt_p += sizeof(struct type6_hdr);
1827 cprb_p = (struct CPRB *) tgt_p;
1828 memcpy(tgt_p, &static_cprb, sizeof(struct CPRB));
1829 cprb_p->usage_domain[0]= *((unsigned char *)(&(cdx))+3);
1830 itoLe2(&parmBlock_l, cprb_p->req_parml);
1831 memcpy(cprb_p->rpl_parml, cprb_p->req_parml,
1832 sizeof(cprb_p->req_parml));
1833 tgt_p += sizeof(struct CPRB);
1834 memcpy(tgt_p, &static_pkd_function_and_rules,
1835 sizeof(struct function_and_rules_block));
1836 tgt_p += sizeof(struct function_and_rules_block);
1837 itoLe2(&vud_len, tgt_p);
1838 tgt_p += 2;
1839 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
1840 return SEN_RELEASED;
1841 if (is_empty(tgt_p, mod_len))
1842 return SEN_USER_ERROR;
1843 tgt_p += mod_len;
1844 tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) +
1845 sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen;
1846 itoLe2(&tmp_l, tgt_p);
1847 temp = tgt_p + 2;
1848 tmp_l -= 2;
1849 itoLe2(&tmp_l, temp);
1850 tgt_p += sizeof(struct T6_keyBlock_hdr);
1851 keyHdr_p = (struct cca_token_hdr *)tgt_p;
1852 keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT;
1853 tmp_l -= 4;
1854 keyHdr_p->token_length = tmp_l;
1855 tgt_p += sizeof(struct cca_token_hdr);
1856 pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p;
1857 pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
1858 pvtSec_p->section_length =
1859 sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen;
1860 pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
1861 pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL;
1862 pvtSec_p->p_len = long_len;
1863 pvtSec_p->q_len = short_len;
1864 pvtSec_p->dp_len = long_len;
1865 pvtSec_p->dq_len = short_len;
1866 pvtSec_p->u_len = long_len;
1867 pvtSec_p->mod_len = mod_len;
1868 pvtSec_p->pad_len = pad_len;
1869 tgt_p += sizeof(struct cca_pvt_ext_CRT_sec);
1870 if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len))
1871 return SEN_RELEASED;
1872 if (is_empty(tgt_p, long_len))
1873 return SEN_USER_ERROR;
1874 tgt_p += long_len;
1875 if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len))
1876 return SEN_RELEASED;
1877 if (is_empty(tgt_p, short_len))
1878 return SEN_USER_ERROR;
1879 tgt_p += short_len;
1880 if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len))
1881 return SEN_RELEASED;
1882 if (is_empty(tgt_p, long_len))
1883 return SEN_USER_ERROR;
1884 tgt_p += long_len;
1885 if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len))
1886 return SEN_RELEASED;
1887 if (is_empty(tgt_p, short_len))
1888 return SEN_USER_ERROR;
1889 tgt_p += short_len;
1890 if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len))
1891 return SEN_RELEASED;
1892 if (is_empty(tgt_p, long_len))
1893 return SEN_USER_ERROR;
1894 tgt_p += long_len;
1895 tgt_p += pad_len;
1896 memset(tgt_p, 0xFF, mod_len);
1897 tgt_p += mod_len;
1898 memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec));
1899 pubSec_p = (struct cca_public_sec *) tgt_p;
1900 pubSec_p->modulus_bit_len = 8 * mod_len;
1901 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1902
1903 return 0;
1904}
1905
1906static int
1907ICAMEX_msg_to_type6MEX_msgX(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1908 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p,
1909 int dev_type)
1910{
1911 int mod_len, exp_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l;
1912 int key_len, i;
1913 unsigned char *temp_exp, *tgt_p, *temp, *exp_p;
1914 struct type6_hdr *tp6Hdr_p;
1915 struct CPRBX *cprbx_p;
1916 struct cca_public_key *key_p;
1917 struct T6_keyBlock_hdrX *keyb_p;
1918
1919 temp_exp = kmalloc(256, GFP_KERNEL);
1920 if (!temp_exp)
1921 return EGETBUFF;
1922 mod_len = icaMsg_p->inputdatalength;
1923 if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len)) {
1924 kfree(temp_exp);
1925 return SEN_RELEASED;
1926 }
1927 if (is_empty(temp_exp, mod_len)) {
1928 kfree(temp_exp);
1929 return SEN_USER_ERROR;
1930 }
1931 exp_p = temp_exp;
1932 for (i = 0; i < mod_len; i++)
1933 if (exp_p[i])
1934 break;
1935 if (i >= mod_len) {
1936 kfree(temp_exp);
1937 return SEN_USER_ERROR;
1938 }
1939 exp_len = mod_len - i;
1940 exp_p += i;
1941 PDEBUG("exp_len after computation: %08x\n", exp_len);
1942 tmp_size = FIXED_TYPE6_ME_EN_LENX + 2 * mod_len + exp_len;
1943 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1944 parmBlock_l = total_CPRB_len - sizeof(struct CPRBX);
1945 tmp_size = tmp_size + CALLER_HEADER;
1946 vud_len = 2 + mod_len;
1947 memset(z90cMsg_p, 0, tmp_size);
1948 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1949 memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr));
1950 tp6Hdr_p = (struct type6_hdr *)tgt_p;
1951 tp6Hdr_p->ToCardLen1 = total_CPRB_len;
1952 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE;
1953 memcpy(tp6Hdr_p->function_code, static_PKE_function_code,
1954 sizeof(static_PKE_function_code));
1955 tgt_p += sizeof(struct type6_hdr);
1956 memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX));
1957 cprbx_p = (struct CPRBX *) tgt_p;
1958 cprbx_p->domain = (unsigned short)cdx;
1959 cprbx_p->rpl_msgbl = RESPONSE_CPRBX_SIZE;
1960 tgt_p += sizeof(struct CPRBX);
1961 if (dev_type == PCIXCC_MCL2)
1962 memcpy(tgt_p, &static_pke_function_and_rulesX_MCL2,
1963 sizeof(struct function_and_rules_block));
1964 else
1965 memcpy(tgt_p, &static_pke_function_and_rulesX,
1966 sizeof(struct function_and_rules_block));
1967 tgt_p += sizeof(struct function_and_rules_block);
1968
1969 tgt_p += 2;
1970 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len)) {
1971 kfree(temp_exp);
1972 return SEN_RELEASED;
1973 }
1974 if (is_empty(tgt_p, mod_len)) {
1975 kfree(temp_exp);
1976 return SEN_USER_ERROR;
1977 }
1978 tgt_p -= 2;
1979 *((short *)tgt_p) = (short) vud_len;
1980 tgt_p += vud_len;
1981 keyb_p = (struct T6_keyBlock_hdrX *)tgt_p;
1982 tgt_p += sizeof(struct T6_keyBlock_hdrX);
1983 memcpy(tgt_p, &static_public_key, sizeof(static_public_key));
1984 key_p = (struct cca_public_key *)tgt_p;
1985 temp = key_p->pubSec.exponent;
1986 memcpy(temp, exp_p, exp_len);
1987 kfree(temp_exp);
1988 temp += exp_len;
1989 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1990 return SEN_RELEASED;
1991 if (is_empty(temp, mod_len))
1992 return SEN_USER_ERROR;
1993 key_p->pubSec.modulus_bit_len = 8 * mod_len;
1994 key_p->pubSec.modulus_byte_len = mod_len;
1995 key_p->pubSec.exponent_len = exp_len;
1996 key_p->pubSec.section_length = CALLER_HEADER + mod_len + exp_len;
1997 key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr);
1998 key_p->pubHdr.token_length = key_len;
1999 key_len += 4;
2000 keyb_p->ulen = (unsigned short)key_len;
2001 key_len += 2;
2002 keyb_p->blen = (unsigned short)key_len;
2003 cprbx_p->req_parml = parmBlock_l;
2004 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
2005
2006 return 0;
2007}
2008
2009static int
2010ICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx,
2011 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p,
2012 int dev_type)
2013{
2014 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len;
2015 int long_len, pad_len, keyPartsLen, tmp_l;
2016 unsigned char *tgt_p, *temp;
2017 struct type6_hdr *tp6Hdr_p;
2018 struct CPRBX *cprbx_p;
2019 struct cca_token_hdr *keyHdr_p;
2020 struct cca_pvt_ext_CRT_sec *pvtSec_p;
2021 struct cca_public_sec *pubSec_p;
2022
2023 mod_len = icaMsg_p->inputdatalength;
2024 short_len = mod_len / 2;
2025 long_len = 8 + short_len;
2026 keyPartsLen = 3 * long_len + 2 * short_len;
2027 pad_len = (8 - (keyPartsLen % 8)) % 8;
2028 keyPartsLen += pad_len + mod_len;
2029 tmp_size = FIXED_TYPE6_CR_LENX + keyPartsLen + mod_len;
2030 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
2031 parmBlock_l = total_CPRB_len - sizeof(struct CPRBX);
2032 vud_len = 2 + mod_len;
2033 tmp_size = tmp_size + CALLER_HEADER;
2034 memset(z90cMsg_p, 0, tmp_size);
2035 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
2036 memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr));
2037 tp6Hdr_p = (struct type6_hdr *)tgt_p;
2038 tp6Hdr_p->ToCardLen1 = total_CPRB_len;
2039 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE;
2040 tgt_p += sizeof(struct type6_hdr);
2041 cprbx_p = (struct CPRBX *) tgt_p;
2042 memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX));
2043 cprbx_p->domain = (unsigned short)cdx;
2044 cprbx_p->req_parml = parmBlock_l;
2045 cprbx_p->rpl_msgbl = parmBlock_l;
2046 tgt_p += sizeof(struct CPRBX);
2047 if (dev_type == PCIXCC_MCL2)
2048 memcpy(tgt_p, &static_pkd_function_and_rulesX_MCL2,
2049 sizeof(struct function_and_rules_block));
2050 else
2051 memcpy(tgt_p, &static_pkd_function_and_rulesX,
2052 sizeof(struct function_and_rules_block));
2053 tgt_p += sizeof(struct function_and_rules_block);
2054 *((short *)tgt_p) = (short) vud_len;
2055 tgt_p += 2;
2056 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
2057 return SEN_RELEASED;
2058 if (is_empty(tgt_p, mod_len))
2059 return SEN_USER_ERROR;
2060 tgt_p += mod_len;
2061 tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) +
2062 sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen;
2063 *((short *)tgt_p) = (short) tmp_l;
2064 temp = tgt_p + 2;
2065 tmp_l -= 2;
2066 *((short *)temp) = (short) tmp_l;
2067 tgt_p += sizeof(struct T6_keyBlock_hdr);
2068 keyHdr_p = (struct cca_token_hdr *)tgt_p;
2069 keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT;
2070 tmp_l -= 4;
2071 keyHdr_p->token_length = tmp_l;
2072 tgt_p += sizeof(struct cca_token_hdr);
2073 pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p;
2074 pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
2075 pvtSec_p->section_length =
2076 sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen;
2077 pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
2078 pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL;
2079 pvtSec_p->p_len = long_len;
2080 pvtSec_p->q_len = short_len;
2081 pvtSec_p->dp_len = long_len;
2082 pvtSec_p->dq_len = short_len;
2083 pvtSec_p->u_len = long_len;
2084 pvtSec_p->mod_len = mod_len;
2085 pvtSec_p->pad_len = pad_len;
2086 tgt_p += sizeof(struct cca_pvt_ext_CRT_sec);
2087 if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len))
2088 return SEN_RELEASED;
2089 if (is_empty(tgt_p, long_len))
2090 return SEN_USER_ERROR;
2091 tgt_p += long_len;
2092 if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len))
2093 return SEN_RELEASED;
2094 if (is_empty(tgt_p, short_len))
2095 return SEN_USER_ERROR;
2096 tgt_p += short_len;
2097 if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len))
2098 return SEN_RELEASED;
2099 if (is_empty(tgt_p, long_len))
2100 return SEN_USER_ERROR;
2101 tgt_p += long_len;
2102 if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len))
2103 return SEN_RELEASED;
2104 if (is_empty(tgt_p, short_len))
2105 return SEN_USER_ERROR;
2106 tgt_p += short_len;
2107 if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len))
2108 return SEN_RELEASED;
2109 if (is_empty(tgt_p, long_len))
2110 return SEN_USER_ERROR;
2111 tgt_p += long_len;
2112 tgt_p += pad_len;
2113 memset(tgt_p, 0xFF, mod_len);
2114 tgt_p += mod_len;
2115 memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec));
2116 pubSec_p = (struct cca_public_sec *) tgt_p;
2117 pubSec_p->modulus_bit_len = 8 * mod_len;
2118 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
2119
2120 return 0;
2121}
2122
2123static int
2124ICAMEX_msg_to_type50MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p,
2125 union type50_msg *z90cMsg_p)
2126{
2127 int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len;
2128 unsigned char *mod_tgt, *exp_tgt, *inp_tgt;
2129 union type50_msg *tmp_type50_msg;
2130
2131 mod_len = icaMex_p->inputdatalength;
2132
2133 msg_size = ((mod_len <= 128) ? TYPE50_MEB1_LEN : TYPE50_MEB2_LEN) +
2134 CALLER_HEADER;
2135
2136 memset(z90cMsg_p, 0, msg_size);
2137
2138 tmp_type50_msg = (union type50_msg *)
2139 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
2140
2141 tmp_type50_msg->meb1.header.msg_type_code = TYPE50_TYPE_CODE;
2142
2143 if (mod_len <= 128) {
2144 tmp_type50_msg->meb1.header.msg_len = TYPE50_MEB1_LEN;
2145 tmp_type50_msg->meb1.keyblock_type = TYPE50_MEB1_FMT;
2146 mod_tgt = tmp_type50_msg->meb1.modulus;
2147 mod_tgt_len = sizeof(tmp_type50_msg->meb1.modulus);
2148 exp_tgt = tmp_type50_msg->meb1.exponent;
2149 exp_tgt_len = sizeof(tmp_type50_msg->meb1.exponent);
2150 inp_tgt = tmp_type50_msg->meb1.message;
2151 inp_tgt_len = sizeof(tmp_type50_msg->meb1.message);
2152 } else {
2153 tmp_type50_msg->meb2.header.msg_len = TYPE50_MEB2_LEN;
2154 tmp_type50_msg->meb2.keyblock_type = TYPE50_MEB2_FMT;
2155 mod_tgt = tmp_type50_msg->meb2.modulus;
2156 mod_tgt_len = sizeof(tmp_type50_msg->meb2.modulus);
2157 exp_tgt = tmp_type50_msg->meb2.exponent;
2158 exp_tgt_len = sizeof(tmp_type50_msg->meb2.exponent);
2159 inp_tgt = tmp_type50_msg->meb2.message;
2160 inp_tgt_len = sizeof(tmp_type50_msg->meb2.message);
2161 }
2162
2163 mod_tgt += (mod_tgt_len - mod_len);
2164 if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len))
2165 return SEN_RELEASED;
2166 if (is_empty(mod_tgt, mod_len))
2167 return SEN_USER_ERROR;
2168 exp_tgt += (exp_tgt_len - mod_len);
2169 if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len))
2170 return SEN_RELEASED;
2171 if (is_empty(exp_tgt, mod_len))
2172 return SEN_USER_ERROR;
2173 inp_tgt += (inp_tgt_len - mod_len);
2174 if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len))
2175 return SEN_RELEASED;
2176 if (is_empty(inp_tgt, mod_len))
2177 return SEN_USER_ERROR;
2178
2179 *z90cMsg_l_p = msg_size - CALLER_HEADER;
2180
2181 return 0;
2182}
2183
2184static int
2185ICACRT_msg_to_type50CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p,
2186 int *z90cMsg_l_p, union type50_msg *z90cMsg_p)
2187{
2188 int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len,
2189 dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len, long_offset;
2190 unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt,
2191 temp[8];
2192 union type50_msg *tmp_type50_msg;
2193
2194 mod_len = icaMsg_p->inputdatalength;
2195 short_len = mod_len / 2;
2196 long_len = mod_len / 2 + 8;
2197 long_offset = 0;
2198
2199 if (long_len > 128) {
2200 memset(temp, 0x00, sizeof(temp));
2201 if (copy_from_user(temp, icaMsg_p->np_prime, long_len-128))
2202 return SEN_RELEASED;
2203 if (!is_empty(temp, 8))
2204 return SEN_NOT_AVAIL;
2205 if (copy_from_user(temp, icaMsg_p->bp_key, long_len-128))
2206 return SEN_RELEASED;
2207 if (!is_empty(temp, 8))
2208 return SEN_NOT_AVAIL;
2209 if (copy_from_user(temp, icaMsg_p->u_mult_inv, long_len-128))
2210 return SEN_RELEASED;
2211 if (!is_empty(temp, 8))
2212 return SEN_NOT_AVAIL;
2213 long_offset = long_len - 128;
2214 long_len = 128;
2215 }
2216
2217 tmp_size = ((long_len <= 64) ? TYPE50_CRB1_LEN : TYPE50_CRB2_LEN) +
2218 CALLER_HEADER;
2219
2220 memset(z90cMsg_p, 0, tmp_size);
2221
2222 tmp_type50_msg = (union type50_msg *)
2223 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
2224
2225 tmp_type50_msg->crb1.header.msg_type_code = TYPE50_TYPE_CODE;
2226 if (long_len <= 64) {
2227 tmp_type50_msg->crb1.header.msg_len = TYPE50_CRB1_LEN;
2228 tmp_type50_msg->crb1.keyblock_type = TYPE50_CRB1_FMT;
2229 p_tgt = tmp_type50_msg->crb1.p;
2230 p_tgt_len = sizeof(tmp_type50_msg->crb1.p);
2231 q_tgt = tmp_type50_msg->crb1.q;
2232 q_tgt_len = sizeof(tmp_type50_msg->crb1.q);
2233 dp_tgt = tmp_type50_msg->crb1.dp;
2234 dp_tgt_len = sizeof(tmp_type50_msg->crb1.dp);
2235 dq_tgt = tmp_type50_msg->crb1.dq;
2236 dq_tgt_len = sizeof(tmp_type50_msg->crb1.dq);
2237 u_tgt = tmp_type50_msg->crb1.u;
2238 u_tgt_len = sizeof(tmp_type50_msg->crb1.u);
2239 inp_tgt = tmp_type50_msg->crb1.message;
2240 inp_tgt_len = sizeof(tmp_type50_msg->crb1.message);
2241 } else {
2242 tmp_type50_msg->crb2.header.msg_len = TYPE50_CRB2_LEN;
2243 tmp_type50_msg->crb2.keyblock_type = TYPE50_CRB2_FMT;
2244 p_tgt = tmp_type50_msg->crb2.p;
2245 p_tgt_len = sizeof(tmp_type50_msg->crb2.p);
2246 q_tgt = tmp_type50_msg->crb2.q;
2247 q_tgt_len = sizeof(tmp_type50_msg->crb2.q);
2248 dp_tgt = tmp_type50_msg->crb2.dp;
2249 dp_tgt_len = sizeof(tmp_type50_msg->crb2.dp);
2250 dq_tgt = tmp_type50_msg->crb2.dq;
2251 dq_tgt_len = sizeof(tmp_type50_msg->crb2.dq);
2252 u_tgt = tmp_type50_msg->crb2.u;
2253 u_tgt_len = sizeof(tmp_type50_msg->crb2.u);
2254 inp_tgt = tmp_type50_msg->crb2.message;
2255 inp_tgt_len = sizeof(tmp_type50_msg->crb2.message);
2256 }
2257
2258 p_tgt += (p_tgt_len - long_len);
2259 if (copy_from_user(p_tgt, icaMsg_p->np_prime + long_offset, long_len))
2260 return SEN_RELEASED;
2261 if (is_empty(p_tgt, long_len))
2262 return SEN_USER_ERROR;
2263 q_tgt += (q_tgt_len - short_len);
2264 if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len))
2265 return SEN_RELEASED;
2266 if (is_empty(q_tgt, short_len))
2267 return SEN_USER_ERROR;
2268 dp_tgt += (dp_tgt_len - long_len);
2269 if (copy_from_user(dp_tgt, icaMsg_p->bp_key + long_offset, long_len))
2270 return SEN_RELEASED;
2271 if (is_empty(dp_tgt, long_len))
2272 return SEN_USER_ERROR;
2273 dq_tgt += (dq_tgt_len - short_len);
2274 if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len))
2275 return SEN_RELEASED;
2276 if (is_empty(dq_tgt, short_len))
2277 return SEN_USER_ERROR;
2278 u_tgt += (u_tgt_len - long_len);
2279 if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv + long_offset, long_len))
2280 return SEN_RELEASED;
2281 if (is_empty(u_tgt, long_len))
2282 return SEN_USER_ERROR;
2283 inp_tgt += (inp_tgt_len - mod_len);
2284 if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len))
2285 return SEN_RELEASED;
2286 if (is_empty(inp_tgt, mod_len))
2287 return SEN_USER_ERROR;
2288
2289 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
2290
2291 return 0;
2292}
2293
2294int
2295convert_request(unsigned char *buffer, int func, unsigned short function,
2296 int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p)
2297{
2298 if (dev_type == PCICA) {
2299 if (func == ICARSACRT)
2300 return ICACRT_msg_to_type4CRT_msg(
2301 (struct ica_rsa_modexpo_crt *) buffer,
2302 msg_l_p, (union type4_msg *) msg_p);
2303 else
2304 return ICAMEX_msg_to_type4MEX_msg(
2305 (struct ica_rsa_modexpo *) buffer,
2306 msg_l_p, (union type4_msg *) msg_p);
2307 }
2308 if (dev_type == PCICC) {
2309 if (func == ICARSACRT)
2310 return ICACRT_msg_to_type6CRT_msg(
2311 (struct ica_rsa_modexpo_crt *) buffer,
2312 cdx, msg_l_p, (struct type6_msg *)msg_p);
2313 if (function == PCI_FUNC_KEY_ENCRYPT)
2314 return ICAMEX_msg_to_type6MEX_en_msg(
2315 (struct ica_rsa_modexpo *) buffer,
2316 cdx, msg_l_p, (struct type6_msg *) msg_p);
2317 else
2318 return ICAMEX_msg_to_type6MEX_de_msg(
2319 (struct ica_rsa_modexpo *) buffer,
2320 cdx, msg_l_p, (struct type6_msg *) msg_p);
2321 }
2322 if ((dev_type == PCIXCC_MCL2) ||
2323 (dev_type == PCIXCC_MCL3) ||
2324 (dev_type == CEX2C)) {
2325 if (func == ICARSACRT)
2326 return ICACRT_msg_to_type6CRT_msgX(
2327 (struct ica_rsa_modexpo_crt *) buffer,
2328 cdx, msg_l_p, (struct type6_msg *) msg_p,
2329 dev_type);
2330 else
2331 return ICAMEX_msg_to_type6MEX_msgX(
2332 (struct ica_rsa_modexpo *) buffer,
2333 cdx, msg_l_p, (struct type6_msg *) msg_p,
2334 dev_type);
2335 }
2336 if (dev_type == CEX2A) {
2337 if (func == ICARSACRT)
2338 return ICACRT_msg_to_type50CRT_msg(
2339 (struct ica_rsa_modexpo_crt *) buffer,
2340 msg_l_p, (union type50_msg *) msg_p);
2341 else
2342 return ICAMEX_msg_to_type50MEX_msg(
2343 (struct ica_rsa_modexpo *) buffer,
2344 msg_l_p, (union type50_msg *) msg_p);
2345 }
2346
2347 return 0;
2348}
2349
2350int ext_bitlens_msg_count = 0;
2351static inline void
2352unset_ext_bitlens(void)
2353{
2354 if (!ext_bitlens_msg_count) {
2355 PRINTK("Unable to use coprocessors for extended bitlengths. "
2356 "Using PCICAs/CEX2As (if present) for extended "
2357 "bitlengths. This is not an error.\n");
2358 ext_bitlens_msg_count++;
2359 }
2360 ext_bitlens = 0;
2361}
2362
2363int
2364convert_response(unsigned char *response, unsigned char *buffer,
2365 int *respbufflen_p, unsigned char *resp_buff)
2366{
2367 struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer;
2368 struct error_hdr *errh_p = (struct error_hdr *) response;
2369 struct type80_hdr *t80h_p = (struct type80_hdr *) response;
2370 struct type84_hdr *t84h_p = (struct type84_hdr *) response;
2371 struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response;
2372 int reply_code, service_rc, service_rs, src_l;
2373 unsigned char *src_p, *tgt_p;
2374 struct CPRB *cprb_p;
2375 struct CPRBX *cprbx_p;
2376
2377 src_p = 0;
2378 reply_code = 0;
2379 service_rc = 0;
2380 service_rs = 0;
2381 src_l = 0;
2382 switch (errh_p->type) {
2383 case TYPE82_RSP_CODE:
2384 case TYPE88_RSP_CODE:
2385 reply_code = errh_p->reply_code;
2386 src_p = (unsigned char *)errh_p;
2387 PRINTK("Hardware error: Type %02X Message Header: "
2388 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2389 errh_p->type,
2390 src_p[0], src_p[1], src_p[2], src_p[3],
2391 src_p[4], src_p[5], src_p[6], src_p[7]);
2392 break;
2393 case TYPE80_RSP_CODE:
2394 src_l = icaMsg_p->outputdatalength;
2395 src_p = response + (int)t80h_p->len - src_l;
2396 break;
2397 case TYPE84_RSP_CODE:
2398 src_l = icaMsg_p->outputdatalength;
2399 src_p = response + (int)t84h_p->len - src_l;
2400 break;
2401 case TYPE86_RSP_CODE:
2402 reply_code = t86m_p->header.reply_code;
2403 if (reply_code != 0)
2404 break;
2405 cprb_p = (struct CPRB *)
2406 (response + sizeof(struct type86_fmt2_msg));
2407 cprbx_p = (struct CPRBX *) cprb_p;
2408 if (cprb_p->cprb_ver_id != 0x02) {
2409 le2toI(cprb_p->ccp_rtcode, &service_rc);
2410 if (service_rc != 0) {
2411 le2toI(cprb_p->ccp_rscode, &service_rs);
2412 if ((service_rc == 8) && (service_rs == 66))
2413 PDEBUG("Bad block format on PCICC\n");
2414 else if ((service_rc == 8) && (service_rs == 65))
2415 PDEBUG("Probably an even modulus on "
2416 "PCICC\n");
2417 else if ((service_rc == 8) && (service_rs == 770)) {
2418 PDEBUG("Invalid key length on PCICC\n");
2419 unset_ext_bitlens();
2420 return REC_USE_PCICA;
2421 }
2422 else if ((service_rc == 8) && (service_rs == 783)) {
2423 PDEBUG("Extended bitlengths not enabled"
2424 "on PCICC\n");
2425 unset_ext_bitlens();
2426 return REC_USE_PCICA;
2427 }
2428 else
2429 PRINTK("service rc/rs (PCICC): %d/%d\n",
2430 service_rc, service_rs);
2431 return REC_OPERAND_INV;
2432 }
2433 src_p = (unsigned char *)cprb_p + sizeof(struct CPRB);
2434 src_p += 4;
2435 le2toI(src_p, &src_l);
2436 src_l -= 2;
2437 src_p += 2;
2438 } else {
2439 service_rc = (int)cprbx_p->ccp_rtcode;
2440 if (service_rc != 0) {
2441 service_rs = (int) cprbx_p->ccp_rscode;
2442 if ((service_rc == 8) && (service_rs == 66))
2443 PDEBUG("Bad block format on PCIXCC\n");
2444 else if ((service_rc == 8) && (service_rs == 65))
2445 PDEBUG("Probably an even modulus on "
2446 "PCIXCC\n");
2447 else if ((service_rc == 8) && (service_rs == 770)) {
2448 PDEBUG("Invalid key length on PCIXCC\n");
2449 unset_ext_bitlens();
2450 return REC_USE_PCICA;
2451 }
2452 else if ((service_rc == 8) && (service_rs == 783)) {
2453 PDEBUG("Extended bitlengths not enabled"
2454 "on PCIXCC\n");
2455 unset_ext_bitlens();
2456 return REC_USE_PCICA;
2457 }
2458 else
2459 PRINTK("service rc/rs (PCIXCC): %d/%d\n",
2460 service_rc, service_rs);
2461 return REC_OPERAND_INV;
2462 }
2463 src_p = (unsigned char *)
2464 cprbx_p + sizeof(struct CPRBX);
2465 src_p += 4;
2466 src_l = (int)(*((short *) src_p));
2467 src_l -= 2;
2468 src_p += 2;
2469 }
2470 break;
2471 default:
2472 src_p = (unsigned char *)errh_p;
2473 PRINTK("Unrecognized Message Header: "
2474 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2475 src_p[0], src_p[1], src_p[2], src_p[3],
2476 src_p[4], src_p[5], src_p[6], src_p[7]);
2477 return REC_BAD_MESSAGE;
2478 }
2479
2480 if (reply_code)
2481 switch (reply_code) {
2482 case REP82_ERROR_MACHINE_FAILURE:
2483 if (errh_p->type == TYPE82_RSP_CODE)
2484 PRINTKW("Machine check failure\n");
2485 else
2486 PRINTKW("Module failure\n");
2487 return REC_HARDWAR_ERR;
2488 case REP82_ERROR_OPERAND_INVALID:
2489 return REC_OPERAND_INV;
2490 case REP88_ERROR_MESSAGE_MALFORMD:
2491 PRINTKW("Message malformed\n");
2492 return REC_OPERAND_INV;
2493 case REP82_ERROR_OPERAND_SIZE:
2494 return REC_OPERAND_SIZE;
2495 case REP82_ERROR_EVEN_MOD_IN_OPND:
2496 return REC_EVEN_MOD;
2497 case REP82_ERROR_MESSAGE_TYPE:
2498 return WRONG_DEVICE_TYPE;
2499 case REP82_ERROR_TRANSPORT_FAIL:
2500 PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n",
2501 t86m_p->apfs[0], t86m_p->apfs[1],
2502 t86m_p->apfs[2], t86m_p->apfs[3]);
2503 return REC_HARDWAR_ERR;
2504 default:
2505 PRINTKW("reply code = %d\n", reply_code);
2506 return REC_HARDWAR_ERR;
2507 }
2508
2509 if (service_rc != 0)
2510 return REC_OPERAND_INV;
2511
2512 if ((src_l > icaMsg_p->outputdatalength) ||
2513 (src_l > RESPBUFFSIZE) ||
2514 (src_l <= 0))
2515 return REC_OPERAND_SIZE;
2516
2517 PDEBUG("Length returned = %d\n", src_l);
2518 tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l;
2519 memcpy(tgt_p, src_p, src_l);
2520 if ((errh_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) {
2521 memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l);
2522 if (pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l))
2523 return REC_INVALID_PAD;
2524 }
2525 *respbufflen_p = icaMsg_p->outputdatalength;
2526 if (*respbufflen_p == 0)
2527 PRINTK("Zero *respbufflen_p\n");
2528
2529 return 0;
2530}
2531
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
deleted file mode 100644
index b2f20ab8431a..000000000000
--- a/drivers/s390/crypto/z90main.c
+++ /dev/null
@@ -1,3379 +0,0 @@
1/*
2 * linux/drivers/s390/crypto/z90main.c
3 *
4 * z90crypt 1.3.3
5 *
6 * Copyright (C) 2001, 2005 IBM Corporation
7 * Author(s): Robert Burroughs (burrough@us.ibm.com)
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <asm/uaccess.h> // copy_(from|to)_user
28#include <linux/compat.h>
29#include <linux/compiler.h>
30#include <linux/delay.h> // mdelay
31#include <linux/init.h>
32#include <linux/interrupt.h> // for tasklets
33#include <linux/miscdevice.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/proc_fs.h>
37#include <linux/syscalls.h>
38#include "z90crypt.h"
39#include "z90common.h"
40
41/**
42 * Defaults that may be modified.
43 */
44
45/**
46 * You can specify a different minor at compile time.
47 */
48#ifndef Z90CRYPT_MINOR
49#define Z90CRYPT_MINOR MISC_DYNAMIC_MINOR
50#endif
51
52/**
53 * You can specify a different domain at compile time or on the insmod
54 * command line.
55 */
56#ifndef DOMAIN_INDEX
57#define DOMAIN_INDEX -1
58#endif
59
60/**
61 * This is the name under which the device is registered in /proc/modules.
62 */
63#define REG_NAME "z90crypt"
64
65/**
66 * Cleanup should run every CLEANUPTIME seconds and should clean up requests
67 * older than CLEANUPTIME seconds in the past.
68 */
69#ifndef CLEANUPTIME
70#define CLEANUPTIME 15
71#endif
72
73/**
74 * Config should run every CONFIGTIME seconds
75 */
76#ifndef CONFIGTIME
77#define CONFIGTIME 30
78#endif
79
80/**
81 * The first execution of the config task should take place
82 * immediately after initialization
83 */
84#ifndef INITIAL_CONFIGTIME
85#define INITIAL_CONFIGTIME 1
86#endif
87
88/**
89 * Reader should run every READERTIME milliseconds
90 * With the 100Hz patch for s390, z90crypt can lock the system solid while
91 * under heavy load. We'll try to avoid that.
92 */
93#ifndef READERTIME
94#if HZ > 1000
95#define READERTIME 2
96#else
97#define READERTIME 10
98#endif
99#endif
100
101/**
102 * turn long device array index into device pointer
103 */
104#define LONG2DEVPTR(ndx) (z90crypt.device_p[(ndx)])
105
106/**
107 * turn short device array index into long device array index
108 */
109#define SHRT2LONG(ndx) (z90crypt.overall_device_x.device_index[(ndx)])
110
111/**
112 * turn short device array index into device pointer
113 */
114#define SHRT2DEVPTR(ndx) LONG2DEVPTR(SHRT2LONG(ndx))
115
116/**
117 * Status for a work-element
118 */
119#define STAT_DEFAULT 0x00 // request has not been processed
120
121#define STAT_ROUTED 0x80 // bit 7: requests get routed to specific device
122 // else, device is determined each write
123#define STAT_FAILED 0x40 // bit 6: this bit is set if the request failed
124 // before being sent to the hardware.
125#define STAT_WRITTEN 0x30 // bits 5-4: work to be done, not sent to device
126// 0x20 // UNUSED state
127#define STAT_READPEND 0x10 // bits 5-4: work done, we're returning data now
128#define STAT_NOWORK 0x00 // bits off: no work on any queue
129#define STAT_RDWRMASK 0x30 // mask for bits 5-4
130
131/**
132 * Macros to check the status RDWRMASK
133 */
134#define CHK_RDWRMASK(statbyte) ((statbyte) & STAT_RDWRMASK)
135#define SET_RDWRMASK(statbyte, newval) \
136 {(statbyte) &= ~STAT_RDWRMASK; (statbyte) |= newval;}
137
138/**
139 * Audit Trail. Progress of a Work element
140 * audit[0]: Unless noted otherwise, these bits are all set by the process
141 */
142#define FP_COPYFROM 0x80 // Caller's buffer has been copied to work element
143#define FP_BUFFREQ 0x40 // Low Level buffer requested
144#define FP_BUFFGOT 0x20 // Low Level buffer obtained
145#define FP_SENT 0x10 // Work element sent to a crypto device
146 // (may be set by process or by reader task)
147#define FP_PENDING 0x08 // Work element placed on pending queue
148 // (may be set by process or by reader task)
149#define FP_REQUEST 0x04 // Work element placed on request queue
150#define FP_ASLEEP 0x02 // Work element about to sleep
151#define FP_AWAKE 0x01 // Work element has been awakened
152
153/**
154 * audit[1]: These bits are set by the reader task and/or the cleanup task
155 */
156#define FP_NOTPENDING 0x80 // Work element removed from pending queue
157#define FP_AWAKENING 0x40 // Caller about to be awakened
158#define FP_TIMEDOUT 0x20 // Caller timed out
159#define FP_RESPSIZESET 0x10 // Response size copied to work element
160#define FP_RESPADDRCOPIED 0x08 // Response address copied to work element
161#define FP_RESPBUFFCOPIED 0x04 // Response buffer copied to work element
162#define FP_REMREQUEST 0x02 // Work element removed from request queue
163#define FP_SIGNALED 0x01 // Work element was awakened by a signal
164
165/**
166 * audit[2]: unused
167 */
168
169/**
170 * state of the file handle in private_data.status
171 */
172#define STAT_OPEN 0
173#define STAT_CLOSED 1
174
175/**
176 * PID() expands to the process ID of the current process
177 */
178#define PID() (current->pid)
179
180/**
181 * Selected Constants. The number of APs and the number of devices
182 */
183#ifndef Z90CRYPT_NUM_APS
184#define Z90CRYPT_NUM_APS 64
185#endif
186#ifndef Z90CRYPT_NUM_DEVS
187#define Z90CRYPT_NUM_DEVS Z90CRYPT_NUM_APS
188#endif
189
190/**
191 * Buffer size for receiving responses. The maximum Response Size
192 * is actually the maximum request size, since in an error condition
193 * the request itself may be returned unchanged.
194 */
195#define MAX_RESPONSE_SIZE 0x0000077C
196
197/**
198 * A count and status-byte mask
199 */
200struct status {
201 int st_count; // # of enabled devices
202 int disabled_count; // # of disabled devices
203 int user_disabled_count; // # of devices disabled via proc fs
204 unsigned char st_mask[Z90CRYPT_NUM_APS]; // current status mask
205};
206
207/**
208 * The array of device indexes is a mechanism for fast indexing into
209 * a long (and sparse) array. For instance, if APs 3, 9 and 47 are
210 * installed, z90CDeviceIndex[0] is 3, z90CDeviceIndex[1] is 9, and
211 * z90CDeviceIndex[2] is 47.
212 */
213struct device_x {
214 int device_index[Z90CRYPT_NUM_DEVS];
215};
216
217/**
218 * All devices are arranged in a single array: 64 APs
219 */
220struct device {
221 int dev_type; // PCICA, PCICC, PCIXCC_MCL2,
222 // PCIXCC_MCL3, CEX2C, CEX2A
223 enum devstat dev_stat; // current device status
224 int dev_self_x; // Index in array
225 int disabled; // Set when device is in error
226 int user_disabled; // Set when device is disabled by user
227 int dev_q_depth; // q depth
228 unsigned char * dev_resp_p; // Response buffer address
229 int dev_resp_l; // Response Buffer length
230 int dev_caller_count; // Number of callers
231 int dev_total_req_cnt; // # requests for device since load
232 struct list_head dev_caller_list; // List of callers
233};
234
235/**
236 * There's a struct status and a struct device_x for each device type.
237 */
238struct hdware_block {
239 struct status hdware_mask;
240 struct status type_mask[Z90CRYPT_NUM_TYPES];
241 struct device_x type_x_addr[Z90CRYPT_NUM_TYPES];
242 unsigned char device_type_array[Z90CRYPT_NUM_APS];
243};
244
245/**
246 * z90crypt is the topmost data structure in the hierarchy.
247 */
248struct z90crypt {
249 int max_count; // Nr of possible crypto devices
250 struct status mask;
251 int q_depth_array[Z90CRYPT_NUM_DEVS];
252 int dev_type_array[Z90CRYPT_NUM_DEVS];
253 struct device_x overall_device_x; // array device indexes
254 struct device * device_p[Z90CRYPT_NUM_DEVS];
255 int terminating;
256 int domain_established;// TRUE: domain has been found
257 int cdx; // Crypto Domain Index
258 int len; // Length of this data structure
259 struct hdware_block *hdware_info;
260};
261
262/**
263 * An array of these structures is pointed to from dev_caller
264 * The length of the array depends on the device type. For APs,
265 * there are 8.
266 *
267 * The caller buffer is allocated to the user at OPEN. At WRITE,
268 * it contains the request; at READ, the response. The function
269 * send_to_crypto_device converts the request to device-dependent
270 * form and use the caller's OPEN-allocated buffer for the response.
271 *
272 * For the contents of caller_dev_dep_req and caller_dev_dep_req_p
273 * because that points to it, see the discussion in z90hardware.c.
274 * Search for "extended request message block".
275 */
276struct caller {
277 int caller_buf_l; // length of original request
278 unsigned char * caller_buf_p; // Original request on WRITE
279 int caller_dev_dep_req_l; // len device dependent request
280 unsigned char * caller_dev_dep_req_p; // Device dependent form
281 unsigned char caller_id[8]; // caller-supplied message id
282 struct list_head caller_liste;
283 unsigned char caller_dev_dep_req[MAX_RESPONSE_SIZE];
284};
285
286/**
287 * Function prototypes from z90hardware.c
288 */
289enum hdstat query_online(int deviceNr, int cdx, int resetNr, int *q_depth,
290 int *dev_type);
291enum devstat reset_device(int deviceNr, int cdx, int resetNr);
292enum devstat send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext);
293enum devstat receive_from_AP(int dev_nr, int cdx, int resplen,
294 unsigned char *resp, unsigned char *psmid);
295int convert_request(unsigned char *buffer, int func, unsigned short function,
296 int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p);
297int convert_response(unsigned char *response, unsigned char *buffer,
298 int *respbufflen_p, unsigned char *resp_buff);
299
300/**
301 * Low level function prototypes
302 */
303static int create_z90crypt(int *cdx_p);
304static int refresh_z90crypt(int *cdx_p);
305static int find_crypto_devices(struct status *deviceMask);
306static int create_crypto_device(int index);
307static int destroy_crypto_device(int index);
308static void destroy_z90crypt(void);
309static int refresh_index_array(struct status *status_str,
310 struct device_x *index_array);
311static int probe_device_type(struct device *devPtr);
312static int probe_PCIXCC_type(struct device *devPtr);
313
314/**
315 * proc fs definitions
316 */
317static struct proc_dir_entry *z90crypt_entry;
318
319/**
320 * data structures
321 */
322
323/**
324 * work_element.opener points back to this structure
325 */
326struct priv_data {
327 pid_t opener_pid;
328 unsigned char status; // 0: open 1: closed
329};
330
331/**
332 * A work element is allocated for each request
333 */
334struct work_element {
335 struct priv_data *priv_data;
336 pid_t pid;
337 int devindex; // index of device processing this w_e
338 // (If request did not specify device,
339 // -1 until placed onto a queue)
340 int devtype;
341 struct list_head liste; // used for requestq and pendingq
342 char buffer[128]; // local copy of user request
343 int buff_size; // size of the buffer for the request
344 char resp_buff[RESPBUFFSIZE];
345 int resp_buff_size;
346 char __user * resp_addr; // address of response in user space
347 unsigned int funccode; // function code of request
348 wait_queue_head_t waitq;
349 unsigned long requestsent; // time at which the request was sent
350 atomic_t alarmrung; // wake-up signal
351 unsigned char caller_id[8]; // pid + counter, for this w_e
352 unsigned char status[1]; // bits to mark status of the request
353 unsigned char audit[3]; // record of work element's progress
354 unsigned char * requestptr; // address of request buffer
355 int retcode; // return code of request
356};
357
358/**
359 * High level function prototypes
360 */
361static int z90crypt_open(struct inode *, struct file *);
362static int z90crypt_release(struct inode *, struct file *);
363static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *);
364static ssize_t z90crypt_write(struct file *, const char __user *,
365 size_t, loff_t *);
366static long z90crypt_unlocked_ioctl(struct file *, unsigned int, unsigned long);
367static long z90crypt_compat_ioctl(struct file *, unsigned int, unsigned long);
368
369static void z90crypt_reader_task(unsigned long);
370static void z90crypt_schedule_reader_task(unsigned long);
371static void z90crypt_config_task(unsigned long);
372static void z90crypt_cleanup_task(unsigned long);
373
374static int z90crypt_status(char *, char **, off_t, int, int *, void *);
375static int z90crypt_status_write(struct file *, const char __user *,
376 unsigned long, void *);
377
378/**
379 * Storage allocated at initialization and used throughout the life of
380 * this insmod
381 */
382static int domain = DOMAIN_INDEX;
383static struct z90crypt z90crypt;
384static int quiesce_z90crypt;
385static spinlock_t queuespinlock;
386static struct list_head request_list;
387static int requestq_count;
388static struct list_head pending_list;
389static int pendingq_count;
390
391static struct tasklet_struct reader_tasklet;
392static struct timer_list reader_timer;
393static struct timer_list config_timer;
394static struct timer_list cleanup_timer;
395static atomic_t total_open;
396static atomic_t z90crypt_step;
397
398static struct file_operations z90crypt_fops = {
399 .owner = THIS_MODULE,
400 .read = z90crypt_read,
401 .write = z90crypt_write,
402 .unlocked_ioctl = z90crypt_unlocked_ioctl,
403#ifdef CONFIG_COMPAT
404 .compat_ioctl = z90crypt_compat_ioctl,
405#endif
406 .open = z90crypt_open,
407 .release = z90crypt_release
408};
409
410static struct miscdevice z90crypt_misc_device = {
411 .minor = Z90CRYPT_MINOR,
412 .name = DEV_NAME,
413 .fops = &z90crypt_fops,
414};
415
416/**
417 * Documentation values.
418 */
419MODULE_AUTHOR("zSeries Linux Crypto Team: Robert H. Burroughs, Eric D. Rossman"
420 "and Jochen Roehrig");
421MODULE_DESCRIPTION("zSeries Linux Cryptographic Coprocessor device driver, "
422 "Copyright 2001, 2005 IBM Corporation");
423MODULE_LICENSE("GPL");
424module_param(domain, int, 0);
425MODULE_PARM_DESC(domain, "domain index for device");
426
427#ifdef CONFIG_COMPAT
428/**
429 * ioctl32 conversion routines
430 */
431struct ica_rsa_modexpo_32 { // For 32-bit callers
432 compat_uptr_t inputdata;
433 unsigned int inputdatalength;
434 compat_uptr_t outputdata;
435 unsigned int outputdatalength;
436 compat_uptr_t b_key;
437 compat_uptr_t n_modulus;
438};
439
440static long
441trans_modexpo32(struct file *filp, unsigned int cmd, unsigned long arg)
442{
443 struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg);
444 struct ica_rsa_modexpo_32 mex32k;
445 struct ica_rsa_modexpo __user *mex64;
446 long ret = 0;
447 unsigned int i;
448
449 if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32)))
450 return -EFAULT;
451 mex64 = compat_alloc_user_space(sizeof(struct ica_rsa_modexpo));
452 if (!access_ok(VERIFY_WRITE, mex64, sizeof(struct ica_rsa_modexpo)))
453 return -EFAULT;
454 if (copy_from_user(&mex32k, mex32u, sizeof(struct ica_rsa_modexpo_32)))
455 return -EFAULT;
456 if (__put_user(compat_ptr(mex32k.inputdata), &mex64->inputdata) ||
457 __put_user(mex32k.inputdatalength, &mex64->inputdatalength) ||
458 __put_user(compat_ptr(mex32k.outputdata), &mex64->outputdata) ||
459 __put_user(mex32k.outputdatalength, &mex64->outputdatalength) ||
460 __put_user(compat_ptr(mex32k.b_key), &mex64->b_key) ||
461 __put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus))
462 return -EFAULT;
463 ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)mex64);
464 if (!ret)
465 if (__get_user(i, &mex64->outputdatalength) ||
466 __put_user(i, &mex32u->outputdatalength))
467 ret = -EFAULT;
468 return ret;
469}
470
471struct ica_rsa_modexpo_crt_32 { // For 32-bit callers
472 compat_uptr_t inputdata;
473 unsigned int inputdatalength;
474 compat_uptr_t outputdata;
475 unsigned int outputdatalength;
476 compat_uptr_t bp_key;
477 compat_uptr_t bq_key;
478 compat_uptr_t np_prime;
479 compat_uptr_t nq_prime;
480 compat_uptr_t u_mult_inv;
481};
482
483static long
484trans_modexpo_crt32(struct file *filp, unsigned int cmd, unsigned long arg)
485{
486 struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg);
487 struct ica_rsa_modexpo_crt_32 crt32k;
488 struct ica_rsa_modexpo_crt __user *crt64;
489 long ret = 0;
490 unsigned int i;
491
492 if (!access_ok(VERIFY_WRITE, crt32u,
493 sizeof(struct ica_rsa_modexpo_crt_32)))
494 return -EFAULT;
495 crt64 = compat_alloc_user_space(sizeof(struct ica_rsa_modexpo_crt));
496 if (!access_ok(VERIFY_WRITE, crt64, sizeof(struct ica_rsa_modexpo_crt)))
497 return -EFAULT;
498 if (copy_from_user(&crt32k, crt32u,
499 sizeof(struct ica_rsa_modexpo_crt_32)))
500 return -EFAULT;
501 if (__put_user(compat_ptr(crt32k.inputdata), &crt64->inputdata) ||
502 __put_user(crt32k.inputdatalength, &crt64->inputdatalength) ||
503 __put_user(compat_ptr(crt32k.outputdata), &crt64->outputdata) ||
504 __put_user(crt32k.outputdatalength, &crt64->outputdatalength) ||
505 __put_user(compat_ptr(crt32k.bp_key), &crt64->bp_key) ||
506 __put_user(compat_ptr(crt32k.bq_key), &crt64->bq_key) ||
507 __put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) ||
508 __put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) ||
509 __put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv))
510 return -EFAULT;
511 ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)crt64);
512 if (!ret)
513 if (__get_user(i, &crt64->outputdatalength) ||
514 __put_user(i, &crt32u->outputdatalength))
515 ret = -EFAULT;
516 return ret;
517}
518
519static long
520z90crypt_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
521{
522 switch (cmd) {
523 case ICAZ90STATUS:
524 case Z90QUIESCE:
525 case Z90STAT_TOTALCOUNT:
526 case Z90STAT_PCICACOUNT:
527 case Z90STAT_PCICCCOUNT:
528 case Z90STAT_PCIXCCCOUNT:
529 case Z90STAT_PCIXCCMCL2COUNT:
530 case Z90STAT_PCIXCCMCL3COUNT:
531 case Z90STAT_CEX2CCOUNT:
532 case Z90STAT_REQUESTQ_COUNT:
533 case Z90STAT_PENDINGQ_COUNT:
534 case Z90STAT_TOTALOPEN_COUNT:
535 case Z90STAT_DOMAIN_INDEX:
536 case Z90STAT_STATUS_MASK:
537 case Z90STAT_QDEPTH_MASK:
538 case Z90STAT_PERDEV_REQCNT:
539 return z90crypt_unlocked_ioctl(filp, cmd, arg);
540 case ICARSAMODEXPO:
541 return trans_modexpo32(filp, cmd, arg);
542 case ICARSACRT:
543 return trans_modexpo_crt32(filp, cmd, arg);
544 default:
545 return -ENOIOCTLCMD;
546 }
547}
548#endif
549
550/**
551 * The module initialization code.
552 */
553static int __init
554z90crypt_init_module(void)
555{
556 int result, nresult;
557 struct proc_dir_entry *entry;
558
559 PDEBUG("PID %d\n", PID());
560
561 if ((domain < -1) || (domain > 15)) {
562 PRINTKW("Invalid param: domain = %d. Not loading.\n", domain);
563 return -EINVAL;
564 }
565
566 /* Register as misc device with given minor (or get a dynamic one). */
567 result = misc_register(&z90crypt_misc_device);
568 if (result < 0) {
569 PRINTKW(KERN_ERR "misc_register (minor %d) failed with %d\n",
570 z90crypt_misc_device.minor, result);
571 return result;
572 }
573
574 PDEBUG("Registered " DEV_NAME " with result %d\n", result);
575
576 result = create_z90crypt(&domain);
577 if (result != 0) {
578 PRINTKW("create_z90crypt (domain index %d) failed with %d.\n",
579 domain, result);
580 result = -ENOMEM;
581 goto init_module_cleanup;
582 }
583
584 if (result == 0) {
585 PRINTKN("Version %d.%d.%d loaded, built on %s %s\n",
586 z90crypt_VERSION, z90crypt_RELEASE, z90crypt_VARIANT,
587 __DATE__, __TIME__);
588 PDEBUG("create_z90crypt (domain index %d) successful.\n",
589 domain);
590 } else
591 PRINTK("No devices at startup\n");
592
593 /* Initialize globals. */
594 spin_lock_init(&queuespinlock);
595
596 INIT_LIST_HEAD(&pending_list);
597 pendingq_count = 0;
598
599 INIT_LIST_HEAD(&request_list);
600 requestq_count = 0;
601
602 quiesce_z90crypt = 0;
603
604 atomic_set(&total_open, 0);
605 atomic_set(&z90crypt_step, 0);
606
607 /* Set up the cleanup task. */
608 init_timer(&cleanup_timer);
609 cleanup_timer.function = z90crypt_cleanup_task;
610 cleanup_timer.data = 0;
611 cleanup_timer.expires = jiffies + (CLEANUPTIME * HZ);
612 add_timer(&cleanup_timer);
613
614 /* Set up the proc file system */
615 entry = create_proc_entry("driver/z90crypt", 0644, 0);
616 if (entry) {
617 entry->nlink = 1;
618 entry->data = 0;
619 entry->read_proc = z90crypt_status;
620 entry->write_proc = z90crypt_status_write;
621 }
622 else
623 PRINTK("Couldn't create z90crypt proc entry\n");
624 z90crypt_entry = entry;
625
626 /* Set up the configuration task. */
627 init_timer(&config_timer);
628 config_timer.function = z90crypt_config_task;
629 config_timer.data = 0;
630 config_timer.expires = jiffies + (INITIAL_CONFIGTIME * HZ);
631 add_timer(&config_timer);
632
633 /* Set up the reader task */
634 tasklet_init(&reader_tasklet, z90crypt_reader_task, 0);
635 init_timer(&reader_timer);
636 reader_timer.function = z90crypt_schedule_reader_task;
637 reader_timer.data = 0;
638 reader_timer.expires = jiffies + (READERTIME * HZ / 1000);
639 add_timer(&reader_timer);
640
641 return 0; // success
642
643init_module_cleanup:
644 if ((nresult = misc_deregister(&z90crypt_misc_device)))
645 PRINTK("misc_deregister failed with %d.\n", nresult);
646 else
647 PDEBUG("misc_deregister successful.\n");
648
649 return result; // failure
650}
651
652/**
653 * The module termination code
654 */
655static void __exit
656z90crypt_cleanup_module(void)
657{
658 int nresult;
659
660 PDEBUG("PID %d\n", PID());
661
662 remove_proc_entry("driver/z90crypt", 0);
663
664 if ((nresult = misc_deregister(&z90crypt_misc_device)))
665 PRINTK("misc_deregister failed with %d.\n", nresult);
666 else
667 PDEBUG("misc_deregister successful.\n");
668
669 /* Remove the tasks */
670 tasklet_kill(&reader_tasklet);
671 del_timer(&reader_timer);
672 del_timer(&config_timer);
673 del_timer(&cleanup_timer);
674
675 destroy_z90crypt();
676
677 PRINTKN("Unloaded.\n");
678}
679
680/**
681 * Functions running under a process id
682 *
683 * The I/O functions:
684 * z90crypt_open
685 * z90crypt_release
686 * z90crypt_read
687 * z90crypt_write
688 * z90crypt_unlocked_ioctl
689 * z90crypt_status
690 * z90crypt_status_write
691 * disable_card
692 * enable_card
693 *
694 * Helper functions:
695 * z90crypt_rsa
696 * z90crypt_prepare
697 * z90crypt_send
698 * z90crypt_process_results
699 *
700 */
701static int
702z90crypt_open(struct inode *inode, struct file *filp)
703{
704 struct priv_data *private_data_p;
705
706 if (quiesce_z90crypt)
707 return -EQUIESCE;
708
709 private_data_p = kzalloc(sizeof(struct priv_data), GFP_KERNEL);
710 if (!private_data_p) {
711 PRINTK("Memory allocate failed\n");
712 return -ENOMEM;
713 }
714
715 private_data_p->status = STAT_OPEN;
716 private_data_p->opener_pid = PID();
717 filp->private_data = private_data_p;
718 atomic_inc(&total_open);
719
720 return 0;
721}
722
723static int
724z90crypt_release(struct inode *inode, struct file *filp)
725{
726 struct priv_data *private_data_p = filp->private_data;
727
728 PDEBUG("PID %d (filp %p)\n", PID(), filp);
729
730 private_data_p->status = STAT_CLOSED;
731 memset(private_data_p, 0, sizeof(struct priv_data));
732 kfree(private_data_p);
733 atomic_dec(&total_open);
734
735 return 0;
736}
737
738/*
739 * there are two read functions, of which compile options will choose one
740 * without USE_GET_RANDOM_BYTES
741 * => read() always returns -EPERM;
742 * otherwise
743 * => read() uses get_random_bytes() kernel function
744 */
745#ifndef USE_GET_RANDOM_BYTES
746/**
747 * z90crypt_read will not be supported beyond z90crypt 1.3.1
748 */
749static ssize_t
750z90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
751{
752 PDEBUG("filp %p (PID %d)\n", filp, PID());
753 return -EPERM;
754}
755#else // we want to use get_random_bytes
756/**
757 * read() just returns a string of random bytes. Since we have no way
758 * to generate these cryptographically, we just execute get_random_bytes
759 * for the length specified.
760 */
761#include <linux/random.h>
762static ssize_t
763z90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
764{
765 unsigned char *temp_buff;
766
767 PDEBUG("filp %p (PID %d)\n", filp, PID());
768
769 if (quiesce_z90crypt)
770 return -EQUIESCE;
771 if (count < 0) {
772 PRINTK("Requested random byte count negative: %ld\n", count);
773 return -EINVAL;
774 }
775 if (count > RESPBUFFSIZE) {
776 PDEBUG("count[%d] > RESPBUFFSIZE", count);
777 return -EINVAL;
778 }
779 if (count == 0)
780 return 0;
781 temp_buff = kmalloc(RESPBUFFSIZE, GFP_KERNEL);
782 if (!temp_buff) {
783 PRINTK("Memory allocate failed\n");
784 return -ENOMEM;
785 }
786 get_random_bytes(temp_buff, count);
787
788 if (copy_to_user(buf, temp_buff, count) != 0) {
789 kfree(temp_buff);
790 return -EFAULT;
791 }
792 kfree(temp_buff);
793 return count;
794}
795#endif
796
797/**
798 * Write is is not allowed
799 */
800static ssize_t
801z90crypt_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
802{
803 PDEBUG("filp %p (PID %d)\n", filp, PID());
804 return -EPERM;
805}
806
807/**
808 * New status functions
809 */
810static inline int
811get_status_totalcount(void)
812{
813 return z90crypt.hdware_info->hdware_mask.st_count;
814}
815
816static inline int
817get_status_PCICAcount(void)
818{
819 return z90crypt.hdware_info->type_mask[PCICA].st_count;
820}
821
822static inline int
823get_status_PCICCcount(void)
824{
825 return z90crypt.hdware_info->type_mask[PCICC].st_count;
826}
827
828static inline int
829get_status_PCIXCCcount(void)
830{
831 return z90crypt.hdware_info->type_mask[PCIXCC_MCL2].st_count +
832 z90crypt.hdware_info->type_mask[PCIXCC_MCL3].st_count;
833}
834
835static inline int
836get_status_PCIXCCMCL2count(void)
837{
838 return z90crypt.hdware_info->type_mask[PCIXCC_MCL2].st_count;
839}
840
841static inline int
842get_status_PCIXCCMCL3count(void)
843{
844 return z90crypt.hdware_info->type_mask[PCIXCC_MCL3].st_count;
845}
846
847static inline int
848get_status_CEX2Ccount(void)
849{
850 return z90crypt.hdware_info->type_mask[CEX2C].st_count;
851}
852
853static inline int
854get_status_CEX2Acount(void)
855{
856 return z90crypt.hdware_info->type_mask[CEX2A].st_count;
857}
858
859static inline int
860get_status_requestq_count(void)
861{
862 return requestq_count;
863}
864
865static inline int
866get_status_pendingq_count(void)
867{
868 return pendingq_count;
869}
870
871static inline int
872get_status_totalopen_count(void)
873{
874 return atomic_read(&total_open);
875}
876
877static inline int
878get_status_domain_index(void)
879{
880 return z90crypt.cdx;
881}
882
883static inline unsigned char *
884get_status_status_mask(unsigned char status[Z90CRYPT_NUM_APS])
885{
886 int i, ix;
887
888 memcpy(status, z90crypt.hdware_info->device_type_array,
889 Z90CRYPT_NUM_APS);
890
891 for (i = 0; i < get_status_totalcount(); i++) {
892 ix = SHRT2LONG(i);
893 if (LONG2DEVPTR(ix)->user_disabled)
894 status[ix] = 0x0d;
895 }
896
897 return status;
898}
899
900static inline unsigned char *
901get_status_qdepth_mask(unsigned char qdepth[Z90CRYPT_NUM_APS])
902{
903 int i, ix;
904
905 memset(qdepth, 0, Z90CRYPT_NUM_APS);
906
907 for (i = 0; i < get_status_totalcount(); i++) {
908 ix = SHRT2LONG(i);
909 qdepth[ix] = LONG2DEVPTR(ix)->dev_caller_count;
910 }
911
912 return qdepth;
913}
914
915static inline unsigned int *
916get_status_perdevice_reqcnt(unsigned int reqcnt[Z90CRYPT_NUM_APS])
917{
918 int i, ix;
919
920 memset(reqcnt, 0, Z90CRYPT_NUM_APS * sizeof(int));
921
922 for (i = 0; i < get_status_totalcount(); i++) {
923 ix = SHRT2LONG(i);
924 reqcnt[ix] = LONG2DEVPTR(ix)->dev_total_req_cnt;
925 }
926
927 return reqcnt;
928}
929
930static inline void
931init_work_element(struct work_element *we_p,
932 struct priv_data *priv_data, pid_t pid)
933{
934 int step;
935
936 we_p->requestptr = (unsigned char *)we_p + sizeof(struct work_element);
937 /* Come up with a unique id for this caller. */
938 step = atomic_inc_return(&z90crypt_step);
939 memcpy(we_p->caller_id+0, (void *) &pid, sizeof(pid));
940 memcpy(we_p->caller_id+4, (void *) &step, sizeof(step));
941 we_p->pid = pid;
942 we_p->priv_data = priv_data;
943 we_p->status[0] = STAT_DEFAULT;
944 we_p->audit[0] = 0x00;
945 we_p->audit[1] = 0x00;
946 we_p->audit[2] = 0x00;
947 we_p->resp_buff_size = 0;
948 we_p->retcode = 0;
949 we_p->devindex = -1;
950 we_p->devtype = -1;
951 atomic_set(&we_p->alarmrung, 0);
952 init_waitqueue_head(&we_p->waitq);
953 INIT_LIST_HEAD(&(we_p->liste));
954}
955
956static inline int
957allocate_work_element(struct work_element **we_pp,
958 struct priv_data *priv_data_p, pid_t pid)
959{
960 struct work_element *we_p;
961
962 we_p = (struct work_element *) get_zeroed_page(GFP_KERNEL);
963 if (!we_p)
964 return -ENOMEM;
965 init_work_element(we_p, priv_data_p, pid);
966 *we_pp = we_p;
967 return 0;
968}
969
970static inline void
971remove_device(struct device *device_p)
972{
973 if (!device_p || (device_p->disabled != 0))
974 return;
975 device_p->disabled = 1;
976 z90crypt.hdware_info->type_mask[device_p->dev_type].disabled_count++;
977 z90crypt.hdware_info->hdware_mask.disabled_count++;
978}
979
980/**
981 * Bitlength limits for each card
982 *
983 * There are new MCLs which allow more bitlengths. See the table for details.
984 * The MCL must be applied and the newer bitlengths enabled for these to work.
985 *
986 * Card Type Old limit New limit
987 * PCICA ??-2048 same (the lower limit is less than 128 bit...)
988 * PCICC 512-1024 512-2048
989 * PCIXCC_MCL2 512-2048 ----- (applying any GA LIC will make an MCL3 card)
990 * PCIXCC_MCL3 ----- 128-2048
991 * CEX2C 512-2048 128-2048
992 * CEX2A ??-2048 same (the lower limit is less than 128 bit...)
993 *
994 * ext_bitlens (extended bitlengths) is a global, since you should not apply an
995 * MCL to just one card in a machine. We assume, at first, that all cards have
996 * these capabilities.
997 */
998int ext_bitlens = 1; // This is global
999#define PCIXCC_MIN_MOD_SIZE 16 // 128 bits
1000#define OLD_PCIXCC_MIN_MOD_SIZE 64 // 512 bits
1001#define PCICC_MIN_MOD_SIZE 64 // 512 bits
1002#define OLD_PCICC_MAX_MOD_SIZE 128 // 1024 bits
1003#define MAX_MOD_SIZE 256 // 2048 bits
1004
1005static inline int
1006select_device_type(int *dev_type_p, int bytelength)
1007{
1008 static int count = 0;
1009 int PCICA_avail, PCIXCC_MCL3_avail, CEX2C_avail, CEX2A_avail,
1010 index_to_use;
1011 struct status *stat;
1012 if ((*dev_type_p != PCICC) && (*dev_type_p != PCICA) &&
1013 (*dev_type_p != PCIXCC_MCL2) && (*dev_type_p != PCIXCC_MCL3) &&
1014 (*dev_type_p != CEX2C) && (*dev_type_p != CEX2A) &&
1015 (*dev_type_p != ANYDEV))
1016 return -1;
1017 if (*dev_type_p != ANYDEV) {
1018 stat = &z90crypt.hdware_info->type_mask[*dev_type_p];
1019 if (stat->st_count >
1020 (stat->disabled_count + stat->user_disabled_count))
1021 return 0;
1022 return -1;
1023 }
1024
1025 /**
1026 * Assumption: PCICA, PCIXCC_MCL3, CEX2C, and CEX2A are all similar in
1027 * speed.
1028 *
1029 * PCICA and CEX2A do NOT co-exist, so it would be either one or the
1030 * other present.
1031 */
1032 stat = &z90crypt.hdware_info->type_mask[PCICA];
1033 PCICA_avail = stat->st_count -
1034 (stat->disabled_count + stat->user_disabled_count);
1035 stat = &z90crypt.hdware_info->type_mask[PCIXCC_MCL3];
1036 PCIXCC_MCL3_avail = stat->st_count -
1037 (stat->disabled_count + stat->user_disabled_count);
1038 stat = &z90crypt.hdware_info->type_mask[CEX2C];
1039 CEX2C_avail = stat->st_count -
1040 (stat->disabled_count + stat->user_disabled_count);
1041 stat = &z90crypt.hdware_info->type_mask[CEX2A];
1042 CEX2A_avail = stat->st_count -
1043 (stat->disabled_count + stat->user_disabled_count);
1044 if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail || CEX2A_avail) {
1045 /**
1046 * bitlength is a factor, PCICA or CEX2A are the most capable,
1047 * even with the new MCL for PCIXCC.
1048 */
1049 if ((bytelength < PCIXCC_MIN_MOD_SIZE) ||
1050 (!ext_bitlens && (bytelength < OLD_PCIXCC_MIN_MOD_SIZE))) {
1051 if (PCICA_avail) {
1052 *dev_type_p = PCICA;
1053 return 0;
1054 }
1055 if (CEX2A_avail) {
1056 *dev_type_p = CEX2A;
1057 return 0;
1058 }
1059 return -1;
1060 }
1061
1062 index_to_use = count % (PCICA_avail + PCIXCC_MCL3_avail +
1063 CEX2C_avail + CEX2A_avail);
1064 if (index_to_use < PCICA_avail)
1065 *dev_type_p = PCICA;
1066 else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail))
1067 *dev_type_p = PCIXCC_MCL3;
1068 else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail +
1069 CEX2C_avail))
1070 *dev_type_p = CEX2C;
1071 else
1072 *dev_type_p = CEX2A;
1073 count++;
1074 return 0;
1075 }
1076
1077 /* Less than OLD_PCIXCC_MIN_MOD_SIZE cannot go to a PCIXCC_MCL2 */
1078 if (bytelength < OLD_PCIXCC_MIN_MOD_SIZE)
1079 return -1;
1080 stat = &z90crypt.hdware_info->type_mask[PCIXCC_MCL2];
1081 if (stat->st_count >
1082 (stat->disabled_count + stat->user_disabled_count)) {
1083 *dev_type_p = PCIXCC_MCL2;
1084 return 0;
1085 }
1086
1087 /**
1088 * Less than PCICC_MIN_MOD_SIZE or more than OLD_PCICC_MAX_MOD_SIZE
1089 * (if we don't have the MCL applied and the newer bitlengths enabled)
1090 * cannot go to a PCICC
1091 */
1092 if ((bytelength < PCICC_MIN_MOD_SIZE) ||
1093 (!ext_bitlens && (bytelength > OLD_PCICC_MAX_MOD_SIZE))) {
1094 return -1;
1095 }
1096 stat = &z90crypt.hdware_info->type_mask[PCICC];
1097 if (stat->st_count >
1098 (stat->disabled_count + stat->user_disabled_count)) {
1099 *dev_type_p = PCICC;
1100 return 0;
1101 }
1102
1103 return -1;
1104}
1105
1106/**
1107 * Try the selected number, then the selected type (can be ANYDEV)
1108 */
1109static inline int
1110select_device(int *dev_type_p, int *device_nr_p, int bytelength)
1111{
1112 int i, indx, devTp, low_count, low_indx;
1113 struct device_x *index_p;
1114 struct device *dev_ptr;
1115
1116 PDEBUG("device type = %d, index = %d\n", *dev_type_p, *device_nr_p);
1117 if ((*device_nr_p >= 0) && (*device_nr_p < Z90CRYPT_NUM_DEVS)) {
1118 PDEBUG("trying index = %d\n", *device_nr_p);
1119 dev_ptr = z90crypt.device_p[*device_nr_p];
1120
1121 if (dev_ptr &&
1122 (dev_ptr->dev_stat != DEV_GONE) &&
1123 (dev_ptr->disabled == 0) &&
1124 (dev_ptr->user_disabled == 0)) {
1125 PDEBUG("selected by number, index = %d\n",
1126 *device_nr_p);
1127 *dev_type_p = dev_ptr->dev_type;
1128 return *device_nr_p;
1129 }
1130 }
1131 *device_nr_p = -1;
1132 PDEBUG("trying type = %d\n", *dev_type_p);
1133 devTp = *dev_type_p;
1134 if (select_device_type(&devTp, bytelength) == -1) {
1135 PDEBUG("failed to select by type\n");
1136 return -1;
1137 }
1138 PDEBUG("selected type = %d\n", devTp);
1139 index_p = &z90crypt.hdware_info->type_x_addr[devTp];
1140 low_count = 0x0000FFFF;
1141 low_indx = -1;
1142 for (i = 0; i < z90crypt.hdware_info->type_mask[devTp].st_count; i++) {
1143 indx = index_p->device_index[i];
1144 dev_ptr = z90crypt.device_p[indx];
1145 if (dev_ptr &&
1146 (dev_ptr->dev_stat != DEV_GONE) &&
1147 (dev_ptr->disabled == 0) &&
1148 (dev_ptr->user_disabled == 0) &&
1149 (devTp == dev_ptr->dev_type) &&
1150 (low_count > dev_ptr->dev_caller_count)) {
1151 low_count = dev_ptr->dev_caller_count;
1152 low_indx = indx;
1153 }
1154 }
1155 *device_nr_p = low_indx;
1156 return low_indx;
1157}
1158
1159static inline int
1160send_to_crypto_device(struct work_element *we_p)
1161{
1162 struct caller *caller_p;
1163 struct device *device_p;
1164 int dev_nr;
1165 int bytelen = ((struct ica_rsa_modexpo *)we_p->buffer)->inputdatalength;
1166
1167 if (!we_p->requestptr)
1168 return SEN_FATAL_ERROR;
1169 caller_p = (struct caller *)we_p->requestptr;
1170 dev_nr = we_p->devindex;
1171 if (select_device(&we_p->devtype, &dev_nr, bytelen) == -1) {
1172 if (z90crypt.hdware_info->hdware_mask.st_count != 0)
1173 return SEN_RETRY;
1174 else
1175 return SEN_NOT_AVAIL;
1176 }
1177 we_p->devindex = dev_nr;
1178 device_p = z90crypt.device_p[dev_nr];
1179 if (!device_p)
1180 return SEN_NOT_AVAIL;
1181 if (device_p->dev_type != we_p->devtype)
1182 return SEN_RETRY;
1183 if (device_p->dev_caller_count >= device_p->dev_q_depth)
1184 return SEN_QUEUE_FULL;
1185 PDEBUG("device number prior to send: %d\n", dev_nr);
1186 switch (send_to_AP(dev_nr, z90crypt.cdx,
1187 caller_p->caller_dev_dep_req_l,
1188 caller_p->caller_dev_dep_req_p)) {
1189 case DEV_SEN_EXCEPTION:
1190 PRINTKC("Exception during send to device %d\n", dev_nr);
1191 z90crypt.terminating = 1;
1192 return SEN_FATAL_ERROR;
1193 case DEV_GONE:
1194 PRINTK("Device %d not available\n", dev_nr);
1195 remove_device(device_p);
1196 return SEN_NOT_AVAIL;
1197 case DEV_EMPTY:
1198 return SEN_NOT_AVAIL;
1199 case DEV_NO_WORK:
1200 return SEN_FATAL_ERROR;
1201 case DEV_BAD_MESSAGE:
1202 return SEN_USER_ERROR;
1203 case DEV_QUEUE_FULL:
1204 return SEN_QUEUE_FULL;
1205 default:
1206 case DEV_ONLINE:
1207 break;
1208 }
1209 list_add_tail(&(caller_p->caller_liste), &(device_p->dev_caller_list));
1210 device_p->dev_caller_count++;
1211 return 0;
1212}
1213
1214/**
1215 * Send puts the user's work on one of two queues:
1216 * the pending queue if the send was successful
1217 * the request queue if the send failed because device full or busy
1218 */
1219static inline int
1220z90crypt_send(struct work_element *we_p, const char *buf)
1221{
1222 int rv;
1223
1224 PDEBUG("PID %d\n", PID());
1225
1226 if (CHK_RDWRMASK(we_p->status[0]) != STAT_NOWORK) {
1227 PDEBUG("PID %d tried to send more work but has outstanding "
1228 "work.\n", PID());
1229 return -EWORKPEND;
1230 }
1231 we_p->devindex = -1; // Reset device number
1232 spin_lock_irq(&queuespinlock);
1233 rv = send_to_crypto_device(we_p);
1234 switch (rv) {
1235 case 0:
1236 we_p->requestsent = jiffies;
1237 we_p->audit[0] |= FP_SENT;
1238 list_add_tail(&we_p->liste, &pending_list);
1239 ++pendingq_count;
1240 we_p->audit[0] |= FP_PENDING;
1241 break;
1242 case SEN_BUSY:
1243 case SEN_QUEUE_FULL:
1244 rv = 0;
1245 we_p->devindex = -1; // any device will do
1246 we_p->requestsent = jiffies;
1247 list_add_tail(&we_p->liste, &request_list);
1248 ++requestq_count;
1249 we_p->audit[0] |= FP_REQUEST;
1250 break;
1251 case SEN_RETRY:
1252 rv = -ERESTARTSYS;
1253 break;
1254 case SEN_NOT_AVAIL:
1255 PRINTK("*** No devices available.\n");
1256 rv = we_p->retcode = -ENODEV;
1257 we_p->status[0] |= STAT_FAILED;
1258 break;
1259 case REC_OPERAND_INV:
1260 case REC_OPERAND_SIZE:
1261 case REC_EVEN_MOD:
1262 case REC_INVALID_PAD:
1263 rv = we_p->retcode = -EINVAL;
1264 we_p->status[0] |= STAT_FAILED;
1265 break;
1266 default:
1267 we_p->retcode = rv;
1268 we_p->status[0] |= STAT_FAILED;
1269 break;
1270 }
1271 if (rv != -ERESTARTSYS)
1272 SET_RDWRMASK(we_p->status[0], STAT_WRITTEN);
1273 spin_unlock_irq(&queuespinlock);
1274 if (rv == 0)
1275 tasklet_schedule(&reader_tasklet);
1276 return rv;
1277}
1278
1279/**
1280 * process_results copies the user's work from kernel space.
1281 */
1282static inline int
1283z90crypt_process_results(struct work_element *we_p, char __user *buf)
1284{
1285 int rv;
1286
1287 PDEBUG("we_p %p (PID %d)\n", we_p, PID());
1288
1289 LONG2DEVPTR(we_p->devindex)->dev_total_req_cnt++;
1290 SET_RDWRMASK(we_p->status[0], STAT_READPEND);
1291
1292 rv = 0;
1293 if (!we_p->buffer) {
1294 PRINTK("we_p %p PID %d in STAT_READPEND: buffer NULL.\n",
1295 we_p, PID());
1296 rv = -ENOBUFF;
1297 }
1298
1299 if (!rv)
1300 if ((rv = copy_to_user(buf, we_p->buffer, we_p->buff_size))) {
1301 PDEBUG("copy_to_user failed: rv = %d\n", rv);
1302 rv = -EFAULT;
1303 }
1304
1305 if (!rv)
1306 rv = we_p->retcode;
1307 if (!rv)
1308 if (we_p->resp_buff_size
1309 && copy_to_user(we_p->resp_addr, we_p->resp_buff,
1310 we_p->resp_buff_size))
1311 rv = -EFAULT;
1312
1313 SET_RDWRMASK(we_p->status[0], STAT_NOWORK);
1314 return rv;
1315}
1316
1317static unsigned char NULL_psmid[8] =
1318{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1319
1320/**
1321 * Used in device configuration functions
1322 */
1323#define MAX_RESET 90
1324
1325/**
1326 * This is used only for PCICC support
1327 */
1328static inline int
1329is_PKCS11_padded(unsigned char *buffer, int length)
1330{
1331 int i;
1332 if ((buffer[0] != 0x00) || (buffer[1] != 0x01))
1333 return 0;
1334 for (i = 2; i < length; i++)
1335 if (buffer[i] != 0xFF)
1336 break;
1337 if ((i < 10) || (i == length))
1338 return 0;
1339 if (buffer[i] != 0x00)
1340 return 0;
1341 return 1;
1342}
1343
1344/**
1345 * This is used only for PCICC support
1346 */
1347static inline int
1348is_PKCS12_padded(unsigned char *buffer, int length)
1349{
1350 int i;
1351 if ((buffer[0] != 0x00) || (buffer[1] != 0x02))
1352 return 0;
1353 for (i = 2; i < length; i++)
1354 if (buffer[i] == 0x00)
1355 break;
1356 if ((i < 10) || (i == length))
1357 return 0;
1358 if (buffer[i] != 0x00)
1359 return 0;
1360 return 1;
1361}
1362
1363/**
1364 * builds struct caller and converts message from generic format to
1365 * device-dependent format
1366 * func is ICARSAMODEXPO or ICARSACRT
1367 * function is PCI_FUNC_KEY_ENCRYPT or PCI_FUNC_KEY_DECRYPT
1368 */
1369static inline int
1370build_caller(struct work_element *we_p, short function)
1371{
1372 int rv;
1373 struct caller *caller_p = (struct caller *)we_p->requestptr;
1374
1375 if ((we_p->devtype != PCICC) && (we_p->devtype != PCICA) &&
1376 (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) &&
1377 (we_p->devtype != CEX2C) && (we_p->devtype != CEX2A))
1378 return SEN_NOT_AVAIL;
1379
1380 memcpy(caller_p->caller_id, we_p->caller_id,
1381 sizeof(caller_p->caller_id));
1382 caller_p->caller_dev_dep_req_p = caller_p->caller_dev_dep_req;
1383 caller_p->caller_dev_dep_req_l = MAX_RESPONSE_SIZE;
1384 caller_p->caller_buf_p = we_p->buffer;
1385 INIT_LIST_HEAD(&(caller_p->caller_liste));
1386
1387 rv = convert_request(we_p->buffer, we_p->funccode, function,
1388 z90crypt.cdx, we_p->devtype,
1389 &caller_p->caller_dev_dep_req_l,
1390 caller_p->caller_dev_dep_req_p);
1391 if (rv) {
1392 if (rv == SEN_NOT_AVAIL)
1393 PDEBUG("request can't be processed on hdwr avail\n");
1394 else
1395 PRINTK("Error from convert_request: %d\n", rv);
1396 }
1397 else
1398 memcpy(&(caller_p->caller_dev_dep_req_p[4]), we_p->caller_id,8);
1399 return rv;
1400}
1401
1402static inline void
1403unbuild_caller(struct device *device_p, struct caller *caller_p)
1404{
1405 if (!caller_p)
1406 return;
1407 if (caller_p->caller_liste.next && caller_p->caller_liste.prev)
1408 if (!list_empty(&caller_p->caller_liste)) {
1409 list_del_init(&caller_p->caller_liste);
1410 device_p->dev_caller_count--;
1411 }
1412 memset(caller_p->caller_id, 0, sizeof(caller_p->caller_id));
1413}
1414
1415static inline int
1416get_crypto_request_buffer(struct work_element *we_p)
1417{
1418 struct ica_rsa_modexpo *mex_p;
1419 struct ica_rsa_modexpo_crt *crt_p;
1420 unsigned char *temp_buffer;
1421 short function;
1422 int rv;
1423
1424 mex_p = (struct ica_rsa_modexpo *) we_p->buffer;
1425 crt_p = (struct ica_rsa_modexpo_crt *) we_p->buffer;
1426
1427 PDEBUG("device type input = %d\n", we_p->devtype);
1428
1429 if (z90crypt.terminating)
1430 return REC_NO_RESPONSE;
1431 if (memcmp(we_p->caller_id, NULL_psmid, 8) == 0) {
1432 PRINTK("psmid zeroes\n");
1433 return SEN_FATAL_ERROR;
1434 }
1435 if (!we_p->buffer) {
1436 PRINTK("buffer pointer NULL\n");
1437 return SEN_USER_ERROR;
1438 }
1439 if (!we_p->requestptr) {
1440 PRINTK("caller pointer NULL\n");
1441 return SEN_USER_ERROR;
1442 }
1443
1444 if ((we_p->devtype != PCICA) && (we_p->devtype != PCICC) &&
1445 (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) &&
1446 (we_p->devtype != CEX2C) && (we_p->devtype != CEX2A) &&
1447 (we_p->devtype != ANYDEV)) {
1448 PRINTK("invalid device type\n");
1449 return SEN_USER_ERROR;
1450 }
1451
1452 if ((mex_p->inputdatalength < 1) ||
1453 (mex_p->inputdatalength > MAX_MOD_SIZE)) {
1454 PRINTK("inputdatalength[%d] is not valid\n",
1455 mex_p->inputdatalength);
1456 return SEN_USER_ERROR;
1457 }
1458
1459 if (mex_p->outputdatalength < mex_p->inputdatalength) {
1460 PRINTK("outputdatalength[%d] < inputdatalength[%d]\n",
1461 mex_p->outputdatalength, mex_p->inputdatalength);
1462 return SEN_USER_ERROR;
1463 }
1464
1465 if (!mex_p->inputdata || !mex_p->outputdata) {
1466 PRINTK("inputdata[%p] or outputdata[%p] is NULL\n",
1467 mex_p->outputdata, mex_p->inputdata);
1468 return SEN_USER_ERROR;
1469 }
1470
1471 /**
1472 * As long as outputdatalength is big enough, we can set the
1473 * outputdatalength equal to the inputdatalength, since that is the
1474 * number of bytes we will copy in any case
1475 */
1476 mex_p->outputdatalength = mex_p->inputdatalength;
1477
1478 rv = 0;
1479 switch (we_p->funccode) {
1480 case ICARSAMODEXPO:
1481 if (!mex_p->b_key || !mex_p->n_modulus)
1482 rv = SEN_USER_ERROR;
1483 break;
1484 case ICARSACRT:
1485 if (!IS_EVEN(crt_p->inputdatalength)) {
1486 PRINTK("inputdatalength[%d] is odd, CRT form\n",
1487 crt_p->inputdatalength);
1488 rv = SEN_USER_ERROR;
1489 break;
1490 }
1491 if (!crt_p->bp_key ||
1492 !crt_p->bq_key ||
1493 !crt_p->np_prime ||
1494 !crt_p->nq_prime ||
1495 !crt_p->u_mult_inv) {
1496 PRINTK("CRT form, bad data: %p/%p/%p/%p/%p\n",
1497 crt_p->bp_key, crt_p->bq_key,
1498 crt_p->np_prime, crt_p->nq_prime,
1499 crt_p->u_mult_inv);
1500 rv = SEN_USER_ERROR;
1501 }
1502 break;
1503 default:
1504 PRINTK("bad func = %d\n", we_p->funccode);
1505 rv = SEN_USER_ERROR;
1506 break;
1507 }
1508 if (rv != 0)
1509 return rv;
1510
1511 if (select_device_type(&we_p->devtype, mex_p->inputdatalength) < 0)
1512 return SEN_NOT_AVAIL;
1513
1514 temp_buffer = (unsigned char *)we_p + sizeof(struct work_element) +
1515 sizeof(struct caller);
1516 if (copy_from_user(temp_buffer, mex_p->inputdata,
1517 mex_p->inputdatalength) != 0)
1518 return SEN_RELEASED;
1519
1520 function = PCI_FUNC_KEY_ENCRYPT;
1521 switch (we_p->devtype) {
1522 /* PCICA and CEX2A do everything with a simple RSA mod-expo operation */
1523 case PCICA:
1524 case CEX2A:
1525 function = PCI_FUNC_KEY_ENCRYPT;
1526 break;
1527 /**
1528 * PCIXCC_MCL2 does all Mod-Expo form with a simple RSA mod-expo
1529 * operation, and all CRT forms with a PKCS-1.2 format decrypt.
1530 * PCIXCC_MCL3 and CEX2C do all Mod-Expo and CRT forms with a simple RSA
1531 * mod-expo operation
1532 */
1533 case PCIXCC_MCL2:
1534 if (we_p->funccode == ICARSAMODEXPO)
1535 function = PCI_FUNC_KEY_ENCRYPT;
1536 else
1537 function = PCI_FUNC_KEY_DECRYPT;
1538 break;
1539 case PCIXCC_MCL3:
1540 case CEX2C:
1541 if (we_p->funccode == ICARSAMODEXPO)
1542 function = PCI_FUNC_KEY_ENCRYPT;
1543 else
1544 function = PCI_FUNC_KEY_DECRYPT;
1545 break;
1546 /**
1547 * PCICC does everything as a PKCS-1.2 format request
1548 */
1549 case PCICC:
1550 /* PCICC cannot handle input that is is PKCS#1.1 padded */
1551 if (is_PKCS11_padded(temp_buffer, mex_p->inputdatalength)) {
1552 return SEN_NOT_AVAIL;
1553 }
1554 if (we_p->funccode == ICARSAMODEXPO) {
1555 if (is_PKCS12_padded(temp_buffer,
1556 mex_p->inputdatalength))
1557 function = PCI_FUNC_KEY_ENCRYPT;
1558 else
1559 function = PCI_FUNC_KEY_DECRYPT;
1560 } else
1561 /* all CRT forms are decrypts */
1562 function = PCI_FUNC_KEY_DECRYPT;
1563 break;
1564 }
1565 PDEBUG("function: %04x\n", function);
1566 rv = build_caller(we_p, function);
1567 PDEBUG("rv from build_caller = %d\n", rv);
1568 return rv;
1569}
1570
1571static inline int
1572z90crypt_prepare(struct work_element *we_p, unsigned int funccode,
1573 const char __user *buffer)
1574{
1575 int rv;
1576
1577 we_p->devindex = -1;
1578 if (funccode == ICARSAMODEXPO)
1579 we_p->buff_size = sizeof(struct ica_rsa_modexpo);
1580 else
1581 we_p->buff_size = sizeof(struct ica_rsa_modexpo_crt);
1582
1583 if (copy_from_user(we_p->buffer, buffer, we_p->buff_size))
1584 return -EFAULT;
1585
1586 we_p->audit[0] |= FP_COPYFROM;
1587 SET_RDWRMASK(we_p->status[0], STAT_WRITTEN);
1588 we_p->funccode = funccode;
1589 we_p->devtype = -1;
1590 we_p->audit[0] |= FP_BUFFREQ;
1591 rv = get_crypto_request_buffer(we_p);
1592 switch (rv) {
1593 case 0:
1594 we_p->audit[0] |= FP_BUFFGOT;
1595 break;
1596 case SEN_USER_ERROR:
1597 rv = -EINVAL;
1598 break;
1599 case SEN_QUEUE_FULL:
1600 rv = 0;
1601 break;
1602 case SEN_RELEASED:
1603 rv = -EFAULT;
1604 break;
1605 case REC_NO_RESPONSE:
1606 rv = -ENODEV;
1607 break;
1608 case SEN_NOT_AVAIL:
1609 case EGETBUFF:
1610 rv = -EGETBUFF;
1611 break;
1612 default:
1613 PRINTK("rv = %d\n", rv);
1614 rv = -EGETBUFF;
1615 break;
1616 }
1617 if (CHK_RDWRMASK(we_p->status[0]) == STAT_WRITTEN)
1618 SET_RDWRMASK(we_p->status[0], STAT_DEFAULT);
1619 return rv;
1620}
1621
1622static inline void
1623purge_work_element(struct work_element *we_p)
1624{
1625 struct list_head *lptr;
1626
1627 spin_lock_irq(&queuespinlock);
1628 list_for_each(lptr, &request_list) {
1629 if (lptr == &we_p->liste) {
1630 list_del_init(lptr);
1631 requestq_count--;
1632 break;
1633 }
1634 }
1635 list_for_each(lptr, &pending_list) {
1636 if (lptr == &we_p->liste) {
1637 list_del_init(lptr);
1638 pendingq_count--;
1639 break;
1640 }
1641 }
1642 spin_unlock_irq(&queuespinlock);
1643}
1644
1645/**
1646 * Build the request and send it.
1647 */
1648static inline int
1649z90crypt_rsa(struct priv_data *private_data_p, pid_t pid,
1650 unsigned int cmd, unsigned long arg)
1651{
1652 struct work_element *we_p;
1653 int rv;
1654
1655 if ((rv = allocate_work_element(&we_p, private_data_p, pid))) {
1656 PDEBUG("PID %d: allocate_work_element returned ENOMEM\n", pid);
1657 return rv;
1658 }
1659 if ((rv = z90crypt_prepare(we_p, cmd, (const char __user *)arg)))
1660 PDEBUG("PID %d: rv = %d from z90crypt_prepare\n", pid, rv);
1661 if (!rv)
1662 if ((rv = z90crypt_send(we_p, (const char *)arg)))
1663 PDEBUG("PID %d: rv %d from z90crypt_send.\n", pid, rv);
1664 if (!rv) {
1665 we_p->audit[0] |= FP_ASLEEP;
1666 wait_event(we_p->waitq, atomic_read(&we_p->alarmrung));
1667 we_p->audit[0] |= FP_AWAKE;
1668 rv = we_p->retcode;
1669 }
1670 if (!rv)
1671 rv = z90crypt_process_results(we_p, (char __user *)arg);
1672
1673 if ((we_p->status[0] & STAT_FAILED)) {
1674 switch (rv) {
1675 /**
1676 * EINVAL *after* receive is almost always a padding error or
1677 * length error issued by a coprocessor (not an accelerator).
1678 * We convert this return value to -EGETBUFF which should
1679 * trigger a fallback to software.
1680 */
1681 case -EINVAL:
1682 if ((we_p->devtype != PCICA) &&
1683 (we_p->devtype != CEX2A))
1684 rv = -EGETBUFF;
1685 break;
1686 case -ETIMEOUT:
1687 if (z90crypt.mask.st_count > 0)
1688 rv = -ERESTARTSYS; // retry with another
1689 else
1690 rv = -ENODEV; // no cards left
1691 /* fall through to clean up request queue */
1692 case -ERESTARTSYS:
1693 case -ERELEASED:
1694 switch (CHK_RDWRMASK(we_p->status[0])) {
1695 case STAT_WRITTEN:
1696 purge_work_element(we_p);
1697 break;
1698 case STAT_READPEND:
1699 case STAT_NOWORK:
1700 default:
1701 break;
1702 }
1703 break;
1704 default:
1705 we_p->status[0] ^= STAT_FAILED;
1706 break;
1707 }
1708 }
1709 free_page((long)we_p);
1710 return rv;
1711}
1712
1713/**
1714 * This function is a little long, but it's really just one large switch
1715 * statement.
1716 */
1717static long
1718z90crypt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1719{
1720 struct priv_data *private_data_p = filp->private_data;
1721 unsigned char *status;
1722 unsigned char *qdepth;
1723 unsigned int *reqcnt;
1724 struct ica_z90_status *pstat;
1725 int ret, i, loopLim, tempstat;
1726 static int deprecated_msg_count1 = 0;
1727 static int deprecated_msg_count2 = 0;
1728
1729 PDEBUG("filp %p (PID %d), cmd 0x%08X\n", filp, PID(), cmd);
1730 PDEBUG("cmd 0x%08X: dir %s, size 0x%04X, type 0x%02X, nr 0x%02X\n",
1731 cmd,
1732 !_IOC_DIR(cmd) ? "NO"
1733 : ((_IOC_DIR(cmd) == (_IOC_READ|_IOC_WRITE)) ? "RW"
1734 : ((_IOC_DIR(cmd) == _IOC_READ) ? "RD"
1735 : "WR")),
1736 _IOC_SIZE(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd));
1737
1738 if (_IOC_TYPE(cmd) != Z90_IOCTL_MAGIC) {
1739 PRINTK("cmd 0x%08X contains bad magic\n", cmd);
1740 return -ENOTTY;
1741 }
1742
1743 ret = 0;
1744 switch (cmd) {
1745 case ICARSAMODEXPO:
1746 case ICARSACRT:
1747 if (quiesce_z90crypt) {
1748 ret = -EQUIESCE;
1749 break;
1750 }
1751 ret = -ENODEV; // Default if no devices
1752 loopLim = z90crypt.hdware_info->hdware_mask.st_count -
1753 (z90crypt.hdware_info->hdware_mask.disabled_count +
1754 z90crypt.hdware_info->hdware_mask.user_disabled_count);
1755 for (i = 0; i < loopLim; i++) {
1756 ret = z90crypt_rsa(private_data_p, PID(), cmd, arg);
1757 if (ret != -ERESTARTSYS)
1758 break;
1759 }
1760 if (ret == -ERESTARTSYS)
1761 ret = -ENODEV;
1762 break;
1763
1764 case Z90STAT_TOTALCOUNT:
1765 tempstat = get_status_totalcount();
1766 if (copy_to_user((int __user *)arg, &tempstat,sizeof(int)) != 0)
1767 ret = -EFAULT;
1768 break;
1769
1770 case Z90STAT_PCICACOUNT:
1771 tempstat = get_status_PCICAcount();
1772 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1773 ret = -EFAULT;
1774 break;
1775
1776 case Z90STAT_PCICCCOUNT:
1777 tempstat = get_status_PCICCcount();
1778 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1779 ret = -EFAULT;
1780 break;
1781
1782 case Z90STAT_PCIXCCMCL2COUNT:
1783 tempstat = get_status_PCIXCCMCL2count();
1784 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1785 ret = -EFAULT;
1786 break;
1787
1788 case Z90STAT_PCIXCCMCL3COUNT:
1789 tempstat = get_status_PCIXCCMCL3count();
1790 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1791 ret = -EFAULT;
1792 break;
1793
1794 case Z90STAT_CEX2CCOUNT:
1795 tempstat = get_status_CEX2Ccount();
1796 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1797 ret = -EFAULT;
1798 break;
1799
1800 case Z90STAT_CEX2ACOUNT:
1801 tempstat = get_status_CEX2Acount();
1802 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1803 ret = -EFAULT;
1804 break;
1805
1806 case Z90STAT_REQUESTQ_COUNT:
1807 tempstat = get_status_requestq_count();
1808 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1809 ret = -EFAULT;
1810 break;
1811
1812 case Z90STAT_PENDINGQ_COUNT:
1813 tempstat = get_status_pendingq_count();
1814 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1815 ret = -EFAULT;
1816 break;
1817
1818 case Z90STAT_TOTALOPEN_COUNT:
1819 tempstat = get_status_totalopen_count();
1820 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1821 ret = -EFAULT;
1822 break;
1823
1824 case Z90STAT_DOMAIN_INDEX:
1825 tempstat = get_status_domain_index();
1826 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
1827 ret = -EFAULT;
1828 break;
1829
1830 case Z90STAT_STATUS_MASK:
1831 status = kmalloc(Z90CRYPT_NUM_APS, GFP_KERNEL);
1832 if (!status) {
1833 PRINTK("kmalloc for status failed!\n");
1834 ret = -ENOMEM;
1835 break;
1836 }
1837 get_status_status_mask(status);
1838 if (copy_to_user((char __user *) arg, status, Z90CRYPT_NUM_APS)
1839 != 0)
1840 ret = -EFAULT;
1841 kfree(status);
1842 break;
1843
1844 case Z90STAT_QDEPTH_MASK:
1845 qdepth = kmalloc(Z90CRYPT_NUM_APS, GFP_KERNEL);
1846 if (!qdepth) {
1847 PRINTK("kmalloc for qdepth failed!\n");
1848 ret = -ENOMEM;
1849 break;
1850 }
1851 get_status_qdepth_mask(qdepth);
1852 if (copy_to_user((char __user *) arg, qdepth, Z90CRYPT_NUM_APS) != 0)
1853 ret = -EFAULT;
1854 kfree(qdepth);
1855 break;
1856
1857 case Z90STAT_PERDEV_REQCNT:
1858 reqcnt = kmalloc(sizeof(int) * Z90CRYPT_NUM_APS, GFP_KERNEL);
1859 if (!reqcnt) {
1860 PRINTK("kmalloc for reqcnt failed!\n");
1861 ret = -ENOMEM;
1862 break;
1863 }
1864 get_status_perdevice_reqcnt(reqcnt);
1865 if (copy_to_user((char __user *) arg, reqcnt,
1866 Z90CRYPT_NUM_APS * sizeof(int)) != 0)
1867 ret = -EFAULT;
1868 kfree(reqcnt);
1869 break;
1870
1871 /* THIS IS DEPRECATED. USE THE NEW STATUS CALLS */
1872 case ICAZ90STATUS:
1873 if (deprecated_msg_count1 < 20) {
1874 PRINTK("deprecated call to ioctl (ICAZ90STATUS)!\n");
1875 deprecated_msg_count1++;
1876 if (deprecated_msg_count1 == 20)
1877 PRINTK("No longer issuing messages related to "
1878 "deprecated call to ICAZ90STATUS.\n");
1879 }
1880
1881 pstat = kmalloc(sizeof(struct ica_z90_status), GFP_KERNEL);
1882 if (!pstat) {
1883 PRINTK("kmalloc for pstat failed!\n");
1884 ret = -ENOMEM;
1885 break;
1886 }
1887
1888 pstat->totalcount = get_status_totalcount();
1889 pstat->leedslitecount = get_status_PCICAcount();
1890 pstat->leeds2count = get_status_PCICCcount();
1891 pstat->requestqWaitCount = get_status_requestq_count();
1892 pstat->pendingqWaitCount = get_status_pendingq_count();
1893 pstat->totalOpenCount = get_status_totalopen_count();
1894 pstat->cryptoDomain = get_status_domain_index();
1895 get_status_status_mask(pstat->status);
1896 get_status_qdepth_mask(pstat->qdepth);
1897
1898 if (copy_to_user((struct ica_z90_status __user *) arg, pstat,
1899 sizeof(struct ica_z90_status)) != 0)
1900 ret = -EFAULT;
1901 kfree(pstat);
1902 break;
1903
1904 /* THIS IS DEPRECATED. USE THE NEW STATUS CALLS */
1905 case Z90STAT_PCIXCCCOUNT:
1906 if (deprecated_msg_count2 < 20) {
1907 PRINTK("deprecated ioctl (Z90STAT_PCIXCCCOUNT)!\n");
1908 deprecated_msg_count2++;
1909 if (deprecated_msg_count2 == 20)
1910 PRINTK("No longer issuing messages about depre"
1911 "cated ioctl Z90STAT_PCIXCCCOUNT.\n");
1912 }
1913
1914 tempstat = get_status_PCIXCCcount();
1915 if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
1916 ret = -EFAULT;
1917 break;
1918
1919 case Z90QUIESCE:
1920 if (current->euid != 0) {
1921 PRINTK("QUIESCE fails: euid %d\n",
1922 current->euid);
1923 ret = -EACCES;
1924 } else {
1925 PRINTK("QUIESCE device from PID %d\n", PID());
1926 quiesce_z90crypt = 1;
1927 }
1928 break;
1929
1930 default:
1931 /* user passed an invalid IOCTL number */
1932 PDEBUG("cmd 0x%08X contains invalid ioctl code\n", cmd);
1933 ret = -ENOTTY;
1934 break;
1935 }
1936
1937 return ret;
1938}
1939
1940static inline int
1941sprintcl(unsigned char *outaddr, unsigned char *addr, unsigned int len)
1942{
1943 int hl, i;
1944
1945 hl = 0;
1946 for (i = 0; i < len; i++)
1947 hl += sprintf(outaddr+hl, "%01x", (unsigned int) addr[i]);
1948 hl += sprintf(outaddr+hl, " ");
1949
1950 return hl;
1951}
1952
1953static inline int
1954sprintrw(unsigned char *outaddr, unsigned char *addr, unsigned int len)
1955{
1956 int hl, inl, c, cx;
1957
1958 hl = sprintf(outaddr, " ");
1959 inl = 0;
1960 for (c = 0; c < (len / 16); c++) {
1961 hl += sprintcl(outaddr+hl, addr+inl, 16);
1962 inl += 16;
1963 }
1964
1965 cx = len%16;
1966 if (cx) {
1967 hl += sprintcl(outaddr+hl, addr+inl, cx);
1968 inl += cx;
1969 }
1970
1971 hl += sprintf(outaddr+hl, "\n");
1972
1973 return hl;
1974}
1975
1976static inline int
1977sprinthx(unsigned char *title, unsigned char *outaddr,
1978 unsigned char *addr, unsigned int len)
1979{
1980 int hl, inl, r, rx;
1981
1982 hl = sprintf(outaddr, "\n%s\n", title);
1983 inl = 0;
1984 for (r = 0; r < (len / 64); r++) {
1985 hl += sprintrw(outaddr+hl, addr+inl, 64);
1986 inl += 64;
1987 }
1988 rx = len % 64;
1989 if (rx) {
1990 hl += sprintrw(outaddr+hl, addr+inl, rx);
1991 inl += rx;
1992 }
1993
1994 hl += sprintf(outaddr+hl, "\n");
1995
1996 return hl;
1997}
1998
1999static inline int
2000sprinthx4(unsigned char *title, unsigned char *outaddr,
2001 unsigned int *array, unsigned int len)
2002{
2003 int hl, r;
2004
2005 hl = sprintf(outaddr, "\n%s\n", title);
2006
2007 for (r = 0; r < len; r++) {
2008 if ((r % 8) == 0)
2009 hl += sprintf(outaddr+hl, " ");
2010 hl += sprintf(outaddr+hl, "%08X ", array[r]);
2011 if ((r % 8) == 7)
2012 hl += sprintf(outaddr+hl, "\n");
2013 }
2014
2015 hl += sprintf(outaddr+hl, "\n");
2016
2017 return hl;
2018}
2019
2020static int
2021z90crypt_status(char *resp_buff, char **start, off_t offset,
2022 int count, int *eof, void *data)
2023{
2024 unsigned char *workarea;
2025 int len;
2026
2027 /* resp_buff is a page. Use the right half for a work area */
2028 workarea = resp_buff+2000;
2029 len = 0;
2030 len += sprintf(resp_buff+len, "\nz90crypt version: %d.%d.%d\n",
2031 z90crypt_VERSION, z90crypt_RELEASE, z90crypt_VARIANT);
2032 len += sprintf(resp_buff+len, "Cryptographic domain: %d\n",
2033 get_status_domain_index());
2034 len += sprintf(resp_buff+len, "Total device count: %d\n",
2035 get_status_totalcount());
2036 len += sprintf(resp_buff+len, "PCICA count: %d\n",
2037 get_status_PCICAcount());
2038 len += sprintf(resp_buff+len, "PCICC count: %d\n",
2039 get_status_PCICCcount());
2040 len += sprintf(resp_buff+len, "PCIXCC MCL2 count: %d\n",
2041 get_status_PCIXCCMCL2count());
2042 len += sprintf(resp_buff+len, "PCIXCC MCL3 count: %d\n",
2043 get_status_PCIXCCMCL3count());
2044 len += sprintf(resp_buff+len, "CEX2C count: %d\n",
2045 get_status_CEX2Ccount());
2046 len += sprintf(resp_buff+len, "CEX2A count: %d\n",
2047 get_status_CEX2Acount());
2048 len += sprintf(resp_buff+len, "requestq count: %d\n",
2049 get_status_requestq_count());
2050 len += sprintf(resp_buff+len, "pendingq count: %d\n",
2051 get_status_pendingq_count());
2052 len += sprintf(resp_buff+len, "Total open handles: %d\n\n",
2053 get_status_totalopen_count());
2054 len += sprinthx(
2055 "Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
2056 "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A",
2057 resp_buff+len,
2058 get_status_status_mask(workarea),
2059 Z90CRYPT_NUM_APS);
2060 len += sprinthx("Waiting work element counts",
2061 resp_buff+len,
2062 get_status_qdepth_mask(workarea),
2063 Z90CRYPT_NUM_APS);
2064 len += sprinthx4(
2065 "Per-device successfully completed request counts",
2066 resp_buff+len,
2067 get_status_perdevice_reqcnt((unsigned int *)workarea),
2068 Z90CRYPT_NUM_APS);
2069 *eof = 1;
2070 memset(workarea, 0, Z90CRYPT_NUM_APS * sizeof(unsigned int));
2071 return len;
2072}
2073
2074static inline void
2075disable_card(int card_index)
2076{
2077 struct device *devp;
2078
2079 devp = LONG2DEVPTR(card_index);
2080 if (!devp || devp->user_disabled)
2081 return;
2082 devp->user_disabled = 1;
2083 z90crypt.hdware_info->hdware_mask.user_disabled_count++;
2084 if (devp->dev_type == -1)
2085 return;
2086 z90crypt.hdware_info->type_mask[devp->dev_type].user_disabled_count++;
2087}
2088
2089static inline void
2090enable_card(int card_index)
2091{
2092 struct device *devp;
2093
2094 devp = LONG2DEVPTR(card_index);
2095 if (!devp || !devp->user_disabled)
2096 return;
2097 devp->user_disabled = 0;
2098 z90crypt.hdware_info->hdware_mask.user_disabled_count--;
2099 if (devp->dev_type == -1)
2100 return;
2101 z90crypt.hdware_info->type_mask[devp->dev_type].user_disabled_count--;
2102}
2103
2104static int
2105z90crypt_status_write(struct file *file, const char __user *buffer,
2106 unsigned long count, void *data)
2107{
2108 int j, eol;
2109 unsigned char *lbuf, *ptr;
2110 unsigned int local_count;
2111
2112#define LBUFSIZE 1200
2113 lbuf = kmalloc(LBUFSIZE, GFP_KERNEL);
2114 if (!lbuf) {
2115 PRINTK("kmalloc failed!\n");
2116 return 0;
2117 }
2118
2119 if (count <= 0)
2120 return 0;
2121
2122 local_count = UMIN((unsigned int)count, LBUFSIZE-1);
2123
2124 if (copy_from_user(lbuf, buffer, local_count) != 0) {
2125 kfree(lbuf);
2126 return -EFAULT;
2127 }
2128
2129 lbuf[local_count] = '\0';
2130
2131 ptr = strstr(lbuf, "Online devices");
2132 if (ptr == 0) {
2133 PRINTK("Unable to parse data (missing \"Online devices\")\n");
2134 kfree(lbuf);
2135 return count;
2136 }
2137
2138 ptr = strstr(ptr, "\n");
2139 if (ptr == 0) {
2140 PRINTK("Unable to parse data (missing newline after \"Online devices\")\n");
2141 kfree(lbuf);
2142 return count;
2143 }
2144 ptr++;
2145
2146 if (strstr(ptr, "Waiting work element counts") == NULL) {
2147 PRINTK("Unable to parse data (missing \"Waiting work element counts\")\n");
2148 kfree(lbuf);
2149 return count;
2150 }
2151
2152 j = 0;
2153 eol = 0;
2154 while ((j < 64) && (*ptr != '\0')) {
2155 switch (*ptr) {
2156 case '\t':
2157 case ' ':
2158 break;
2159 case '\n':
2160 default:
2161 eol = 1;
2162 break;
2163 case '0': // no device
2164 case '1': // PCICA
2165 case '2': // PCICC
2166 case '3': // PCIXCC_MCL2
2167 case '4': // PCIXCC_MCL3
2168 case '5': // CEX2C
2169 case '6': // CEX2A
2170 j++;
2171 break;
2172 case 'd':
2173 case 'D':
2174 disable_card(j);
2175 j++;
2176 break;
2177 case 'e':
2178 case 'E':
2179 enable_card(j);
2180 j++;
2181 break;
2182 }
2183 if (eol)
2184 break;
2185 ptr++;
2186 }
2187
2188 kfree(lbuf);
2189 return count;
2190}
2191
2192/**
2193 * Functions that run under a timer, with no process id
2194 *
2195 * The task functions:
2196 * z90crypt_reader_task
2197 * helper_send_work
2198 * helper_handle_work_element
2199 * helper_receive_rc
2200 * z90crypt_config_task
2201 * z90crypt_cleanup_task
2202 *
2203 * Helper functions:
2204 * z90crypt_schedule_reader_timer
2205 * z90crypt_schedule_reader_task
2206 * z90crypt_schedule_config_task
2207 * z90crypt_schedule_cleanup_task
2208 */
2209static inline int
2210receive_from_crypto_device(int index, unsigned char *psmid, int *buff_len_p,
2211 unsigned char *buff, unsigned char __user **dest_p_p)
2212{
2213 int dv, rv;
2214 struct device *dev_ptr;
2215 struct caller *caller_p;
2216 struct ica_rsa_modexpo *icaMsg_p;
2217 struct list_head *ptr, *tptr;
2218
2219 memcpy(psmid, NULL_psmid, sizeof(NULL_psmid));
2220
2221 if (z90crypt.terminating)
2222 return REC_FATAL_ERROR;
2223
2224 caller_p = 0;
2225 dev_ptr = z90crypt.device_p[index];
2226 rv = 0;
2227 do {
2228 if (!dev_ptr || dev_ptr->disabled) {
2229 rv = REC_NO_WORK; // a disabled device can't return work
2230 break;
2231 }
2232 if (dev_ptr->dev_self_x != index) {
2233 PRINTKC("Corrupt dev ptr\n");
2234 z90crypt.terminating = 1;
2235 rv = REC_FATAL_ERROR;
2236 break;
2237 }
2238 if (!dev_ptr->dev_resp_l || !dev_ptr->dev_resp_p) {
2239 dv = DEV_REC_EXCEPTION;
2240 PRINTK("dev_resp_l = %d, dev_resp_p = %p\n",
2241 dev_ptr->dev_resp_l, dev_ptr->dev_resp_p);
2242 } else {
2243 PDEBUG("Dequeue called for device %d\n", index);
2244 dv = receive_from_AP(index, z90crypt.cdx,
2245 dev_ptr->dev_resp_l,
2246 dev_ptr->dev_resp_p, psmid);
2247 }
2248 switch (dv) {
2249 case DEV_REC_EXCEPTION:
2250 rv = REC_FATAL_ERROR;
2251 z90crypt.terminating = 1;
2252 PRINTKC("Exception in receive from device %d\n",
2253 index);
2254 break;
2255 case DEV_ONLINE:
2256 rv = 0;
2257 break;
2258 case DEV_EMPTY:
2259 rv = REC_EMPTY;
2260 break;
2261 case DEV_NO_WORK:
2262 rv = REC_NO_WORK;
2263 break;
2264 case DEV_BAD_MESSAGE:
2265 case DEV_GONE:
2266 case REC_HARDWAR_ERR:
2267 default:
2268 rv = REC_NO_RESPONSE;
2269 break;
2270 }
2271 if (rv)
2272 break;
2273 if (dev_ptr->dev_caller_count <= 0) {
2274 rv = REC_USER_GONE;
2275 break;
2276 }
2277
2278 list_for_each_safe(ptr, tptr, &dev_ptr->dev_caller_list) {
2279 caller_p = list_entry(ptr, struct caller, caller_liste);
2280 if (!memcmp(caller_p->caller_id, psmid,
2281 sizeof(caller_p->caller_id))) {
2282 if (!list_empty(&caller_p->caller_liste)) {
2283 list_del_init(ptr);
2284 dev_ptr->dev_caller_count--;
2285 break;
2286 }
2287 }
2288 caller_p = 0;
2289 }
2290 if (!caller_p) {
2291 PRINTKW("Unable to locate PSMID %02X%02X%02X%02X%02X"
2292 "%02X%02X%02X in device list\n",
2293 psmid[0], psmid[1], psmid[2], psmid[3],
2294 psmid[4], psmid[5], psmid[6], psmid[7]);
2295 rv = REC_USER_GONE;
2296 break;
2297 }
2298
2299 PDEBUG("caller_p after successful receive: %p\n", caller_p);
2300 rv = convert_response(dev_ptr->dev_resp_p,
2301 caller_p->caller_buf_p, buff_len_p, buff);
2302 switch (rv) {
2303 case REC_USE_PCICA:
2304 break;
2305 case REC_OPERAND_INV:
2306 case REC_OPERAND_SIZE:
2307 case REC_EVEN_MOD:
2308 case REC_INVALID_PAD:
2309 PDEBUG("device %d: 'user error' %d\n", index, rv);
2310 break;
2311 case WRONG_DEVICE_TYPE:
2312 case REC_HARDWAR_ERR:
2313 case REC_BAD_MESSAGE:
2314 PRINTKW("device %d: hardware error %d\n", index, rv);
2315 rv = REC_NO_RESPONSE;
2316 break;
2317 default:
2318 PDEBUG("device %d: rv = %d\n", index, rv);
2319 break;
2320 }
2321 } while (0);
2322
2323 switch (rv) {
2324 case 0:
2325 PDEBUG("Successful receive from device %d\n", index);
2326 icaMsg_p = (struct ica_rsa_modexpo *)caller_p->caller_buf_p;
2327 *dest_p_p = icaMsg_p->outputdata;
2328 if (*buff_len_p == 0)
2329 PRINTK("Zero *buff_len_p\n");
2330 break;
2331 case REC_NO_RESPONSE:
2332 PRINTKW("Removing device %d from availability\n", index);
2333 remove_device(dev_ptr);
2334 break;
2335 }
2336
2337 if (caller_p)
2338 unbuild_caller(dev_ptr, caller_p);
2339
2340 return rv;
2341}
2342
2343static inline void
2344helper_send_work(int index)
2345{
2346 struct work_element *rq_p;
2347 int rv;
2348
2349 if (list_empty(&request_list))
2350 return;
2351 requestq_count--;
2352 rq_p = list_entry(request_list.next, struct work_element, liste);
2353 list_del_init(&rq_p->liste);
2354 rq_p->audit[1] |= FP_REMREQUEST;
2355 if (rq_p->devtype == SHRT2DEVPTR(index)->dev_type) {
2356 rq_p->devindex = SHRT2LONG(index);
2357 rv = send_to_crypto_device(rq_p);
2358 if (rv == 0) {
2359 rq_p->requestsent = jiffies;
2360 rq_p->audit[0] |= FP_SENT;
2361 list_add_tail(&rq_p->liste, &pending_list);
2362 ++pendingq_count;
2363 rq_p->audit[0] |= FP_PENDING;
2364 } else {
2365 switch (rv) {
2366 case REC_OPERAND_INV:
2367 case REC_OPERAND_SIZE:
2368 case REC_EVEN_MOD:
2369 case REC_INVALID_PAD:
2370 rq_p->retcode = -EINVAL;
2371 break;
2372 case SEN_NOT_AVAIL:
2373 case SEN_RETRY:
2374 case REC_NO_RESPONSE:
2375 default:
2376 if (z90crypt.mask.st_count > 1)
2377 rq_p->retcode =
2378 -ERESTARTSYS;
2379 else
2380 rq_p->retcode = -ENODEV;
2381 break;
2382 }
2383 rq_p->status[0] |= STAT_FAILED;
2384 rq_p->audit[1] |= FP_AWAKENING;
2385 atomic_set(&rq_p->alarmrung, 1);
2386 wake_up(&rq_p->waitq);
2387 }
2388 } else {
2389 if (z90crypt.mask.st_count > 1)
2390 rq_p->retcode = -ERESTARTSYS;
2391 else
2392 rq_p->retcode = -ENODEV;
2393 rq_p->status[0] |= STAT_FAILED;
2394 rq_p->audit[1] |= FP_AWAKENING;
2395 atomic_set(&rq_p->alarmrung, 1);
2396 wake_up(&rq_p->waitq);
2397 }
2398}
2399
2400static inline void
2401helper_handle_work_element(int index, unsigned char psmid[8], int rc,
2402 int buff_len, unsigned char *buff,
2403 unsigned char __user *resp_addr)
2404{
2405 struct work_element *pq_p;
2406 struct list_head *lptr, *tptr;
2407
2408 pq_p = 0;
2409 list_for_each_safe(lptr, tptr, &pending_list) {
2410 pq_p = list_entry(lptr, struct work_element, liste);
2411 if (!memcmp(pq_p->caller_id, psmid, sizeof(pq_p->caller_id))) {
2412 list_del_init(lptr);
2413 pendingq_count--;
2414 pq_p->audit[1] |= FP_NOTPENDING;
2415 break;
2416 }
2417 pq_p = 0;
2418 }
2419
2420 if (!pq_p) {
2421 PRINTK("device %d has work but no caller exists on pending Q\n",
2422 SHRT2LONG(index));
2423 return;
2424 }
2425
2426 switch (rc) {
2427 case 0:
2428 pq_p->resp_buff_size = buff_len;
2429 pq_p->audit[1] |= FP_RESPSIZESET;
2430 if (buff_len) {
2431 pq_p->resp_addr = resp_addr;
2432 pq_p->audit[1] |= FP_RESPADDRCOPIED;
2433 memcpy(pq_p->resp_buff, buff, buff_len);
2434 pq_p->audit[1] |= FP_RESPBUFFCOPIED;
2435 }
2436 break;
2437 case REC_OPERAND_INV:
2438 case REC_OPERAND_SIZE:
2439 case REC_EVEN_MOD:
2440 case REC_INVALID_PAD:
2441 PDEBUG("-EINVAL after application error %d\n", rc);
2442 pq_p->retcode = -EINVAL;
2443 pq_p->status[0] |= STAT_FAILED;
2444 break;
2445 case REC_USE_PCICA:
2446 pq_p->retcode = -ERESTARTSYS;
2447 pq_p->status[0] |= STAT_FAILED;
2448 break;
2449 case REC_NO_RESPONSE:
2450 default:
2451 if (z90crypt.mask.st_count > 1)
2452 pq_p->retcode = -ERESTARTSYS;
2453 else
2454 pq_p->retcode = -ENODEV;
2455 pq_p->status[0] |= STAT_FAILED;
2456 break;
2457 }
2458 if ((pq_p->status[0] != STAT_FAILED) || (pq_p->retcode != -ERELEASED)) {
2459 pq_p->audit[1] |= FP_AWAKENING;
2460 atomic_set(&pq_p->alarmrung, 1);
2461 wake_up(&pq_p->waitq);
2462 }
2463}
2464
2465/**
2466 * return TRUE if the work element should be removed from the queue
2467 */
2468static inline int
2469helper_receive_rc(int index, int *rc_p)
2470{
2471 switch (*rc_p) {
2472 case 0:
2473 case REC_OPERAND_INV:
2474 case REC_OPERAND_SIZE:
2475 case REC_EVEN_MOD:
2476 case REC_INVALID_PAD:
2477 case REC_USE_PCICA:
2478 break;
2479
2480 case REC_BUSY:
2481 case REC_NO_WORK:
2482 case REC_EMPTY:
2483 case REC_RETRY_DEV:
2484 case REC_FATAL_ERROR:
2485 return 0;
2486
2487 case REC_NO_RESPONSE:
2488 break;
2489
2490 default:
2491 PRINTK("rc %d, device %d converted to REC_NO_RESPONSE\n",
2492 *rc_p, SHRT2LONG(index));
2493 *rc_p = REC_NO_RESPONSE;
2494 break;
2495 }
2496 return 1;
2497}
2498
2499static inline void
2500z90crypt_schedule_reader_timer(void)
2501{
2502 if (timer_pending(&reader_timer))
2503 return;
2504 if (mod_timer(&reader_timer, jiffies+(READERTIME*HZ/1000)) != 0)
2505 PRINTK("Timer pending while modifying reader timer\n");
2506}
2507
2508static void
2509z90crypt_reader_task(unsigned long ptr)
2510{
2511 int workavail, index, rc, buff_len;
2512 unsigned char psmid[8];
2513 unsigned char __user *resp_addr;
2514 static unsigned char buff[1024];
2515
2516 /**
2517 * we use workavail = 2 to ensure 2 passes with nothing dequeued before
2518 * exiting the loop. If (pendingq_count+requestq_count) == 0 after the
2519 * loop, there is no work remaining on the queues.
2520 */
2521 resp_addr = 0;
2522 workavail = 2;
2523 buff_len = 0;
2524 while (workavail) {
2525 workavail--;
2526 rc = 0;
2527 spin_lock_irq(&queuespinlock);
2528 memset(buff, 0x00, sizeof(buff));
2529
2530 /* Dequeue once from each device in round robin. */
2531 for (index = 0; index < z90crypt.mask.st_count; index++) {
2532 PDEBUG("About to receive.\n");
2533 rc = receive_from_crypto_device(SHRT2LONG(index),
2534 psmid,
2535 &buff_len,
2536 buff,
2537 &resp_addr);
2538 PDEBUG("Dequeued: rc = %d.\n", rc);
2539
2540 if (helper_receive_rc(index, &rc)) {
2541 if (rc != REC_NO_RESPONSE) {
2542 helper_send_work(index);
2543 workavail = 2;
2544 }
2545
2546 helper_handle_work_element(index, psmid, rc,
2547 buff_len, buff,
2548 resp_addr);
2549 }
2550
2551 if (rc == REC_FATAL_ERROR)
2552 PRINTKW("REC_FATAL_ERROR from device %d!\n",
2553 SHRT2LONG(index));
2554 }
2555 spin_unlock_irq(&queuespinlock);
2556 }
2557
2558 if (pendingq_count + requestq_count)
2559 z90crypt_schedule_reader_timer();
2560}
2561
2562static inline void
2563z90crypt_schedule_config_task(unsigned int expiration)
2564{
2565 if (timer_pending(&config_timer))
2566 return;
2567 if (mod_timer(&config_timer, jiffies+(expiration*HZ)) != 0)
2568 PRINTK("Timer pending while modifying config timer\n");
2569}
2570
2571static void
2572z90crypt_config_task(unsigned long ptr)
2573{
2574 int rc;
2575
2576 PDEBUG("jiffies %ld\n", jiffies);
2577
2578 if ((rc = refresh_z90crypt(&z90crypt.cdx)))
2579 PRINTK("Error %d detected in refresh_z90crypt.\n", rc);
2580 /* If return was fatal, don't bother reconfiguring */
2581 if ((rc != TSQ_FATAL_ERROR) && (rc != RSQ_FATAL_ERROR))
2582 z90crypt_schedule_config_task(CONFIGTIME);
2583}
2584
2585static inline void
2586z90crypt_schedule_cleanup_task(void)
2587{
2588 if (timer_pending(&cleanup_timer))
2589 return;
2590 if (mod_timer(&cleanup_timer, jiffies+(CLEANUPTIME*HZ)) != 0)
2591 PRINTK("Timer pending while modifying cleanup timer\n");
2592}
2593
2594static inline void
2595helper_drain_queues(void)
2596{
2597 struct work_element *pq_p;
2598 struct list_head *lptr, *tptr;
2599
2600 list_for_each_safe(lptr, tptr, &pending_list) {
2601 pq_p = list_entry(lptr, struct work_element, liste);
2602 pq_p->retcode = -ENODEV;
2603 pq_p->status[0] |= STAT_FAILED;
2604 unbuild_caller(LONG2DEVPTR(pq_p->devindex),
2605 (struct caller *)pq_p->requestptr);
2606 list_del_init(lptr);
2607 pendingq_count--;
2608 pq_p->audit[1] |= FP_NOTPENDING;
2609 pq_p->audit[1] |= FP_AWAKENING;
2610 atomic_set(&pq_p->alarmrung, 1);
2611 wake_up(&pq_p->waitq);
2612 }
2613
2614 list_for_each_safe(lptr, tptr, &request_list) {
2615 pq_p = list_entry(lptr, struct work_element, liste);
2616 pq_p->retcode = -ENODEV;
2617 pq_p->status[0] |= STAT_FAILED;
2618 list_del_init(lptr);
2619 requestq_count--;
2620 pq_p->audit[1] |= FP_REMREQUEST;
2621 pq_p->audit[1] |= FP_AWAKENING;
2622 atomic_set(&pq_p->alarmrung, 1);
2623 wake_up(&pq_p->waitq);
2624 }
2625}
2626
2627static inline void
2628helper_timeout_requests(void)
2629{
2630 struct work_element *pq_p;
2631 struct list_head *lptr, *tptr;
2632 long timelimit;
2633
2634 timelimit = jiffies - (CLEANUPTIME * HZ);
2635 /* The list is in strict chronological order */
2636 list_for_each_safe(lptr, tptr, &pending_list) {
2637 pq_p = list_entry(lptr, struct work_element, liste);
2638 if (pq_p->requestsent >= timelimit)
2639 break;
2640 PRINTKW("Purging(PQ) PSMID %02X%02X%02X%02X%02X%02X%02X%02X\n",
2641 ((struct caller *)pq_p->requestptr)->caller_id[0],
2642 ((struct caller *)pq_p->requestptr)->caller_id[1],
2643 ((struct caller *)pq_p->requestptr)->caller_id[2],
2644 ((struct caller *)pq_p->requestptr)->caller_id[3],
2645 ((struct caller *)pq_p->requestptr)->caller_id[4],
2646 ((struct caller *)pq_p->requestptr)->caller_id[5],
2647 ((struct caller *)pq_p->requestptr)->caller_id[6],
2648 ((struct caller *)pq_p->requestptr)->caller_id[7]);
2649 pq_p->retcode = -ETIMEOUT;
2650 pq_p->status[0] |= STAT_FAILED;
2651 /* get this off any caller queue it may be on */
2652 unbuild_caller(LONG2DEVPTR(pq_p->devindex),
2653 (struct caller *) pq_p->requestptr);
2654 list_del_init(lptr);
2655 pendingq_count--;
2656 pq_p->audit[1] |= FP_TIMEDOUT;
2657 pq_p->audit[1] |= FP_NOTPENDING;
2658 pq_p->audit[1] |= FP_AWAKENING;
2659 atomic_set(&pq_p->alarmrung, 1);
2660 wake_up(&pq_p->waitq);
2661 }
2662
2663 /**
2664 * If pending count is zero, items left on the request queue may
2665 * never be processed.
2666 */
2667 if (pendingq_count <= 0) {
2668 list_for_each_safe(lptr, tptr, &request_list) {
2669 pq_p = list_entry(lptr, struct work_element, liste);
2670 if (pq_p->requestsent >= timelimit)
2671 break;
2672 PRINTKW("Purging(RQ) PSMID %02X%02X%02X%02X%02X%02X%02X%02X\n",
2673 ((struct caller *)pq_p->requestptr)->caller_id[0],
2674 ((struct caller *)pq_p->requestptr)->caller_id[1],
2675 ((struct caller *)pq_p->requestptr)->caller_id[2],
2676 ((struct caller *)pq_p->requestptr)->caller_id[3],
2677 ((struct caller *)pq_p->requestptr)->caller_id[4],
2678 ((struct caller *)pq_p->requestptr)->caller_id[5],
2679 ((struct caller *)pq_p->requestptr)->caller_id[6],
2680 ((struct caller *)pq_p->requestptr)->caller_id[7]);
2681 pq_p->retcode = -ETIMEOUT;
2682 pq_p->status[0] |= STAT_FAILED;
2683 list_del_init(lptr);
2684 requestq_count--;
2685 pq_p->audit[1] |= FP_TIMEDOUT;
2686 pq_p->audit[1] |= FP_REMREQUEST;
2687 pq_p->audit[1] |= FP_AWAKENING;
2688 atomic_set(&pq_p->alarmrung, 1);
2689 wake_up(&pq_p->waitq);
2690 }
2691 }
2692}
2693
2694static void
2695z90crypt_cleanup_task(unsigned long ptr)
2696{
2697 PDEBUG("jiffies %ld\n", jiffies);
2698 spin_lock_irq(&queuespinlock);
2699 if (z90crypt.mask.st_count <= 0) // no devices!
2700 helper_drain_queues();
2701 else
2702 helper_timeout_requests();
2703 spin_unlock_irq(&queuespinlock);
2704 z90crypt_schedule_cleanup_task();
2705}
2706
2707static void
2708z90crypt_schedule_reader_task(unsigned long ptr)
2709{
2710 tasklet_schedule(&reader_tasklet);
2711}
2712
2713/**
2714 * Lowlevel Functions:
2715 *
2716 * create_z90crypt: creates and initializes basic data structures
2717 * refresh_z90crypt: re-initializes basic data structures
2718 * find_crypto_devices: returns a count and mask of hardware status
2719 * create_crypto_device: builds the descriptor for a device
2720 * destroy_crypto_device: unallocates the descriptor for a device
2721 * destroy_z90crypt: drains all work, unallocates structs
2722 */
2723
2724/**
2725 * build the z90crypt root structure using the given domain index
2726 */
2727static int
2728create_z90crypt(int *cdx_p)
2729{
2730 struct hdware_block *hdware_blk_p;
2731
2732 memset(&z90crypt, 0x00, sizeof(struct z90crypt));
2733 z90crypt.domain_established = 0;
2734 z90crypt.len = sizeof(struct z90crypt);
2735 z90crypt.max_count = Z90CRYPT_NUM_DEVS;
2736 z90crypt.cdx = *cdx_p;
2737
2738 hdware_blk_p = kzalloc(sizeof(struct hdware_block), GFP_ATOMIC);
2739 if (!hdware_blk_p) {
2740 PDEBUG("kmalloc for hardware block failed\n");
2741 return ENOMEM;
2742 }
2743 z90crypt.hdware_info = hdware_blk_p;
2744
2745 return 0;
2746}
2747
2748static inline int
2749helper_scan_devices(int cdx_array[16], int *cdx_p, int *correct_cdx_found)
2750{
2751 enum hdstat hd_stat;
2752 int q_depth, dev_type;
2753 int indx, chkdom, numdomains;
2754
2755 q_depth = dev_type = numdomains = 0;
2756 for (chkdom = 0; chkdom <= 15; cdx_array[chkdom++] = -1);
2757 for (indx = 0; indx < z90crypt.max_count; indx++) {
2758 hd_stat = HD_NOT_THERE;
2759 numdomains = 0;
2760 for (chkdom = 0; chkdom <= 15; chkdom++) {
2761 hd_stat = query_online(indx, chkdom, MAX_RESET,
2762 &q_depth, &dev_type);
2763 if (hd_stat == HD_TSQ_EXCEPTION) {
2764 z90crypt.terminating = 1;
2765 PRINTKC("exception taken!\n");
2766 break;
2767 }
2768 if (hd_stat == HD_ONLINE) {
2769 cdx_array[numdomains++] = chkdom;
2770 if (*cdx_p == chkdom) {
2771 *correct_cdx_found = 1;
2772 break;
2773 }
2774 }
2775 }
2776 if ((*correct_cdx_found == 1) || (numdomains != 0))
2777 break;
2778 if (z90crypt.terminating)
2779 break;
2780 }
2781 return numdomains;
2782}
2783
2784static inline int
2785probe_crypto_domain(int *cdx_p)
2786{
2787 int cdx_array[16];
2788 char cdx_array_text[53], temp[5];
2789 int correct_cdx_found, numdomains;
2790
2791 correct_cdx_found = 0;
2792 numdomains = helper_scan_devices(cdx_array, cdx_p, &correct_cdx_found);
2793
2794 if (z90crypt.terminating)
2795 return TSQ_FATAL_ERROR;
2796
2797 if (correct_cdx_found)
2798 return 0;
2799
2800 if (numdomains == 0) {
2801 PRINTKW("Unable to find crypto domain: No devices found\n");
2802 return Z90C_NO_DEVICES;
2803 }
2804
2805 if (numdomains == 1) {
2806 if (*cdx_p == -1) {
2807 *cdx_p = cdx_array[0];
2808 return 0;
2809 }
2810 PRINTKW("incorrect domain: specified = %d, found = %d\n",
2811 *cdx_p, cdx_array[0]);
2812 return Z90C_INCORRECT_DOMAIN;
2813 }
2814
2815 numdomains--;
2816 sprintf(cdx_array_text, "%d", cdx_array[numdomains]);
2817 while (numdomains) {
2818 numdomains--;
2819 sprintf(temp, ", %d", cdx_array[numdomains]);
2820 strcat(cdx_array_text, temp);
2821 }
2822
2823 PRINTKW("ambiguous domain detected: specified = %d, found array = %s\n",
2824 *cdx_p, cdx_array_text);
2825 return Z90C_AMBIGUOUS_DOMAIN;
2826}
2827
2828static int
2829refresh_z90crypt(int *cdx_p)
2830{
2831 int i, j, indx, rv;
2832 static struct status local_mask;
2833 struct device *devPtr;
2834 unsigned char oldStat, newStat;
2835 int return_unchanged;
2836
2837 if (z90crypt.len != sizeof(z90crypt))
2838 return ENOTINIT;
2839 if (z90crypt.terminating)
2840 return TSQ_FATAL_ERROR;
2841 rv = 0;
2842 if (!z90crypt.hdware_info->hdware_mask.st_count &&
2843 !z90crypt.domain_established) {
2844 rv = probe_crypto_domain(cdx_p);
2845 if (z90crypt.terminating)
2846 return TSQ_FATAL_ERROR;
2847 if (rv == Z90C_NO_DEVICES)
2848 return 0; // try later
2849 if (rv)
2850 return rv;
2851 z90crypt.cdx = *cdx_p;
2852 z90crypt.domain_established = 1;
2853 }
2854 rv = find_crypto_devices(&local_mask);
2855 if (rv) {
2856 PRINTK("find crypto devices returned %d\n", rv);
2857 return rv;
2858 }
2859 if (!memcmp(&local_mask, &z90crypt.hdware_info->hdware_mask,
2860 sizeof(struct status))) {
2861 return_unchanged = 1;
2862 for (i = 0; i < Z90CRYPT_NUM_TYPES; i++) {
2863 /**
2864 * Check for disabled cards. If any device is marked
2865 * disabled, destroy it.
2866 */
2867 for (j = 0;
2868 j < z90crypt.hdware_info->type_mask[i].st_count;
2869 j++) {
2870 indx = z90crypt.hdware_info->type_x_addr[i].
2871 device_index[j];
2872 devPtr = z90crypt.device_p[indx];
2873 if (devPtr && devPtr->disabled) {
2874 local_mask.st_mask[indx] = HD_NOT_THERE;
2875 return_unchanged = 0;
2876 }
2877 }
2878 }
2879 if (return_unchanged == 1)
2880 return 0;
2881 }
2882
2883 spin_lock_irq(&queuespinlock);
2884 for (i = 0; i < z90crypt.max_count; i++) {
2885 oldStat = z90crypt.hdware_info->hdware_mask.st_mask[i];
2886 newStat = local_mask.st_mask[i];
2887 if ((oldStat == HD_ONLINE) && (newStat != HD_ONLINE))
2888 destroy_crypto_device(i);
2889 else if ((oldStat != HD_ONLINE) && (newStat == HD_ONLINE)) {
2890 rv = create_crypto_device(i);
2891 if (rv >= REC_FATAL_ERROR)
2892 return rv;
2893 if (rv != 0) {
2894 local_mask.st_mask[i] = HD_NOT_THERE;
2895 local_mask.st_count--;
2896 }
2897 }
2898 }
2899 memcpy(z90crypt.hdware_info->hdware_mask.st_mask, local_mask.st_mask,
2900 sizeof(local_mask.st_mask));
2901 z90crypt.hdware_info->hdware_mask.st_count = local_mask.st_count;
2902 z90crypt.hdware_info->hdware_mask.disabled_count =
2903 local_mask.disabled_count;
2904 refresh_index_array(&z90crypt.mask, &z90crypt.overall_device_x);
2905 for (i = 0; i < Z90CRYPT_NUM_TYPES; i++)
2906 refresh_index_array(&(z90crypt.hdware_info->type_mask[i]),
2907 &(z90crypt.hdware_info->type_x_addr[i]));
2908 spin_unlock_irq(&queuespinlock);
2909
2910 return rv;
2911}
2912
2913static int
2914find_crypto_devices(struct status *deviceMask)
2915{
2916 int i, q_depth, dev_type;
2917 enum hdstat hd_stat;
2918
2919 deviceMask->st_count = 0;
2920 deviceMask->disabled_count = 0;
2921 deviceMask->user_disabled_count = 0;
2922
2923 for (i = 0; i < z90crypt.max_count; i++) {
2924 hd_stat = query_online(i, z90crypt.cdx, MAX_RESET, &q_depth,
2925 &dev_type);
2926 if (hd_stat == HD_TSQ_EXCEPTION) {
2927 z90crypt.terminating = 1;
2928 PRINTKC("Exception during probe for crypto devices\n");
2929 return TSQ_FATAL_ERROR;
2930 }
2931 deviceMask->st_mask[i] = hd_stat;
2932 if (hd_stat == HD_ONLINE) {
2933 PDEBUG("Got an online crypto!: %d\n", i);
2934 PDEBUG("Got a queue depth of %d\n", q_depth);
2935 PDEBUG("Got a device type of %d\n", dev_type);
2936 if (q_depth <= 0)
2937 return TSQ_FATAL_ERROR;
2938 deviceMask->st_count++;
2939 z90crypt.q_depth_array[i] = q_depth;
2940 z90crypt.dev_type_array[i] = dev_type;
2941 }
2942 }
2943
2944 return 0;
2945}
2946
2947static int
2948refresh_index_array(struct status *status_str, struct device_x *index_array)
2949{
2950 int i, count;
2951 enum devstat stat;
2952
2953 i = -1;
2954 count = 0;
2955 do {
2956 stat = status_str->st_mask[++i];
2957 if (stat == DEV_ONLINE)
2958 index_array->device_index[count++] = i;
2959 } while ((i < Z90CRYPT_NUM_DEVS) && (count < status_str->st_count));
2960
2961 return count;
2962}
2963
2964static int
2965create_crypto_device(int index)
2966{
2967 int rv, devstat, total_size;
2968 struct device *dev_ptr;
2969 struct status *type_str_p;
2970 int deviceType;
2971
2972 dev_ptr = z90crypt.device_p[index];
2973 if (!dev_ptr) {
2974 total_size = sizeof(struct device) +
2975 z90crypt.q_depth_array[index] * sizeof(int);
2976
2977 dev_ptr = kzalloc(total_size, GFP_ATOMIC);
2978 if (!dev_ptr) {
2979 PRINTK("kmalloc device %d failed\n", index);
2980 return ENOMEM;
2981 }
2982 dev_ptr->dev_resp_p = kmalloc(MAX_RESPONSE_SIZE, GFP_ATOMIC);
2983 if (!dev_ptr->dev_resp_p) {
2984 kfree(dev_ptr);
2985 PRINTK("kmalloc device %d rec buffer failed\n", index);
2986 return ENOMEM;
2987 }
2988 dev_ptr->dev_resp_l = MAX_RESPONSE_SIZE;
2989 INIT_LIST_HEAD(&(dev_ptr->dev_caller_list));
2990 }
2991
2992 devstat = reset_device(index, z90crypt.cdx, MAX_RESET);
2993 if (devstat == DEV_RSQ_EXCEPTION) {
2994 PRINTK("exception during reset device %d\n", index);
2995 kfree(dev_ptr->dev_resp_p);
2996 kfree(dev_ptr);
2997 return RSQ_FATAL_ERROR;
2998 }
2999 if (devstat == DEV_ONLINE) {
3000 dev_ptr->dev_self_x = index;
3001 dev_ptr->dev_type = z90crypt.dev_type_array[index];
3002 if (dev_ptr->dev_type == NILDEV) {
3003 rv = probe_device_type(dev_ptr);
3004 if (rv) {
3005 PRINTK("rv = %d from probe_device_type %d\n",
3006 rv, index);
3007 kfree(dev_ptr->dev_resp_p);
3008 kfree(dev_ptr);
3009 return rv;
3010 }
3011 }
3012 if (dev_ptr->dev_type == PCIXCC_UNK) {
3013 rv = probe_PCIXCC_type(dev_ptr);
3014 if (rv) {
3015 PRINTK("rv = %d from probe_PCIXCC_type %d\n",
3016 rv, index);
3017 kfree(dev_ptr->dev_resp_p);
3018 kfree(dev_ptr);
3019 return rv;
3020 }
3021 }
3022 deviceType = dev_ptr->dev_type;
3023 z90crypt.dev_type_array[index] = deviceType;
3024 if (deviceType == PCICA)
3025 z90crypt.hdware_info->device_type_array[index] = 1;
3026 else if (deviceType == PCICC)
3027 z90crypt.hdware_info->device_type_array[index] = 2;
3028 else if (deviceType == PCIXCC_MCL2)
3029 z90crypt.hdware_info->device_type_array[index] = 3;
3030 else if (deviceType == PCIXCC_MCL3)
3031 z90crypt.hdware_info->device_type_array[index] = 4;
3032 else if (deviceType == CEX2C)
3033 z90crypt.hdware_info->device_type_array[index] = 5;
3034 else if (deviceType == CEX2A)
3035 z90crypt.hdware_info->device_type_array[index] = 6;
3036 else // No idea how this would happen.
3037 z90crypt.hdware_info->device_type_array[index] = -1;
3038 }
3039
3040 /**
3041 * 'q_depth' returned by the hardware is one less than
3042 * the actual depth
3043 */
3044 dev_ptr->dev_q_depth = z90crypt.q_depth_array[index];
3045 dev_ptr->dev_type = z90crypt.dev_type_array[index];
3046 dev_ptr->dev_stat = devstat;
3047 dev_ptr->disabled = 0;
3048 z90crypt.device_p[index] = dev_ptr;
3049
3050 if (devstat == DEV_ONLINE) {
3051 if (z90crypt.mask.st_mask[index] != DEV_ONLINE) {
3052 z90crypt.mask.st_mask[index] = DEV_ONLINE;
3053 z90crypt.mask.st_count++;
3054 }
3055 deviceType = dev_ptr->dev_type;
3056 type_str_p = &z90crypt.hdware_info->type_mask[deviceType];
3057 if (type_str_p->st_mask[index] != DEV_ONLINE) {
3058 type_str_p->st_mask[index] = DEV_ONLINE;
3059 type_str_p->st_count++;
3060 }
3061 }
3062
3063 return 0;
3064}
3065
3066static int
3067destroy_crypto_device(int index)
3068{
3069 struct device *dev_ptr;
3070 int t, disabledFlag;
3071
3072 dev_ptr = z90crypt.device_p[index];
3073
3074 /* remember device type; get rid of device struct */
3075 if (dev_ptr) {
3076 disabledFlag = dev_ptr->disabled;
3077 t = dev_ptr->dev_type;
3078 kfree(dev_ptr->dev_resp_p);
3079 kfree(dev_ptr);
3080 } else {
3081 disabledFlag = 0;
3082 t = -1;
3083 }
3084 z90crypt.device_p[index] = 0;
3085
3086 /* if the type is valid, remove the device from the type_mask */
3087 if ((t != -1) && z90crypt.hdware_info->type_mask[t].st_mask[index]) {
3088 z90crypt.hdware_info->type_mask[t].st_mask[index] = 0x00;
3089 z90crypt.hdware_info->type_mask[t].st_count--;
3090 if (disabledFlag == 1)
3091 z90crypt.hdware_info->type_mask[t].disabled_count--;
3092 }
3093 if (z90crypt.mask.st_mask[index] != DEV_GONE) {
3094 z90crypt.mask.st_mask[index] = DEV_GONE;
3095 z90crypt.mask.st_count--;
3096 }
3097 z90crypt.hdware_info->device_type_array[index] = 0;
3098
3099 return 0;
3100}
3101
3102static void
3103destroy_z90crypt(void)
3104{
3105 int i;
3106
3107 for (i = 0; i < z90crypt.max_count; i++)
3108 if (z90crypt.device_p[i])
3109 destroy_crypto_device(i);
3110 kfree(z90crypt.hdware_info);
3111 memset((void *)&z90crypt, 0, sizeof(z90crypt));
3112}
3113
3114static unsigned char static_testmsg[384] = {
31150x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x00,0x06,0x00,0x00,
31160x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,
31170x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x43,0x43,
31180x41,0x2d,0x41,0x50,0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,0x00,0x00,0x00,0x00,
31190x50,0x4b,0x00,0x00,0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
31200x00,0x00,0x00,0x00,0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
31210x00,0x00,0x00,0x00,0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x32,
31220x01,0x00,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
31230xb8,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
31240x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
31250x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
31260x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
31270x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x43,0x53,0x46,
31280x20,0x20,0x20,0x20,0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,0x2d,0x31,0x2e,0x32,
31290x37,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
31300x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
31310x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
31320x77,0x88,0x99,0x00,0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,0x88,0x1e,0x00,0x00,
31330x57,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,0x03,0x02,0x00,0x00,
31340x40,0x01,0x00,0x01,0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,0xf6,0xd2,0x7b,0x58,
31350x4b,0xf9,0x28,0x68,0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,0x63,0x42,0xef,0xf8,
31360xfd,0xa4,0xf8,0xb0,0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,0x53,0x8c,0x6f,0x4e,
31370x72,0x8f,0x6c,0x04,0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,0xf7,0xdd,0xfd,0x4f,
31380x11,0x36,0x95,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
3139};
3140
3141static int
3142probe_device_type(struct device *devPtr)
3143{
3144 int rv, dv, i, index, length;
3145 unsigned char psmid[8];
3146 static unsigned char loc_testmsg[sizeof(static_testmsg)];
3147
3148 index = devPtr->dev_self_x;
3149 rv = 0;
3150 do {
3151 memcpy(loc_testmsg, static_testmsg, sizeof(static_testmsg));
3152 length = sizeof(static_testmsg) - 24;
3153 /* the -24 allows for the header */
3154 dv = send_to_AP(index, z90crypt.cdx, length, loc_testmsg);
3155 if (dv) {
3156 PDEBUG("dv returned by send during probe: %d\n", dv);
3157 if (dv == DEV_SEN_EXCEPTION) {
3158 rv = SEN_FATAL_ERROR;
3159 PRINTKC("exception in send to AP %d\n", index);
3160 break;
3161 }
3162 PDEBUG("return value from send_to_AP: %d\n", rv);
3163 switch (dv) {
3164 case DEV_GONE:
3165 PDEBUG("dev %d not available\n", index);
3166 rv = SEN_NOT_AVAIL;
3167 break;
3168 case DEV_ONLINE:
3169 rv = 0;
3170 break;
3171 case DEV_EMPTY:
3172 rv = SEN_NOT_AVAIL;
3173 break;
3174 case DEV_NO_WORK:
3175 rv = SEN_FATAL_ERROR;
3176 break;
3177 case DEV_BAD_MESSAGE:
3178 rv = SEN_USER_ERROR;
3179 break;
3180 case DEV_QUEUE_FULL:
3181 rv = SEN_QUEUE_FULL;
3182 break;
3183 default:
3184 PRINTK("unknown dv=%d for dev %d\n", dv, index);
3185 rv = SEN_NOT_AVAIL;
3186 break;
3187 }
3188 }
3189
3190 if (rv)
3191 break;
3192
3193 for (i = 0; i < 6; i++) {
3194 mdelay(300);
3195 dv = receive_from_AP(index, z90crypt.cdx,
3196 devPtr->dev_resp_l,
3197 devPtr->dev_resp_p, psmid);
3198 PDEBUG("dv returned by DQ = %d\n", dv);
3199 if (dv == DEV_REC_EXCEPTION) {
3200 rv = REC_FATAL_ERROR;
3201 PRINTKC("exception in dequeue %d\n",
3202 index);
3203 break;
3204 }
3205 switch (dv) {
3206 case DEV_ONLINE:
3207 rv = 0;
3208 break;
3209 case DEV_EMPTY:
3210 rv = REC_EMPTY;
3211 break;
3212 case DEV_NO_WORK:
3213 rv = REC_NO_WORK;
3214 break;
3215 case DEV_BAD_MESSAGE:
3216 case DEV_GONE:
3217 default:
3218 rv = REC_NO_RESPONSE;
3219 break;
3220 }
3221 if ((rv != 0) && (rv != REC_NO_WORK))
3222 break;
3223 if (rv == 0)
3224 break;
3225 }
3226 if (rv)
3227 break;
3228 rv = (devPtr->dev_resp_p[0] == 0x00) &&
3229 (devPtr->dev_resp_p[1] == 0x86);
3230 if (rv)
3231 devPtr->dev_type = PCICC;
3232 else
3233 devPtr->dev_type = PCICA;
3234 rv = 0;
3235 } while (0);
3236 /* In a general error case, the card is not marked online */
3237 return rv;
3238}
3239
3240static unsigned char MCL3_testmsg[] = {
32410x00,0x00,0x00,0x00,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,
32420x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32430x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32440x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32450x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
32460x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
32470x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
32480x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
32490x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32500x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32510x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32520x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32530x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32540x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32550x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32560x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32570x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32580x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32590x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32600x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32610x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
32620x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
32630x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
32640xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
32650x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
32660x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
32670x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
32680x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
32690x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
32700xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
32710xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
32720x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
32730x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
32740xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
32750x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,0xF1,0x3D,0x93,0x53
3276};
3277
3278static int
3279probe_PCIXCC_type(struct device *devPtr)
3280{
3281 int rv, dv, i, index, length;
3282 unsigned char psmid[8];
3283 static unsigned char loc_testmsg[548];
3284 struct CPRBX *cprbx_p;
3285
3286 index = devPtr->dev_self_x;
3287 rv = 0;
3288 do {
3289 memcpy(loc_testmsg, MCL3_testmsg, sizeof(MCL3_testmsg));
3290 length = sizeof(MCL3_testmsg) - 0x0C;
3291 dv = send_to_AP(index, z90crypt.cdx, length, loc_testmsg);
3292 if (dv) {
3293 PDEBUG("dv returned = %d\n", dv);
3294 if (dv == DEV_SEN_EXCEPTION) {
3295 rv = SEN_FATAL_ERROR;
3296 PRINTKC("exception in send to AP %d\n", index);
3297 break;
3298 }
3299 PDEBUG("return value from send_to_AP: %d\n", rv);
3300 switch (dv) {
3301 case DEV_GONE:
3302 PDEBUG("dev %d not available\n", index);
3303 rv = SEN_NOT_AVAIL;
3304 break;
3305 case DEV_ONLINE:
3306 rv = 0;
3307 break;
3308 case DEV_EMPTY:
3309 rv = SEN_NOT_AVAIL;
3310 break;
3311 case DEV_NO_WORK:
3312 rv = SEN_FATAL_ERROR;
3313 break;
3314 case DEV_BAD_MESSAGE:
3315 rv = SEN_USER_ERROR;
3316 break;
3317 case DEV_QUEUE_FULL:
3318 rv = SEN_QUEUE_FULL;
3319 break;
3320 default:
3321 PRINTK("unknown dv=%d for dev %d\n", dv, index);
3322 rv = SEN_NOT_AVAIL;
3323 break;
3324 }
3325 }
3326
3327 if (rv)
3328 break;
3329
3330 for (i = 0; i < 6; i++) {
3331 mdelay(300);
3332 dv = receive_from_AP(index, z90crypt.cdx,
3333 devPtr->dev_resp_l,
3334 devPtr->dev_resp_p, psmid);
3335 PDEBUG("dv returned by DQ = %d\n", dv);
3336 if (dv == DEV_REC_EXCEPTION) {
3337 rv = REC_FATAL_ERROR;
3338 PRINTKC("exception in dequeue %d\n",
3339 index);
3340 break;
3341 }
3342 switch (dv) {
3343 case DEV_ONLINE:
3344 rv = 0;
3345 break;
3346 case DEV_EMPTY:
3347 rv = REC_EMPTY;
3348 break;
3349 case DEV_NO_WORK:
3350 rv = REC_NO_WORK;
3351 break;
3352 case DEV_BAD_MESSAGE:
3353 case DEV_GONE:
3354 default:
3355 rv = REC_NO_RESPONSE;
3356 break;
3357 }
3358 if ((rv != 0) && (rv != REC_NO_WORK))
3359 break;
3360 if (rv == 0)
3361 break;
3362 }
3363 if (rv)
3364 break;
3365 cprbx_p = (struct CPRBX *) (devPtr->dev_resp_p + 48);
3366 if ((cprbx_p->ccp_rtcode == 8) && (cprbx_p->ccp_rscode == 33)) {
3367 devPtr->dev_type = PCIXCC_MCL2;
3368 PDEBUG("device %d is MCL2\n", index);
3369 } else {
3370 devPtr->dev_type = PCIXCC_MCL3;
3371 PDEBUG("device %d is MCL3\n", index);
3372 }
3373 } while (0);
3374 /* In a general error case, the card is not marked online */
3375 return rv;
3376}
3377
3378module_init(z90crypt_init_module);
3379module_exit(z90crypt_cleanup_module);
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
new file mode 100644
index 000000000000..1edc10a7a6f2
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -0,0 +1,1091 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_api.c
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 * Cornelia Huck <cornelia.huck@de.ibm.com>
10 *
11 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
12 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
13 * Ralph Wuerthner <rwuerthn@de.ibm.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/interrupt.h>
33#include <linux/miscdevice.h>
34#include <linux/fs.h>
35#include <linux/proc_fs.h>
36#include <linux/compat.h>
37#include <asm/atomic.h>
38#include <asm/uaccess.h>
39
40#include "zcrypt_api.h"
41
42/**
43 * Module description.
44 */
45MODULE_AUTHOR("IBM Corporation");
46MODULE_DESCRIPTION("Cryptographic Coprocessor interface, "
47 "Copyright 2001, 2006 IBM Corporation");
48MODULE_LICENSE("GPL");
49
50static DEFINE_SPINLOCK(zcrypt_device_lock);
51static LIST_HEAD(zcrypt_device_list);
52static int zcrypt_device_count = 0;
53static atomic_t zcrypt_open_count = ATOMIC_INIT(0);
54
55/**
56 * Device attributes common for all crypto devices.
57 */
58static ssize_t zcrypt_type_show(struct device *dev,
59 struct device_attribute *attr, char *buf)
60{
61 struct zcrypt_device *zdev = to_ap_dev(dev)->private;
62 return snprintf(buf, PAGE_SIZE, "%s\n", zdev->type_string);
63}
64
65static DEVICE_ATTR(type, 0444, zcrypt_type_show, NULL);
66
67static ssize_t zcrypt_online_show(struct device *dev,
68 struct device_attribute *attr, char *buf)
69{
70 struct zcrypt_device *zdev = to_ap_dev(dev)->private;
71 return snprintf(buf, PAGE_SIZE, "%d\n", zdev->online);
72}
73
74static ssize_t zcrypt_online_store(struct device *dev,
75 struct device_attribute *attr,
76 const char *buf, size_t count)
77{
78 struct zcrypt_device *zdev = to_ap_dev(dev)->private;
79 int online;
80
81 if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
82 return -EINVAL;
83 zdev->online = online;
84 if (!online)
85 ap_flush_queue(zdev->ap_dev);
86 return count;
87}
88
89static DEVICE_ATTR(online, 0644, zcrypt_online_show, zcrypt_online_store);
90
91static struct attribute * zcrypt_device_attrs[] = {
92 &dev_attr_type.attr,
93 &dev_attr_online.attr,
94 NULL,
95};
96
97static struct attribute_group zcrypt_device_attr_group = {
98 .attrs = zcrypt_device_attrs,
99};
100
101/**
102 * Move the device towards the head of the device list.
103 * Need to be called while holding the zcrypt device list lock.
104 * Note: cards with speed_rating of 0 are kept at the end of the list.
105 */
106static void __zcrypt_increase_preference(struct zcrypt_device *zdev)
107{
108 struct zcrypt_device *tmp;
109 struct list_head *l;
110
111 if (zdev->speed_rating == 0)
112 return;
113 for (l = zdev->list.prev; l != &zcrypt_device_list; l = l->prev) {
114 tmp = list_entry(l, struct zcrypt_device, list);
115 if ((tmp->request_count + 1) * tmp->speed_rating <=
116 (zdev->request_count + 1) * zdev->speed_rating &&
117 tmp->speed_rating != 0)
118 break;
119 }
120 if (l == zdev->list.prev)
121 return;
122 /* Move zdev behind l */
123 list_del(&zdev->list);
124 list_add(&zdev->list, l);
125}
126
127/**
128 * Move the device towards the tail of the device list.
129 * Need to be called while holding the zcrypt device list lock.
130 * Note: cards with speed_rating of 0 are kept at the end of the list.
131 */
132static void __zcrypt_decrease_preference(struct zcrypt_device *zdev)
133{
134 struct zcrypt_device *tmp;
135 struct list_head *l;
136
137 if (zdev->speed_rating == 0)
138 return;
139 for (l = zdev->list.next; l != &zcrypt_device_list; l = l->next) {
140 tmp = list_entry(l, struct zcrypt_device, list);
141 if ((tmp->request_count + 1) * tmp->speed_rating >
142 (zdev->request_count + 1) * zdev->speed_rating ||
143 tmp->speed_rating == 0)
144 break;
145 }
146 if (l == zdev->list.next)
147 return;
148 /* Move zdev before l */
149 list_del(&zdev->list);
150 list_add_tail(&zdev->list, l);
151}
152
153static void zcrypt_device_release(struct kref *kref)
154{
155 struct zcrypt_device *zdev =
156 container_of(kref, struct zcrypt_device, refcount);
157 zcrypt_device_free(zdev);
158}
159
160void zcrypt_device_get(struct zcrypt_device *zdev)
161{
162 kref_get(&zdev->refcount);
163}
164EXPORT_SYMBOL(zcrypt_device_get);
165
166int zcrypt_device_put(struct zcrypt_device *zdev)
167{
168 return kref_put(&zdev->refcount, zcrypt_device_release);
169}
170EXPORT_SYMBOL(zcrypt_device_put);
171
172struct zcrypt_device *zcrypt_device_alloc(size_t max_response_size)
173{
174 struct zcrypt_device *zdev;
175
176 zdev = kzalloc(sizeof(struct zcrypt_device), GFP_KERNEL);
177 if (!zdev)
178 return NULL;
179 zdev->reply.message = kmalloc(max_response_size, GFP_KERNEL);
180 if (!zdev->reply.message)
181 goto out_free;
182 zdev->reply.length = max_response_size;
183 spin_lock_init(&zdev->lock);
184 INIT_LIST_HEAD(&zdev->list);
185 return zdev;
186
187out_free:
188 kfree(zdev);
189 return NULL;
190}
191EXPORT_SYMBOL(zcrypt_device_alloc);
192
193void zcrypt_device_free(struct zcrypt_device *zdev)
194{
195 kfree(zdev->reply.message);
196 kfree(zdev);
197}
198EXPORT_SYMBOL(zcrypt_device_free);
199
200/**
201 * Register a crypto device.
202 */
203int zcrypt_device_register(struct zcrypt_device *zdev)
204{
205 int rc;
206
207 rc = sysfs_create_group(&zdev->ap_dev->device.kobj,
208 &zcrypt_device_attr_group);
209 if (rc)
210 goto out;
211 get_device(&zdev->ap_dev->device);
212 kref_init(&zdev->refcount);
213 spin_lock_bh(&zcrypt_device_lock);
214 zdev->online = 1; /* New devices are online by default. */
215 list_add_tail(&zdev->list, &zcrypt_device_list);
216 __zcrypt_increase_preference(zdev);
217 zcrypt_device_count++;
218 spin_unlock_bh(&zcrypt_device_lock);
219out:
220 return rc;
221}
222EXPORT_SYMBOL(zcrypt_device_register);
223
224/**
225 * Unregister a crypto device.
226 */
227void zcrypt_device_unregister(struct zcrypt_device *zdev)
228{
229 spin_lock_bh(&zcrypt_device_lock);
230 zcrypt_device_count--;
231 list_del_init(&zdev->list);
232 spin_unlock_bh(&zcrypt_device_lock);
233 sysfs_remove_group(&zdev->ap_dev->device.kobj,
234 &zcrypt_device_attr_group);
235 put_device(&zdev->ap_dev->device);
236 zcrypt_device_put(zdev);
237}
238EXPORT_SYMBOL(zcrypt_device_unregister);
239
240/**
241 * zcrypt_read is not be supported beyond zcrypt 1.3.1
242 */
243static ssize_t zcrypt_read(struct file *filp, char __user *buf,
244 size_t count, loff_t *f_pos)
245{
246 return -EPERM;
247}
248
249/**
250 * Write is is not allowed
251 */
252static ssize_t zcrypt_write(struct file *filp, const char __user *buf,
253 size_t count, loff_t *f_pos)
254{
255 return -EPERM;
256}
257
258/**
259 * Device open/close functions to count number of users.
260 */
261static int zcrypt_open(struct inode *inode, struct file *filp)
262{
263 atomic_inc(&zcrypt_open_count);
264 return 0;
265}
266
267static int zcrypt_release(struct inode *inode, struct file *filp)
268{
269 atomic_dec(&zcrypt_open_count);
270 return 0;
271}
272
273/**
274 * zcrypt ioctls.
275 */
276static long zcrypt_rsa_modexpo(struct ica_rsa_modexpo *mex)
277{
278 struct zcrypt_device *zdev;
279 int rc;
280
281 if (mex->outputdatalength < mex->inputdatalength)
282 return -EINVAL;
283 /**
284 * As long as outputdatalength is big enough, we can set the
285 * outputdatalength equal to the inputdatalength, since that is the
286 * number of bytes we will copy in any case
287 */
288 mex->outputdatalength = mex->inputdatalength;
289
290 spin_lock_bh(&zcrypt_device_lock);
291 list_for_each_entry(zdev, &zcrypt_device_list, list) {
292 if (!zdev->online ||
293 !zdev->ops->rsa_modexpo ||
294 zdev->min_mod_size > mex->inputdatalength ||
295 zdev->max_mod_size < mex->inputdatalength)
296 continue;
297 zcrypt_device_get(zdev);
298 get_device(&zdev->ap_dev->device);
299 zdev->request_count++;
300 __zcrypt_decrease_preference(zdev);
301 spin_unlock_bh(&zcrypt_device_lock);
302 if (try_module_get(zdev->ap_dev->drv->driver.owner)) {
303 rc = zdev->ops->rsa_modexpo(zdev, mex);
304 module_put(zdev->ap_dev->drv->driver.owner);
305 }
306 else
307 rc = -EAGAIN;
308 spin_lock_bh(&zcrypt_device_lock);
309 zdev->request_count--;
310 __zcrypt_increase_preference(zdev);
311 put_device(&zdev->ap_dev->device);
312 zcrypt_device_put(zdev);
313 spin_unlock_bh(&zcrypt_device_lock);
314 return rc;
315 }
316 spin_unlock_bh(&zcrypt_device_lock);
317 return -ENODEV;
318}
319
320static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt)
321{
322 struct zcrypt_device *zdev;
323 unsigned long long z1, z2, z3;
324 int rc, copied;
325
326 if (crt->outputdatalength < crt->inputdatalength ||
327 (crt->inputdatalength & 1))
328 return -EINVAL;
329 /**
330 * As long as outputdatalength is big enough, we can set the
331 * outputdatalength equal to the inputdatalength, since that is the
332 * number of bytes we will copy in any case
333 */
334 crt->outputdatalength = crt->inputdatalength;
335
336 copied = 0;
337 restart:
338 spin_lock_bh(&zcrypt_device_lock);
339 list_for_each_entry(zdev, &zcrypt_device_list, list) {
340 if (!zdev->online ||
341 !zdev->ops->rsa_modexpo_crt ||
342 zdev->min_mod_size > crt->inputdatalength ||
343 zdev->max_mod_size < crt->inputdatalength)
344 continue;
345 if (zdev->short_crt && crt->inputdatalength > 240) {
346 /**
347 * Check inputdata for leading zeros for cards
348 * that can't handle np_prime, bp_key, or
349 * u_mult_inv > 128 bytes.
350 */
351 if (copied == 0) {
352 int len;
353 spin_unlock_bh(&zcrypt_device_lock);
354 /* len is max 256 / 2 - 120 = 8 */
355 len = crt->inputdatalength / 2 - 120;
356 z1 = z2 = z3 = 0;
357 if (copy_from_user(&z1, crt->np_prime, len) ||
358 copy_from_user(&z2, crt->bp_key, len) ||
359 copy_from_user(&z3, crt->u_mult_inv, len))
360 return -EFAULT;
361 copied = 1;
362 /**
363 * We have to restart device lookup -
364 * the device list may have changed by now.
365 */
366 goto restart;
367 }
368 if (z1 != 0ULL || z2 != 0ULL || z3 != 0ULL)
369 /* The device can't handle this request. */
370 continue;
371 }
372 zcrypt_device_get(zdev);
373 get_device(&zdev->ap_dev->device);
374 zdev->request_count++;
375 __zcrypt_decrease_preference(zdev);
376 spin_unlock_bh(&zcrypt_device_lock);
377 if (try_module_get(zdev->ap_dev->drv->driver.owner)) {
378 rc = zdev->ops->rsa_modexpo_crt(zdev, crt);
379 module_put(zdev->ap_dev->drv->driver.owner);
380 }
381 else
382 rc = -EAGAIN;
383 spin_lock_bh(&zcrypt_device_lock);
384 zdev->request_count--;
385 __zcrypt_increase_preference(zdev);
386 put_device(&zdev->ap_dev->device);
387 zcrypt_device_put(zdev);
388 spin_unlock_bh(&zcrypt_device_lock);
389 return rc;
390 }
391 spin_unlock_bh(&zcrypt_device_lock);
392 return -ENODEV;
393}
394
395static long zcrypt_send_cprb(struct ica_xcRB *xcRB)
396{
397 struct zcrypt_device *zdev;
398 int rc;
399
400 spin_lock_bh(&zcrypt_device_lock);
401 list_for_each_entry(zdev, &zcrypt_device_list, list) {
402 if (!zdev->online || !zdev->ops->send_cprb ||
403 (xcRB->user_defined != AUTOSELECT &&
404 AP_QID_DEVICE(zdev->ap_dev->qid) != xcRB->user_defined)
405 )
406 continue;
407 zcrypt_device_get(zdev);
408 get_device(&zdev->ap_dev->device);
409 zdev->request_count++;
410 __zcrypt_decrease_preference(zdev);
411 spin_unlock_bh(&zcrypt_device_lock);
412 if (try_module_get(zdev->ap_dev->drv->driver.owner)) {
413 rc = zdev->ops->send_cprb(zdev, xcRB);
414 module_put(zdev->ap_dev->drv->driver.owner);
415 }
416 else
417 rc = -EAGAIN;
418 spin_lock_bh(&zcrypt_device_lock);
419 zdev->request_count--;
420 __zcrypt_increase_preference(zdev);
421 put_device(&zdev->ap_dev->device);
422 zcrypt_device_put(zdev);
423 spin_unlock_bh(&zcrypt_device_lock);
424 return rc;
425 }
426 spin_unlock_bh(&zcrypt_device_lock);
427 return -ENODEV;
428}
429
430static void zcrypt_status_mask(char status[AP_DEVICES])
431{
432 struct zcrypt_device *zdev;
433
434 memset(status, 0, sizeof(char) * AP_DEVICES);
435 spin_lock_bh(&zcrypt_device_lock);
436 list_for_each_entry(zdev, &zcrypt_device_list, list)
437 status[AP_QID_DEVICE(zdev->ap_dev->qid)] =
438 zdev->online ? zdev->user_space_type : 0x0d;
439 spin_unlock_bh(&zcrypt_device_lock);
440}
441
442static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES])
443{
444 struct zcrypt_device *zdev;
445
446 memset(qdepth, 0, sizeof(char) * AP_DEVICES);
447 spin_lock_bh(&zcrypt_device_lock);
448 list_for_each_entry(zdev, &zcrypt_device_list, list) {
449 spin_lock(&zdev->ap_dev->lock);
450 qdepth[AP_QID_DEVICE(zdev->ap_dev->qid)] =
451 zdev->ap_dev->pendingq_count +
452 zdev->ap_dev->requestq_count;
453 spin_unlock(&zdev->ap_dev->lock);
454 }
455 spin_unlock_bh(&zcrypt_device_lock);
456}
457
458static void zcrypt_perdev_reqcnt(int reqcnt[AP_DEVICES])
459{
460 struct zcrypt_device *zdev;
461
462 memset(reqcnt, 0, sizeof(int) * AP_DEVICES);
463 spin_lock_bh(&zcrypt_device_lock);
464 list_for_each_entry(zdev, &zcrypt_device_list, list) {
465 spin_lock(&zdev->ap_dev->lock);
466 reqcnt[AP_QID_DEVICE(zdev->ap_dev->qid)] =
467 zdev->ap_dev->total_request_count;
468 spin_unlock(&zdev->ap_dev->lock);
469 }
470 spin_unlock_bh(&zcrypt_device_lock);
471}
472
473static int zcrypt_pendingq_count(void)
474{
475 struct zcrypt_device *zdev;
476 int pendingq_count = 0;
477
478 spin_lock_bh(&zcrypt_device_lock);
479 list_for_each_entry(zdev, &zcrypt_device_list, list) {
480 spin_lock(&zdev->ap_dev->lock);
481 pendingq_count += zdev->ap_dev->pendingq_count;
482 spin_unlock(&zdev->ap_dev->lock);
483 }
484 spin_unlock_bh(&zcrypt_device_lock);
485 return pendingq_count;
486}
487
488static int zcrypt_requestq_count(void)
489{
490 struct zcrypt_device *zdev;
491 int requestq_count = 0;
492
493 spin_lock_bh(&zcrypt_device_lock);
494 list_for_each_entry(zdev, &zcrypt_device_list, list) {
495 spin_lock(&zdev->ap_dev->lock);
496 requestq_count += zdev->ap_dev->requestq_count;
497 spin_unlock(&zdev->ap_dev->lock);
498 }
499 spin_unlock_bh(&zcrypt_device_lock);
500 return requestq_count;
501}
502
503static int zcrypt_count_type(int type)
504{
505 struct zcrypt_device *zdev;
506 int device_count = 0;
507
508 spin_lock_bh(&zcrypt_device_lock);
509 list_for_each_entry(zdev, &zcrypt_device_list, list)
510 if (zdev->user_space_type == type)
511 device_count++;
512 spin_unlock_bh(&zcrypt_device_lock);
513 return device_count;
514}
515
516/**
517 * Old, deprecated combi status call.
518 */
519static long zcrypt_ica_status(struct file *filp, unsigned long arg)
520{
521 struct ica_z90_status *pstat;
522 int ret;
523
524 pstat = kzalloc(sizeof(*pstat), GFP_KERNEL);
525 if (!pstat)
526 return -ENOMEM;
527 pstat->totalcount = zcrypt_device_count;
528 pstat->leedslitecount = zcrypt_count_type(ZCRYPT_PCICA);
529 pstat->leeds2count = zcrypt_count_type(ZCRYPT_PCICC);
530 pstat->requestqWaitCount = zcrypt_requestq_count();
531 pstat->pendingqWaitCount = zcrypt_pendingq_count();
532 pstat->totalOpenCount = atomic_read(&zcrypt_open_count);
533 pstat->cryptoDomain = ap_domain_index;
534 zcrypt_status_mask(pstat->status);
535 zcrypt_qdepth_mask(pstat->qdepth);
536 ret = 0;
537 if (copy_to_user((void __user *) arg, pstat, sizeof(*pstat)))
538 ret = -EFAULT;
539 kfree(pstat);
540 return ret;
541}
542
543static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
544 unsigned long arg)
545{
546 int rc;
547
548 switch (cmd) {
549 case ICARSAMODEXPO: {
550 struct ica_rsa_modexpo __user *umex = (void __user *) arg;
551 struct ica_rsa_modexpo mex;
552 if (copy_from_user(&mex, umex, sizeof(mex)))
553 return -EFAULT;
554 do {
555 rc = zcrypt_rsa_modexpo(&mex);
556 } while (rc == -EAGAIN);
557 if (rc)
558 return rc;
559 return put_user(mex.outputdatalength, &umex->outputdatalength);
560 }
561 case ICARSACRT: {
562 struct ica_rsa_modexpo_crt __user *ucrt = (void __user *) arg;
563 struct ica_rsa_modexpo_crt crt;
564 if (copy_from_user(&crt, ucrt, sizeof(crt)))
565 return -EFAULT;
566 do {
567 rc = zcrypt_rsa_crt(&crt);
568 } while (rc == -EAGAIN);
569 if (rc)
570 return rc;
571 return put_user(crt.outputdatalength, &ucrt->outputdatalength);
572 }
573 case ZSECSENDCPRB: {
574 struct ica_xcRB __user *uxcRB = (void __user *) arg;
575 struct ica_xcRB xcRB;
576 if (copy_from_user(&xcRB, uxcRB, sizeof(xcRB)))
577 return -EFAULT;
578 do {
579 rc = zcrypt_send_cprb(&xcRB);
580 } while (rc == -EAGAIN);
581 if (copy_to_user(uxcRB, &xcRB, sizeof(xcRB)))
582 return -EFAULT;
583 return rc;
584 }
585 case Z90STAT_STATUS_MASK: {
586 char status[AP_DEVICES];
587 zcrypt_status_mask(status);
588 if (copy_to_user((char __user *) arg, status,
589 sizeof(char) * AP_DEVICES))
590 return -EFAULT;
591 return 0;
592 }
593 case Z90STAT_QDEPTH_MASK: {
594 char qdepth[AP_DEVICES];
595 zcrypt_qdepth_mask(qdepth);
596 if (copy_to_user((char __user *) arg, qdepth,
597 sizeof(char) * AP_DEVICES))
598 return -EFAULT;
599 return 0;
600 }
601 case Z90STAT_PERDEV_REQCNT: {
602 int reqcnt[AP_DEVICES];
603 zcrypt_perdev_reqcnt(reqcnt);
604 if (copy_to_user((int __user *) arg, reqcnt,
605 sizeof(int) * AP_DEVICES))
606 return -EFAULT;
607 return 0;
608 }
609 case Z90STAT_REQUESTQ_COUNT:
610 return put_user(zcrypt_requestq_count(), (int __user *) arg);
611 case Z90STAT_PENDINGQ_COUNT:
612 return put_user(zcrypt_pendingq_count(), (int __user *) arg);
613 case Z90STAT_TOTALOPEN_COUNT:
614 return put_user(atomic_read(&zcrypt_open_count),
615 (int __user *) arg);
616 case Z90STAT_DOMAIN_INDEX:
617 return put_user(ap_domain_index, (int __user *) arg);
618 /**
619 * Deprecated ioctls. Don't add another device count ioctl,
620 * you can count them yourself in the user space with the
621 * output of the Z90STAT_STATUS_MASK ioctl.
622 */
623 case ICAZ90STATUS:
624 return zcrypt_ica_status(filp, arg);
625 case Z90STAT_TOTALCOUNT:
626 return put_user(zcrypt_device_count, (int __user *) arg);
627 case Z90STAT_PCICACOUNT:
628 return put_user(zcrypt_count_type(ZCRYPT_PCICA),
629 (int __user *) arg);
630 case Z90STAT_PCICCCOUNT:
631 return put_user(zcrypt_count_type(ZCRYPT_PCICC),
632 (int __user *) arg);
633 case Z90STAT_PCIXCCMCL2COUNT:
634 return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL2),
635 (int __user *) arg);
636 case Z90STAT_PCIXCCMCL3COUNT:
637 return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL3),
638 (int __user *) arg);
639 case Z90STAT_PCIXCCCOUNT:
640 return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL2) +
641 zcrypt_count_type(ZCRYPT_PCIXCC_MCL3),
642 (int __user *) arg);
643 case Z90STAT_CEX2CCOUNT:
644 return put_user(zcrypt_count_type(ZCRYPT_CEX2C),
645 (int __user *) arg);
646 case Z90STAT_CEX2ACOUNT:
647 return put_user(zcrypt_count_type(ZCRYPT_CEX2A),
648 (int __user *) arg);
649 default:
650 /* unknown ioctl number */
651 return -ENOIOCTLCMD;
652 }
653}
654
655#ifdef CONFIG_COMPAT
656/**
657 * ioctl32 conversion routines
658 */
659struct compat_ica_rsa_modexpo {
660 compat_uptr_t inputdata;
661 unsigned int inputdatalength;
662 compat_uptr_t outputdata;
663 unsigned int outputdatalength;
664 compat_uptr_t b_key;
665 compat_uptr_t n_modulus;
666};
667
668static long trans_modexpo32(struct file *filp, unsigned int cmd,
669 unsigned long arg)
670{
671 struct compat_ica_rsa_modexpo __user *umex32 = compat_ptr(arg);
672 struct compat_ica_rsa_modexpo mex32;
673 struct ica_rsa_modexpo mex64;
674 long rc;
675
676 if (copy_from_user(&mex32, umex32, sizeof(mex32)))
677 return -EFAULT;
678 mex64.inputdata = compat_ptr(mex32.inputdata);
679 mex64.inputdatalength = mex32.inputdatalength;
680 mex64.outputdata = compat_ptr(mex32.outputdata);
681 mex64.outputdatalength = mex32.outputdatalength;
682 mex64.b_key = compat_ptr(mex32.b_key);
683 mex64.n_modulus = compat_ptr(mex32.n_modulus);
684 do {
685 rc = zcrypt_rsa_modexpo(&mex64);
686 } while (rc == -EAGAIN);
687 if (!rc)
688 rc = put_user(mex64.outputdatalength,
689 &umex32->outputdatalength);
690 return rc;
691}
692
693struct compat_ica_rsa_modexpo_crt {
694 compat_uptr_t inputdata;
695 unsigned int inputdatalength;
696 compat_uptr_t outputdata;
697 unsigned int outputdatalength;
698 compat_uptr_t bp_key;
699 compat_uptr_t bq_key;
700 compat_uptr_t np_prime;
701 compat_uptr_t nq_prime;
702 compat_uptr_t u_mult_inv;
703};
704
705static long trans_modexpo_crt32(struct file *filp, unsigned int cmd,
706 unsigned long arg)
707{
708 struct compat_ica_rsa_modexpo_crt __user *ucrt32 = compat_ptr(arg);
709 struct compat_ica_rsa_modexpo_crt crt32;
710 struct ica_rsa_modexpo_crt crt64;
711 long rc;
712
713 if (copy_from_user(&crt32, ucrt32, sizeof(crt32)))
714 return -EFAULT;
715 crt64.inputdata = compat_ptr(crt32.inputdata);
716 crt64.inputdatalength = crt32.inputdatalength;
717 crt64.outputdata= compat_ptr(crt32.outputdata);
718 crt64.outputdatalength = crt32.outputdatalength;
719 crt64.bp_key = compat_ptr(crt32.bp_key);
720 crt64.bq_key = compat_ptr(crt32.bq_key);
721 crt64.np_prime = compat_ptr(crt32.np_prime);
722 crt64.nq_prime = compat_ptr(crt32.nq_prime);
723 crt64.u_mult_inv = compat_ptr(crt32.u_mult_inv);
724 do {
725 rc = zcrypt_rsa_crt(&crt64);
726 } while (rc == -EAGAIN);
727 if (!rc)
728 rc = put_user(crt64.outputdatalength,
729 &ucrt32->outputdatalength);
730 return rc;
731}
732
733struct compat_ica_xcRB {
734 unsigned short agent_ID;
735 unsigned int user_defined;
736 unsigned short request_ID;
737 unsigned int request_control_blk_length;
738 unsigned char padding1[16 - sizeof (compat_uptr_t)];
739 compat_uptr_t request_control_blk_addr;
740 unsigned int request_data_length;
741 char padding2[16 - sizeof (compat_uptr_t)];
742 compat_uptr_t request_data_address;
743 unsigned int reply_control_blk_length;
744 char padding3[16 - sizeof (compat_uptr_t)];
745 compat_uptr_t reply_control_blk_addr;
746 unsigned int reply_data_length;
747 char padding4[16 - sizeof (compat_uptr_t)];
748 compat_uptr_t reply_data_addr;
749 unsigned short priority_window;
750 unsigned int status;
751} __attribute__((packed));
752
753static long trans_xcRB32(struct file *filp, unsigned int cmd,
754 unsigned long arg)
755{
756 struct compat_ica_xcRB __user *uxcRB32 = compat_ptr(arg);
757 struct compat_ica_xcRB xcRB32;
758 struct ica_xcRB xcRB64;
759 long rc;
760
761 if (copy_from_user(&xcRB32, uxcRB32, sizeof(xcRB32)))
762 return -EFAULT;
763 xcRB64.agent_ID = xcRB32.agent_ID;
764 xcRB64.user_defined = xcRB32.user_defined;
765 xcRB64.request_ID = xcRB32.request_ID;
766 xcRB64.request_control_blk_length =
767 xcRB32.request_control_blk_length;
768 xcRB64.request_control_blk_addr =
769 compat_ptr(xcRB32.request_control_blk_addr);
770 xcRB64.request_data_length =
771 xcRB32.request_data_length;
772 xcRB64.request_data_address =
773 compat_ptr(xcRB32.request_data_address);
774 xcRB64.reply_control_blk_length =
775 xcRB32.reply_control_blk_length;
776 xcRB64.reply_control_blk_addr =
777 compat_ptr(xcRB32.reply_control_blk_addr);
778 xcRB64.reply_data_length = xcRB32.reply_data_length;
779 xcRB64.reply_data_addr =
780 compat_ptr(xcRB32.reply_data_addr);
781 xcRB64.priority_window = xcRB32.priority_window;
782 xcRB64.status = xcRB32.status;
783 do {
784 rc = zcrypt_send_cprb(&xcRB64);
785 } while (rc == -EAGAIN);
786 xcRB32.reply_control_blk_length = xcRB64.reply_control_blk_length;
787 xcRB32.reply_data_length = xcRB64.reply_data_length;
788 xcRB32.status = xcRB64.status;
789 if (copy_to_user(uxcRB32, &xcRB32, sizeof(xcRB32)))
790 return -EFAULT;
791 return rc;
792}
793
794long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd,
795 unsigned long arg)
796{
797 if (cmd == ICARSAMODEXPO)
798 return trans_modexpo32(filp, cmd, arg);
799 if (cmd == ICARSACRT)
800 return trans_modexpo_crt32(filp, cmd, arg);
801 if (cmd == ZSECSENDCPRB)
802 return trans_xcRB32(filp, cmd, arg);
803 return zcrypt_unlocked_ioctl(filp, cmd, arg);
804}
805#endif
806
807/**
808 * Misc device file operations.
809 */
810static struct file_operations zcrypt_fops = {
811 .owner = THIS_MODULE,
812 .read = zcrypt_read,
813 .write = zcrypt_write,
814 .unlocked_ioctl = zcrypt_unlocked_ioctl,
815#ifdef CONFIG_COMPAT
816 .compat_ioctl = zcrypt_compat_ioctl,
817#endif
818 .open = zcrypt_open,
819 .release = zcrypt_release
820};
821
822/**
823 * Misc device.
824 */
825static struct miscdevice zcrypt_misc_device = {
826 .minor = MISC_DYNAMIC_MINOR,
827 .name = "z90crypt",
828 .fops = &zcrypt_fops,
829};
830
831/**
832 * Deprecated /proc entry support.
833 */
834static struct proc_dir_entry *zcrypt_entry;
835
836static inline int sprintcl(unsigned char *outaddr, unsigned char *addr,
837 unsigned int len)
838{
839 int hl, i;
840
841 hl = 0;
842 for (i = 0; i < len; i++)
843 hl += sprintf(outaddr+hl, "%01x", (unsigned int) addr[i]);
844 hl += sprintf(outaddr+hl, " ");
845 return hl;
846}
847
848static inline int sprintrw(unsigned char *outaddr, unsigned char *addr,
849 unsigned int len)
850{
851 int hl, inl, c, cx;
852
853 hl = sprintf(outaddr, " ");
854 inl = 0;
855 for (c = 0; c < (len / 16); c++) {
856 hl += sprintcl(outaddr+hl, addr+inl, 16);
857 inl += 16;
858 }
859 cx = len%16;
860 if (cx) {
861 hl += sprintcl(outaddr+hl, addr+inl, cx);
862 inl += cx;
863 }
864 hl += sprintf(outaddr+hl, "\n");
865 return hl;
866}
867
868static inline int sprinthx(unsigned char *title, unsigned char *outaddr,
869 unsigned char *addr, unsigned int len)
870{
871 int hl, inl, r, rx;
872
873 hl = sprintf(outaddr, "\n%s\n", title);
874 inl = 0;
875 for (r = 0; r < (len / 64); r++) {
876 hl += sprintrw(outaddr+hl, addr+inl, 64);
877 inl += 64;
878 }
879 rx = len % 64;
880 if (rx) {
881 hl += sprintrw(outaddr+hl, addr+inl, rx);
882 inl += rx;
883 }
884 hl += sprintf(outaddr+hl, "\n");
885 return hl;
886}
887
888static inline int sprinthx4(unsigned char *title, unsigned char *outaddr,
889 unsigned int *array, unsigned int len)
890{
891 int hl, r;
892
893 hl = sprintf(outaddr, "\n%s\n", title);
894 for (r = 0; r < len; r++) {
895 if ((r % 8) == 0)
896 hl += sprintf(outaddr+hl, " ");
897 hl += sprintf(outaddr+hl, "%08X ", array[r]);
898 if ((r % 8) == 7)
899 hl += sprintf(outaddr+hl, "\n");
900 }
901 hl += sprintf(outaddr+hl, "\n");
902 return hl;
903}
904
905static int zcrypt_status_read(char *resp_buff, char **start, off_t offset,
906 int count, int *eof, void *data)
907{
908 unsigned char *workarea;
909 int len;
910
911 len = 0;
912
913 /* resp_buff is a page. Use the right half for a work area */
914 workarea = resp_buff + 2000;
915 len += sprintf(resp_buff + len, "\nzcrypt version: %d.%d.%d\n",
916 ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT);
917 len += sprintf(resp_buff + len, "Cryptographic domain: %d\n",
918 ap_domain_index);
919 len += sprintf(resp_buff + len, "Total device count: %d\n",
920 zcrypt_device_count);
921 len += sprintf(resp_buff + len, "PCICA count: %d\n",
922 zcrypt_count_type(ZCRYPT_PCICA));
923 len += sprintf(resp_buff + len, "PCICC count: %d\n",
924 zcrypt_count_type(ZCRYPT_PCICC));
925 len += sprintf(resp_buff + len, "PCIXCC MCL2 count: %d\n",
926 zcrypt_count_type(ZCRYPT_PCIXCC_MCL2));
927 len += sprintf(resp_buff + len, "PCIXCC MCL3 count: %d\n",
928 zcrypt_count_type(ZCRYPT_PCIXCC_MCL3));
929 len += sprintf(resp_buff + len, "CEX2C count: %d\n",
930 zcrypt_count_type(ZCRYPT_CEX2C));
931 len += sprintf(resp_buff + len, "CEX2A count: %d\n",
932 zcrypt_count_type(ZCRYPT_CEX2A));
933 len += sprintf(resp_buff + len, "requestq count: %d\n",
934 zcrypt_requestq_count());
935 len += sprintf(resp_buff + len, "pendingq count: %d\n",
936 zcrypt_pendingq_count());
937 len += sprintf(resp_buff + len, "Total open handles: %d\n\n",
938 atomic_read(&zcrypt_open_count));
939 zcrypt_status_mask(workarea);
940 len += sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
941 "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A",
942 resp_buff+len, workarea, AP_DEVICES);
943 zcrypt_qdepth_mask(workarea);
944 len += sprinthx("Waiting work element counts",
945 resp_buff+len, workarea, AP_DEVICES);
946 zcrypt_perdev_reqcnt((unsigned int *) workarea);
947 len += sprinthx4("Per-device successfully completed request counts",
948 resp_buff+len,(unsigned int *) workarea, AP_DEVICES);
949 *eof = 1;
950 memset((void *) workarea, 0x00, AP_DEVICES * sizeof(unsigned int));
951 return len;
952}
953
954static void zcrypt_disable_card(int index)
955{
956 struct zcrypt_device *zdev;
957
958 spin_lock_bh(&zcrypt_device_lock);
959 list_for_each_entry(zdev, &zcrypt_device_list, list)
960 if (AP_QID_DEVICE(zdev->ap_dev->qid) == index) {
961 zdev->online = 0;
962 ap_flush_queue(zdev->ap_dev);
963 break;
964 }
965 spin_unlock_bh(&zcrypt_device_lock);
966}
967
968static void zcrypt_enable_card(int index)
969{
970 struct zcrypt_device *zdev;
971
972 spin_lock_bh(&zcrypt_device_lock);
973 list_for_each_entry(zdev, &zcrypt_device_list, list)
974 if (AP_QID_DEVICE(zdev->ap_dev->qid) == index) {
975 zdev->online = 1;
976 break;
977 }
978 spin_unlock_bh(&zcrypt_device_lock);
979}
980
981static int zcrypt_status_write(struct file *file, const char __user *buffer,
982 unsigned long count, void *data)
983{
984 unsigned char *lbuf, *ptr;
985 unsigned long local_count;
986 int j;
987
988 if (count <= 0)
989 return 0;
990
991#define LBUFSIZE 1200UL
992 lbuf = kmalloc(LBUFSIZE, GFP_KERNEL);
993 if (!lbuf) {
994 PRINTK("kmalloc failed!\n");
995 return 0;
996 }
997
998 local_count = min(LBUFSIZE - 1, count);
999 if (copy_from_user(lbuf, buffer, local_count) != 0) {
1000 kfree(lbuf);
1001 return -EFAULT;
1002 }
1003 lbuf[local_count] = '\0';
1004
1005 ptr = strstr(lbuf, "Online devices");
1006 if (!ptr) {
1007 PRINTK("Unable to parse data (missing \"Online devices\")\n");
1008 goto out;
1009 }
1010 ptr = strstr(ptr, "\n");
1011 if (!ptr) {
1012 PRINTK("Unable to parse data (missing newline "
1013 "after \"Online devices\")\n");
1014 goto out;
1015 }
1016 ptr++;
1017
1018 if (strstr(ptr, "Waiting work element counts") == NULL) {
1019 PRINTK("Unable to parse data (missing "
1020 "\"Waiting work element counts\")\n");
1021 goto out;
1022 }
1023
1024 for (j = 0; j < 64 && *ptr; ptr++) {
1025 /**
1026 * '0' for no device, '1' for PCICA, '2' for PCICC,
1027 * '3' for PCIXCC_MCL2, '4' for PCIXCC_MCL3,
1028 * '5' for CEX2C and '6' for CEX2A'
1029 */
1030 if (*ptr >= '0' && *ptr <= '6')
1031 j++;
1032 else if (*ptr == 'd' || *ptr == 'D')
1033 zcrypt_disable_card(j++);
1034 else if (*ptr == 'e' || *ptr == 'E')
1035 zcrypt_enable_card(j++);
1036 else if (*ptr != ' ' && *ptr != '\t')
1037 break;
1038 }
1039out:
1040 kfree(lbuf);
1041 return count;
1042}
1043
1044/**
1045 * The module initialization code.
1046 */
1047int __init zcrypt_api_init(void)
1048{
1049 int rc;
1050
1051 /* Register the request sprayer. */
1052 rc = misc_register(&zcrypt_misc_device);
1053 if (rc < 0) {
1054 PRINTKW(KERN_ERR "misc_register (minor %d) failed with %d\n",
1055 zcrypt_misc_device.minor, rc);
1056 goto out;
1057 }
1058
1059 /* Set up the proc file system */
1060 zcrypt_entry = create_proc_entry("driver/z90crypt", 0644, NULL);
1061 if (!zcrypt_entry) {
1062 PRINTK("Couldn't create z90crypt proc entry\n");
1063 rc = -ENOMEM;
1064 goto out_misc;
1065 }
1066 zcrypt_entry->nlink = 1;
1067 zcrypt_entry->data = NULL;
1068 zcrypt_entry->read_proc = zcrypt_status_read;
1069 zcrypt_entry->write_proc = zcrypt_status_write;
1070
1071 return 0;
1072
1073out_misc:
1074 misc_deregister(&zcrypt_misc_device);
1075out:
1076 return rc;
1077}
1078
1079/**
1080 * The module termination code.
1081 */
1082void zcrypt_api_exit(void)
1083{
1084 remove_proc_entry("driver/z90crypt", NULL);
1085 misc_deregister(&zcrypt_misc_device);
1086}
1087
1088#ifndef CONFIG_ZCRYPT_MONOLITHIC
1089module_init(zcrypt_api_init);
1090module_exit(zcrypt_api_exit);
1091#endif
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
new file mode 100644
index 000000000000..de4877ee618f
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -0,0 +1,141 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_api.h
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 * Cornelia Huck <cornelia.huck@de.ibm.com>
10 *
11 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
12 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
13 * Ralph Wuerthner <rwuerthn@de.ibm.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef _ZCRYPT_API_H_
31#define _ZCRYPT_API_H_
32
33/**
34 * Macro definitions
35 *
36 * PDEBUG debugs in the form "zcrypt: function_name -> message"
37 *
38 * PRINTK is like PDEBUG, except that it is always enabled
39 * PRINTKN is like PRINTK, except that it does not include the function name
40 * PRINTKW is like PRINTK, except that it uses KERN_WARNING
41 * PRINTKC is like PRINTK, except that it uses KERN_CRIT
42 */
43#define DEV_NAME "zcrypt"
44
45#define PRINTK(fmt, args...) \
46 printk(KERN_DEBUG DEV_NAME ": %s -> " fmt, __FUNCTION__ , ## args)
47#define PRINTKN(fmt, args...) \
48 printk(KERN_DEBUG DEV_NAME ": " fmt, ## args)
49#define PRINTKW(fmt, args...) \
50 printk(KERN_WARNING DEV_NAME ": %s -> " fmt, __FUNCTION__ , ## args)
51#define PRINTKC(fmt, args...) \
52 printk(KERN_CRIT DEV_NAME ": %s -> " fmt, __FUNCTION__ , ## args)
53
54#ifdef ZCRYPT_DEBUG
55#define PDEBUG(fmt, args...) \
56 printk(KERN_DEBUG DEV_NAME ": %s -> " fmt, __FUNCTION__ , ## args)
57#else
58#define PDEBUG(fmt, args...) do {} while (0)
59#endif
60
61#include "ap_bus.h"
62#include <asm/zcrypt.h>
63
64/* deprecated status calls */
65#define ICAZ90STATUS _IOR(ZCRYPT_IOCTL_MAGIC, 0x10, struct ica_z90_status)
66#define Z90STAT_PCIXCCCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x43, int)
67
68/**
69 * This structure is deprecated and the corresponding ioctl() has been
70 * replaced with individual ioctl()s for each piece of data!
71 */
72struct ica_z90_status {
73 int totalcount;
74 int leedslitecount; // PCICA
75 int leeds2count; // PCICC
76 // int PCIXCCCount; is not in struct for backward compatibility
77 int requestqWaitCount;
78 int pendingqWaitCount;
79 int totalOpenCount;
80 int cryptoDomain;
81 // status: 0=not there, 1=PCICA, 2=PCICC, 3=PCIXCC_MCL2, 4=PCIXCC_MCL3,
82 // 5=CEX2C
83 unsigned char status[64];
84 // qdepth: # work elements waiting for each device
85 unsigned char qdepth[64];
86};
87
88/**
89 * device type for an actual device is either PCICA, PCICC, PCIXCC_MCL2,
90 * PCIXCC_MCL3, CEX2C, or CEX2A
91 *
92 * NOTE: PCIXCC_MCL3 refers to a PCIXCC with May 2004 version of Licensed
93 * Internal Code (LIC) (EC J12220 level 29).
94 * PCIXCC_MCL2 refers to any LIC before this level.
95 */
96#define ZCRYPT_PCICA 1
97#define ZCRYPT_PCICC 2
98#define ZCRYPT_PCIXCC_MCL2 3
99#define ZCRYPT_PCIXCC_MCL3 4
100#define ZCRYPT_CEX2C 5
101#define ZCRYPT_CEX2A 6
102
103struct zcrypt_device;
104
105struct zcrypt_ops {
106 long (*rsa_modexpo)(struct zcrypt_device *, struct ica_rsa_modexpo *);
107 long (*rsa_modexpo_crt)(struct zcrypt_device *,
108 struct ica_rsa_modexpo_crt *);
109 long (*send_cprb)(struct zcrypt_device *, struct ica_xcRB *);
110};
111
112struct zcrypt_device {
113 struct list_head list; /* Device list. */
114 spinlock_t lock; /* Per device lock. */
115 struct kref refcount; /* device refcounting */
116 struct ap_device *ap_dev; /* The "real" ap device. */
117 struct zcrypt_ops *ops; /* Crypto operations. */
118 int online; /* User online/offline */
119
120 int user_space_type; /* User space device id. */
121 char *type_string; /* User space device name. */
122 int min_mod_size; /* Min number of bits. */
123 int max_mod_size; /* Max number of bits. */
124 int short_crt; /* Card has crt length restriction. */
125 int speed_rating; /* Speed of the crypto device. */
126
127 int request_count; /* # current requests. */
128
129 struct ap_message reply; /* Per-device reply structure. */
130};
131
132struct zcrypt_device *zcrypt_device_alloc(size_t);
133void zcrypt_device_free(struct zcrypt_device *);
134void zcrypt_device_get(struct zcrypt_device *);
135int zcrypt_device_put(struct zcrypt_device *);
136int zcrypt_device_register(struct zcrypt_device *);
137void zcrypt_device_unregister(struct zcrypt_device *);
138int zcrypt_api_init(void);
139void zcrypt_api_exit(void);
140
141#endif /* _ZCRYPT_API_H_ */
diff --git a/drivers/s390/crypto/zcrypt_cca_key.h b/drivers/s390/crypto/zcrypt_cca_key.h
new file mode 100644
index 000000000000..8dbcf0eef3e5
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_cca_key.h
@@ -0,0 +1,350 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_cca_key.h
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_CCA_KEY_H_
29#define _ZCRYPT_CCA_KEY_H_
30
31struct T6_keyBlock_hdr {
32 unsigned short blen;
33 unsigned short ulen;
34 unsigned short flags;
35};
36
37/**
38 * mapping for the cca private ME key token.
39 * Three parts of interest here: the header, the private section and
40 * the public section.
41 *
42 * mapping for the cca key token header
43 */
44struct cca_token_hdr {
45 unsigned char token_identifier;
46 unsigned char version;
47 unsigned short token_length;
48 unsigned char reserved[4];
49} __attribute__((packed));
50
51#define CCA_TKN_HDR_ID_EXT 0x1E
52
53/**
54 * mapping for the cca private ME section
55 */
56struct cca_private_ext_ME_sec {
57 unsigned char section_identifier;
58 unsigned char version;
59 unsigned short section_length;
60 unsigned char private_key_hash[20];
61 unsigned char reserved1[4];
62 unsigned char key_format;
63 unsigned char reserved2;
64 unsigned char key_name_hash[20];
65 unsigned char key_use_flags[4];
66 unsigned char reserved3[6];
67 unsigned char reserved4[24];
68 unsigned char confounder[24];
69 unsigned char exponent[128];
70 unsigned char modulus[128];
71} __attribute__((packed));
72
73#define CCA_PVT_USAGE_ALL 0x80
74
75/**
76 * mapping for the cca public section
77 * In a private key, the modulus doesn't appear in the public
78 * section. So, an arbitrary public exponent of 0x010001 will be
79 * used, for a section length of 0x0F always.
80 */
81struct cca_public_sec {
82 unsigned char section_identifier;
83 unsigned char version;
84 unsigned short section_length;
85 unsigned char reserved[2];
86 unsigned short exponent_len;
87 unsigned short modulus_bit_len;
88 unsigned short modulus_byte_len; /* In a private key, this is 0 */
89} __attribute__((packed));
90
91/**
92 * mapping for the cca private CRT key 'token'
93 * The first three parts (the only parts considered in this release)
94 * are: the header, the private section and the public section.
95 * The header and public section are the same as for the
96 * struct cca_private_ext_ME
97 *
98 * Following the structure are the quantities p, q, dp, dq, u, pad,
99 * and modulus, in that order, where pad_len is the modulo 8
100 * complement of the residue modulo 8 of the sum of
101 * (p_len + q_len + dp_len + dq_len + u_len).
102 */
103struct cca_pvt_ext_CRT_sec {
104 unsigned char section_identifier;
105 unsigned char version;
106 unsigned short section_length;
107 unsigned char private_key_hash[20];
108 unsigned char reserved1[4];
109 unsigned char key_format;
110 unsigned char reserved2;
111 unsigned char key_name_hash[20];
112 unsigned char key_use_flags[4];
113 unsigned short p_len;
114 unsigned short q_len;
115 unsigned short dp_len;
116 unsigned short dq_len;
117 unsigned short u_len;
118 unsigned short mod_len;
119 unsigned char reserved3[4];
120 unsigned short pad_len;
121 unsigned char reserved4[52];
122 unsigned char confounder[8];
123} __attribute__((packed));
124
125#define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
126#define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
127
128/**
129 * Set up private key fields of a type6 MEX message.
130 * Note that all numerics in the key token are big-endian,
131 * while the entries in the key block header are little-endian.
132 *
133 * @mex: pointer to user input data
134 * @p: pointer to memory area for the key
135 *
136 * Returns the size of the key area or -EFAULT
137 */
138static inline int zcrypt_type6_mex_key_de(struct ica_rsa_modexpo *mex,
139 void *p, int big_endian)
140{
141 static struct cca_token_hdr static_pvt_me_hdr = {
142 .token_identifier = 0x1E,
143 .token_length = 0x0183,
144 };
145 static struct cca_private_ext_ME_sec static_pvt_me_sec = {
146 .section_identifier = 0x02,
147 .section_length = 0x016C,
148 .key_use_flags = {0x80,0x00,0x00,0x00},
149 };
150 static struct cca_public_sec static_pub_me_sec = {
151 .section_identifier = 0x04,
152 .section_length = 0x000F,
153 .exponent_len = 0x0003,
154 };
155 static char pk_exponent[3] = { 0x01, 0x00, 0x01 };
156 struct {
157 struct T6_keyBlock_hdr t6_hdr;
158 struct cca_token_hdr pvtMeHdr;
159 struct cca_private_ext_ME_sec pvtMeSec;
160 struct cca_public_sec pubMeSec;
161 char exponent[3];
162 } __attribute__((packed)) *key = p;
163 unsigned char *temp;
164
165 memset(key, 0, sizeof(*key));
166
167 if (big_endian) {
168 key->t6_hdr.blen = cpu_to_be16(0x189);
169 key->t6_hdr.ulen = cpu_to_be16(0x189 - 2);
170 } else {
171 key->t6_hdr.blen = cpu_to_le16(0x189);
172 key->t6_hdr.ulen = cpu_to_le16(0x189 - 2);
173 }
174 key->pvtMeHdr = static_pvt_me_hdr;
175 key->pvtMeSec = static_pvt_me_sec;
176 key->pubMeSec = static_pub_me_sec;
177 /**
178 * In a private key, the modulus doesn't appear in the public
179 * section. So, an arbitrary public exponent of 0x010001 will be
180 * used.
181 */
182 memcpy(key->exponent, pk_exponent, 3);
183
184 /* key parameter block */
185 temp = key->pvtMeSec.exponent +
186 sizeof(key->pvtMeSec.exponent) - mex->inputdatalength;
187 if (copy_from_user(temp, mex->b_key, mex->inputdatalength))
188 return -EFAULT;
189
190 /* modulus */
191 temp = key->pvtMeSec.modulus +
192 sizeof(key->pvtMeSec.modulus) - mex->inputdatalength;
193 if (copy_from_user(temp, mex->n_modulus, mex->inputdatalength))
194 return -EFAULT;
195 key->pubMeSec.modulus_bit_len = 8 * mex->inputdatalength;
196 return sizeof(*key);
197}
198
199/**
200 * Set up private key fields of a type6 MEX message. The _pad variant
201 * strips leading zeroes from the b_key.
202 * Note that all numerics in the key token are big-endian,
203 * while the entries in the key block header are little-endian.
204 *
205 * @mex: pointer to user input data
206 * @p: pointer to memory area for the key
207 *
208 * Returns the size of the key area or -EFAULT
209 */
210static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex,
211 void *p, int big_endian)
212{
213 static struct cca_token_hdr static_pub_hdr = {
214 .token_identifier = 0x1E,
215 };
216 static struct cca_public_sec static_pub_sec = {
217 .section_identifier = 0x04,
218 };
219 struct {
220 struct T6_keyBlock_hdr t6_hdr;
221 struct cca_token_hdr pubHdr;
222 struct cca_public_sec pubSec;
223 char exponent[0];
224 } __attribute__((packed)) *key = p;
225 unsigned char *temp;
226 int i;
227
228 memset(key, 0, sizeof(*key));
229
230 key->pubHdr = static_pub_hdr;
231 key->pubSec = static_pub_sec;
232
233 /* key parameter block */
234 temp = key->exponent;
235 if (copy_from_user(temp, mex->b_key, mex->inputdatalength))
236 return -EFAULT;
237 /* Strip leading zeroes from b_key. */
238 for (i = 0; i < mex->inputdatalength; i++)
239 if (temp[i])
240 break;
241 if (i >= mex->inputdatalength)
242 return -EINVAL;
243 memmove(temp, temp + i, mex->inputdatalength - i);
244 temp += mex->inputdatalength - i;
245 /* modulus */
246 if (copy_from_user(temp, mex->n_modulus, mex->inputdatalength))
247 return -EFAULT;
248
249 key->pubSec.modulus_bit_len = 8 * mex->inputdatalength;
250 key->pubSec.modulus_byte_len = mex->inputdatalength;
251 key->pubSec.exponent_len = mex->inputdatalength - i;
252 key->pubSec.section_length = sizeof(key->pubSec) +
253 2*mex->inputdatalength - i;
254 key->pubHdr.token_length =
255 key->pubSec.section_length + sizeof(key->pubHdr);
256 if (big_endian) {
257 key->t6_hdr.ulen = cpu_to_be16(key->pubHdr.token_length + 4);
258 key->t6_hdr.blen = cpu_to_be16(key->pubHdr.token_length + 6);
259 } else {
260 key->t6_hdr.ulen = cpu_to_le16(key->pubHdr.token_length + 4);
261 key->t6_hdr.blen = cpu_to_le16(key->pubHdr.token_length + 6);
262 }
263 return sizeof(*key) + 2*mex->inputdatalength - i;
264}
265
266/**
267 * Set up private key fields of a type6 CRT message.
268 * Note that all numerics in the key token are big-endian,
269 * while the entries in the key block header are little-endian.
270 *
271 * @mex: pointer to user input data
272 * @p: pointer to memory area for the key
273 *
274 * Returns the size of the key area or -EFAULT
275 */
276static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt,
277 void *p, int big_endian)
278{
279 static struct cca_public_sec static_cca_pub_sec = {
280 .section_identifier = 4,
281 .section_length = 0x000f,
282 .exponent_len = 0x0003,
283 };
284 static char pk_exponent[3] = { 0x01, 0x00, 0x01 };
285 struct {
286 struct T6_keyBlock_hdr t6_hdr;
287 struct cca_token_hdr token;
288 struct cca_pvt_ext_CRT_sec pvt;
289 char key_parts[0];
290 } __attribute__((packed)) *key = p;
291 struct cca_public_sec *pub;
292 int short_len, long_len, pad_len, key_len, size;
293
294 memset(key, 0, sizeof(*key));
295
296 short_len = crt->inputdatalength / 2;
297 long_len = short_len + 8;
298 pad_len = -(3*long_len + 2*short_len) & 7;
299 key_len = 3*long_len + 2*short_len + pad_len + crt->inputdatalength;
300 size = sizeof(*key) + key_len + sizeof(*pub) + 3;
301
302 /* parameter block.key block */
303 if (big_endian) {
304 key->t6_hdr.blen = cpu_to_be16(size);
305 key->t6_hdr.ulen = cpu_to_be16(size - 2);
306 } else {
307 key->t6_hdr.blen = cpu_to_le16(size);
308 key->t6_hdr.ulen = cpu_to_le16(size - 2);
309 }
310
311 /* key token header */
312 key->token.token_identifier = CCA_TKN_HDR_ID_EXT;
313 key->token.token_length = size - 6;
314
315 /* private section */
316 key->pvt.section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
317 key->pvt.section_length = sizeof(key->pvt) + key_len;
318 key->pvt.key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
319 key->pvt.key_use_flags[0] = CCA_PVT_USAGE_ALL;
320 key->pvt.p_len = key->pvt.dp_len = key->pvt.u_len = long_len;
321 key->pvt.q_len = key->pvt.dq_len = short_len;
322 key->pvt.mod_len = crt->inputdatalength;
323 key->pvt.pad_len = pad_len;
324
325 /* key parts */
326 if (copy_from_user(key->key_parts, crt->np_prime, long_len) ||
327 copy_from_user(key->key_parts + long_len,
328 crt->nq_prime, short_len) ||
329 copy_from_user(key->key_parts + long_len + short_len,
330 crt->bp_key, long_len) ||
331 copy_from_user(key->key_parts + 2*long_len + short_len,
332 crt->bq_key, short_len) ||
333 copy_from_user(key->key_parts + 2*long_len + 2*short_len,
334 crt->u_mult_inv, long_len))
335 return -EFAULT;
336 memset(key->key_parts + 3*long_len + 2*short_len + pad_len,
337 0xff, crt->inputdatalength);
338 pub = (struct cca_public_sec *)(key->key_parts + key_len);
339 *pub = static_cca_pub_sec;
340 pub->modulus_bit_len = 8 * crt->inputdatalength;
341 /**
342 * In a private key, the modulus doesn't appear in the public
343 * section. So, an arbitrary public exponent of 0x010001 will be
344 * used.
345 */
346 memcpy((char *) (pub + 1), pk_exponent, 3);
347 return size;
348}
349
350#endif /* _ZCRYPT_CCA_KEY_H_ */
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
new file mode 100644
index 000000000000..a62b00083d0c
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -0,0 +1,435 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_cex2a.c
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 * Ralph Wuerthner <rwuerthn@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/err.h>
32#include <asm/atomic.h>
33#include <asm/uaccess.h>
34
35#include "ap_bus.h"
36#include "zcrypt_api.h"
37#include "zcrypt_error.h"
38#include "zcrypt_cex2a.h"
39
40#define CEX2A_MIN_MOD_SIZE 1 /* 8 bits */
41#define CEX2A_MAX_MOD_SIZE 256 /* 2048 bits */
42
43#define CEX2A_SPEED_RATING 970
44
45#define CEX2A_MAX_MESSAGE_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */
46#define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */
47
48#define CEX2A_CLEANUP_TIME (15*HZ)
49
50static struct ap_device_id zcrypt_cex2a_ids[] = {
51 { AP_DEVICE(AP_DEVICE_TYPE_CEX2A) },
52 { /* end of list */ },
53};
54
55#ifndef CONFIG_ZCRYPT_MONOLITHIC
56MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_ids);
57MODULE_AUTHOR("IBM Corporation");
58MODULE_DESCRIPTION("CEX2A Cryptographic Coprocessor device driver, "
59 "Copyright 2001, 2006 IBM Corporation");
60MODULE_LICENSE("GPL");
61#endif
62
63static int zcrypt_cex2a_probe(struct ap_device *ap_dev);
64static void zcrypt_cex2a_remove(struct ap_device *ap_dev);
65static void zcrypt_cex2a_receive(struct ap_device *, struct ap_message *,
66 struct ap_message *);
67
68static struct ap_driver zcrypt_cex2a_driver = {
69 .probe = zcrypt_cex2a_probe,
70 .remove = zcrypt_cex2a_remove,
71 .receive = zcrypt_cex2a_receive,
72 .ids = zcrypt_cex2a_ids,
73};
74
75/**
76 * Convert a ICAMEX message to a type50 MEX message.
77 *
78 * @zdev: crypto device pointer
79 * @zreq: crypto request pointer
80 * @mex: pointer to user input data
81 *
82 * Returns 0 on success or -EFAULT.
83 */
84static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_device *zdev,
85 struct ap_message *ap_msg,
86 struct ica_rsa_modexpo *mex)
87{
88 unsigned char *mod, *exp, *inp;
89 int mod_len;
90
91 mod_len = mex->inputdatalength;
92
93 if (mod_len <= 128) {
94 struct type50_meb1_msg *meb1 = ap_msg->message;
95 memset(meb1, 0, sizeof(*meb1));
96 ap_msg->length = sizeof(*meb1);
97 meb1->header.msg_type_code = TYPE50_TYPE_CODE;
98 meb1->header.msg_len = sizeof(*meb1);
99 meb1->keyblock_type = TYPE50_MEB1_FMT;
100 mod = meb1->modulus + sizeof(meb1->modulus) - mod_len;
101 exp = meb1->exponent + sizeof(meb1->exponent) - mod_len;
102 inp = meb1->message + sizeof(meb1->message) - mod_len;
103 } else {
104 struct type50_meb2_msg *meb2 = ap_msg->message;
105 memset(meb2, 0, sizeof(*meb2));
106 ap_msg->length = sizeof(*meb2);
107 meb2->header.msg_type_code = TYPE50_TYPE_CODE;
108 meb2->header.msg_len = sizeof(*meb2);
109 meb2->keyblock_type = TYPE50_MEB2_FMT;
110 mod = meb2->modulus + sizeof(meb2->modulus) - mod_len;
111 exp = meb2->exponent + sizeof(meb2->exponent) - mod_len;
112 inp = meb2->message + sizeof(meb2->message) - mod_len;
113 }
114
115 if (copy_from_user(mod, mex->n_modulus, mod_len) ||
116 copy_from_user(exp, mex->b_key, mod_len) ||
117 copy_from_user(inp, mex->inputdata, mod_len))
118 return -EFAULT;
119 return 0;
120}
121
122/**
123 * Convert a ICACRT message to a type50 CRT message.
124 *
125 * @zdev: crypto device pointer
126 * @zreq: crypto request pointer
127 * @crt: pointer to user input data
128 *
129 * Returns 0 on success or -EFAULT.
130 */
131static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
132 struct ap_message *ap_msg,
133 struct ica_rsa_modexpo_crt *crt)
134{
135 int mod_len, short_len, long_len, long_offset;
136 unsigned char *p, *q, *dp, *dq, *u, *inp;
137
138 mod_len = crt->inputdatalength;
139 short_len = mod_len / 2;
140 long_len = mod_len / 2 + 8;
141
142 /*
143 * CEX2A cannot handle p, dp, or U > 128 bytes.
144 * If we have one of these, we need to do extra checking.
145 */
146 if (long_len > 128) {
147 /*
148 * zcrypt_rsa_crt already checked for the leading
149 * zeroes of np_prime, bp_key and u_mult_inc.
150 */
151 long_offset = long_len - 128;
152 long_len = 128;
153 } else
154 long_offset = 0;
155
156 /*
157 * Instead of doing extra work for p, dp, U > 64 bytes, we'll just use
158 * the larger message structure.
159 */
160 if (long_len <= 64) {
161 struct type50_crb1_msg *crb1 = ap_msg->message;
162 memset(crb1, 0, sizeof(*crb1));
163 ap_msg->length = sizeof(*crb1);
164 crb1->header.msg_type_code = TYPE50_TYPE_CODE;
165 crb1->header.msg_len = sizeof(*crb1);
166 crb1->keyblock_type = TYPE50_CRB1_FMT;
167 p = crb1->p + sizeof(crb1->p) - long_len;
168 q = crb1->q + sizeof(crb1->q) - short_len;
169 dp = crb1->dp + sizeof(crb1->dp) - long_len;
170 dq = crb1->dq + sizeof(crb1->dq) - short_len;
171 u = crb1->u + sizeof(crb1->u) - long_len;
172 inp = crb1->message + sizeof(crb1->message) - mod_len;
173 } else {
174 struct type50_crb2_msg *crb2 = ap_msg->message;
175 memset(crb2, 0, sizeof(*crb2));
176 ap_msg->length = sizeof(*crb2);
177 crb2->header.msg_type_code = TYPE50_TYPE_CODE;
178 crb2->header.msg_len = sizeof(*crb2);
179 crb2->keyblock_type = TYPE50_CRB2_FMT;
180 p = crb2->p + sizeof(crb2->p) - long_len;
181 q = crb2->q + sizeof(crb2->q) - short_len;
182 dp = crb2->dp + sizeof(crb2->dp) - long_len;
183 dq = crb2->dq + sizeof(crb2->dq) - short_len;
184 u = crb2->u + sizeof(crb2->u) - long_len;
185 inp = crb2->message + sizeof(crb2->message) - mod_len;
186 }
187
188 if (copy_from_user(p, crt->np_prime + long_offset, long_len) ||
189 copy_from_user(q, crt->nq_prime, short_len) ||
190 copy_from_user(dp, crt->bp_key + long_offset, long_len) ||
191 copy_from_user(dq, crt->bq_key, short_len) ||
192 copy_from_user(u, crt->u_mult_inv + long_offset, long_len) ||
193 copy_from_user(inp, crt->inputdata, mod_len))
194 return -EFAULT;
195
196
197 return 0;
198}
199
200/**
201 * Copy results from a type 80 reply message back to user space.
202 *
203 * @zdev: crypto device pointer
204 * @reply: reply AP message.
205 * @data: pointer to user output data
206 * @length: size of user output data
207 *
208 * Returns 0 on success or -EFAULT.
209 */
210static int convert_type80(struct zcrypt_device *zdev,
211 struct ap_message *reply,
212 char __user *outputdata,
213 unsigned int outputdatalength)
214{
215 struct type80_hdr *t80h = reply->message;
216 unsigned char *data;
217
218 if (t80h->len < sizeof(*t80h) + outputdatalength) {
219 /* The result is too short, the CEX2A card may not do that.. */
220 zdev->online = 0;
221 return -EAGAIN; /* repeat the request on a different device. */
222 }
223 BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE);
224 data = reply->message + t80h->len - outputdatalength;
225 if (copy_to_user(outputdata, data, outputdatalength))
226 return -EFAULT;
227 return 0;
228}
229
230static int convert_response(struct zcrypt_device *zdev,
231 struct ap_message *reply,
232 char __user *outputdata,
233 unsigned int outputdatalength)
234{
235 /* Response type byte is the second byte in the response. */
236 switch (((unsigned char *) reply->message)[1]) {
237 case TYPE82_RSP_CODE:
238 case TYPE88_RSP_CODE:
239 return convert_error(zdev, reply);
240 case TYPE80_RSP_CODE:
241 return convert_type80(zdev, reply,
242 outputdata, outputdatalength);
243 default: /* Unknown response type, this should NEVER EVER happen */
244 PRINTK("Unrecognized Message Header: %08x%08x\n",
245 *(unsigned int *) reply->message,
246 *(unsigned int *) (reply->message+4));
247 zdev->online = 0;
248 return -EAGAIN; /* repeat the request on a different device. */
249 }
250}
251
252/**
253 * This function is called from the AP bus code after a crypto request
254 * "msg" has finished with the reply message "reply".
255 * It is called from tasklet context.
256 * @ap_dev: pointer to the AP device
257 * @msg: pointer to the AP message
258 * @reply: pointer to the AP reply message
259 */
260static void zcrypt_cex2a_receive(struct ap_device *ap_dev,
261 struct ap_message *msg,
262 struct ap_message *reply)
263{
264 static struct error_hdr error_reply = {
265 .type = TYPE82_RSP_CODE,
266 .reply_code = REP82_ERROR_MACHINE_FAILURE,
267 };
268 struct type80_hdr *t80h = reply->message;
269 int length;
270
271 /* Copy the reply message to the request message buffer. */
272 if (IS_ERR(reply))
273 memcpy(msg->message, &error_reply, sizeof(error_reply));
274 else if (t80h->type == TYPE80_RSP_CODE) {
275 length = min(CEX2A_MAX_RESPONSE_SIZE, (int) t80h->len);
276 memcpy(msg->message, reply->message, length);
277 } else
278 memcpy(msg->message, reply->message, sizeof error_reply);
279 complete((struct completion *) msg->private);
280}
281
282static atomic_t zcrypt_step = ATOMIC_INIT(0);
283
284/**
285 * The request distributor calls this function if it picked the CEX2A
286 * device to handle a modexpo request.
287 * @zdev: pointer to zcrypt_device structure that identifies the
288 * CEX2A device to the request distributor
289 * @mex: pointer to the modexpo request buffer
290 */
291static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
292 struct ica_rsa_modexpo *mex)
293{
294 struct ap_message ap_msg;
295 struct completion work;
296 int rc;
297
298 ap_msg.message = (void *) kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
299 if (!ap_msg.message)
300 return -ENOMEM;
301 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
302 atomic_inc_return(&zcrypt_step);
303 ap_msg.private = &work;
304 rc = ICAMEX_msg_to_type50MEX_msg(zdev, &ap_msg, mex);
305 if (rc)
306 goto out_free;
307 init_completion(&work);
308 ap_queue_message(zdev->ap_dev, &ap_msg);
309 rc = wait_for_completion_interruptible_timeout(
310 &work, CEX2A_CLEANUP_TIME);
311 if (rc > 0)
312 rc = convert_response(zdev, &ap_msg, mex->outputdata,
313 mex->outputdatalength);
314 else {
315 /* Signal pending or message timed out. */
316 ap_cancel_message(zdev->ap_dev, &ap_msg);
317 if (rc == 0)
318 /* Message timed out. */
319 rc = -ETIME;
320 }
321out_free:
322 kfree(ap_msg.message);
323 return rc;
324}
325
326/**
327 * The request distributor calls this function if it picked the CEX2A
328 * device to handle a modexpo_crt request.
329 * @zdev: pointer to zcrypt_device structure that identifies the
330 * CEX2A device to the request distributor
331 * @crt: pointer to the modexpoc_crt request buffer
332 */
333static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
334 struct ica_rsa_modexpo_crt *crt)
335{
336 struct ap_message ap_msg;
337 struct completion work;
338 int rc;
339
340 ap_msg.message = (void *) kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
341 if (!ap_msg.message)
342 return -ENOMEM;
343 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
344 atomic_inc_return(&zcrypt_step);
345 ap_msg.private = &work;
346 rc = ICACRT_msg_to_type50CRT_msg(zdev, &ap_msg, crt);
347 if (rc)
348 goto out_free;
349 init_completion(&work);
350 ap_queue_message(zdev->ap_dev, &ap_msg);
351 rc = wait_for_completion_interruptible_timeout(
352 &work, CEX2A_CLEANUP_TIME);
353 if (rc > 0)
354 rc = convert_response(zdev, &ap_msg, crt->outputdata,
355 crt->outputdatalength);
356 else {
357 /* Signal pending or message timed out. */
358 ap_cancel_message(zdev->ap_dev, &ap_msg);
359 if (rc == 0)
360 /* Message timed out. */
361 rc = -ETIME;
362 }
363out_free:
364 kfree(ap_msg.message);
365 return rc;
366}
367
368/**
369 * The crypto operations for a CEX2A card.
370 */
371static struct zcrypt_ops zcrypt_cex2a_ops = {
372 .rsa_modexpo = zcrypt_cex2a_modexpo,
373 .rsa_modexpo_crt = zcrypt_cex2a_modexpo_crt,
374};
375
376/**
377 * Probe function for CEX2A cards. It always accepts the AP device
378 * since the bus_match already checked the hardware type.
379 * @ap_dev: pointer to the AP device.
380 */
381static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
382{
383 struct zcrypt_device *zdev;
384 int rc;
385
386 zdev = zcrypt_device_alloc(CEX2A_MAX_RESPONSE_SIZE);
387 if (!zdev)
388 return -ENOMEM;
389 zdev->ap_dev = ap_dev;
390 zdev->ops = &zcrypt_cex2a_ops;
391 zdev->online = 1;
392 zdev->user_space_type = ZCRYPT_CEX2A;
393 zdev->type_string = "CEX2A";
394 zdev->min_mod_size = CEX2A_MIN_MOD_SIZE;
395 zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
396 zdev->short_crt = 1;
397 zdev->speed_rating = CEX2A_SPEED_RATING;
398 ap_dev->reply = &zdev->reply;
399 ap_dev->private = zdev;
400 rc = zcrypt_device_register(zdev);
401 if (rc)
402 goto out_free;
403 return 0;
404
405out_free:
406 ap_dev->private = NULL;
407 zcrypt_device_free(zdev);
408 return rc;
409}
410
411/**
412 * This is called to remove the extended CEX2A driver information
413 * if an AP device is removed.
414 */
415static void zcrypt_cex2a_remove(struct ap_device *ap_dev)
416{
417 struct zcrypt_device *zdev = ap_dev->private;
418
419 zcrypt_device_unregister(zdev);
420}
421
422int __init zcrypt_cex2a_init(void)
423{
424 return ap_driver_register(&zcrypt_cex2a_driver, THIS_MODULE, "cex2a");
425}
426
427void __exit zcrypt_cex2a_exit(void)
428{
429 ap_driver_unregister(&zcrypt_cex2a_driver);
430}
431
432#ifndef CONFIG_ZCRYPT_MONOLITHIC
433module_init(zcrypt_cex2a_init);
434module_exit(zcrypt_cex2a_exit);
435#endif
diff --git a/drivers/s390/crypto/zcrypt_cex2a.h b/drivers/s390/crypto/zcrypt_cex2a.h
new file mode 100644
index 000000000000..8f69d1dacab8
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_cex2a.h
@@ -0,0 +1,126 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_cex2a.h
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_CEX2A_H_
29#define _ZCRYPT_CEX2A_H_
30
31/**
32 * The type 50 message family is associated with a CEX2A card.
33 *
34 * The four members of the family are described below.
35 *
36 * Note that all unsigned char arrays are right-justified and left-padded
37 * with zeroes.
38 *
39 * Note that all reserved fields must be zeroes.
40 */
41struct type50_hdr {
42 unsigned char reserved1;
43 unsigned char msg_type_code; /* 0x50 */
44 unsigned short msg_len;
45 unsigned char reserved2;
46 unsigned char ignored;
47 unsigned short reserved3;
48} __attribute__((packed));
49
50#define TYPE50_TYPE_CODE 0x50
51
52#define TYPE50_MEB1_FMT 0x0001
53#define TYPE50_MEB2_FMT 0x0002
54#define TYPE50_CRB1_FMT 0x0011
55#define TYPE50_CRB2_FMT 0x0012
56
57/* Mod-Exp, with a small modulus */
58struct type50_meb1_msg {
59 struct type50_hdr header;
60 unsigned short keyblock_type; /* 0x0001 */
61 unsigned char reserved[6];
62 unsigned char exponent[128];
63 unsigned char modulus[128];
64 unsigned char message[128];
65} __attribute__((packed));
66
67/* Mod-Exp, with a large modulus */
68struct type50_meb2_msg {
69 struct type50_hdr header;
70 unsigned short keyblock_type; /* 0x0002 */
71 unsigned char reserved[6];
72 unsigned char exponent[256];
73 unsigned char modulus[256];
74 unsigned char message[256];
75} __attribute__((packed));
76
77/* CRT, with a small modulus */
78struct type50_crb1_msg {
79 struct type50_hdr header;
80 unsigned short keyblock_type; /* 0x0011 */
81 unsigned char reserved[6];
82 unsigned char p[64];
83 unsigned char q[64];
84 unsigned char dp[64];
85 unsigned char dq[64];
86 unsigned char u[64];
87 unsigned char message[128];
88} __attribute__((packed));
89
90/* CRT, with a large modulus */
91struct type50_crb2_msg {
92 struct type50_hdr header;
93 unsigned short keyblock_type; /* 0x0012 */
94 unsigned char reserved[6];
95 unsigned char p[128];
96 unsigned char q[128];
97 unsigned char dp[128];
98 unsigned char dq[128];
99 unsigned char u[128];
100 unsigned char message[256];
101} __attribute__((packed));
102
103/**
104 * The type 80 response family is associated with a CEX2A card.
105 *
106 * Note that all unsigned char arrays are right-justified and left-padded
107 * with zeroes.
108 *
109 * Note that all reserved fields must be zeroes.
110 */
111
112#define TYPE80_RSP_CODE 0x80
113
114struct type80_hdr {
115 unsigned char reserved1;
116 unsigned char type; /* 0x80 */
117 unsigned short len;
118 unsigned char code; /* 0x00 */
119 unsigned char reserved2[3];
120 unsigned char reserved3[8];
121} __attribute__((packed));
122
123int zcrypt_cex2a_init(void);
124void zcrypt_cex2a_exit(void);
125
126#endif /* _ZCRYPT_CEX2A_H_ */
diff --git a/drivers/s390/crypto/zcrypt_error.h b/drivers/s390/crypto/zcrypt_error.h
new file mode 100644
index 000000000000..2cb616ba8bec
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_error.h
@@ -0,0 +1,133 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_error.h
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_ERROR_H_
29#define _ZCRYPT_ERROR_H_
30
31#include "zcrypt_api.h"
32
33/**
34 * Reply Messages
35 *
36 * Error reply messages are of two types:
37 * 82: Error (see below)
38 * 88: Error (see below)
39 * Both type 82 and type 88 have the same structure in the header.
40 *
41 * Request reply messages are of three known types:
42 * 80: Reply from a Type 50 Request (see CEX2A-RELATED STRUCTS)
43 * 84: Reply from a Type 4 Request (see PCICA-RELATED STRUCTS)
44 * 86: Reply from a Type 6 Request (see PCICC/PCIXCC/CEX2C-RELATED STRUCTS)
45 *
46 */
47struct error_hdr {
48 unsigned char reserved1; /* 0x00 */
49 unsigned char type; /* 0x82 or 0x88 */
50 unsigned char reserved2[2]; /* 0x0000 */
51 unsigned char reply_code; /* reply code */
52 unsigned char reserved3[3]; /* 0x000000 */
53};
54
55#define TYPE82_RSP_CODE 0x82
56#define TYPE88_RSP_CODE 0x88
57
58#define REP82_ERROR_MACHINE_FAILURE 0x10
59#define REP82_ERROR_PREEMPT_FAILURE 0x12
60#define REP82_ERROR_CHECKPT_FAILURE 0x14
61#define REP82_ERROR_MESSAGE_TYPE 0x20
62#define REP82_ERROR_INVALID_COMM_CD 0x21 /* Type 84 */
63#define REP82_ERROR_INVALID_MSG_LEN 0x23
64#define REP82_ERROR_RESERVD_FIELD 0x24 /* was 0x50 */
65#define REP82_ERROR_FORMAT_FIELD 0x29
66#define REP82_ERROR_INVALID_COMMAND 0x30
67#define REP82_ERROR_MALFORMED_MSG 0x40
68#define REP82_ERROR_RESERVED_FIELDO 0x50 /* old value */
69#define REP82_ERROR_WORD_ALIGNMENT 0x60
70#define REP82_ERROR_MESSAGE_LENGTH 0x80
71#define REP82_ERROR_OPERAND_INVALID 0x82
72#define REP82_ERROR_OPERAND_SIZE 0x84
73#define REP82_ERROR_EVEN_MOD_IN_OPND 0x85
74#define REP82_ERROR_RESERVED_FIELD 0x88
75#define REP82_ERROR_TRANSPORT_FAIL 0x90
76#define REP82_ERROR_PACKET_TRUNCATED 0xA0
77#define REP82_ERROR_ZERO_BUFFER_LEN 0xB0
78
79#define REP88_ERROR_MODULE_FAILURE 0x10
80
81#define REP88_ERROR_MESSAGE_TYPE 0x20
82#define REP88_ERROR_MESSAGE_MALFORMD 0x22
83#define REP88_ERROR_MESSAGE_LENGTH 0x23
84#define REP88_ERROR_RESERVED_FIELD 0x24
85#define REP88_ERROR_KEY_TYPE 0x34
86#define REP88_ERROR_INVALID_KEY 0x82 /* CEX2A */
87#define REP88_ERROR_OPERAND 0x84 /* CEX2A */
88#define REP88_ERROR_OPERAND_EVEN_MOD 0x85 /* CEX2A */
89
90static inline int convert_error(struct zcrypt_device *zdev,
91 struct ap_message *reply)
92{
93 struct error_hdr *ehdr = reply->message;
94
95 PRINTK("Hardware error : Type %02x Message Header: %08x%08x\n",
96 ehdr->type, *(unsigned int *) reply->message,
97 *(unsigned int *) (reply->message + 4));
98
99 switch (ehdr->reply_code) {
100 case REP82_ERROR_OPERAND_INVALID:
101 case REP82_ERROR_OPERAND_SIZE:
102 case REP82_ERROR_EVEN_MOD_IN_OPND:
103 case REP88_ERROR_MESSAGE_MALFORMD:
104 // REP88_ERROR_INVALID_KEY // '82' CEX2A
105 // REP88_ERROR_OPERAND // '84' CEX2A
106 // REP88_ERROR_OPERAND_EVEN_MOD // '85' CEX2A
107 /* Invalid input data. */
108 return -EINVAL;
109 case REP82_ERROR_MESSAGE_TYPE:
110 // REP88_ERROR_MESSAGE_TYPE // '20' CEX2A
111 /**
112 * To sent a message of the wrong type is a bug in the
113 * device driver. Warn about it, disable the device
114 * and then repeat the request.
115 */
116 WARN_ON(1);
117 zdev->online = 0;
118 return -EAGAIN;
119 case REP82_ERROR_TRANSPORT_FAIL:
120 case REP82_ERROR_MACHINE_FAILURE:
121 // REP88_ERROR_MODULE_FAILURE // '10' CEX2A
122 /* If a card fails disable it and repeat the request. */
123 zdev->online = 0;
124 return -EAGAIN;
125 default:
126 PRINTKW("unknown type %02x reply code = %d\n",
127 ehdr->type, ehdr->reply_code);
128 zdev->online = 0;
129 return -EAGAIN; /* repeat the request on a different device. */
130 }
131}
132
133#endif /* _ZCRYPT_ERROR_H_ */
diff --git a/drivers/s390/crypto/zcrypt_mono.c b/drivers/s390/crypto/zcrypt_mono.c
new file mode 100644
index 000000000000..2a9349ad68b7
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_mono.c
@@ -0,0 +1,100 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_mono.c
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/miscdevice.h>
32#include <linux/fs.h>
33#include <linux/proc_fs.h>
34#include <linux/compat.h>
35#include <asm/atomic.h>
36#include <asm/uaccess.h>
37
38#include "ap_bus.h"
39#include "zcrypt_api.h"
40#include "zcrypt_pcica.h"
41#include "zcrypt_pcicc.h"
42#include "zcrypt_pcixcc.h"
43#include "zcrypt_cex2a.h"
44
45/**
46 * The module initialization code.
47 */
48int __init zcrypt_init(void)
49{
50 int rc;
51
52 rc = ap_module_init();
53 if (rc)
54 goto out;
55 rc = zcrypt_api_init();
56 if (rc)
57 goto out_ap;
58 rc = zcrypt_pcica_init();
59 if (rc)
60 goto out_api;
61 rc = zcrypt_pcicc_init();
62 if (rc)
63 goto out_pcica;
64 rc = zcrypt_pcixcc_init();
65 if (rc)
66 goto out_pcicc;
67 rc = zcrypt_cex2a_init();
68 if (rc)
69 goto out_pcixcc;
70 return 0;
71
72out_pcixcc:
73 zcrypt_pcixcc_exit();
74out_pcicc:
75 zcrypt_pcicc_exit();
76out_pcica:
77 zcrypt_pcica_exit();
78out_api:
79 zcrypt_api_exit();
80out_ap:
81 ap_module_exit();
82out:
83 return rc;
84}
85
86/**
87 * The module termination code.
88 */
89void __exit zcrypt_exit(void)
90{
91 zcrypt_cex2a_exit();
92 zcrypt_pcixcc_exit();
93 zcrypt_pcicc_exit();
94 zcrypt_pcica_exit();
95 zcrypt_api_exit();
96 ap_module_exit();
97}
98
99module_init(zcrypt_init);
100module_exit(zcrypt_exit);
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
new file mode 100644
index 000000000000..b6a4ecdc8025
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -0,0 +1,418 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcica.c
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 * Ralph Wuerthner <rwuerthn@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/err.h>
32#include <asm/atomic.h>
33#include <asm/uaccess.h>
34
35#include "ap_bus.h"
36#include "zcrypt_api.h"
37#include "zcrypt_error.h"
38#include "zcrypt_pcica.h"
39
40#define PCICA_MIN_MOD_SIZE 1 /* 8 bits */
41#define PCICA_MAX_MOD_SIZE 256 /* 2048 bits */
42
43#define PCICA_SPEED_RATING 2800
44
45#define PCICA_MAX_MESSAGE_SIZE 0x3a0 /* sizeof(struct type4_lcr) */
46#define PCICA_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */
47
48#define PCICA_CLEANUP_TIME (15*HZ)
49
50static struct ap_device_id zcrypt_pcica_ids[] = {
51 { AP_DEVICE(AP_DEVICE_TYPE_PCICA) },
52 { /* end of list */ },
53};
54
55#ifndef CONFIG_ZCRYPT_MONOLITHIC
56MODULE_DEVICE_TABLE(ap, zcrypt_pcica_ids);
57MODULE_AUTHOR("IBM Corporation");
58MODULE_DESCRIPTION("PCICA Cryptographic Coprocessor device driver, "
59 "Copyright 2001, 2006 IBM Corporation");
60MODULE_LICENSE("GPL");
61#endif
62
63static int zcrypt_pcica_probe(struct ap_device *ap_dev);
64static void zcrypt_pcica_remove(struct ap_device *ap_dev);
65static void zcrypt_pcica_receive(struct ap_device *, struct ap_message *,
66 struct ap_message *);
67
68static struct ap_driver zcrypt_pcica_driver = {
69 .probe = zcrypt_pcica_probe,
70 .remove = zcrypt_pcica_remove,
71 .receive = zcrypt_pcica_receive,
72 .ids = zcrypt_pcica_ids,
73};
74
75/**
76 * Convert a ICAMEX message to a type4 MEX message.
77 *
78 * @zdev: crypto device pointer
79 * @zreq: crypto request pointer
80 * @mex: pointer to user input data
81 *
82 * Returns 0 on success or -EFAULT.
83 */
84static int ICAMEX_msg_to_type4MEX_msg(struct zcrypt_device *zdev,
85 struct ap_message *ap_msg,
86 struct ica_rsa_modexpo *mex)
87{
88 unsigned char *modulus, *exponent, *message;
89 int mod_len;
90
91 mod_len = mex->inputdatalength;
92
93 if (mod_len <= 128) {
94 struct type4_sme *sme = ap_msg->message;
95 memset(sme, 0, sizeof(*sme));
96 ap_msg->length = sizeof(*sme);
97 sme->header.msg_fmt = TYPE4_SME_FMT;
98 sme->header.msg_len = sizeof(*sme);
99 sme->header.msg_type_code = TYPE4_TYPE_CODE;
100 sme->header.request_code = TYPE4_REQU_CODE;
101 modulus = sme->modulus + sizeof(sme->modulus) - mod_len;
102 exponent = sme->exponent + sizeof(sme->exponent) - mod_len;
103 message = sme->message + sizeof(sme->message) - mod_len;
104 } else {
105 struct type4_lme *lme = ap_msg->message;
106 memset(lme, 0, sizeof(*lme));
107 ap_msg->length = sizeof(*lme);
108 lme->header.msg_fmt = TYPE4_LME_FMT;
109 lme->header.msg_len = sizeof(*lme);
110 lme->header.msg_type_code = TYPE4_TYPE_CODE;
111 lme->header.request_code = TYPE4_REQU_CODE;
112 modulus = lme->modulus + sizeof(lme->modulus) - mod_len;
113 exponent = lme->exponent + sizeof(lme->exponent) - mod_len;
114 message = lme->message + sizeof(lme->message) - mod_len;
115 }
116
117 if (copy_from_user(modulus, mex->n_modulus, mod_len) ||
118 copy_from_user(exponent, mex->b_key, mod_len) ||
119 copy_from_user(message, mex->inputdata, mod_len))
120 return -EFAULT;
121 return 0;
122}
123
124/**
125 * Convert a ICACRT message to a type4 CRT message.
126 *
127 * @zdev: crypto device pointer
128 * @zreq: crypto request pointer
129 * @crt: pointer to user input data
130 *
131 * Returns 0 on success or -EFAULT.
132 */
133static int ICACRT_msg_to_type4CRT_msg(struct zcrypt_device *zdev,
134 struct ap_message *ap_msg,
135 struct ica_rsa_modexpo_crt *crt)
136{
137 unsigned char *p, *q, *dp, *dq, *u, *inp;
138 int mod_len, short_len, long_len;
139
140 mod_len = crt->inputdatalength;
141 short_len = mod_len / 2;
142 long_len = mod_len / 2 + 8;
143
144 if (mod_len <= 128) {
145 struct type4_scr *scr = ap_msg->message;
146 memset(scr, 0, sizeof(*scr));
147 ap_msg->length = sizeof(*scr);
148 scr->header.msg_type_code = TYPE4_TYPE_CODE;
149 scr->header.request_code = TYPE4_REQU_CODE;
150 scr->header.msg_fmt = TYPE4_SCR_FMT;
151 scr->header.msg_len = sizeof(*scr);
152 p = scr->p + sizeof(scr->p) - long_len;
153 q = scr->q + sizeof(scr->q) - short_len;
154 dp = scr->dp + sizeof(scr->dp) - long_len;
155 dq = scr->dq + sizeof(scr->dq) - short_len;
156 u = scr->u + sizeof(scr->u) - long_len;
157 inp = scr->message + sizeof(scr->message) - mod_len;
158 } else {
159 struct type4_lcr *lcr = ap_msg->message;
160 memset(lcr, 0, sizeof(*lcr));
161 ap_msg->length = sizeof(*lcr);
162 lcr->header.msg_type_code = TYPE4_TYPE_CODE;
163 lcr->header.request_code = TYPE4_REQU_CODE;
164 lcr->header.msg_fmt = TYPE4_LCR_FMT;
165 lcr->header.msg_len = sizeof(*lcr);
166 p = lcr->p + sizeof(lcr->p) - long_len;
167 q = lcr->q + sizeof(lcr->q) - short_len;
168 dp = lcr->dp + sizeof(lcr->dp) - long_len;
169 dq = lcr->dq + sizeof(lcr->dq) - short_len;
170 u = lcr->u + sizeof(lcr->u) - long_len;
171 inp = lcr->message + sizeof(lcr->message) - mod_len;
172 }
173
174 if (copy_from_user(p, crt->np_prime, long_len) ||
175 copy_from_user(q, crt->nq_prime, short_len) ||
176 copy_from_user(dp, crt->bp_key, long_len) ||
177 copy_from_user(dq, crt->bq_key, short_len) ||
178 copy_from_user(u, crt->u_mult_inv, long_len) ||
179 copy_from_user(inp, crt->inputdata, mod_len))
180 return -EFAULT;
181 return 0;
182}
183
184/**
185 * Copy results from a type 84 reply message back to user space.
186 *
187 * @zdev: crypto device pointer
188 * @reply: reply AP message.
189 * @data: pointer to user output data
190 * @length: size of user output data
191 *
192 * Returns 0 on success or -EFAULT.
193 */
194static inline int convert_type84(struct zcrypt_device *zdev,
195 struct ap_message *reply,
196 char __user *outputdata,
197 unsigned int outputdatalength)
198{
199 struct type84_hdr *t84h = reply->message;
200 char *data;
201
202 if (t84h->len < sizeof(*t84h) + outputdatalength) {
203 /* The result is too short, the PCICA card may not do that.. */
204 zdev->online = 0;
205 return -EAGAIN; /* repeat the request on a different device. */
206 }
207 BUG_ON(t84h->len > PCICA_MAX_RESPONSE_SIZE);
208 data = reply->message + t84h->len - outputdatalength;
209 if (copy_to_user(outputdata, data, outputdatalength))
210 return -EFAULT;
211 return 0;
212}
213
214static int convert_response(struct zcrypt_device *zdev,
215 struct ap_message *reply,
216 char __user *outputdata,
217 unsigned int outputdatalength)
218{
219 /* Response type byte is the second byte in the response. */
220 switch (((unsigned char *) reply->message)[1]) {
221 case TYPE82_RSP_CODE:
222 case TYPE88_RSP_CODE:
223 return convert_error(zdev, reply);
224 case TYPE84_RSP_CODE:
225 return convert_type84(zdev, reply,
226 outputdata, outputdatalength);
227 default: /* Unknown response type, this should NEVER EVER happen */
228 PRINTK("Unrecognized Message Header: %08x%08x\n",
229 *(unsigned int *) reply->message,
230 *(unsigned int *) (reply->message+4));
231 zdev->online = 0;
232 return -EAGAIN; /* repeat the request on a different device. */
233 }
234}
235
236/**
237 * This function is called from the AP bus code after a crypto request
238 * "msg" has finished with the reply message "reply".
239 * It is called from tasklet context.
240 * @ap_dev: pointer to the AP device
241 * @msg: pointer to the AP message
242 * @reply: pointer to the AP reply message
243 */
244static void zcrypt_pcica_receive(struct ap_device *ap_dev,
245 struct ap_message *msg,
246 struct ap_message *reply)
247{
248 static struct error_hdr error_reply = {
249 .type = TYPE82_RSP_CODE,
250 .reply_code = REP82_ERROR_MACHINE_FAILURE,
251 };
252 struct type84_hdr *t84h = reply->message;
253 int length;
254
255 /* Copy the reply message to the request message buffer. */
256 if (IS_ERR(reply))
257 memcpy(msg->message, &error_reply, sizeof(error_reply));
258 else if (t84h->code == TYPE84_RSP_CODE) {
259 length = min(PCICA_MAX_RESPONSE_SIZE, (int) t84h->len);
260 memcpy(msg->message, reply->message, length);
261 } else
262 memcpy(msg->message, reply->message, sizeof error_reply);
263 complete((struct completion *) msg->private);
264}
265
266static atomic_t zcrypt_step = ATOMIC_INIT(0);
267
268/**
269 * The request distributor calls this function if it picked the PCICA
270 * device to handle a modexpo request.
271 * @zdev: pointer to zcrypt_device structure that identifies the
272 * PCICA device to the request distributor
273 * @mex: pointer to the modexpo request buffer
274 */
275static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
276 struct ica_rsa_modexpo *mex)
277{
278 struct ap_message ap_msg;
279 struct completion work;
280 int rc;
281
282 ap_msg.message = (void *) kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
283 if (!ap_msg.message)
284 return -ENOMEM;
285 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
286 atomic_inc_return(&zcrypt_step);
287 ap_msg.private = &work;
288 rc = ICAMEX_msg_to_type4MEX_msg(zdev, &ap_msg, mex);
289 if (rc)
290 goto out_free;
291 init_completion(&work);
292 ap_queue_message(zdev->ap_dev, &ap_msg);
293 rc = wait_for_completion_interruptible_timeout(
294 &work, PCICA_CLEANUP_TIME);
295 if (rc > 0)
296 rc = convert_response(zdev, &ap_msg, mex->outputdata,
297 mex->outputdatalength);
298 else {
299 /* Signal pending or message timed out. */
300 ap_cancel_message(zdev->ap_dev, &ap_msg);
301 if (rc == 0)
302 /* Message timed out. */
303 rc = -ETIME;
304 }
305out_free:
306 kfree(ap_msg.message);
307 return rc;
308}
309
310/**
311 * The request distributor calls this function if it picked the PCICA
312 * device to handle a modexpo_crt request.
313 * @zdev: pointer to zcrypt_device structure that identifies the
314 * PCICA device to the request distributor
315 * @crt: pointer to the modexpoc_crt request buffer
316 */
317static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
318 struct ica_rsa_modexpo_crt *crt)
319{
320 struct ap_message ap_msg;
321 struct completion work;
322 int rc;
323
324 ap_msg.message = (void *) kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
325 if (!ap_msg.message)
326 return -ENOMEM;
327 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
328 atomic_inc_return(&zcrypt_step);
329 ap_msg.private = &work;
330 rc = ICACRT_msg_to_type4CRT_msg(zdev, &ap_msg, crt);
331 if (rc)
332 goto out_free;
333 init_completion(&work);
334 ap_queue_message(zdev->ap_dev, &ap_msg);
335 rc = wait_for_completion_interruptible_timeout(
336 &work, PCICA_CLEANUP_TIME);
337 if (rc > 0)
338 rc = convert_response(zdev, &ap_msg, crt->outputdata,
339 crt->outputdatalength);
340 else {
341 /* Signal pending or message timed out. */
342 ap_cancel_message(zdev->ap_dev, &ap_msg);
343 if (rc == 0)
344 /* Message timed out. */
345 rc = -ETIME;
346 }
347out_free:
348 kfree(ap_msg.message);
349 return rc;
350}
351
352/**
353 * The crypto operations for a PCICA card.
354 */
355static struct zcrypt_ops zcrypt_pcica_ops = {
356 .rsa_modexpo = zcrypt_pcica_modexpo,
357 .rsa_modexpo_crt = zcrypt_pcica_modexpo_crt,
358};
359
360/**
361 * Probe function for PCICA cards. It always accepts the AP device
362 * since the bus_match already checked the hardware type.
363 * @ap_dev: pointer to the AP device.
364 */
365static int zcrypt_pcica_probe(struct ap_device *ap_dev)
366{
367 struct zcrypt_device *zdev;
368 int rc;
369
370 zdev = zcrypt_device_alloc(PCICA_MAX_RESPONSE_SIZE);
371 if (!zdev)
372 return -ENOMEM;
373 zdev->ap_dev = ap_dev;
374 zdev->ops = &zcrypt_pcica_ops;
375 zdev->online = 1;
376 zdev->user_space_type = ZCRYPT_PCICA;
377 zdev->type_string = "PCICA";
378 zdev->min_mod_size = PCICA_MIN_MOD_SIZE;
379 zdev->max_mod_size = PCICA_MAX_MOD_SIZE;
380 zdev->speed_rating = PCICA_SPEED_RATING;
381 ap_dev->reply = &zdev->reply;
382 ap_dev->private = zdev;
383 rc = zcrypt_device_register(zdev);
384 if (rc)
385 goto out_free;
386 return 0;
387
388out_free:
389 ap_dev->private = NULL;
390 zcrypt_device_free(zdev);
391 return rc;
392}
393
394/**
395 * This is called to remove the extended PCICA driver information
396 * if an AP device is removed.
397 */
398static void zcrypt_pcica_remove(struct ap_device *ap_dev)
399{
400 struct zcrypt_device *zdev = ap_dev->private;
401
402 zcrypt_device_unregister(zdev);
403}
404
405int __init zcrypt_pcica_init(void)
406{
407 return ap_driver_register(&zcrypt_pcica_driver, THIS_MODULE, "pcica");
408}
409
410void zcrypt_pcica_exit(void)
411{
412 ap_driver_unregister(&zcrypt_pcica_driver);
413}
414
415#ifndef CONFIG_ZCRYPT_MONOLITHIC
416module_init(zcrypt_pcica_init);
417module_exit(zcrypt_pcica_exit);
418#endif
diff --git a/drivers/s390/crypto/zcrypt_pcica.h b/drivers/s390/crypto/zcrypt_pcica.h
new file mode 100644
index 000000000000..3be11187f6df
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcica.h
@@ -0,0 +1,117 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcica.h
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_PCICA_H_
29#define _ZCRYPT_PCICA_H_
30
31/**
32 * The type 4 message family is associated with a PCICA card.
33 *
34 * The four members of the family are described below.
35 *
36 * Note that all unsigned char arrays are right-justified and left-padded
37 * with zeroes.
38 *
39 * Note that all reserved fields must be zeroes.
40 */
41struct type4_hdr {
42 unsigned char reserved1;
43 unsigned char msg_type_code; /* 0x04 */
44 unsigned short msg_len;
45 unsigned char request_code; /* 0x40 */
46 unsigned char msg_fmt;
47 unsigned short reserved2;
48} __attribute__((packed));
49
50#define TYPE4_TYPE_CODE 0x04
51#define TYPE4_REQU_CODE 0x40
52
53#define TYPE4_SME_FMT 0x00
54#define TYPE4_LME_FMT 0x10
55#define TYPE4_SCR_FMT 0x40
56#define TYPE4_LCR_FMT 0x50
57
58/* Mod-Exp, with a small modulus */
59struct type4_sme {
60 struct type4_hdr header;
61 unsigned char message[128];
62 unsigned char exponent[128];
63 unsigned char modulus[128];
64} __attribute__((packed));
65
66/* Mod-Exp, with a large modulus */
67struct type4_lme {
68 struct type4_hdr header;
69 unsigned char message[256];
70 unsigned char exponent[256];
71 unsigned char modulus[256];
72} __attribute__((packed));
73
74/* CRT, with a small modulus */
75struct type4_scr {
76 struct type4_hdr header;
77 unsigned char message[128];
78 unsigned char dp[72];
79 unsigned char dq[64];
80 unsigned char p[72];
81 unsigned char q[64];
82 unsigned char u[72];
83} __attribute__((packed));
84
85/* CRT, with a large modulus */
86struct type4_lcr {
87 struct type4_hdr header;
88 unsigned char message[256];
89 unsigned char dp[136];
90 unsigned char dq[128];
91 unsigned char p[136];
92 unsigned char q[128];
93 unsigned char u[136];
94} __attribute__((packed));
95
96/**
97 * The type 84 response family is associated with a PCICA card.
98 *
99 * Note that all unsigned char arrays are right-justified and left-padded
100 * with zeroes.
101 *
102 * Note that all reserved fields must be zeroes.
103 */
104
105struct type84_hdr {
106 unsigned char reserved1;
107 unsigned char code;
108 unsigned short len;
109 unsigned char reserved2[4];
110} __attribute__((packed));
111
112#define TYPE84_RSP_CODE 0x84
113
114int zcrypt_pcica_init(void);
115void zcrypt_pcica_exit(void);
116
117#endif /* _ZCRYPT_PCICA_H_ */
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
new file mode 100644
index 000000000000..f295a403b29a
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -0,0 +1,630 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcicc.c
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 * Ralph Wuerthner <rwuerthn@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/err.h>
32#include <asm/atomic.h>
33#include <asm/uaccess.h>
34
35#include "ap_bus.h"
36#include "zcrypt_api.h"
37#include "zcrypt_error.h"
38#include "zcrypt_pcicc.h"
39#include "zcrypt_cca_key.h"
40
41#define PCICC_MIN_MOD_SIZE 64 /* 512 bits */
42#define PCICC_MAX_MOD_SIZE_OLD 128 /* 1024 bits */
43#define PCICC_MAX_MOD_SIZE 256 /* 2048 bits */
44
45/**
46 * PCICC cards need a speed rating of 0. This keeps them at the end of
47 * the zcrypt device list (see zcrypt_api.c). PCICC cards are only
48 * used if no other cards are present because they are slow and can only
49 * cope with PKCS12 padded requests. The logic is queer. PKCS11 padded
50 * requests are rejected. The modexpo function encrypts PKCS12 padded data
51 * and decrypts any non-PKCS12 padded data (except PKCS11) in the assumption
52 * that it's encrypted PKCS12 data. The modexpo_crt function always decrypts
53 * the data in the assumption that its PKCS12 encrypted data.
54 */
55#define PCICC_SPEED_RATING 0
56
57#define PCICC_MAX_MESSAGE_SIZE 0x710 /* max size type6 v1 crt message */
58#define PCICC_MAX_RESPONSE_SIZE 0x710 /* max size type86 v1 reply */
59
60#define PCICC_CLEANUP_TIME (15*HZ)
61
62static struct ap_device_id zcrypt_pcicc_ids[] = {
63 { AP_DEVICE(AP_DEVICE_TYPE_PCICC) },
64 { /* end of list */ },
65};
66
67#ifndef CONFIG_ZCRYPT_MONOLITHIC
68MODULE_DEVICE_TABLE(ap, zcrypt_pcicc_ids);
69MODULE_AUTHOR("IBM Corporation");
70MODULE_DESCRIPTION("PCICC Cryptographic Coprocessor device driver, "
71 "Copyright 2001, 2006 IBM Corporation");
72MODULE_LICENSE("GPL");
73#endif
74
75static int zcrypt_pcicc_probe(struct ap_device *ap_dev);
76static void zcrypt_pcicc_remove(struct ap_device *ap_dev);
77static void zcrypt_pcicc_receive(struct ap_device *, struct ap_message *,
78 struct ap_message *);
79
80static struct ap_driver zcrypt_pcicc_driver = {
81 .probe = zcrypt_pcicc_probe,
82 .remove = zcrypt_pcicc_remove,
83 .receive = zcrypt_pcicc_receive,
84 .ids = zcrypt_pcicc_ids,
85};
86
87/**
88 * The following is used to initialize the CPRB passed to the PCICC card
89 * in a type6 message. The 3 fields that must be filled in at execution
90 * time are req_parml, rpl_parml and usage_domain. Note that all three
91 * fields are *little*-endian. Actually, everything about this interface
92 * is ascii/little-endian, since the device has 'Intel inside'.
93 *
94 * The CPRB is followed immediately by the parm block.
95 * The parm block contains:
96 * - function code ('PD' 0x5044 or 'PK' 0x504B)
97 * - rule block (0x0A00 'PKCS-1.2' or 0x0A00 'ZERO-PAD')
98 * - VUD block
99 */
100static struct CPRB static_cprb = {
101 .cprb_len = __constant_cpu_to_le16(0x0070),
102 .cprb_ver_id = 0x41,
103 .func_id = {0x54,0x32},
104 .checkpoint_flag= 0x01,
105 .svr_namel = __constant_cpu_to_le16(0x0008),
106 .svr_name = {'I','C','S','F',' ',' ',' ',' '}
107};
108
109/**
110 * Check the message for PKCS11 padding.
111 */
112static inline int is_PKCS11_padded(unsigned char *buffer, int length)
113{
114 int i;
115 if ((buffer[0] != 0x00) || (buffer[1] != 0x01))
116 return 0;
117 for (i = 2; i < length; i++)
118 if (buffer[i] != 0xFF)
119 break;
120 if (i < 10 || i == length)
121 return 0;
122 if (buffer[i] != 0x00)
123 return 0;
124 return 1;
125}
126
127/**
128 * Check the message for PKCS12 padding.
129 */
130static inline int is_PKCS12_padded(unsigned char *buffer, int length)
131{
132 int i;
133 if ((buffer[0] != 0x00) || (buffer[1] != 0x02))
134 return 0;
135 for (i = 2; i < length; i++)
136 if (buffer[i] == 0x00)
137 break;
138 if ((i < 10) || (i == length))
139 return 0;
140 if (buffer[i] != 0x00)
141 return 0;
142 return 1;
143}
144
145/**
146 * Convert a ICAMEX message to a type6 MEX message.
147 *
148 * @zdev: crypto device pointer
149 * @zreq: crypto request pointer
150 * @mex: pointer to user input data
151 *
152 * Returns 0 on success or -EFAULT.
153 */
154static int ICAMEX_msg_to_type6MEX_msg(struct zcrypt_device *zdev,
155 struct ap_message *ap_msg,
156 struct ica_rsa_modexpo *mex)
157{
158 static struct type6_hdr static_type6_hdr = {
159 .type = 0x06,
160 .offset1 = 0x00000058,
161 .agent_id = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
162 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
163 .function_code = {'P','K'},
164 };
165 static struct function_and_rules_block static_pke_function_and_rules ={
166 .function_code = {'P','K'},
167 .ulen = __constant_cpu_to_le16(10),
168 .only_rule = {'P','K','C','S','-','1','.','2'}
169 };
170 struct {
171 struct type6_hdr hdr;
172 struct CPRB cprb;
173 struct function_and_rules_block fr;
174 unsigned short length;
175 char text[0];
176 } __attribute__((packed)) *msg = ap_msg->message;
177 int vud_len, pad_len, size;
178
179 /* VUD.ciphertext */
180 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
181 return -EFAULT;
182
183 if (is_PKCS11_padded(msg->text, mex->inputdatalength))
184 return -EINVAL;
185
186 /* static message header and f&r */
187 msg->hdr = static_type6_hdr;
188 msg->fr = static_pke_function_and_rules;
189
190 if (is_PKCS12_padded(msg->text, mex->inputdatalength)) {
191 /* strip the padding and adjust the data length */
192 pad_len = strnlen(msg->text + 2, mex->inputdatalength - 2) + 3;
193 if (pad_len <= 9 || pad_len >= mex->inputdatalength)
194 return -ENODEV;
195 vud_len = mex->inputdatalength - pad_len;
196 memmove(msg->text, msg->text + pad_len, vud_len);
197 msg->length = cpu_to_le16(vud_len + 2);
198
199 /* Set up key after the variable length text. */
200 size = zcrypt_type6_mex_key_en(mex, msg->text + vud_len, 0);
201 if (size < 0)
202 return size;
203 size += sizeof(*msg) + vud_len; /* total size of msg */
204 } else {
205 vud_len = mex->inputdatalength;
206 msg->length = cpu_to_le16(2 + vud_len);
207
208 msg->hdr.function_code[1] = 'D';
209 msg->fr.function_code[1] = 'D';
210
211 /* Set up key after the variable length text. */
212 size = zcrypt_type6_mex_key_de(mex, msg->text + vud_len, 0);
213 if (size < 0)
214 return size;
215 size += sizeof(*msg) + vud_len; /* total size of msg */
216 }
217
218 /* message header, cprb and f&r */
219 msg->hdr.ToCardLen1 = (size - sizeof(msg->hdr) + 3) & -4;
220 msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
221
222 msg->cprb = static_cprb;
223 msg->cprb.usage_domain[0]= AP_QID_QUEUE(zdev->ap_dev->qid);
224 msg->cprb.req_parml = cpu_to_le16(size - sizeof(msg->hdr) -
225 sizeof(msg->cprb));
226 msg->cprb.rpl_parml = cpu_to_le16(msg->hdr.FromCardLen1);
227
228 ap_msg->length = (size + 3) & -4;
229 return 0;
230}
231
232/**
233 * Convert a ICACRT message to a type6 CRT message.
234 *
235 * @zdev: crypto device pointer
236 * @zreq: crypto request pointer
237 * @crt: pointer to user input data
238 *
239 * Returns 0 on success or -EFAULT.
240 */
241static int ICACRT_msg_to_type6CRT_msg(struct zcrypt_device *zdev,
242 struct ap_message *ap_msg,
243 struct ica_rsa_modexpo_crt *crt)
244{
245 static struct type6_hdr static_type6_hdr = {
246 .type = 0x06,
247 .offset1 = 0x00000058,
248 .agent_id = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
249 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
250 .function_code = {'P','D'},
251 };
252 static struct function_and_rules_block static_pkd_function_and_rules ={
253 .function_code = {'P','D'},
254 .ulen = __constant_cpu_to_le16(10),
255 .only_rule = {'P','K','C','S','-','1','.','2'}
256 };
257 struct {
258 struct type6_hdr hdr;
259 struct CPRB cprb;
260 struct function_and_rules_block fr;
261 unsigned short length;
262 char text[0];
263 } __attribute__((packed)) *msg = ap_msg->message;
264 int size;
265
266 /* VUD.ciphertext */
267 msg->length = cpu_to_le16(2 + crt->inputdatalength);
268 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
269 return -EFAULT;
270
271 if (is_PKCS11_padded(msg->text, crt->inputdatalength))
272 return -EINVAL;
273
274 /* Set up key after the variable length text. */
275 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 0);
276 if (size < 0)
277 return size;
278 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
279
280 /* message header, cprb and f&r */
281 msg->hdr = static_type6_hdr;
282 msg->hdr.ToCardLen1 = (size - sizeof(msg->hdr) + 3) & -4;
283 msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
284
285 msg->cprb = static_cprb;
286 msg->cprb.usage_domain[0] = AP_QID_QUEUE(zdev->ap_dev->qid);
287 msg->cprb.req_parml = msg->cprb.rpl_parml =
288 cpu_to_le16(size - sizeof(msg->hdr) - sizeof(msg->cprb));
289
290 msg->fr = static_pkd_function_and_rules;
291
292 ap_msg->length = (size + 3) & -4;
293 return 0;
294}
295
296/**
297 * Copy results from a type 86 reply message back to user space.
298 *
299 * @zdev: crypto device pointer
300 * @reply: reply AP message.
301 * @data: pointer to user output data
302 * @length: size of user output data
303 *
304 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
305 */
306struct type86_reply {
307 struct type86_hdr hdr;
308 struct type86_fmt2_ext fmt2;
309 struct CPRB cprb;
310 unsigned char pad[4]; /* 4 byte function code/rules block ? */
311 unsigned short length;
312 char text[0];
313} __attribute__((packed));
314
315static int convert_type86(struct zcrypt_device *zdev,
316 struct ap_message *reply,
317 char __user *outputdata,
318 unsigned int outputdatalength)
319{
320 static unsigned char static_pad[] = {
321 0x00,0x02,
322 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
323 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
324 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
325 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
326 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
327 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
328 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
329 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
330 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
331 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
332 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
333 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
334 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
335 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
336 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
337 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
338 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
339 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
340 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
341 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
342 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
343 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
344 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
345 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
346 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
347 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
348 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
349 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
350 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
351 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
352 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
353 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
354 };
355 struct type86_reply *msg = reply->message;
356 unsigned short service_rc, service_rs;
357 unsigned int reply_len, pad_len;
358 char *data;
359
360 service_rc = le16_to_cpu(msg->cprb.ccp_rtcode);
361 if (unlikely(service_rc != 0)) {
362 service_rs = le16_to_cpu(msg->cprb.ccp_rscode);
363 if (service_rc == 8 && service_rs == 66) {
364 PDEBUG("Bad block format on PCICC\n");
365 return -EINVAL;
366 }
367 if (service_rc == 8 && service_rs == 65) {
368 PDEBUG("Probably an even modulus on PCICC\n");
369 return -EINVAL;
370 }
371 if (service_rc == 8 && service_rs == 770) {
372 PDEBUG("Invalid key length on PCICC\n");
373 zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
374 return -EAGAIN;
375 }
376 if (service_rc == 8 && service_rs == 783) {
377 PDEBUG("Extended bitlengths not enabled on PCICC\n");
378 zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
379 return -EAGAIN;
380 }
381 PRINTK("Unknown service rc/rs (PCICC): %d/%d\n",
382 service_rc, service_rs);
383 zdev->online = 0;
384 return -EAGAIN; /* repeat the request on a different device. */
385 }
386 data = msg->text;
387 reply_len = le16_to_cpu(msg->length) - 2;
388 if (reply_len > outputdatalength)
389 return -EINVAL;
390 /**
391 * For all encipher requests, the length of the ciphertext (reply_len)
392 * will always equal the modulus length. For MEX decipher requests
393 * the output needs to get padded. Minimum pad size is 10.
394 *
395 * Currently, the cases where padding will be added is for:
396 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
397 * ZERO-PAD and CRT is only supported for PKD requests)
398 * - PCICC, always
399 */
400 pad_len = outputdatalength - reply_len;
401 if (pad_len > 0) {
402 if (pad_len < 10)
403 return -EINVAL;
404 /* 'restore' padding left in the PCICC/PCIXCC card. */
405 if (copy_to_user(outputdata, static_pad, pad_len - 1))
406 return -EFAULT;
407 if (put_user(0, outputdata + pad_len - 1))
408 return -EFAULT;
409 }
410 /* Copy the crypto response to user space. */
411 if (copy_to_user(outputdata + pad_len, data, reply_len))
412 return -EFAULT;
413 return 0;
414}
415
416static int convert_response(struct zcrypt_device *zdev,
417 struct ap_message *reply,
418 char __user *outputdata,
419 unsigned int outputdatalength)
420{
421 struct type86_reply *msg = reply->message;
422
423 /* Response type byte is the second byte in the response. */
424 switch (msg->hdr.type) {
425 case TYPE82_RSP_CODE:
426 case TYPE88_RSP_CODE:
427 return convert_error(zdev, reply);
428 case TYPE86_RSP_CODE:
429 if (msg->hdr.reply_code)
430 return convert_error(zdev, reply);
431 if (msg->cprb.cprb_ver_id == 0x01)
432 return convert_type86(zdev, reply,
433 outputdata, outputdatalength);
434 /* no break, incorrect cprb version is an unknown response */
435 default: /* Unknown response type, this should NEVER EVER happen */
436 PRINTK("Unrecognized Message Header: %08x%08x\n",
437 *(unsigned int *) reply->message,
438 *(unsigned int *) (reply->message+4));
439 zdev->online = 0;
440 return -EAGAIN; /* repeat the request on a different device. */
441 }
442}
443
444/**
445 * This function is called from the AP bus code after a crypto request
446 * "msg" has finished with the reply message "reply".
447 * It is called from tasklet context.
448 * @ap_dev: pointer to the AP device
449 * @msg: pointer to the AP message
450 * @reply: pointer to the AP reply message
451 */
452static void zcrypt_pcicc_receive(struct ap_device *ap_dev,
453 struct ap_message *msg,
454 struct ap_message *reply)
455{
456 static struct error_hdr error_reply = {
457 .type = TYPE82_RSP_CODE,
458 .reply_code = REP82_ERROR_MACHINE_FAILURE,
459 };
460 struct type86_reply *t86r = reply->message;
461 int length;
462
463 /* Copy the reply message to the request message buffer. */
464 if (IS_ERR(reply))
465 memcpy(msg->message, &error_reply, sizeof(error_reply));
466 else if (t86r->hdr.type == TYPE86_RSP_CODE &&
467 t86r->cprb.cprb_ver_id == 0x01) {
468 length = sizeof(struct type86_reply) + t86r->length - 2;
469 length = min(PCICC_MAX_RESPONSE_SIZE, length);
470 memcpy(msg->message, reply->message, length);
471 } else
472 memcpy(msg->message, reply->message, sizeof error_reply);
473 complete((struct completion *) msg->private);
474}
475
476static atomic_t zcrypt_step = ATOMIC_INIT(0);
477
478/**
479 * The request distributor calls this function if it picked the PCICC
480 * device to handle a modexpo request.
481 * @zdev: pointer to zcrypt_device structure that identifies the
482 * PCICC device to the request distributor
483 * @mex: pointer to the modexpo request buffer
484 */
485static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
486 struct ica_rsa_modexpo *mex)
487{
488 struct ap_message ap_msg;
489 struct completion work;
490 int rc;
491
492 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
493 if (!ap_msg.message)
494 return -ENOMEM;
495 ap_msg.length = PAGE_SIZE;
496 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
497 atomic_inc_return(&zcrypt_step);
498 ap_msg.private = &work;
499 rc = ICAMEX_msg_to_type6MEX_msg(zdev, &ap_msg, mex);
500 if (rc)
501 goto out_free;
502 init_completion(&work);
503 ap_queue_message(zdev->ap_dev, &ap_msg);
504 rc = wait_for_completion_interruptible_timeout(
505 &work, PCICC_CLEANUP_TIME);
506 if (rc > 0)
507 rc = convert_response(zdev, &ap_msg, mex->outputdata,
508 mex->outputdatalength);
509 else {
510 /* Signal pending or message timed out. */
511 ap_cancel_message(zdev->ap_dev, &ap_msg);
512 if (rc == 0)
513 /* Message timed out. */
514 rc = -ETIME;
515 }
516out_free:
517 free_page((unsigned long) ap_msg.message);
518 return rc;
519}
520
521/**
522 * The request distributor calls this function if it picked the PCICC
523 * device to handle a modexpo_crt request.
524 * @zdev: pointer to zcrypt_device structure that identifies the
525 * PCICC device to the request distributor
526 * @crt: pointer to the modexpoc_crt request buffer
527 */
528static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
529 struct ica_rsa_modexpo_crt *crt)
530{
531 struct ap_message ap_msg;
532 struct completion work;
533 int rc;
534
535 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
536 if (!ap_msg.message)
537 return -ENOMEM;
538 ap_msg.length = PAGE_SIZE;
539 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
540 atomic_inc_return(&zcrypt_step);
541 ap_msg.private = &work;
542 rc = ICACRT_msg_to_type6CRT_msg(zdev, &ap_msg, crt);
543 if (rc)
544 goto out_free;
545 init_completion(&work);
546 ap_queue_message(zdev->ap_dev, &ap_msg);
547 rc = wait_for_completion_interruptible_timeout(
548 &work, PCICC_CLEANUP_TIME);
549 if (rc > 0)
550 rc = convert_response(zdev, &ap_msg, crt->outputdata,
551 crt->outputdatalength);
552 else {
553 /* Signal pending or message timed out. */
554 ap_cancel_message(zdev->ap_dev, &ap_msg);
555 if (rc == 0)
556 /* Message timed out. */
557 rc = -ETIME;
558 }
559out_free:
560 free_page((unsigned long) ap_msg.message);
561 return rc;
562}
563
564/**
565 * The crypto operations for a PCICC card.
566 */
567static struct zcrypt_ops zcrypt_pcicc_ops = {
568 .rsa_modexpo = zcrypt_pcicc_modexpo,
569 .rsa_modexpo_crt = zcrypt_pcicc_modexpo_crt,
570};
571
572/**
573 * Probe function for PCICC cards. It always accepts the AP device
574 * since the bus_match already checked the hardware type.
575 * @ap_dev: pointer to the AP device.
576 */
577static int zcrypt_pcicc_probe(struct ap_device *ap_dev)
578{
579 struct zcrypt_device *zdev;
580 int rc;
581
582 zdev = zcrypt_device_alloc(PCICC_MAX_RESPONSE_SIZE);
583 if (!zdev)
584 return -ENOMEM;
585 zdev->ap_dev = ap_dev;
586 zdev->ops = &zcrypt_pcicc_ops;
587 zdev->online = 1;
588 zdev->user_space_type = ZCRYPT_PCICC;
589 zdev->type_string = "PCICC";
590 zdev->min_mod_size = PCICC_MIN_MOD_SIZE;
591 zdev->max_mod_size = PCICC_MAX_MOD_SIZE;
592 zdev->speed_rating = PCICC_SPEED_RATING;
593 ap_dev->reply = &zdev->reply;
594 ap_dev->private = zdev;
595 rc = zcrypt_device_register(zdev);
596 if (rc)
597 goto out_free;
598 return 0;
599
600 out_free:
601 ap_dev->private = NULL;
602 zcrypt_device_free(zdev);
603 return rc;
604}
605
606/**
607 * This is called to remove the extended PCICC driver information
608 * if an AP device is removed.
609 */
610static void zcrypt_pcicc_remove(struct ap_device *ap_dev)
611{
612 struct zcrypt_device *zdev = ap_dev->private;
613
614 zcrypt_device_unregister(zdev);
615}
616
617int __init zcrypt_pcicc_init(void)
618{
619 return ap_driver_register(&zcrypt_pcicc_driver, THIS_MODULE, "pcicc");
620}
621
622void zcrypt_pcicc_exit(void)
623{
624 ap_driver_unregister(&zcrypt_pcicc_driver);
625}
626
627#ifndef CONFIG_ZCRYPT_MONOLITHIC
628module_init(zcrypt_pcicc_init);
629module_exit(zcrypt_pcicc_exit);
630#endif
diff --git a/drivers/s390/crypto/zcrypt_pcicc.h b/drivers/s390/crypto/zcrypt_pcicc.h
new file mode 100644
index 000000000000..6d4454846c8f
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcicc.h
@@ -0,0 +1,176 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcicc.h
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_PCICC_H_
29#define _ZCRYPT_PCICC_H_
30
31/**
32 * The type 6 message family is associated with PCICC or PCIXCC cards.
33 *
34 * It contains a message header followed by a CPRB, both of which
35 * are described below.
36 *
37 * Note that all reserved fields must be zeroes.
38 */
39struct type6_hdr {
40 unsigned char reserved1; /* 0x00 */
41 unsigned char type; /* 0x06 */
42 unsigned char reserved2[2]; /* 0x0000 */
43 unsigned char right[4]; /* 0x00000000 */
44 unsigned char reserved3[2]; /* 0x0000 */
45 unsigned char reserved4[2]; /* 0x0000 */
46 unsigned char apfs[4]; /* 0x00000000 */
47 unsigned int offset1; /* 0x00000058 (offset to CPRB) */
48 unsigned int offset2; /* 0x00000000 */
49 unsigned int offset3; /* 0x00000000 */
50 unsigned int offset4; /* 0x00000000 */
51 unsigned char agent_id[16]; /* PCICC: */
52 /* 0x0100 */
53 /* 0x4343412d4150504c202020 */
54 /* 0x010101 */
55 /* PCIXCC: */
56 /* 0x4341000000000000 */
57 /* 0x0000000000000000 */
58 unsigned char rqid[2]; /* rqid. internal to 603 */
59 unsigned char reserved5[2]; /* 0x0000 */
60 unsigned char function_code[2]; /* for PKD, 0x5044 (ascii 'PD') */
61 unsigned char reserved6[2]; /* 0x0000 */
62 unsigned int ToCardLen1; /* (request CPRB len + 3) & -4 */
63 unsigned int ToCardLen2; /* db len 0x00000000 for PKD */
64 unsigned int ToCardLen3; /* 0x00000000 */
65 unsigned int ToCardLen4; /* 0x00000000 */
66 unsigned int FromCardLen1; /* response buffer length */
67 unsigned int FromCardLen2; /* db len 0x00000000 for PKD */
68 unsigned int FromCardLen3; /* 0x00000000 */
69 unsigned int FromCardLen4; /* 0x00000000 */
70} __attribute__((packed));
71
72/**
73 * CPRB
74 * Note that all shorts, ints and longs are little-endian.
75 * All pointer fields are 32-bits long, and mean nothing
76 *
77 * A request CPRB is followed by a request_parameter_block.
78 *
79 * The request (or reply) parameter block is organized thus:
80 * function code
81 * VUD block
82 * key block
83 */
84struct CPRB {
85 unsigned short cprb_len; /* CPRB length */
86 unsigned char cprb_ver_id; /* CPRB version id. */
87 unsigned char pad_000; /* Alignment pad byte. */
88 unsigned char srpi_rtcode[4]; /* SRPI return code LELONG */
89 unsigned char srpi_verb; /* SRPI verb type */
90 unsigned char flags; /* flags */
91 unsigned char func_id[2]; /* function id */
92 unsigned char checkpoint_flag; /* */
93 unsigned char resv2; /* reserved */
94 unsigned short req_parml; /* request parameter buffer */
95 /* length 16-bit little endian */
96 unsigned char req_parmp[4]; /* request parameter buffer *
97 * pointer (means nothing: the *
98 * parameter buffer follows *
99 * the CPRB). */
100 unsigned char req_datal[4]; /* request data buffer */
101 /* length ULELONG */
102 unsigned char req_datap[4]; /* request data buffer */
103 /* pointer */
104 unsigned short rpl_parml; /* reply parameter buffer */
105 /* length 16-bit little endian */
106 unsigned char pad_001[2]; /* Alignment pad bytes. ULESHORT */
107 unsigned char rpl_parmp[4]; /* reply parameter buffer *
108 * pointer (means nothing: the *
109 * parameter buffer follows *
110 * the CPRB). */
111 unsigned char rpl_datal[4]; /* reply data buffer len ULELONG */
112 unsigned char rpl_datap[4]; /* reply data buffer */
113 /* pointer */
114 unsigned short ccp_rscode; /* server reason code ULESHORT */
115 unsigned short ccp_rtcode; /* server return code ULESHORT */
116 unsigned char repd_parml[2]; /* replied parameter len ULESHORT*/
117 unsigned char mac_data_len[2]; /* Mac Data Length ULESHORT */
118 unsigned char repd_datal[4]; /* replied data length ULELONG */
119 unsigned char req_pc[2]; /* PC identifier */
120 unsigned char res_origin[8]; /* resource origin */
121 unsigned char mac_value[8]; /* Mac Value */
122 unsigned char logon_id[8]; /* Logon Identifier */
123 unsigned char usage_domain[2]; /* cdx */
124 unsigned char resv3[18]; /* reserved for requestor */
125 unsigned short svr_namel; /* server name length ULESHORT */
126 unsigned char svr_name[8]; /* server name */
127} __attribute__((packed));
128
129/**
130 * The type 86 message family is associated with PCICC and PCIXCC cards.
131 *
132 * It contains a message header followed by a CPRB. The CPRB is
133 * the same as the request CPRB, which is described above.
134 *
135 * If format is 1, an error condition exists and no data beyond
136 * the 8-byte message header is of interest.
137 *
138 * The non-error message is shown below.
139 *
140 * Note that all reserved fields must be zeroes.
141 */
142struct type86_hdr {
143 unsigned char reserved1; /* 0x00 */
144 unsigned char type; /* 0x86 */
145 unsigned char format; /* 0x01 (error) or 0x02 (ok) */
146 unsigned char reserved2; /* 0x00 */
147 unsigned char reply_code; /* reply code (see above) */
148 unsigned char reserved3[3]; /* 0x000000 */
149} __attribute__((packed));
150
151#define TYPE86_RSP_CODE 0x86
152#define TYPE86_FMT2 0x02
153
154struct type86_fmt2_ext {
155 unsigned char reserved[4]; /* 0x00000000 */
156 unsigned char apfs[4]; /* final status */
157 unsigned int count1; /* length of CPRB + parameters */
158 unsigned int offset1; /* offset to CPRB */
159 unsigned int count2; /* 0x00000000 */
160 unsigned int offset2; /* db offset 0x00000000 for PKD */
161 unsigned int count3; /* 0x00000000 */
162 unsigned int offset3; /* 0x00000000 */
163 unsigned int count4; /* 0x00000000 */
164 unsigned int offset4; /* 0x00000000 */
165} __attribute__((packed));
166
167struct function_and_rules_block {
168 unsigned char function_code[2];
169 unsigned short ulen;
170 unsigned char only_rule[8];
171} __attribute__((packed));
172
173int zcrypt_pcicc_init(void);
174void zcrypt_pcicc_exit(void);
175
176#endif /* _ZCRYPT_PCICC_H_ */
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
new file mode 100644
index 000000000000..2da8b9381407
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -0,0 +1,951 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcixcc.c
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 * Ralph Wuerthner <rwuerthn@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/err.h>
32#include <linux/delay.h>
33#include <asm/atomic.h>
34#include <asm/uaccess.h>
35
36#include "ap_bus.h"
37#include "zcrypt_api.h"
38#include "zcrypt_error.h"
39#include "zcrypt_pcicc.h"
40#include "zcrypt_pcixcc.h"
41#include "zcrypt_cca_key.h"
42
43#define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */
44#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
45#define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */
46
47#define PCIXCC_MCL2_SPEED_RATING 7870 /* FIXME: needs finetuning */
48#define PCIXCC_MCL3_SPEED_RATING 7870
49#define CEX2C_SPEED_RATING 8540
50
51#define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */
52#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
53
54#define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
55#define PCIXCC_MAX_XCRB_RESPONSE_SIZE PCIXCC_MAX_XCRB_MESSAGE_SIZE
56#define PCIXCC_MAX_XCRB_DATA_SIZE (11*1024)
57#define PCIXCC_MAX_XCRB_REPLY_SIZE (5*1024)
58
59#define PCIXCC_MAX_RESPONSE_SIZE PCIXCC_MAX_XCRB_RESPONSE_SIZE
60
61#define PCIXCC_CLEANUP_TIME (15*HZ)
62
63#define CEIL4(x) ((((x)+3)/4)*4)
64
65struct response_type {
66 struct completion work;
67 int type;
68};
69#define PCIXCC_RESPONSE_TYPE_ICA 0
70#define PCIXCC_RESPONSE_TYPE_XCRB 1
71
72static struct ap_device_id zcrypt_pcixcc_ids[] = {
73 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
74 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
75 { /* end of list */ },
76};
77
78#ifndef CONFIG_ZCRYPT_MONOLITHIC
79MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
80MODULE_AUTHOR("IBM Corporation");
81MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
82 "Copyright 2001, 2006 IBM Corporation");
83MODULE_LICENSE("GPL");
84#endif
85
86static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
87static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
88static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
89 struct ap_message *);
90
91static struct ap_driver zcrypt_pcixcc_driver = {
92 .probe = zcrypt_pcixcc_probe,
93 .remove = zcrypt_pcixcc_remove,
94 .receive = zcrypt_pcixcc_receive,
95 .ids = zcrypt_pcixcc_ids,
96};
97
98/**
99 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
100 * card in a type6 message. The 3 fields that must be filled in at execution
101 * time are req_parml, rpl_parml and usage_domain.
102 * Everything about this interface is ascii/big-endian, since the
103 * device does *not* have 'Intel inside'.
104 *
105 * The CPRBX is followed immediately by the parm block.
106 * The parm block contains:
107 * - function code ('PD' 0x5044 or 'PK' 0x504B)
108 * - rule block (one of:)
109 * + 0x000A 'PKCS-1.2' (MCL2 'PD')
110 * + 0x000A 'ZERO-PAD' (MCL2 'PK')
111 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
112 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
113 * - VUD block
114 */
115static struct CPRBX static_cprbx = {
116 .cprb_len = 0x00DC,
117 .cprb_ver_id = 0x02,
118 .func_id = {0x54,0x32},
119};
120
121/**
122 * Convert a ICAMEX message to a type6 MEX message.
123 *
124 * @zdev: crypto device pointer
125 * @ap_msg: pointer to AP message
126 * @mex: pointer to user input data
127 *
128 * Returns 0 on success or -EFAULT.
129 */
130static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
131 struct ap_message *ap_msg,
132 struct ica_rsa_modexpo *mex)
133{
134 static struct type6_hdr static_type6_hdrX = {
135 .type = 0x06,
136 .offset1 = 0x00000058,
137 .agent_id = {'C','A',},
138 .function_code = {'P','K'},
139 };
140 static struct function_and_rules_block static_pke_fnr = {
141 .function_code = {'P','K'},
142 .ulen = 10,
143 .only_rule = {'M','R','P',' ',' ',' ',' ',' '}
144 };
145 static struct function_and_rules_block static_pke_fnr_MCL2 = {
146 .function_code = {'P','K'},
147 .ulen = 10,
148 .only_rule = {'Z','E','R','O','-','P','A','D'}
149 };
150 struct {
151 struct type6_hdr hdr;
152 struct CPRBX cprbx;
153 struct function_and_rules_block fr;
154 unsigned short length;
155 char text[0];
156 } __attribute__((packed)) *msg = ap_msg->message;
157 int size;
158
159 /* VUD.ciphertext */
160 msg->length = mex->inputdatalength + 2;
161 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
162 return -EFAULT;
163
164 /* Set up key which is located after the variable length text. */
165 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
166 if (size < 0)
167 return size;
168 size += sizeof(*msg) + mex->inputdatalength;
169
170 /* message header, cprbx and f&r */
171 msg->hdr = static_type6_hdrX;
172 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
173 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
174
175 msg->cprbx = static_cprbx;
176 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
177 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
178
179 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
180 static_pke_fnr_MCL2 : static_pke_fnr;
181
182 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
183
184 ap_msg->length = size;
185 return 0;
186}
187
188/**
189 * Convert a ICACRT message to a type6 CRT message.
190 *
191 * @zdev: crypto device pointer
192 * @ap_msg: pointer to AP message
193 * @crt: pointer to user input data
194 *
195 * Returns 0 on success or -EFAULT.
196 */
197static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
198 struct ap_message *ap_msg,
199 struct ica_rsa_modexpo_crt *crt)
200{
201 static struct type6_hdr static_type6_hdrX = {
202 .type = 0x06,
203 .offset1 = 0x00000058,
204 .agent_id = {'C','A',},
205 .function_code = {'P','D'},
206 };
207 static struct function_and_rules_block static_pkd_fnr = {
208 .function_code = {'P','D'},
209 .ulen = 10,
210 .only_rule = {'Z','E','R','O','-','P','A','D'}
211 };
212
213 static struct function_and_rules_block static_pkd_fnr_MCL2 = {
214 .function_code = {'P','D'},
215 .ulen = 10,
216 .only_rule = {'P','K','C','S','-','1','.','2'}
217 };
218 struct {
219 struct type6_hdr hdr;
220 struct CPRBX cprbx;
221 struct function_and_rules_block fr;
222 unsigned short length;
223 char text[0];
224 } __attribute__((packed)) *msg = ap_msg->message;
225 int size;
226
227 /* VUD.ciphertext */
228 msg->length = crt->inputdatalength + 2;
229 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
230 return -EFAULT;
231
232 /* Set up key which is located after the variable length text. */
233 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
234 if (size < 0)
235 return size;
236 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
237
238 /* message header, cprbx and f&r */
239 msg->hdr = static_type6_hdrX;
240 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
241 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
242
243 msg->cprbx = static_cprbx;
244 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
245 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
246 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
247
248 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
249 static_pkd_fnr_MCL2 : static_pkd_fnr;
250
251 ap_msg->length = size;
252 return 0;
253}
254
255/**
256 * Convert a XCRB message to a type6 CPRB message.
257 *
258 * @zdev: crypto device pointer
259 * @ap_msg: pointer to AP message
260 * @xcRB: pointer to user input data
261 *
262 * Returns 0 on success or -EFAULT.
263 */
264struct type86_fmt2_msg {
265 struct type86_hdr hdr;
266 struct type86_fmt2_ext fmt2;
267} __attribute__((packed));
268
269static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
270 struct ap_message *ap_msg,
271 struct ica_xcRB *xcRB)
272{
273 static struct type6_hdr static_type6_hdrX = {
274 .type = 0x06,
275 .offset1 = 0x00000058,
276 };
277 struct {
278 struct type6_hdr hdr;
279 struct ica_CPRBX cprbx;
280 } __attribute__((packed)) *msg = ap_msg->message;
281
282 int rcblen = CEIL4(xcRB->request_control_blk_length);
283 int replylen;
284 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
285 char *function_code;
286
287 /* length checks */
288 ap_msg->length = sizeof(struct type6_hdr) +
289 CEIL4(xcRB->request_control_blk_length) +
290 xcRB->request_data_length;
291 if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) {
292 PRINTK("Combined message is too large (%ld/%d/%d).\n",
293 sizeof(struct type6_hdr),
294 xcRB->request_control_blk_length,
295 xcRB->request_data_length);
296 return -EFAULT;
297 }
298 if (CEIL4(xcRB->reply_control_blk_length) >
299 PCIXCC_MAX_XCRB_REPLY_SIZE) {
300 PDEBUG("Reply CPRB length is too large (%d).\n",
301 xcRB->request_control_blk_length);
302 return -EFAULT;
303 }
304 if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE) {
305 PDEBUG("Reply data block length is too large (%d).\n",
306 xcRB->reply_data_length);
307 return -EFAULT;
308 }
309 replylen = CEIL4(xcRB->reply_control_blk_length) +
310 CEIL4(xcRB->reply_data_length) +
311 sizeof(struct type86_fmt2_msg);
312 if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) {
313 PDEBUG("Reply CPRB + data block > PCIXCC_MAX_XCRB_RESPONSE_SIZE"
314 " (%d/%d/%d).\n",
315 sizeof(struct type86_fmt2_msg),
316 xcRB->reply_control_blk_length,
317 xcRB->reply_data_length);
318 xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
319 (sizeof(struct type86_fmt2_msg) +
320 CEIL4(xcRB->reply_data_length));
321 PDEBUG("Capping Reply CPRB length at %d\n",
322 xcRB->reply_control_blk_length);
323 }
324
325 /* prepare type6 header */
326 msg->hdr = static_type6_hdrX;
327 memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
328 msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
329 if (xcRB->request_data_length) {
330 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
331 msg->hdr.ToCardLen2 = xcRB->request_data_length;
332 }
333 msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
334 msg->hdr.FromCardLen2 = xcRB->reply_data_length;
335
336 /* prepare CPRB */
337 if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
338 xcRB->request_control_blk_length))
339 return -EFAULT;
340 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
341 xcRB->request_control_blk_length) {
342 PDEBUG("cprb_len too large (%d/%d)\n", msg->cprbx.cprb_len,
343 xcRB->request_control_blk_length);
344 return -EFAULT;
345 }
346 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
347 memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
348
349 /* copy data block */
350 if (xcRB->request_data_length &&
351 copy_from_user(req_data, xcRB->request_data_address,
352 xcRB->request_data_length))
353 return -EFAULT;
354 return 0;
355}
356
357/**
358 * Copy results from a type 86 ICA reply message back to user space.
359 *
360 * @zdev: crypto device pointer
361 * @reply: reply AP message.
362 * @data: pointer to user output data
363 * @length: size of user output data
364 *
365 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
366 */
367struct type86x_reply {
368 struct type86_hdr hdr;
369 struct type86_fmt2_ext fmt2;
370 struct CPRBX cprbx;
371 unsigned char pad[4]; /* 4 byte function code/rules block ? */
372 unsigned short length;
373 char text[0];
374} __attribute__((packed));
375
376static int convert_type86_ica(struct zcrypt_device *zdev,
377 struct ap_message *reply,
378 char __user *outputdata,
379 unsigned int outputdatalength)
380{
381 static unsigned char static_pad[] = {
382 0x00,0x02,
383 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
384 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
385 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
386 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
387 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
388 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
389 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
390 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
391 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
392 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
393 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
394 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
395 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
396 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
397 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
398 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
399 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
400 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
401 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
402 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
403 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
404 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
405 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
406 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
407 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
408 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
409 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
410 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
411 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
412 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
413 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
414 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
415 };
416 struct type86x_reply *msg = reply->message;
417 unsigned short service_rc, service_rs;
418 unsigned int reply_len, pad_len;
419 char *data;
420
421 service_rc = msg->cprbx.ccp_rtcode;
422 if (unlikely(service_rc != 0)) {
423 service_rs = msg->cprbx.ccp_rscode;
424 if (service_rc == 8 && service_rs == 66) {
425 PDEBUG("Bad block format on PCIXCC/CEX2C\n");
426 return -EINVAL;
427 }
428 if (service_rc == 8 && service_rs == 65) {
429 PDEBUG("Probably an even modulus on PCIXCC/CEX2C\n");
430 return -EINVAL;
431 }
432 if (service_rc == 8 && service_rs == 770) {
433 PDEBUG("Invalid key length on PCIXCC/CEX2C\n");
434 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
435 return -EAGAIN;
436 }
437 if (service_rc == 8 && service_rs == 783) {
438 PDEBUG("Extended bitlengths not enabled on PCIXCC/CEX2C\n");
439 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
440 return -EAGAIN;
441 }
442 PRINTK("Unknown service rc/rs (PCIXCC/CEX2C): %d/%d\n",
443 service_rc, service_rs);
444 zdev->online = 0;
445 return -EAGAIN; /* repeat the request on a different device. */
446 }
447 data = msg->text;
448 reply_len = msg->length - 2;
449 if (reply_len > outputdatalength)
450 return -EINVAL;
451 /**
452 * For all encipher requests, the length of the ciphertext (reply_len)
453 * will always equal the modulus length. For MEX decipher requests
454 * the output needs to get padded. Minimum pad size is 10.
455 *
456 * Currently, the cases where padding will be added is for:
457 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
458 * ZERO-PAD and CRT is only supported for PKD requests)
459 * - PCICC, always
460 */
461 pad_len = outputdatalength - reply_len;
462 if (pad_len > 0) {
463 if (pad_len < 10)
464 return -EINVAL;
465 /* 'restore' padding left in the PCICC/PCIXCC card. */
466 if (copy_to_user(outputdata, static_pad, pad_len - 1))
467 return -EFAULT;
468 if (put_user(0, outputdata + pad_len - 1))
469 return -EFAULT;
470 }
471 /* Copy the crypto response to user space. */
472 if (copy_to_user(outputdata + pad_len, data, reply_len))
473 return -EFAULT;
474 return 0;
475}
476
477/**
478 * Copy results from a type 86 XCRB reply message back to user space.
479 *
480 * @zdev: crypto device pointer
481 * @reply: reply AP message.
482 * @xcRB: pointer to XCRB
483 *
484 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
485 */
486static int convert_type86_xcrb(struct zcrypt_device *zdev,
487 struct ap_message *reply,
488 struct ica_xcRB *xcRB)
489{
490 struct type86_fmt2_msg *msg = reply->message;
491 char *data = reply->message;
492
493 /* Copy CPRB to user */
494 if (copy_to_user(xcRB->reply_control_blk_addr,
495 data + msg->fmt2.offset1, msg->fmt2.count1))
496 return -EFAULT;
497 xcRB->reply_control_blk_length = msg->fmt2.count1;
498
499 /* Copy data buffer to user */
500 if (msg->fmt2.count2)
501 if (copy_to_user(xcRB->reply_data_addr,
502 data + msg->fmt2.offset2, msg->fmt2.count2))
503 return -EFAULT;
504 xcRB->reply_data_length = msg->fmt2.count2;
505 return 0;
506}
507
508static int convert_response_ica(struct zcrypt_device *zdev,
509 struct ap_message *reply,
510 char __user *outputdata,
511 unsigned int outputdatalength)
512{
513 struct type86x_reply *msg = reply->message;
514
515 /* Response type byte is the second byte in the response. */
516 switch (((unsigned char *) reply->message)[1]) {
517 case TYPE82_RSP_CODE:
518 case TYPE88_RSP_CODE:
519 return convert_error(zdev, reply);
520 case TYPE86_RSP_CODE:
521 if (msg->hdr.reply_code)
522 return convert_error(zdev, reply);
523 if (msg->cprbx.cprb_ver_id == 0x02)
524 return convert_type86_ica(zdev, reply,
525 outputdata, outputdatalength);
526 /* no break, incorrect cprb version is an unknown response */
527 default: /* Unknown response type, this should NEVER EVER happen */
528 PRINTK("Unrecognized Message Header: %08x%08x\n",
529 *(unsigned int *) reply->message,
530 *(unsigned int *) (reply->message+4));
531 zdev->online = 0;
532 return -EAGAIN; /* repeat the request on a different device. */
533 }
534}
535
536static int convert_response_xcrb(struct zcrypt_device *zdev,
537 struct ap_message *reply,
538 struct ica_xcRB *xcRB)
539{
540 struct type86x_reply *msg = reply->message;
541
542 /* Response type byte is the second byte in the response. */
543 switch (((unsigned char *) reply->message)[1]) {
544 case TYPE82_RSP_CODE:
545 case TYPE88_RSP_CODE:
546 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
547 return convert_error(zdev, reply);
548 case TYPE86_RSP_CODE:
549 if (msg->hdr.reply_code) {
550 memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
551 return convert_error(zdev, reply);
552 }
553 if (msg->cprbx.cprb_ver_id == 0x02)
554 return convert_type86_xcrb(zdev, reply, xcRB);
555 /* no break, incorrect cprb version is an unknown response */
556 default: /* Unknown response type, this should NEVER EVER happen */
557 PRINTK("Unrecognized Message Header: %08x%08x\n",
558 *(unsigned int *) reply->message,
559 *(unsigned int *) (reply->message+4));
560 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
561 zdev->online = 0;
562 return -EAGAIN; /* repeat the request on a different device. */
563 }
564}
565
566/**
567 * This function is called from the AP bus code after a crypto request
568 * "msg" has finished with the reply message "reply".
569 * It is called from tasklet context.
570 * @ap_dev: pointer to the AP device
571 * @msg: pointer to the AP message
572 * @reply: pointer to the AP reply message
573 */
574static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
575 struct ap_message *msg,
576 struct ap_message *reply)
577{
578 static struct error_hdr error_reply = {
579 .type = TYPE82_RSP_CODE,
580 .reply_code = REP82_ERROR_MACHINE_FAILURE,
581 };
582 struct response_type *resp_type =
583 (struct response_type *) msg->private;
584 struct type86x_reply *t86r = reply->message;
585 int length;
586
587 /* Copy the reply message to the request message buffer. */
588 if (IS_ERR(reply))
589 memcpy(msg->message, &error_reply, sizeof(error_reply));
590 else if (t86r->hdr.type == TYPE86_RSP_CODE &&
591 t86r->cprbx.cprb_ver_id == 0x02) {
592 switch (resp_type->type) {
593 case PCIXCC_RESPONSE_TYPE_ICA:
594 length = sizeof(struct type86x_reply)
595 + t86r->length - 2;
596 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
597 memcpy(msg->message, reply->message, length);
598 break;
599 case PCIXCC_RESPONSE_TYPE_XCRB:
600 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
601 length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
602 memcpy(msg->message, reply->message, length);
603 break;
604 default:
605 PRINTK("Invalid internal response type: %i\n",
606 resp_type->type);
607 memcpy(msg->message, &error_reply,
608 sizeof error_reply);
609 }
610 } else
611 memcpy(msg->message, reply->message, sizeof error_reply);
612 complete(&(resp_type->work));
613}
614
615static atomic_t zcrypt_step = ATOMIC_INIT(0);
616
617/**
618 * The request distributor calls this function if it picked the PCIXCC/CEX2C
619 * device to handle a modexpo request.
620 * @zdev: pointer to zcrypt_device structure that identifies the
621 * PCIXCC/CEX2C device to the request distributor
622 * @mex: pointer to the modexpo request buffer
623 */
624static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
625 struct ica_rsa_modexpo *mex)
626{
627 struct ap_message ap_msg;
628 struct response_type resp_type = {
629 .type = PCIXCC_RESPONSE_TYPE_ICA,
630 };
631 int rc;
632
633 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
634 if (!ap_msg.message)
635 return -ENOMEM;
636 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
637 atomic_inc_return(&zcrypt_step);
638 ap_msg.private = &resp_type;
639 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
640 if (rc)
641 goto out_free;
642 init_completion(&resp_type.work);
643 ap_queue_message(zdev->ap_dev, &ap_msg);
644 rc = wait_for_completion_interruptible_timeout(
645 &resp_type.work, PCIXCC_CLEANUP_TIME);
646 if (rc > 0)
647 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
648 mex->outputdatalength);
649 else {
650 /* Signal pending or message timed out. */
651 ap_cancel_message(zdev->ap_dev, &ap_msg);
652 if (rc == 0)
653 /* Message timed out. */
654 rc = -ETIME;
655 }
656out_free:
657 free_page((unsigned long) ap_msg.message);
658 return rc;
659}
660
661/**
662 * The request distributor calls this function if it picked the PCIXCC/CEX2C
663 * device to handle a modexpo_crt request.
664 * @zdev: pointer to zcrypt_device structure that identifies the
665 * PCIXCC/CEX2C device to the request distributor
666 * @crt: pointer to the modexpoc_crt request buffer
667 */
668static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
669 struct ica_rsa_modexpo_crt *crt)
670{
671 struct ap_message ap_msg;
672 struct response_type resp_type = {
673 .type = PCIXCC_RESPONSE_TYPE_ICA,
674 };
675 int rc;
676
677 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
678 if (!ap_msg.message)
679 return -ENOMEM;
680 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
681 atomic_inc_return(&zcrypt_step);
682 ap_msg.private = &resp_type;
683 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
684 if (rc)
685 goto out_free;
686 init_completion(&resp_type.work);
687 ap_queue_message(zdev->ap_dev, &ap_msg);
688 rc = wait_for_completion_interruptible_timeout(
689 &resp_type.work, PCIXCC_CLEANUP_TIME);
690 if (rc > 0)
691 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
692 crt->outputdatalength);
693 else {
694 /* Signal pending or message timed out. */
695 ap_cancel_message(zdev->ap_dev, &ap_msg);
696 if (rc == 0)
697 /* Message timed out. */
698 rc = -ETIME;
699 }
700out_free:
701 free_page((unsigned long) ap_msg.message);
702 return rc;
703}
704
705/**
706 * The request distributor calls this function if it picked the PCIXCC/CEX2C
707 * device to handle a send_cprb request.
708 * @zdev: pointer to zcrypt_device structure that identifies the
709 * PCIXCC/CEX2C device to the request distributor
710 * @xcRB: pointer to the send_cprb request buffer
711 */
712long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, struct ica_xcRB *xcRB)
713{
714 struct ap_message ap_msg;
715 struct response_type resp_type = {
716 .type = PCIXCC_RESPONSE_TYPE_XCRB,
717 };
718 int rc;
719
720 ap_msg.message = (void *) kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
721 if (!ap_msg.message)
722 return -ENOMEM;
723 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
724 atomic_inc_return(&zcrypt_step);
725 ap_msg.private = &resp_type;
726 rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
727 if (rc)
728 goto out_free;
729 init_completion(&resp_type.work);
730 ap_queue_message(zdev->ap_dev, &ap_msg);
731 rc = wait_for_completion_interruptible_timeout(
732 &resp_type.work, PCIXCC_CLEANUP_TIME);
733 if (rc > 0)
734 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
735 else {
736 /* Signal pending or message timed out. */
737 ap_cancel_message(zdev->ap_dev, &ap_msg);
738 if (rc == 0)
739 /* Message timed out. */
740 rc = -ETIME;
741 }
742out_free:
743 memset(ap_msg.message, 0x0, ap_msg.length);
744 kfree(ap_msg.message);
745 return rc;
746}
747
748/**
749 * The crypto operations for a PCIXCC/CEX2C card.
750 */
751static struct zcrypt_ops zcrypt_pcixcc_ops = {
752 .rsa_modexpo = zcrypt_pcixcc_modexpo,
753 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
754 .send_cprb = zcrypt_pcixcc_send_cprb,
755};
756
757/**
758 * Micro-code detection function. Its sends a message to a pcixcc card
759 * to find out the microcode level.
760 * @ap_dev: pointer to the AP device.
761 */
762static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
763{
764 static unsigned char msg[] = {
765 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
766 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
767 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
768 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
769 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
770 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
771 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
772 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
773 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
774 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
775 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
776 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
777 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
778 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
779 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
780 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
781 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
782 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
783 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
784 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
785 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
786 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
787 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
788 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
789 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
790 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
791 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
792 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
793 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
794 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
795 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
796 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
797 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
798 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
799 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
800 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
801 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
802 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
803 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
804 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
805 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
806 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
807 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
808 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
809 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
810 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
811 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
812 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
813 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
814 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
815 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
816 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
817 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
818 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
819 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
820 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
821 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
822 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
823 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
824 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
825 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
826 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
827 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
828 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
829 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
830 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
831 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
832 0xF1,0x3D,0x93,0x53
833 };
834 unsigned long long psmid;
835 struct CPRBX *cprbx;
836 char *reply;
837 int rc, i;
838
839 reply = (void *) get_zeroed_page(GFP_KERNEL);
840 if (!reply)
841 return -ENOMEM;
842
843 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
844 if (rc)
845 goto out_free;
846
847 /* Wait for the test message to complete. */
848 for (i = 0; i < 6; i++) {
849 mdelay(300);
850 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
851 if (rc == 0 && psmid == 0x0102030405060708ULL)
852 break;
853 }
854
855 if (i >= 6) {
856 /* Got no answer. */
857 rc = -ENODEV;
858 goto out_free;
859 }
860
861 cprbx = (struct CPRBX *) (reply + 48);
862 if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
863 rc = ZCRYPT_PCIXCC_MCL2;
864 else
865 rc = ZCRYPT_PCIXCC_MCL3;
866out_free:
867 free_page((unsigned long) reply);
868 return rc;
869}
870
871/**
872 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
873 * since the bus_match already checked the hardware type. The PCIXCC
874 * cards come in two flavours: micro code level 2 and micro code level 3.
875 * This is checked by sending a test message to the device.
876 * @ap_dev: pointer to the AP device.
877 */
878static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
879{
880 struct zcrypt_device *zdev;
881 int rc;
882
883 zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
884 if (!zdev)
885 return -ENOMEM;
886 zdev->ap_dev = ap_dev;
887 zdev->ops = &zcrypt_pcixcc_ops;
888 zdev->online = 1;
889 if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
890 rc = zcrypt_pcixcc_mcl(ap_dev);
891 if (rc < 0) {
892 zcrypt_device_free(zdev);
893 return rc;
894 }
895 zdev->user_space_type = rc;
896 if (rc == ZCRYPT_PCIXCC_MCL2) {
897 zdev->type_string = "PCIXCC_MCL2";
898 zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
899 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
900 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
901 } else {
902 zdev->type_string = "PCIXCC_MCL3";
903 zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
904 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
905 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
906 }
907 } else {
908 zdev->user_space_type = ZCRYPT_CEX2C;
909 zdev->type_string = "CEX2C";
910 zdev->speed_rating = CEX2C_SPEED_RATING;
911 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
912 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
913 }
914 ap_dev->reply = &zdev->reply;
915 ap_dev->private = zdev;
916 rc = zcrypt_device_register(zdev);
917 if (rc)
918 goto out_free;
919 return 0;
920
921 out_free:
922 ap_dev->private = NULL;
923 zcrypt_device_free(zdev);
924 return rc;
925}
926
927/**
928 * This is called to remove the extended PCIXCC/CEX2C driver information
929 * if an AP device is removed.
930 */
931static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
932{
933 struct zcrypt_device *zdev = ap_dev->private;
934
935 zcrypt_device_unregister(zdev);
936}
937
938int __init zcrypt_pcixcc_init(void)
939{
940 return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
941}
942
943void zcrypt_pcixcc_exit(void)
944{
945 ap_driver_unregister(&zcrypt_pcixcc_driver);
946}
947
948#ifndef CONFIG_ZCRYPT_MONOLITHIC
949module_init(zcrypt_pcixcc_init);
950module_exit(zcrypt_pcixcc_exit);
951#endif
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.h b/drivers/s390/crypto/zcrypt_pcixcc.h
new file mode 100644
index 000000000000..a78ff307fd19
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcixcc.h
@@ -0,0 +1,79 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcixcc.h
3 *
4 * zcrypt 2.1.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_PCIXCC_H_
29#define _ZCRYPT_PCIXCC_H_
30
31/**
32 * CPRBX
33 * Note that all shorts and ints are big-endian.
34 * All pointer fields are 16 bytes long, and mean nothing.
35 *
36 * A request CPRB is followed by a request_parameter_block.
37 *
38 * The request (or reply) parameter block is organized thus:
39 * function code
40 * VUD block
41 * key block
42 */
43struct CPRBX {
44 unsigned short cprb_len; /* CPRB length 220 */
45 unsigned char cprb_ver_id; /* CPRB version id. 0x02 */
46 unsigned char pad_000[3]; /* Alignment pad bytes */
47 unsigned char func_id[2]; /* function id 0x5432 */
48 unsigned char cprb_flags[4]; /* Flags */
49 unsigned int req_parml; /* request parameter buffer len */
50 unsigned int req_datal; /* request data buffer */
51 unsigned int rpl_msgbl; /* reply message block length */
52 unsigned int rpld_parml; /* replied parameter block len */
53 unsigned int rpl_datal; /* reply data block len */
54 unsigned int rpld_datal; /* replied data block len */
55 unsigned int req_extbl; /* request extension block len */
56 unsigned char pad_001[4]; /* reserved */
57 unsigned int rpld_extbl; /* replied extension block len */
58 unsigned char req_parmb[16]; /* request parm block 'address' */
59 unsigned char req_datab[16]; /* request data block 'address' */
60 unsigned char rpl_parmb[16]; /* reply parm block 'address' */
61 unsigned char rpl_datab[16]; /* reply data block 'address' */
62 unsigned char req_extb[16]; /* request extension block 'addr'*/
63 unsigned char rpl_extb[16]; /* reply extension block 'addres'*/
64 unsigned short ccp_rtcode; /* server return code */
65 unsigned short ccp_rscode; /* server reason code */
66 unsigned int mac_data_len; /* Mac Data Length */
67 unsigned char logon_id[8]; /* Logon Identifier */
68 unsigned char mac_value[8]; /* Mac Value */
69 unsigned char mac_content_flgs;/* Mac content flag byte */
70 unsigned char pad_002; /* Alignment */
71 unsigned short domain; /* Domain */
72 unsigned char pad_003[12]; /* Domain masks */
73 unsigned char pad_004[36]; /* reserved */
74} __attribute__((packed));
75
76int zcrypt_pcixcc_init(void);
77void zcrypt_pcixcc_exit(void);
78
79#endif /* _ZCRYPT_PCIXCC_H_ */
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 5399c5d99b81..a914129a4da9 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -19,9 +19,6 @@
19 19
20#include "s390mach.h" 20#include "s390mach.h"
21 21
22#define DBG printk
23// #define DBG(args,...) do {} while (0);
24
25static struct semaphore m_sem; 22static struct semaphore m_sem;
26 23
27extern int css_process_crw(int, int); 24extern int css_process_crw(int, int);
@@ -83,11 +80,11 @@ repeat:
83 ccode = stcrw(&crw[chain]); 80 ccode = stcrw(&crw[chain]);
84 if (ccode != 0) 81 if (ccode != 0)
85 break; 82 break;
86 DBG(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, " 83 printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
87 "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", 84 "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
88 crw[chain].slct, crw[chain].oflw, crw[chain].chn, 85 crw[chain].slct, crw[chain].oflw, crw[chain].chn,
89 crw[chain].rsc, crw[chain].anc, crw[chain].erc, 86 crw[chain].rsc, crw[chain].anc, crw[chain].erc,
90 crw[chain].rsid); 87 crw[chain].rsid);
91 /* Check for overflows. */ 88 /* Check for overflows. */
92 if (crw[chain].oflw) { 89 if (crw[chain].oflw) {
93 pr_debug("%s: crw overflow detected!\n", __FUNCTION__); 90 pr_debug("%s: crw overflow detected!\n", __FUNCTION__);
@@ -117,8 +114,8 @@ repeat:
117 * reported to the common I/O layer. 114 * reported to the common I/O layer.
118 */ 115 */
119 if (crw[chain].slct) { 116 if (crw[chain].slct) {
120 DBG(KERN_INFO"solicited machine check for " 117 pr_debug("solicited machine check for "
121 "channel path %02X\n", crw[0].rsid); 118 "channel path %02X\n", crw[0].rsid);
122 break; 119 break;
123 } 120 }
124 switch (crw[0].erc) { 121 switch (crw[0].erc) {
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 94d1b74db356..7c84b3d4bd94 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -543,7 +543,7 @@ do { \
543} while (0) 543} while (0)
544 544
545#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL 545#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL
546# define ZFCP_LOG_NORMAL(fmt, args...) 546# define ZFCP_LOG_NORMAL(fmt, args...) do { } while (0)
547#else 547#else
548# define ZFCP_LOG_NORMAL(fmt, args...) \ 548# define ZFCP_LOG_NORMAL(fmt, args...) \
549do { \ 549do { \
@@ -553,7 +553,7 @@ do { \
553#endif 553#endif
554 554
555#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_INFO 555#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_INFO
556# define ZFCP_LOG_INFO(fmt, args...) 556# define ZFCP_LOG_INFO(fmt, args...) do { } while (0)
557#else 557#else
558# define ZFCP_LOG_INFO(fmt, args...) \ 558# define ZFCP_LOG_INFO(fmt, args...) \
559do { \ 559do { \
@@ -563,14 +563,14 @@ do { \
563#endif 563#endif
564 564
565#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_DEBUG 565#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_DEBUG
566# define ZFCP_LOG_DEBUG(fmt, args...) 566# define ZFCP_LOG_DEBUG(fmt, args...) do { } while (0)
567#else 567#else
568# define ZFCP_LOG_DEBUG(fmt, args...) \ 568# define ZFCP_LOG_DEBUG(fmt, args...) \
569 ZFCP_LOG(ZFCP_LOG_LEVEL_DEBUG, fmt , ##args) 569 ZFCP_LOG(ZFCP_LOG_LEVEL_DEBUG, fmt , ##args)
570#endif 570#endif
571 571
572#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_TRACE 572#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_TRACE
573# define ZFCP_LOG_TRACE(fmt, args...) 573# define ZFCP_LOG_TRACE(fmt, args...) do { } while (0)
574#else 574#else
575# define ZFCP_LOG_TRACE(fmt, args...) \ 575# define ZFCP_LOG_TRACE(fmt, args...) \
576 ZFCP_LOG(ZFCP_LOG_LEVEL_TRACE, fmt , ##args) 576 ZFCP_LOG(ZFCP_LOG_LEVEL_TRACE, fmt , ##args)
diff --git a/drivers/s390/sysinfo.c b/drivers/s390/sysinfo.c
index d1c1e75bfd60..1e788e815ce7 100644
--- a/drivers/s390/sysinfo.c
+++ b/drivers/s390/sysinfo.c
@@ -11,19 +11,18 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <asm/ebcdic.h> 12#include <asm/ebcdic.h>
13 13
14struct sysinfo_1_1_1 14struct sysinfo_1_1_1 {
15{
16 char reserved_0[32]; 15 char reserved_0[32];
17 char manufacturer[16]; 16 char manufacturer[16];
18 char type[4]; 17 char type[4];
19 char reserved_1[12]; 18 char reserved_1[12];
20 char model[16]; 19 char model_capacity[16];
21 char sequence[16]; 20 char sequence[16];
22 char plant[4]; 21 char plant[4];
22 char model[16];
23}; 23};
24 24
25struct sysinfo_1_2_1 25struct sysinfo_1_2_1 {
26{
27 char reserved_0[80]; 26 char reserved_0[80];
28 char sequence[16]; 27 char sequence[16];
29 char plant[4]; 28 char plant[4];
@@ -31,9 +30,12 @@ struct sysinfo_1_2_1
31 unsigned short cpu_address; 30 unsigned short cpu_address;
32}; 31};
33 32
34struct sysinfo_1_2_2 33struct sysinfo_1_2_2 {
35{ 34 char format;
36 char reserved_0[32]; 35 char reserved_0[1];
36 unsigned short acc_offset;
37 char reserved_1[24];
38 unsigned int secondary_capability;
37 unsigned int capability; 39 unsigned int capability;
38 unsigned short cpus_total; 40 unsigned short cpus_total;
39 unsigned short cpus_configured; 41 unsigned short cpus_configured;
@@ -42,8 +44,12 @@ struct sysinfo_1_2_2
42 unsigned short adjustment[0]; 44 unsigned short adjustment[0];
43}; 45};
44 46
45struct sysinfo_2_2_1 47struct sysinfo_1_2_2_extension {
46{ 48 unsigned int alt_capability;
49 unsigned short alt_adjustment[0];
50};
51
52struct sysinfo_2_2_1 {
47 char reserved_0[80]; 53 char reserved_0[80];
48 char sequence[16]; 54 char sequence[16];
49 char plant[4]; 55 char plant[4];
@@ -51,15 +57,11 @@ struct sysinfo_2_2_1
51 unsigned short cpu_address; 57 unsigned short cpu_address;
52}; 58};
53 59
54struct sysinfo_2_2_2 60struct sysinfo_2_2_2 {
55{
56 char reserved_0[32]; 61 char reserved_0[32];
57 unsigned short lpar_number; 62 unsigned short lpar_number;
58 char reserved_1; 63 char reserved_1;
59 unsigned char characteristics; 64 unsigned char characteristics;
60 #define LPAR_CHAR_DEDICATED (1 << 7)
61 #define LPAR_CHAR_SHARED (1 << 6)
62 #define LPAR_CHAR_LIMITED (1 << 5)
63 unsigned short cpus_total; 65 unsigned short cpus_total;
64 unsigned short cpus_configured; 66 unsigned short cpus_configured;
65 unsigned short cpus_standby; 67 unsigned short cpus_standby;
@@ -71,12 +73,14 @@ struct sysinfo_2_2_2
71 unsigned short cpus_shared; 73 unsigned short cpus_shared;
72}; 74};
73 75
74struct sysinfo_3_2_2 76#define LPAR_CHAR_DEDICATED (1 << 7)
75{ 77#define LPAR_CHAR_SHARED (1 << 6)
78#define LPAR_CHAR_LIMITED (1 << 5)
79
80struct sysinfo_3_2_2 {
76 char reserved_0[31]; 81 char reserved_0[31];
77 unsigned char count; 82 unsigned char count;
78 struct 83 struct {
79 {
80 char reserved_0[4]; 84 char reserved_0[4];
81 unsigned short cpus_total; 85 unsigned short cpus_total;
82 unsigned short cpus_configured; 86 unsigned short cpus_configured;
@@ -90,136 +94,223 @@ struct sysinfo_3_2_2
90 } vm[8]; 94 } vm[8];
91}; 95};
92 96
93union s390_sysinfo 97static inline int stsi(void *sysinfo, int fc, int sel1, int sel2)
94{ 98{
95 struct sysinfo_1_1_1 sysinfo_1_1_1; 99 register int r0 asm("0") = (fc << 28) | sel1;
96 struct sysinfo_1_2_1 sysinfo_1_2_1; 100 register int r1 asm("1") = sel2;
97 struct sysinfo_1_2_2 sysinfo_1_2_2; 101
98 struct sysinfo_2_2_1 sysinfo_2_2_1; 102 asm volatile(
99 struct sysinfo_2_2_2 sysinfo_2_2_2; 103 " stsi 0(%2)\n"
100 struct sysinfo_3_2_2 sysinfo_3_2_2; 104 "0: jz 2f\n"
101}; 105 "1: lhi %0,%3\n"
102 106 "2:\n"
103static inline int stsi (void *sysinfo, 107 EX_TABLE(0b,1b)
104 int fc, int sel1, int sel2) 108 : "+d" (r0) : "d" (r1), "a" (sysinfo), "K" (-ENOSYS)
105{ 109 : "cc", "memory" );
106 int cc, retv; 110 return r0;
107
108#ifndef CONFIG_64BIT
109 __asm__ __volatile__ ( "lr\t0,%2\n"
110 "\tlr\t1,%3\n"
111 "\tstsi\t0(%4)\n"
112 "0:\tipm\t%0\n"
113 "\tsrl\t%0,28\n"
114 "1:lr\t%1,0\n"
115 ".section .fixup,\"ax\"\n"
116 "2:\tlhi\t%0,3\n"
117 "\tbras\t1,3f\n"
118 "\t.long 1b\n"
119 "3:\tl\t1,0(1)\n"
120 "\tbr\t1\n"
121 ".previous\n"
122 ".section __ex_table,\"a\"\n"
123 "\t.align 4\n"
124 "\t.long 0b,2b\n"
125 ".previous\n"
126 : "=d" (cc), "=d" (retv)
127 : "d" ((fc << 28) | sel1), "d" (sel2), "a" (sysinfo)
128 : "cc", "memory", "0", "1" );
129#else
130 __asm__ __volatile__ ( "lr\t0,%2\n"
131 "lr\t1,%3\n"
132 "\tstsi\t0(%4)\n"
133 "0:\tipm\t%0\n"
134 "\tsrl\t%0,28\n"
135 "1:lr\t%1,0\n"
136 ".section .fixup,\"ax\"\n"
137 "2:\tlhi\t%0,3\n"
138 "\tjg\t1b\n"
139 ".previous\n"
140 ".section __ex_table,\"a\"\n"
141 "\t.align 8\n"
142 "\t.quad 0b,2b\n"
143 ".previous\n"
144 : "=d" (cc), "=d" (retv)
145 : "d" ((fc << 28) | sel1), "d" (sel2), "a" (sysinfo)
146 : "cc", "memory", "0", "1" );
147#endif
148
149 return cc? -1 : retv;
150} 111}
151 112
152static inline int stsi_0 (void) 113static inline int stsi_0(void)
153{ 114{
154 int rc = stsi (NULL, 0, 0, 0); 115 int rc = stsi (NULL, 0, 0, 0);
155 return rc == -1 ? rc : (((unsigned int)rc) >> 28); 116 return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
156} 117}
157 118
158static inline int stsi_1_1_1 (struct sysinfo_1_1_1 *info) 119static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
159{ 120{
160 int rc = stsi (info, 1, 1, 1); 121 if (stsi(info, 1, 1, 1) == -ENOSYS)
161 if (rc != -1) 122 return len;
162 { 123
163 EBCASC (info->manufacturer, sizeof(info->manufacturer)); 124 EBCASC(info->manufacturer, sizeof(info->manufacturer));
164 EBCASC (info->type, sizeof(info->type)); 125 EBCASC(info->type, sizeof(info->type));
165 EBCASC (info->model, sizeof(info->model)); 126 EBCASC(info->model, sizeof(info->model));
166 EBCASC (info->sequence, sizeof(info->sequence)); 127 EBCASC(info->sequence, sizeof(info->sequence));
167 EBCASC (info->plant, sizeof(info->plant)); 128 EBCASC(info->plant, sizeof(info->plant));
168 } 129 EBCASC(info->model_capacity, sizeof(info->model_capacity));
169 return rc == -1 ? rc : 0; 130 len += sprintf(page + len, "Manufacturer: %-16.16s\n",
131 info->manufacturer);
132 len += sprintf(page + len, "Type: %-4.4s\n",
133 info->type);
134 if (info->model[0] != '\0')
135 /*
136 * Sigh: the model field has been renamed with System z9
137 * to model_capacity and a new model field has been added
138 * after the plant field. To avoid confusing older programs
139 * the "Model:" prints "model_capacity model" or just
140 * "model_capacity" if the model string is empty .
141 */
142 len += sprintf(page + len,
143 "Model: %-16.16s %-16.16s\n",
144 info->model_capacity, info->model);
145 else
146 len += sprintf(page + len, "Model: %-16.16s\n",
147 info->model_capacity);
148 len += sprintf(page + len, "Sequence Code: %-16.16s\n",
149 info->sequence);
150 len += sprintf(page + len, "Plant: %-4.4s\n",
151 info->plant);
152 len += sprintf(page + len, "Model Capacity: %-16.16s\n",
153 info->model_capacity);
154 return len;
170} 155}
171 156
172static inline int stsi_1_2_1 (struct sysinfo_1_2_1 *info) 157#if 0 /* Currently unused */
158static int stsi_1_2_1(struct sysinfo_1_2_1 *info, char *page, int len)
173{ 159{
174 int rc = stsi (info, 1, 2, 1); 160 if (stsi(info, 1, 2, 1) == -ENOSYS)
175 if (rc != -1) 161 return len;
176 { 162
177 EBCASC (info->sequence, sizeof(info->sequence)); 163 len += sprintf(page + len, "\n");
178 EBCASC (info->plant, sizeof(info->plant)); 164 EBCASC(info->sequence, sizeof(info->sequence));
179 } 165 EBCASC(info->plant, sizeof(info->plant));
180 return rc == -1 ? rc : 0; 166 len += sprintf(page + len, "Sequence Code of CPU: %-16.16s\n",
167 info->sequence);
168 len += sprintf(page + len, "Plant of CPU: %-16.16s\n",
169 info->plant);
170 return len;
181} 171}
172#endif
182 173
183static inline int stsi_1_2_2 (struct sysinfo_1_2_2 *info) 174static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
184{ 175{
185 int rc = stsi (info, 1, 2, 2); 176 struct sysinfo_1_2_2_extension *ext;
186 return rc == -1 ? rc : 0; 177 int i;
178
179 if (stsi(info, 1, 2, 2) == -ENOSYS)
180 return len;
181 ext = (struct sysinfo_1_2_2_extension *)
182 ((unsigned long) info + info->acc_offset);
183
184 len += sprintf(page + len, "\n");
185 len += sprintf(page + len, "CPUs Total: %d\n",
186 info->cpus_total);
187 len += sprintf(page + len, "CPUs Configured: %d\n",
188 info->cpus_configured);
189 len += sprintf(page + len, "CPUs Standby: %d\n",
190 info->cpus_standby);
191 len += sprintf(page + len, "CPUs Reserved: %d\n",
192 info->cpus_reserved);
193
194 if (info->format == 1) {
195 /*
196 * Sigh 2. According to the specification the alternate
197 * capability field is a 32 bit floating point number
198 * if the higher order 8 bits are not zero. Printing
199 * a floating point number in the kernel is a no-no,
200 * always print the number as 32 bit unsigned integer.
201 * The user-space needs to know about the stange
202 * encoding of the alternate cpu capability.
203 */
204 len += sprintf(page + len, "Capability: %u %u\n",
205 info->capability, ext->alt_capability);
206 for (i = 2; i <= info->cpus_total; i++)
207 len += sprintf(page + len,
208 "Adjustment %02d-way: %u %u\n",
209 i, info->adjustment[i-2],
210 ext->alt_adjustment[i-2]);
211
212 } else {
213 len += sprintf(page + len, "Capability: %u\n",
214 info->capability);
215 for (i = 2; i <= info->cpus_total; i++)
216 len += sprintf(page + len,
217 "Adjustment %02d-way: %u\n",
218 i, info->adjustment[i-2]);
219 }
220
221 if (info->secondary_capability != 0)
222 len += sprintf(page + len, "Secondary Capability: %d\n",
223 info->secondary_capability);
224
225 return len;
187} 226}
188 227
189static inline int stsi_2_2_1 (struct sysinfo_2_2_1 *info) 228#if 0 /* Currently unused */
229static int stsi_2_2_1(struct sysinfo_2_2_1 *info, char *page, int len)
190{ 230{
191 int rc = stsi (info, 2, 2, 1); 231 if (stsi(info, 2, 2, 1) == -ENOSYS)
192 if (rc != -1) 232 return len;
193 { 233
194 EBCASC (info->sequence, sizeof(info->sequence)); 234 len += sprintf(page + len, "\n");
195 EBCASC (info->plant, sizeof(info->plant)); 235 EBCASC (info->sequence, sizeof(info->sequence));
196 } 236 EBCASC (info->plant, sizeof(info->plant));
197 return rc == -1 ? rc : 0; 237 len += sprintf(page + len, "Sequence Code of logical CPU: %-16.16s\n",
238 info->sequence);
239 len += sprintf(page + len, "Plant of logical CPU: %-16.16s\n",
240 info->plant);
241 return len;
198} 242}
243#endif
199 244
200static inline int stsi_2_2_2 (struct sysinfo_2_2_2 *info) 245static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len)
201{ 246{
202 int rc = stsi (info, 2, 2, 2); 247 if (stsi(info, 2, 2, 2) == -ENOSYS)
203 if (rc != -1) 248 return len;
204 { 249
205 EBCASC (info->name, sizeof(info->name)); 250 EBCASC (info->name, sizeof(info->name));
206 } 251
207 return rc == -1 ? rc : 0; 252 len += sprintf(page + len, "\n");
253 len += sprintf(page + len, "LPAR Number: %d\n",
254 info->lpar_number);
255
256 len += sprintf(page + len, "LPAR Characteristics: ");
257 if (info->characteristics & LPAR_CHAR_DEDICATED)
258 len += sprintf(page + len, "Dedicated ");
259 if (info->characteristics & LPAR_CHAR_SHARED)
260 len += sprintf(page + len, "Shared ");
261 if (info->characteristics & LPAR_CHAR_LIMITED)
262 len += sprintf(page + len, "Limited ");
263 len += sprintf(page + len, "\n");
264
265 len += sprintf(page + len, "LPAR Name: %-8.8s\n",
266 info->name);
267
268 len += sprintf(page + len, "LPAR Adjustment: %d\n",
269 info->caf);
270
271 len += sprintf(page + len, "LPAR CPUs Total: %d\n",
272 info->cpus_total);
273 len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
274 info->cpus_configured);
275 len += sprintf(page + len, "LPAR CPUs Standby: %d\n",
276 info->cpus_standby);
277 len += sprintf(page + len, "LPAR CPUs Reserved: %d\n",
278 info->cpus_reserved);
279 len += sprintf(page + len, "LPAR CPUs Dedicated: %d\n",
280 info->cpus_dedicated);
281 len += sprintf(page + len, "LPAR CPUs Shared: %d\n",
282 info->cpus_shared);
283 return len;
208} 284}
209 285
210static inline int stsi_3_2_2 (struct sysinfo_3_2_2 *info) 286static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
211{ 287{
212 int rc = stsi (info, 3, 2, 2); 288 int i;
213 if (rc != -1) 289
214 { 290 if (stsi(info, 3, 2, 2) == -ENOSYS)
215 int i; 291 return len;
216 for (i = 0; i < info->count; i++) 292 for (i = 0; i < info->count; i++) {
217 { 293 EBCASC (info->vm[i].name, sizeof(info->vm[i].name));
218 EBCASC (info->vm[i].name, sizeof(info->vm[i].name)); 294 EBCASC (info->vm[i].cpi, sizeof(info->vm[i].cpi));
219 EBCASC (info->vm[i].cpi, sizeof(info->vm[i].cpi)); 295 len += sprintf(page + len, "\n");
220 } 296 len += sprintf(page + len, "VM%02d Name: %-8.8s\n",
297 i, info->vm[i].name);
298 len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n",
299 i, info->vm[i].cpi);
300
301 len += sprintf(page + len, "VM%02d Adjustment: %d\n",
302 i, info->vm[i].caf);
303
304 len += sprintf(page + len, "VM%02d CPUs Total: %d\n",
305 i, info->vm[i].cpus_total);
306 len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
307 i, info->vm[i].cpus_configured);
308 len += sprintf(page + len, "VM%02d CPUs Standby: %d\n",
309 i, info->vm[i].cpus_standby);
310 len += sprintf(page + len, "VM%02d CPUs Reserved: %d\n",
311 i, info->vm[i].cpus_reserved);
221 } 312 }
222 return rc == -1 ? rc : 0; 313 return len;
223} 314}
224 315
225 316
@@ -227,118 +318,34 @@ static int proc_read_sysinfo(char *page, char **start,
227 off_t off, int count, 318 off_t off, int count,
228 int *eof, void *data) 319 int *eof, void *data)
229{ 320{
230 unsigned long info_page = get_zeroed_page (GFP_KERNEL); 321 unsigned long info = get_zeroed_page (GFP_KERNEL);
231 union s390_sysinfo *info = (union s390_sysinfo *) info_page; 322 int level, len;
232 int len = 0;
233 int level;
234 int i;
235 323
236 if (!info) 324 if (!info)
237 return 0; 325 return 0;
238 326
239 level = stsi_0 (); 327 len = 0;
240 328 level = stsi_0();
241 if (level >= 1 && stsi_1_1_1 (&info->sysinfo_1_1_1) == 0) 329 if (level >= 1)
242 { 330 len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
243 len += sprintf (page+len, "Manufacturer: %-16.16s\n",
244 info->sysinfo_1_1_1.manufacturer);
245 len += sprintf (page+len, "Type: %-4.4s\n",
246 info->sysinfo_1_1_1.type);
247 len += sprintf (page+len, "Model: %-16.16s\n",
248 info->sysinfo_1_1_1.model);
249 len += sprintf (page+len, "Sequence Code: %-16.16s\n",
250 info->sysinfo_1_1_1.sequence);
251 len += sprintf (page+len, "Plant: %-4.4s\n",
252 info->sysinfo_1_1_1.plant);
253 }
254
255 if (level >= 1 && stsi_1_2_2 (&info->sysinfo_1_2_2) == 0)
256 {
257 len += sprintf (page+len, "\n");
258 len += sprintf (page+len, "CPUs Total: %d\n",
259 info->sysinfo_1_2_2.cpus_total);
260 len += sprintf (page+len, "CPUs Configured: %d\n",
261 info->sysinfo_1_2_2.cpus_configured);
262 len += sprintf (page+len, "CPUs Standby: %d\n",
263 info->sysinfo_1_2_2.cpus_standby);
264 len += sprintf (page+len, "CPUs Reserved: %d\n",
265 info->sysinfo_1_2_2.cpus_reserved);
266
267 len += sprintf (page+len, "Capability: %d\n",
268 info->sysinfo_1_2_2.capability);
269 331
270 for (i = 2; i <= info->sysinfo_1_2_2.cpus_total; i++) 332 if (level >= 1)
271 len += sprintf (page+len, "Adjustment %02d-way: %d\n", 333 len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
272 i, info->sysinfo_1_2_2.adjustment[i-2]);
273 }
274 334
275 if (level >= 2 && stsi_2_2_2 (&info->sysinfo_2_2_2) == 0) 335 if (level >= 2)
276 { 336 len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len);
277 len += sprintf (page+len, "\n");
278 len += sprintf (page+len, "LPAR Number: %d\n",
279 info->sysinfo_2_2_2.lpar_number);
280
281 len += sprintf (page+len, "LPAR Characteristics: ");
282 if (info->sysinfo_2_2_2.characteristics & LPAR_CHAR_DEDICATED)
283 len += sprintf (page+len, "Dedicated ");
284 if (info->sysinfo_2_2_2.characteristics & LPAR_CHAR_SHARED)
285 len += sprintf (page+len, "Shared ");
286 if (info->sysinfo_2_2_2.characteristics & LPAR_CHAR_LIMITED)
287 len += sprintf (page+len, "Limited ");
288 len += sprintf (page+len, "\n");
289
290 len += sprintf (page+len, "LPAR Name: %-8.8s\n",
291 info->sysinfo_2_2_2.name);
292
293 len += sprintf (page+len, "LPAR Adjustment: %d\n",
294 info->sysinfo_2_2_2.caf);
295
296 len += sprintf (page+len, "LPAR CPUs Total: %d\n",
297 info->sysinfo_2_2_2.cpus_total);
298 len += sprintf (page+len, "LPAR CPUs Configured: %d\n",
299 info->sysinfo_2_2_2.cpus_configured);
300 len += sprintf (page+len, "LPAR CPUs Standby: %d\n",
301 info->sysinfo_2_2_2.cpus_standby);
302 len += sprintf (page+len, "LPAR CPUs Reserved: %d\n",
303 info->sysinfo_2_2_2.cpus_reserved);
304 len += sprintf (page+len, "LPAR CPUs Dedicated: %d\n",
305 info->sysinfo_2_2_2.cpus_dedicated);
306 len += sprintf (page+len, "LPAR CPUs Shared: %d\n",
307 info->sysinfo_2_2_2.cpus_shared);
308 }
309 337
310 if (level >= 3 && stsi_3_2_2 (&info->sysinfo_3_2_2) == 0) 338 if (level >= 3)
311 { 339 len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
312 for (i = 0; i < info->sysinfo_3_2_2.count; i++)
313 {
314 len += sprintf (page+len, "\n");
315 len += sprintf (page+len, "VM%02d Name: %-8.8s\n",
316 i, info->sysinfo_3_2_2.vm[i].name);
317 len += sprintf (page+len, "VM%02d Control Program: %-16.16s\n",
318 i, info->sysinfo_3_2_2.vm[i].cpi);
319
320 len += sprintf (page+len, "VM%02d Adjustment: %d\n",
321 i, info->sysinfo_3_2_2.vm[i].caf);
322
323 len += sprintf (page+len, "VM%02d CPUs Total: %d\n",
324 i, info->sysinfo_3_2_2.vm[i].cpus_total);
325 len += sprintf (page+len, "VM%02d CPUs Configured: %d\n",
326 i, info->sysinfo_3_2_2.vm[i].cpus_configured);
327 len += sprintf (page+len, "VM%02d CPUs Standby: %d\n",
328 i, info->sysinfo_3_2_2.vm[i].cpus_standby);
329 len += sprintf (page+len, "VM%02d CPUs Reserved: %d\n",
330 i, info->sysinfo_3_2_2.vm[i].cpus_reserved);
331 }
332 }
333 340
334 free_page (info_page); 341 free_page (info);
335 return len; 342 return len;
336} 343}
337 344
338static __init int create_proc_sysinfo(void) 345static __init int create_proc_sysinfo(void)
339{ 346{
340 create_proc_read_entry ("sysinfo", 0444, NULL, 347 create_proc_read_entry("sysinfo", 0444, NULL,
341 proc_read_sysinfo, NULL); 348 proc_read_sysinfo, NULL);
342 return 0; 349 return 0;
343} 350}
344 351
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index ed22b96580c6..01b8ac641eb8 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -156,8 +156,8 @@ static void gather_partition_info(void)
156{ 156{
157 struct device_node *rootdn; 157 struct device_node *rootdn;
158 158
159 char *ppartition_name; 159 const char *ppartition_name;
160 unsigned int *p_number_ptr; 160 const unsigned int *p_number_ptr;
161 161
162 /* Retrieve information about this partition */ 162 /* Retrieve information about this partition */
163 rootdn = find_path_device("/"); 163 rootdn = find_path_device("/");
@@ -165,14 +165,11 @@ static void gather_partition_info(void)
165 return; 165 return;
166 } 166 }
167 167
168 ppartition_name = 168 ppartition_name = get_property(rootdn, "ibm,partition-name", NULL);
169 get_property(rootdn, "ibm,partition-name", NULL);
170 if (ppartition_name) 169 if (ppartition_name)
171 strncpy(partition_name, ppartition_name, 170 strncpy(partition_name, ppartition_name,
172 sizeof(partition_name)); 171 sizeof(partition_name));
173 p_number_ptr = 172 p_number_ptr = get_property(rootdn, "ibm,partition-no", NULL);
174 (unsigned int *)get_property(rootdn, "ibm,partition-no",
175 NULL);
176 if (p_number_ptr) 173 if (p_number_ptr)
177 partition_number = *p_number_ptr; 174 partition_number = *p_number_ptr;
178} 175}
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 058f094f945a..66a1ae1d6982 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -26,6 +26,7 @@
26 * Zhenyu Wang 26 * Zhenyu Wang
27 */ 27 */
28 28
29#include <linux/err.h>
29#include <linux/types.h> 30#include <linux/types.h>
30#include <linux/list.h> 31#include <linux/list.h>
31#include <linux/inet.h> 32#include <linux/inet.h>
@@ -107,8 +108,11 @@ iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
107 u8* crc) 108 u8* crc)
108{ 109{
109 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 110 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
111 struct hash_desc desc;
110 112
111 crypto_digest_digest(tcp_conn->tx_tfm, &buf->sg, 1, crc); 113 desc.tfm = tcp_conn->tx_tfm;
114 desc.flags = 0;
115 crypto_hash_digest(&desc, &buf->sg, buf->sg.length, crc);
112 buf->sg.length += sizeof(uint32_t); 116 buf->sg.length += sizeof(uint32_t);
113} 117}
114 118
@@ -452,11 +456,14 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
452 } 456 }
453 457
454 if (conn->hdrdgst_en) { 458 if (conn->hdrdgst_en) {
459 struct hash_desc desc;
455 struct scatterlist sg; 460 struct scatterlist sg;
456 461
457 sg_init_one(&sg, (u8 *)hdr, 462 sg_init_one(&sg, (u8 *)hdr,
458 sizeof(struct iscsi_hdr) + ahslen); 463 sizeof(struct iscsi_hdr) + ahslen);
459 crypto_digest_digest(tcp_conn->rx_tfm, &sg, 1, (u8 *)&cdgst); 464 desc.tfm = tcp_conn->rx_tfm;
465 desc.flags = 0;
466 crypto_hash_digest(&desc, &sg, sg.length, (u8 *)&cdgst);
460 rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) + 467 rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
461 ahslen); 468 ahslen);
462 if (cdgst != rdgst) { 469 if (cdgst != rdgst) {
@@ -673,7 +680,7 @@ partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn,
673 memcpy(&temp, sg, sizeof(struct scatterlist)); 680 memcpy(&temp, sg, sizeof(struct scatterlist));
674 temp.offset = offset; 681 temp.offset = offset;
675 temp.length = length; 682 temp.length = length;
676 crypto_digest_update(tcp_conn->data_rx_tfm, &temp, 1); 683 crypto_hash_update(&tcp_conn->data_rx_hash, &temp, length);
677} 684}
678 685
679static void 686static void
@@ -682,7 +689,7 @@ iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len)
682 struct scatterlist tmp; 689 struct scatterlist tmp;
683 690
684 sg_init_one(&tmp, buf, len); 691 sg_init_one(&tmp, buf, len);
685 crypto_digest_update(tcp_conn->data_rx_tfm, &tmp, 1); 692 crypto_hash_update(&tcp_conn->data_rx_hash, &tmp, len);
686} 693}
687 694
688static int iscsi_scsi_data_in(struct iscsi_conn *conn) 695static int iscsi_scsi_data_in(struct iscsi_conn *conn)
@@ -736,9 +743,9 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
736 if (!rc) { 743 if (!rc) {
737 if (conn->datadgst_en) { 744 if (conn->datadgst_en) {
738 if (!offset) 745 if (!offset)
739 crypto_digest_update( 746 crypto_hash_update(
740 tcp_conn->data_rx_tfm, 747 &tcp_conn->data_rx_hash,
741 &sg[i], 1); 748 &sg[i], sg[i].length);
742 else 749 else
743 partial_sg_digest_update(tcp_conn, 750 partial_sg_digest_update(tcp_conn,
744 &sg[i], 751 &sg[i],
@@ -877,8 +884,7 @@ more:
877 rc = iscsi_tcp_hdr_recv(conn); 884 rc = iscsi_tcp_hdr_recv(conn);
878 if (!rc && tcp_conn->in.datalen) { 885 if (!rc && tcp_conn->in.datalen) {
879 if (conn->datadgst_en) { 886 if (conn->datadgst_en) {
880 BUG_ON(!tcp_conn->data_rx_tfm); 887 crypto_hash_init(&tcp_conn->data_rx_hash);
881 crypto_digest_init(tcp_conn->data_rx_tfm);
882 } 888 }
883 tcp_conn->in_progress = IN_PROGRESS_DATA_RECV; 889 tcp_conn->in_progress = IN_PROGRESS_DATA_RECV;
884 } else if (rc) { 890 } else if (rc) {
@@ -931,11 +937,11 @@ more:
931 tcp_conn->in.padding); 937 tcp_conn->in.padding);
932 memset(pad, 0, tcp_conn->in.padding); 938 memset(pad, 0, tcp_conn->in.padding);
933 sg_init_one(&sg, pad, tcp_conn->in.padding); 939 sg_init_one(&sg, pad, tcp_conn->in.padding);
934 crypto_digest_update(tcp_conn->data_rx_tfm, 940 crypto_hash_update(&tcp_conn->data_rx_hash,
935 &sg, 1); 941 &sg, sg.length);
936 } 942 }
937 crypto_digest_final(tcp_conn->data_rx_tfm, 943 crypto_hash_final(&tcp_conn->data_rx_hash,
938 (u8 *) & tcp_conn->in.datadgst); 944 (u8 *)&tcp_conn->in.datadgst);
939 debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst); 945 debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
940 tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV; 946 tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
941 } else 947 } else
@@ -1181,8 +1187,7 @@ iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
1181{ 1187{
1182 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1188 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1183 1189
1184 BUG_ON(!tcp_conn->data_tx_tfm); 1190 crypto_hash_init(&tcp_conn->data_tx_hash);
1185 crypto_digest_init(tcp_conn->data_tx_tfm);
1186 tcp_ctask->digest_count = 4; 1191 tcp_ctask->digest_count = 4;
1187} 1192}
1188 1193
@@ -1196,7 +1201,7 @@ iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1196 int sent = 0; 1201 int sent = 0;
1197 1202
1198 if (final) 1203 if (final)
1199 crypto_digest_final(tcp_conn->data_tx_tfm, (u8*)digest); 1204 crypto_hash_final(&tcp_conn->data_tx_hash, (u8 *)digest);
1200 1205
1201 iscsi_buf_init_iov(buf, (char*)digest, 4); 1206 iscsi_buf_init_iov(buf, (char*)digest, 4);
1202 rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent); 1207 rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
@@ -1491,16 +1496,17 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1491 if (rc) { 1496 if (rc) {
1492 tcp_ctask->xmstate |= XMSTATE_IMM_DATA; 1497 tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
1493 if (conn->datadgst_en) { 1498 if (conn->datadgst_en) {
1494 crypto_digest_final(tcp_conn->data_tx_tfm, 1499 crypto_hash_final(&tcp_conn->data_tx_hash,
1495 (u8*)&tcp_ctask->immdigest); 1500 (u8 *)&tcp_ctask->immdigest);
1496 debug_tcp("tx imm sendpage fail 0x%x\n", 1501 debug_tcp("tx imm sendpage fail 0x%x\n",
1497 tcp_ctask->datadigest); 1502 tcp_ctask->datadigest);
1498 } 1503 }
1499 return rc; 1504 return rc;
1500 } 1505 }
1501 if (conn->datadgst_en) 1506 if (conn->datadgst_en)
1502 crypto_digest_update(tcp_conn->data_tx_tfm, 1507 crypto_hash_update(&tcp_conn->data_tx_hash,
1503 &tcp_ctask->sendbuf.sg, 1); 1508 &tcp_ctask->sendbuf.sg,
1509 tcp_ctask->sendbuf.sg.length);
1504 1510
1505 if (!ctask->imm_count) 1511 if (!ctask->imm_count)
1506 break; 1512 break;
@@ -1577,8 +1583,8 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1577 tcp_ctask->xmstate |= XMSTATE_UNS_DATA; 1583 tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
1578 /* will continue with this ctask later.. */ 1584 /* will continue with this ctask later.. */
1579 if (conn->datadgst_en) { 1585 if (conn->datadgst_en) {
1580 crypto_digest_final(tcp_conn->data_tx_tfm, 1586 crypto_hash_final(&tcp_conn->data_tx_hash,
1581 (u8 *)&dtask->digest); 1587 (u8 *)&dtask->digest);
1582 debug_tcp("tx uns data fail 0x%x\n", 1588 debug_tcp("tx uns data fail 0x%x\n",
1583 dtask->digest); 1589 dtask->digest);
1584 } 1590 }
@@ -1593,8 +1599,9 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1593 * so pass it 1599 * so pass it
1594 */ 1600 */
1595 if (conn->datadgst_en && tcp_ctask->sent - start > 0) 1601 if (conn->datadgst_en && tcp_ctask->sent - start > 0)
1596 crypto_digest_update(tcp_conn->data_tx_tfm, 1602 crypto_hash_update(&tcp_conn->data_tx_hash,
1597 &tcp_ctask->sendbuf.sg, 1); 1603 &tcp_ctask->sendbuf.sg,
1604 tcp_ctask->sendbuf.sg.length);
1598 1605
1599 if (!ctask->data_count) 1606 if (!ctask->data_count)
1600 break; 1607 break;
@@ -1668,7 +1675,7 @@ solicit_again:
1668 tcp_ctask->xmstate |= XMSTATE_SOL_DATA; 1675 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1669 /* will continue with this ctask later.. */ 1676 /* will continue with this ctask later.. */
1670 if (conn->datadgst_en) { 1677 if (conn->datadgst_en) {
1671 crypto_digest_final(tcp_conn->data_tx_tfm, 1678 crypto_hash_final(&tcp_conn->data_tx_hash,
1672 (u8 *)&dtask->digest); 1679 (u8 *)&dtask->digest);
1673 debug_tcp("r2t data send fail 0x%x\n", dtask->digest); 1680 debug_tcp("r2t data send fail 0x%x\n", dtask->digest);
1674 } 1681 }
@@ -1677,8 +1684,8 @@ solicit_again:
1677 1684
1678 BUG_ON(r2t->data_count < 0); 1685 BUG_ON(r2t->data_count < 0);
1679 if (conn->datadgst_en) 1686 if (conn->datadgst_en)
1680 crypto_digest_update(tcp_conn->data_tx_tfm, &r2t->sendbuf.sg, 1687 crypto_hash_update(&tcp_conn->data_tx_hash, &r2t->sendbuf.sg,
1681 1); 1688 r2t->sendbuf.sg.length);
1682 1689
1683 if (r2t->data_count) { 1690 if (r2t->data_count) {
1684 BUG_ON(ctask->sc->use_sg == 0); 1691 BUG_ON(ctask->sc->use_sg == 0);
@@ -1766,8 +1773,9 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1766 } 1773 }
1767 1774
1768 if (conn->datadgst_en) { 1775 if (conn->datadgst_en) {
1769 crypto_digest_update(tcp_conn->data_tx_tfm, 1776 crypto_hash_update(&tcp_conn->data_tx_hash,
1770 &tcp_ctask->sendbuf.sg, 1); 1777 &tcp_ctask->sendbuf.sg,
1778 tcp_ctask->sendbuf.sg.length);
1771 /* imm data? */ 1779 /* imm data? */
1772 if (!dtask) { 1780 if (!dtask) {
1773 rc = iscsi_digest_final_send(conn, ctask, 1781 rc = iscsi_digest_final_send(conn, ctask,
@@ -1963,13 +1971,13 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
1963 /* now free tcp_conn */ 1971 /* now free tcp_conn */
1964 if (digest) { 1972 if (digest) {
1965 if (tcp_conn->tx_tfm) 1973 if (tcp_conn->tx_tfm)
1966 crypto_free_tfm(tcp_conn->tx_tfm); 1974 crypto_free_hash(tcp_conn->tx_tfm);
1967 if (tcp_conn->rx_tfm) 1975 if (tcp_conn->rx_tfm)
1968 crypto_free_tfm(tcp_conn->rx_tfm); 1976 crypto_free_hash(tcp_conn->rx_tfm);
1969 if (tcp_conn->data_tx_tfm) 1977 if (tcp_conn->data_tx_hash.tfm)
1970 crypto_free_tfm(tcp_conn->data_tx_tfm); 1978 crypto_free_hash(tcp_conn->data_tx_hash.tfm);
1971 if (tcp_conn->data_rx_tfm) 1979 if (tcp_conn->data_rx_hash.tfm)
1972 crypto_free_tfm(tcp_conn->data_rx_tfm); 1980 crypto_free_hash(tcp_conn->data_rx_hash.tfm);
1973 } 1981 }
1974 1982
1975 kfree(tcp_conn); 1983 kfree(tcp_conn);
@@ -2130,44 +2138,48 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2130 if (conn->hdrdgst_en) { 2138 if (conn->hdrdgst_en) {
2131 tcp_conn->hdr_size += sizeof(__u32); 2139 tcp_conn->hdr_size += sizeof(__u32);
2132 if (!tcp_conn->tx_tfm) 2140 if (!tcp_conn->tx_tfm)
2133 tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c", 2141 tcp_conn->tx_tfm =
2134 0); 2142 crypto_alloc_hash("crc32c", 0,
2135 if (!tcp_conn->tx_tfm) 2143 CRYPTO_ALG_ASYNC);
2136 return -ENOMEM; 2144 if (IS_ERR(tcp_conn->tx_tfm))
2145 return PTR_ERR(tcp_conn->tx_tfm);
2137 if (!tcp_conn->rx_tfm) 2146 if (!tcp_conn->rx_tfm)
2138 tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c", 2147 tcp_conn->rx_tfm =
2139 0); 2148 crypto_alloc_hash("crc32c", 0,
2140 if (!tcp_conn->rx_tfm) { 2149 CRYPTO_ALG_ASYNC);
2141 crypto_free_tfm(tcp_conn->tx_tfm); 2150 if (IS_ERR(tcp_conn->rx_tfm)) {
2142 return -ENOMEM; 2151 crypto_free_hash(tcp_conn->tx_tfm);
2152 return PTR_ERR(tcp_conn->rx_tfm);
2143 } 2153 }
2144 } else { 2154 } else {
2145 if (tcp_conn->tx_tfm) 2155 if (tcp_conn->tx_tfm)
2146 crypto_free_tfm(tcp_conn->tx_tfm); 2156 crypto_free_hash(tcp_conn->tx_tfm);
2147 if (tcp_conn->rx_tfm) 2157 if (tcp_conn->rx_tfm)
2148 crypto_free_tfm(tcp_conn->rx_tfm); 2158 crypto_free_hash(tcp_conn->rx_tfm);
2149 } 2159 }
2150 break; 2160 break;
2151 case ISCSI_PARAM_DATADGST_EN: 2161 case ISCSI_PARAM_DATADGST_EN:
2152 iscsi_set_param(cls_conn, param, buf, buflen); 2162 iscsi_set_param(cls_conn, param, buf, buflen);
2153 if (conn->datadgst_en) { 2163 if (conn->datadgst_en) {
2154 if (!tcp_conn->data_tx_tfm) 2164 if (!tcp_conn->data_tx_hash.tfm)
2155 tcp_conn->data_tx_tfm = 2165 tcp_conn->data_tx_hash.tfm =
2156 crypto_alloc_tfm("crc32c", 0); 2166 crypto_alloc_hash("crc32c", 0,
2157 if (!tcp_conn->data_tx_tfm) 2167 CRYPTO_ALG_ASYNC);
2158 return -ENOMEM; 2168 if (IS_ERR(tcp_conn->data_tx_hash.tfm))
2159 if (!tcp_conn->data_rx_tfm) 2169 return PTR_ERR(tcp_conn->data_tx_hash.tfm);
2160 tcp_conn->data_rx_tfm = 2170 if (!tcp_conn->data_rx_hash.tfm)
2161 crypto_alloc_tfm("crc32c", 0); 2171 tcp_conn->data_rx_hash.tfm =
2162 if (!tcp_conn->data_rx_tfm) { 2172 crypto_alloc_hash("crc32c", 0,
2163 crypto_free_tfm(tcp_conn->data_tx_tfm); 2173 CRYPTO_ALG_ASYNC);
2164 return -ENOMEM; 2174 if (IS_ERR(tcp_conn->data_rx_hash.tfm)) {
2175 crypto_free_hash(tcp_conn->data_tx_hash.tfm);
2176 return PTR_ERR(tcp_conn->data_rx_hash.tfm);
2165 } 2177 }
2166 } else { 2178 } else {
2167 if (tcp_conn->data_tx_tfm) 2179 if (tcp_conn->data_tx_hash.tfm)
2168 crypto_free_tfm(tcp_conn->data_tx_tfm); 2180 crypto_free_hash(tcp_conn->data_tx_hash.tfm);
2169 if (tcp_conn->data_rx_tfm) 2181 if (tcp_conn->data_rx_hash.tfm)
2170 crypto_free_tfm(tcp_conn->data_rx_tfm); 2182 crypto_free_hash(tcp_conn->data_rx_hash.tfm);
2171 } 2183 }
2172 tcp_conn->sendpage = conn->datadgst_en ? 2184 tcp_conn->sendpage = conn->datadgst_en ?
2173 sock_no_sendpage : tcp_conn->sock->ops->sendpage; 2185 sock_no_sendpage : tcp_conn->sock->ops->sendpage;
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index 6a4ee704e46e..e35701305fc9 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -51,6 +51,7 @@
51#define ISCSI_SG_TABLESIZE SG_ALL 51#define ISCSI_SG_TABLESIZE SG_ALL
52#define ISCSI_TCP_MAX_CMD_LEN 16 52#define ISCSI_TCP_MAX_CMD_LEN 16
53 53
54struct crypto_hash;
54struct socket; 55struct socket;
55 56
56/* Socket connection recieve helper */ 57/* Socket connection recieve helper */
@@ -84,8 +85,8 @@ struct iscsi_tcp_conn {
84 /* iSCSI connection-wide sequencing */ 85 /* iSCSI connection-wide sequencing */
85 int hdr_size; /* PDU header size */ 86 int hdr_size; /* PDU header size */
86 87
87 struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */ 88 struct crypto_hash *rx_tfm; /* CRC32C (Rx) */
88 struct crypto_tfm *data_rx_tfm; /* CRC32C (Rx) for data */ 89 struct hash_desc data_rx_hash; /* CRC32C (Rx) for data */
89 90
90 /* control data */ 91 /* control data */
91 struct iscsi_tcp_recv in; /* TCP receive context */ 92 struct iscsi_tcp_recv in; /* TCP receive context */
@@ -97,8 +98,8 @@ struct iscsi_tcp_conn {
97 void (*old_write_space)(struct sock *); 98 void (*old_write_space)(struct sock *);
98 99
99 /* xmit */ 100 /* xmit */
100 struct crypto_tfm *tx_tfm; /* CRC32C (Tx) */ 101 struct crypto_hash *tx_tfm; /* CRC32C (Tx) */
101 struct crypto_tfm *data_tx_tfm; /* CRC32C (Tx) for data */ 102 struct hash_desc data_tx_hash; /* CRC32C (Tx) for data */
102 103
103 /* MIB custom statistics */ 104 /* MIB custom statistics */
104 uint32_t sendpage_failures_cnt; 105 uint32_t sendpage_failures_cnt;
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 89ef34df5a1d..6422de72bf43 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -431,7 +431,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat
431 struct fsc_state *state; 431 struct fsc_state *state;
432 struct Scsi_Host *host; 432 struct Scsi_Host *host;
433 void *dma_cmd_space; 433 void *dma_cmd_space;
434 unsigned char *clkprop; 434 const unsigned char *clkprop;
435 int proplen, rc = -ENODEV; 435 int proplen, rc = -ENODEV;
436 436
437 if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { 437 if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) {
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 5572981a9f92..592b52afe658 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1850,7 +1850,8 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
1850{ 1850{
1851 struct device_node *mesh = macio_get_of_node(mdev); 1851 struct device_node *mesh = macio_get_of_node(mdev);
1852 struct pci_dev* pdev = macio_get_pci_dev(mdev); 1852 struct pci_dev* pdev = macio_get_pci_dev(mdev);
1853 int tgt, *cfp, minper; 1853 int tgt, minper;
1854 const int *cfp;
1854 struct mesh_state *ms; 1855 struct mesh_state *ms;
1855 struct Scsi_Host *mesh_host; 1856 struct Scsi_Host *mesh_host;
1856 void *dma_cmd_space; 1857 void *dma_cmd_space;
@@ -1939,7 +1940,7 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
1939 ms->tgts[tgt].current_req = NULL; 1940 ms->tgts[tgt].current_req = NULL;
1940 } 1941 }
1941 1942
1942 if ((cfp = (int *) get_property(mesh, "clock-frequency", NULL))) 1943 if ((cfp = get_property(mesh, "clock-frequency", NULL)))
1943 ms->clk_freq = *cfp; 1944 ms->clk_freq = *cfp;
1944 else { 1945 else {
1945 printk(KERN_INFO "mesh: assuming 50MHz clock frequency\n"); 1946 printk(KERN_INFO "mesh: assuming 50MHz clock frequency\n");
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 7d0858095e1f..6b70c3c76dfd 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -268,7 +268,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
268 /* Match it to a port node */ 268 /* Match it to a port node */
269 index = (ap == ap->host_set->ports[0]) ? 0 : 1; 269 index = (ap == ap->host_set->ports[0]) ? 0 : 1;
270 for (np = np->child; np != NULL; np = np->sibling) { 270 for (np = np->child; np != NULL; np = np->sibling) {
271 u32 *reg = (u32 *)get_property(np, "reg", NULL); 271 const u32 *reg = get_property(np, "reg", NULL);
272 if (!reg) 272 if (!reg)
273 continue; 273 continue;
274 if (index == *reg) 274 if (index == *reg)
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index bfd2a22759eb..a3b99caf80e6 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1400,8 +1400,8 @@ static struct uart_ops pmz_pops = {
1400static int __init pmz_init_port(struct uart_pmac_port *uap) 1400static int __init pmz_init_port(struct uart_pmac_port *uap)
1401{ 1401{
1402 struct device_node *np = uap->node; 1402 struct device_node *np = uap->node;
1403 char *conn; 1403 const char *conn;
1404 struct slot_names_prop { 1404 const struct slot_names_prop {
1405 int count; 1405 int count;
1406 char name[1]; 1406 char name[1];
1407 } *slots; 1407 } *slots;
@@ -1458,7 +1458,7 @@ no_dma:
1458 uap->flags |= PMACZILOG_FLAG_IS_IRDA; 1458 uap->flags |= PMACZILOG_FLAG_IS_IRDA;
1459 uap->port_type = PMAC_SCC_ASYNC; 1459 uap->port_type = PMAC_SCC_ASYNC;
1460 /* 1999 Powerbook G3 has slot-names property instead */ 1460 /* 1999 Powerbook G3 has slot-names property instead */
1461 slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); 1461 slots = get_property(np, "slot-names", &len);
1462 if (slots && slots->count > 0) { 1462 if (slots && slots->count > 0) {
1463 if (strcmp(slots->name, "IrDA") == 0) 1463 if (strcmp(slots->name, "IrDA") == 0)
1464 uap->flags |= PMACZILOG_FLAG_IS_IRDA; 1464 uap->flags |= PMACZILOG_FLAG_IS_IRDA;
@@ -1470,7 +1470,8 @@ no_dma:
1470 if (ZS_IS_INTMODEM(uap)) { 1470 if (ZS_IS_INTMODEM(uap)) {
1471 struct device_node* i2c_modem = find_devices("i2c-modem"); 1471 struct device_node* i2c_modem = find_devices("i2c-modem");
1472 if (i2c_modem) { 1472 if (i2c_modem) {
1473 char* mid = get_property(i2c_modem, "modem-id", NULL); 1473 const char* mid =
1474 get_property(i2c_modem, "modem-id", NULL);
1474 if (mid) switch(*mid) { 1475 if (mid) switch(*mid) {
1475 case 0x04 : 1476 case 0x04 :
1476 case 0x05 : 1477 case 0x05 :
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index afd146f5f683..397005eb392d 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -349,30 +349,30 @@ static void __init s3triofb_of_init(struct device_node *dp)
349 s3trio_name[sizeof(s3trio_name)-1] = '\0'; 349 s3trio_name[sizeof(s3trio_name)-1] = '\0';
350 strcpy(fb_fix.id, s3trio_name); 350 strcpy(fb_fix.id, s3trio_name);
351 351
352 if((pp = (int *)get_property(dp, "vendor-id", &len)) != NULL 352 if((pp = get_property(dp, "vendor-id", &len)) != NULL
353 && *pp!=PCI_VENDOR_ID_S3) { 353 && *pp!=PCI_VENDOR_ID_S3) {
354 printk("%s: can't find S3 Trio board\n", dp->full_name); 354 printk("%s: can't find S3 Trio board\n", dp->full_name);
355 return; 355 return;
356 } 356 }
357 357
358 if((pp = (int *)get_property(dp, "device-id", &len)) != NULL 358 if((pp = get_property(dp, "device-id", &len)) != NULL
359 && *pp!=PCI_DEVICE_ID_S3_TRIO) { 359 && *pp!=PCI_DEVICE_ID_S3_TRIO) {
360 printk("%s: can't find S3 Trio board\n", dp->full_name); 360 printk("%s: can't find S3 Trio board\n", dp->full_name);
361 return; 361 return;
362 } 362 }
363 363
364 if ((pp = (int *)get_property(dp, "depth", &len)) != NULL 364 if ((pp = get_property(dp, "depth", &len)) != NULL
365 && len == sizeof(int) && *pp != 8) { 365 && len == sizeof(int) && *pp != 8) {
366 printk("%s: can't use depth = %d\n", dp->full_name, *pp); 366 printk("%s: can't use depth = %d\n", dp->full_name, *pp);
367 return; 367 return;
368 } 368 }
369 if ((pp = (int *)get_property(dp, "width", &len)) != NULL 369 if ((pp = get_property(dp, "width", &len)) != NULL
370 && len == sizeof(int)) 370 && len == sizeof(int))
371 fb_var.xres = fb_var.xres_virtual = *pp; 371 fb_var.xres = fb_var.xres_virtual = *pp;
372 if ((pp = (int *)get_property(dp, "height", &len)) != NULL 372 if ((pp = get_property(dp, "height", &len)) != NULL
373 && len == sizeof(int)) 373 && len == sizeof(int))
374 fb_var.yres = fb_var.yres_virtual = *pp; 374 fb_var.yres = fb_var.yres_virtual = *pp;
375 if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL 375 if ((pp = get_property(dp, "linebytes", &len)) != NULL
376 && len == sizeof(int)) 376 && len == sizeof(int))
377 fb_fix.line_length = *pp; 377 fb_fix.line_length = *pp;
378 else 378 else
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 8e3400d5dd21..0ed577e7cc21 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -413,11 +413,11 @@ static int __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo)
413static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo) 413static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
414{ 414{
415 struct device_node *dp = rinfo->of_node; 415 struct device_node *dp = rinfo->of_node;
416 u32 *val; 416 const u32 *val;
417 417
418 if (dp == NULL) 418 if (dp == NULL)
419 return -ENODEV; 419 return -ENODEV;
420 val = (u32 *) get_property(dp, "ATY,RefCLK", NULL); 420 val = get_property(dp, "ATY,RefCLK", NULL);
421 if (!val || !*val) { 421 if (!val || !*val) {
422 printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n"); 422 printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n");
423 return -EINVAL; 423 return -EINVAL;
@@ -425,11 +425,11 @@ static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
425 425
426 rinfo->pll.ref_clk = (*val) / 10; 426 rinfo->pll.ref_clk = (*val) / 10;
427 427
428 val = (u32 *) get_property(dp, "ATY,SCLK", NULL); 428 val = get_property(dp, "ATY,SCLK", NULL);
429 if (val && *val) 429 if (val && *val)
430 rinfo->pll.sclk = (*val) / 10; 430 rinfo->pll.sclk = (*val) / 10;
431 431
432 val = (u32 *) get_property(dp, "ATY,MCLK", NULL); 432 val = get_property(dp, "ATY,MCLK", NULL);
433 if (val && *val) 433 if (val && *val)
434 rinfo->pll.mclk = (*val) / 10; 434 rinfo->pll.mclk = (*val) / 10;
435 435
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index 98c05bc0de44..ea531a6f45d1 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -64,13 +64,13 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
64{ 64{
65 static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", 65 static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID",
66 "EDID1", "EDID2", NULL }; 66 "EDID1", "EDID2", NULL };
67 u8 *pedid = NULL; 67 const u8 *pedid = NULL;
68 u8 *pmt = NULL; 68 const u8 *pmt = NULL;
69 u8 *tmp; 69 u8 *tmp;
70 int i, mt = MT_NONE; 70 int i, mt = MT_NONE;
71 71
72 RTRACE("analyzing OF properties...\n"); 72 RTRACE("analyzing OF properties...\n");
73 pmt = (u8 *)get_property(dp, "display-type", NULL); 73 pmt = get_property(dp, "display-type", NULL);
74 if (!pmt) 74 if (!pmt)
75 return MT_NONE; 75 return MT_NONE;
76 RTRACE("display-type: %s\n", pmt); 76 RTRACE("display-type: %s\n", pmt);
@@ -89,7 +89,7 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
89 } 89 }
90 90
91 for (i = 0; propnames[i] != NULL; ++i) { 91 for (i = 0; propnames[i] != NULL; ++i) {
92 pedid = (u8 *)get_property(dp, propnames[i], NULL); 92 pedid = get_property(dp, propnames[i], NULL);
93 if (pedid != NULL) 93 if (pedid != NULL)
94 break; 94 break;
95 } 95 }
@@ -124,14 +124,14 @@ static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_
124 return MT_NONE; 124 return MT_NONE;
125 125
126 if (rinfo->has_CRTC2) { 126 if (rinfo->has_CRTC2) {
127 char *pname; 127 const char *pname;
128 int len, second = 0; 128 int len, second = 0;
129 129
130 dp = dp->child; 130 dp = dp->child;
131 do { 131 do {
132 if (!dp) 132 if (!dp)
133 return MT_NONE; 133 return MT_NONE;
134 pname = (char *)get_property(dp, "name", NULL); 134 pname = get_property(dp, "name", NULL);
135 if (!pname) 135 if (!pname)
136 return MT_NONE; 136 return MT_NONE;
137 len = strlen(pname); 137 len = strlen(pname);
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index f31e606a2ded..e308ed2d249a 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -1268,7 +1268,7 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
1268 0x21320032, 0xa1320032, 0x21320032, 0xffffffff, 1268 0x21320032, 0xa1320032, 0x21320032, 0xffffffff,
1269 0x31320032 }; 1269 0x31320032 };
1270 1270
1271 u32 *mrtable = default_mrtable; 1271 const u32 *mrtable = default_mrtable;
1272 int i, mrtable_size = ARRAY_SIZE(default_mrtable); 1272 int i, mrtable_size = ARRAY_SIZE(default_mrtable);
1273 1273
1274 mdelay(30); 1274 mdelay(30);
@@ -1287,7 +1287,7 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
1287 if (rinfo->of_node != NULL) { 1287 if (rinfo->of_node != NULL) {
1288 int size; 1288 int size;
1289 1289
1290 mrtable = (u32 *)get_property(rinfo->of_node, "ATY,MRT", &size); 1290 mrtable = get_property(rinfo->of_node, "ATY,MRT", &size);
1291 if (mrtable) 1291 if (mrtable)
1292 mrtable_size = size >> 2; 1292 mrtable_size = size >> 2;
1293 else 1293 else
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 8209106e26ee..d9af88c2b580 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -32,7 +32,7 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
32{ 32{
33 struct nvidia_par *par = info->par; 33 struct nvidia_par *par = info->par;
34 struct device_node *parent, *dp; 34 struct device_node *parent, *dp;
35 unsigned char *pedid = NULL; 35 const unsigned char *pedid = NULL;
36 static char *propnames[] = { 36 static char *propnames[] = {
37 "DFP,EDID", "LCD,EDID", "EDID", "EDID1", 37 "DFP,EDID", "LCD,EDID", "EDID", "EDID1",
38 "EDID,B", "EDID,A", NULL }; 38 "EDID,B", "EDID,A", NULL };
@@ -42,20 +42,19 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
42 if (parent == NULL) 42 if (parent == NULL)
43 return -1; 43 return -1;
44 if (par->twoHeads) { 44 if (par->twoHeads) {
45 char *pname; 45 const char *pname;
46 int len; 46 int len;
47 47
48 for (dp = NULL; 48 for (dp = NULL;
49 (dp = of_get_next_child(parent, dp)) != NULL;) { 49 (dp = of_get_next_child(parent, dp)) != NULL;) {
50 pname = (char *)get_property(dp, "name", NULL); 50 pname = get_property(dp, "name", NULL);
51 if (!pname) 51 if (!pname)
52 continue; 52 continue;
53 len = strlen(pname); 53 len = strlen(pname);
54 if ((pname[len-1] == 'A' && conn == 1) || 54 if ((pname[len-1] == 'A' && conn == 1) ||
55 (pname[len-1] == 'B' && conn == 2)) { 55 (pname[len-1] == 'B' && conn == 2)) {
56 for (i = 0; propnames[i] != NULL; ++i) { 56 for (i = 0; propnames[i] != NULL; ++i) {
57 pedid = (unsigned char *) 57 pedid = get_property(dp, propnames[i],
58 get_property(dp, propnames[i],
59 NULL); 58 NULL);
60 if (pedid != NULL) 59 if (pedid != NULL)
61 break; 60 break;
@@ -67,8 +66,7 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
67 } 66 }
68 if (pedid == NULL) { 67 if (pedid == NULL) {
69 for (i = 0; propnames[i] != NULL; ++i) { 68 for (i = 0; propnames[i] != NULL; ++i) {
70 pedid = (unsigned char *) 69 pedid = get_property(parent, propnames[i], NULL);
71 get_property(parent, propnames[i], NULL);
72 if (pedid != NULL) 70 if (pedid != NULL)
73 break; 71 break;
74 } 72 }
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 0013311e0564..bad0e98fb3b6 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -409,30 +409,30 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
409 unsigned int flags, rsize, addr_prop = 0; 409 unsigned int flags, rsize, addr_prop = 0;
410 unsigned long max_size = 0; 410 unsigned long max_size = 0;
411 u64 rstart, address = OF_BAD_ADDR; 411 u64 rstart, address = OF_BAD_ADDR;
412 u32 *pp, *addrp, *up; 412 const u32 *pp, *addrp, *up;
413 u64 asize; 413 u64 asize;
414 414
415 pp = (u32 *)get_property(dp, "linux,bootx-depth", &len); 415 pp = get_property(dp, "linux,bootx-depth", &len);
416 if (pp == NULL) 416 if (pp == NULL)
417 pp = (u32 *)get_property(dp, "depth", &len); 417 pp = get_property(dp, "depth", &len);
418 if (pp && len == sizeof(u32)) 418 if (pp && len == sizeof(u32))
419 depth = *pp; 419 depth = *pp;
420 420
421 pp = (u32 *)get_property(dp, "linux,bootx-width", &len); 421 pp = get_property(dp, "linux,bootx-width", &len);
422 if (pp == NULL) 422 if (pp == NULL)
423 pp = (u32 *)get_property(dp, "width", &len); 423 pp = get_property(dp, "width", &len);
424 if (pp && len == sizeof(u32)) 424 if (pp && len == sizeof(u32))
425 width = *pp; 425 width = *pp;
426 426
427 pp = (u32 *)get_property(dp, "linux,bootx-height", &len); 427 pp = get_property(dp, "linux,bootx-height", &len);
428 if (pp == NULL) 428 if (pp == NULL)
429 pp = (u32 *)get_property(dp, "height", &len); 429 pp = get_property(dp, "height", &len);
430 if (pp && len == sizeof(u32)) 430 if (pp && len == sizeof(u32))
431 height = *pp; 431 height = *pp;
432 432
433 pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len); 433 pp = get_property(dp, "linux,bootx-linebytes", &len);
434 if (pp == NULL) 434 if (pp == NULL)
435 pp = (u32 *)get_property(dp, "linebytes", &len); 435 pp = get_property(dp, "linebytes", &len);
436 if (pp && len == sizeof(u32)) 436 if (pp && len == sizeof(u32))
437 pitch = *pp; 437 pitch = *pp;
438 else 438 else
@@ -450,9 +450,9 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
450 * ranges and pick one that is both big enough and if possible encloses 450 * ranges and pick one that is both big enough and if possible encloses
451 * the "address" property. If none match, we pick the biggest 451 * the "address" property. If none match, we pick the biggest
452 */ 452 */
453 up = (u32 *)get_property(dp, "linux,bootx-addr", &len); 453 up = get_property(dp, "linux,bootx-addr", &len);
454 if (up == NULL) 454 if (up == NULL)
455 up = (u32 *)get_property(dp, "address", &len); 455 up = get_property(dp, "address", &len);
456 if (up && len == sizeof(u32)) 456 if (up && len == sizeof(u32))
457 addr_prop = *up; 457 addr_prop = *up;
458 458
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 8ddb47a56b07..67d1e1c8813d 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1835,14 +1835,13 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
1835 NVTRACE_ENTER(); 1835 NVTRACE_ENTER();
1836 dp = pci_device_to_OF_node(pd); 1836 dp = pci_device_to_OF_node(pd);
1837 for (; dp != NULL; dp = dp->child) { 1837 for (; dp != NULL; dp = dp->child) {
1838 disptype = (unsigned char *)get_property(dp, "display-type", NULL); 1838 disptype = get_property(dp, "display-type", NULL);
1839 if (disptype == NULL) 1839 if (disptype == NULL)
1840 continue; 1840 continue;
1841 if (strncmp(disptype, "LCD", 3) != 0) 1841 if (strncmp(disptype, "LCD", 3) != 0)
1842 continue; 1842 continue;
1843 for (i = 0; propnames[i] != NULL; ++i) { 1843 for (i = 0; propnames[i] != NULL; ++i) {
1844 pedid = (unsigned char *) 1844 pedid = get_property(dp, propnames[i], NULL);
1845 get_property(dp, propnames[i], NULL);
1846 if (pedid != NULL) { 1845 if (pedid != NULL) {
1847 par->EDID = pedid; 1846 par->EDID = pedid;
1848 NVTRACE("LCD found.\n"); 1847 NVTRACE("LCD found.\n");
diff --git a/fs/Kconfig b/fs/Kconfig
index 3f00a9faabcb..530581628311 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -325,8 +325,8 @@ config FS_POSIX_ACL
325source "fs/xfs/Kconfig" 325source "fs/xfs/Kconfig"
326 326
327config OCFS2_FS 327config OCFS2_FS
328 tristate "OCFS2 file system support (EXPERIMENTAL)" 328 tristate "OCFS2 file system support"
329 depends on NET && SYSFS && EXPERIMENTAL 329 depends on NET && SYSFS
330 select CONFIGFS_FS 330 select CONFIGFS_FS
331 select JBD 331 select JBD
332 select CRC32 332 select CRC32
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index df025453dd97..816e8ef64560 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -86,6 +86,32 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare
86 return sd; 86 return sd;
87} 87}
88 88
89/*
90 *
91 * Return -EEXIST if there is already a configfs element with the same
92 * name for the same parent.
93 *
94 * called with parent inode's i_mutex held
95 */
96int configfs_dirent_exists(struct configfs_dirent *parent_sd,
97 const unsigned char *new)
98{
99 struct configfs_dirent * sd;
100
101 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
102 if (sd->s_element) {
103 const unsigned char *existing = configfs_get_name(sd);
104 if (strcmp(existing, new))
105 continue;
106 else
107 return -EEXIST;
108 }
109 }
110
111 return 0;
112}
113
114
89int configfs_make_dirent(struct configfs_dirent * parent_sd, 115int configfs_make_dirent(struct configfs_dirent * parent_sd,
90 struct dentry * dentry, void * element, 116 struct dentry * dentry, void * element,
91 umode_t mode, int type) 117 umode_t mode, int type)
@@ -136,8 +162,10 @@ static int create_dir(struct config_item * k, struct dentry * p,
136 int error; 162 int error;
137 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 163 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
138 164
139 error = configfs_make_dirent(p->d_fsdata, d, k, mode, 165 error = configfs_dirent_exists(p->d_fsdata, d->d_name.name);
140 CONFIGFS_DIR); 166 if (!error)
167 error = configfs_make_dirent(p->d_fsdata, d, k, mode,
168 CONFIGFS_DIR);
141 if (!error) { 169 if (!error) {
142 error = configfs_create(d, mode, init_dir); 170 error = configfs_create(d, mode, init_dir);
143 if (!error) { 171 if (!error) {
diff --git a/fs/jffs2/jffs2_fs_i.h b/fs/jffs2/jffs2_fs_i.h
index 2e0cc8e00b85..3a566077ac95 100644
--- a/fs/jffs2/jffs2_fs_i.h
+++ b/fs/jffs2/jffs2_fs_i.h
@@ -41,11 +41,7 @@ struct jffs2_inode_info {
41 41
42 uint16_t flags; 42 uint16_t flags;
43 uint8_t usercompr; 43 uint8_t usercompr;
44#if !defined (__ECOS)
45#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
46 struct inode vfs_inode; 44 struct inode vfs_inode;
47#endif
48#endif
49#ifdef CONFIG_JFFS2_FS_POSIX_ACL 45#ifdef CONFIG_JFFS2_FS_POSIX_ACL
50 struct posix_acl *i_acl_access; 46 struct posix_acl *i_acl_access;
51 struct posix_acl *i_acl_default; 47 struct posix_acl *i_acl_default;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 06da7506363c..e35d7e52fdeb 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -33,7 +33,7 @@
33* 33*
34*/ 34*/
35 35
36 36#include <linux/err.h>
37#include <linux/sunrpc/svc.h> 37#include <linux/sunrpc/svc.h>
38#include <linux/nfsd/nfsd.h> 38#include <linux/nfsd/nfsd.h>
39#include <linux/nfs4.h> 39#include <linux/nfs4.h>
@@ -87,34 +87,35 @@ int
87nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) 87nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
88{ 88{
89 struct xdr_netobj cksum; 89 struct xdr_netobj cksum;
90 struct crypto_tfm *tfm; 90 struct hash_desc desc;
91 struct scatterlist sg[1]; 91 struct scatterlist sg[1];
92 int status = nfserr_resource; 92 int status = nfserr_resource;
93 93
94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", 94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
95 clname->len, clname->data); 95 clname->len, clname->data);
96 tfm = crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP); 96 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
97 if (tfm == NULL) 97 desc.tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
98 goto out; 98 if (IS_ERR(desc.tfm))
99 cksum.len = crypto_tfm_alg_digestsize(tfm); 99 goto out_no_tfm;
100 cksum.len = crypto_hash_digestsize(desc.tfm);
100 cksum.data = kmalloc(cksum.len, GFP_KERNEL); 101 cksum.data = kmalloc(cksum.len, GFP_KERNEL);
101 if (cksum.data == NULL) 102 if (cksum.data == NULL)
102 goto out; 103 goto out;
103 crypto_digest_init(tfm);
104 104
105 sg[0].page = virt_to_page(clname->data); 105 sg[0].page = virt_to_page(clname->data);
106 sg[0].offset = offset_in_page(clname->data); 106 sg[0].offset = offset_in_page(clname->data);
107 sg[0].length = clname->len; 107 sg[0].length = clname->len;
108 108
109 crypto_digest_update(tfm, sg, 1); 109 if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
110 crypto_digest_final(tfm, cksum.data); 110 goto out;
111 111
112 md5_to_hex(dname, cksum.data); 112 md5_to_hex(dname, cksum.data);
113 113
114 kfree(cksum.data); 114 kfree(cksum.data);
115 status = nfs_ok; 115 status = nfs_ok;
116out: 116out:
117 crypto_free_tfm(tfm); 117 crypto_free_hash(desc.tfm);
118out_no_tfm:
118 return status; 119 return status;
119} 120}
120 121
diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile
index 7d3be845a614..9fb8132f19b0 100644
--- a/fs/ocfs2/Makefile
+++ b/fs/ocfs2/Makefile
@@ -16,6 +16,7 @@ ocfs2-objs := \
16 file.o \ 16 file.o \
17 heartbeat.o \ 17 heartbeat.o \
18 inode.o \ 18 inode.o \
19 ioctl.o \
19 journal.o \ 20 journal.o \
20 localalloc.o \ 21 localalloc.o \
21 mmap.o \ 22 mmap.o \
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index edaab05a93e0..f43bc5f18a35 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -1717,17 +1717,29 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
1717 1717
1718 ocfs2_remove_from_cache(inode, eb_bh); 1718 ocfs2_remove_from_cache(inode, eb_bh);
1719 1719
1720 BUG_ON(eb->h_suballoc_slot);
1721 BUG_ON(el->l_recs[0].e_clusters); 1720 BUG_ON(el->l_recs[0].e_clusters);
1722 BUG_ON(el->l_recs[0].e_cpos); 1721 BUG_ON(el->l_recs[0].e_cpos);
1723 BUG_ON(el->l_recs[0].e_blkno); 1722 BUG_ON(el->l_recs[0].e_blkno);
1724 status = ocfs2_free_extent_block(handle, 1723 if (eb->h_suballoc_slot == 0) {
1725 tc->tc_ext_alloc_inode, 1724 /*
1726 tc->tc_ext_alloc_bh, 1725 * This code only understands how to
1727 eb); 1726 * lock the suballocator in slot 0,
1728 if (status < 0) { 1727 * which is fine because allocation is
1729 mlog_errno(status); 1728 * only ever done out of that
1730 goto bail; 1729 * suballocator too. A future version
1730 * might change that however, so avoid
1731 * a free if we don't know how to
1732 * handle it. This way an fs incompat
1733 * bit will not be necessary.
1734 */
1735 status = ocfs2_free_extent_block(handle,
1736 tc->tc_ext_alloc_inode,
1737 tc->tc_ext_alloc_bh,
1738 eb);
1739 if (status < 0) {
1740 mlog_errno(status);
1741 goto bail;
1742 }
1731 } 1743 }
1732 } 1744 }
1733 brelse(eb_bh); 1745 brelse(eb_bh);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index f1d1c342ce01..3d7c082a8f58 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -391,31 +391,28 @@ out:
391static int ocfs2_commit_write(struct file *file, struct page *page, 391static int ocfs2_commit_write(struct file *file, struct page *page,
392 unsigned from, unsigned to) 392 unsigned from, unsigned to)
393{ 393{
394 int ret, extending = 0, locklevel = 0; 394 int ret;
395 loff_t new_i_size;
396 struct buffer_head *di_bh = NULL; 395 struct buffer_head *di_bh = NULL;
397 struct inode *inode = page->mapping->host; 396 struct inode *inode = page->mapping->host;
398 struct ocfs2_journal_handle *handle = NULL; 397 struct ocfs2_journal_handle *handle = NULL;
398 struct ocfs2_dinode *di;
399 399
400 mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); 400 mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to);
401 401
402 /* NOTE: ocfs2_file_aio_write has ensured that it's safe for 402 /* NOTE: ocfs2_file_aio_write has ensured that it's safe for
403 * us to sample inode->i_size here without the metadata lock: 403 * us to continue here without rechecking the I/O against
404 * changed inode values.
404 * 405 *
405 * 1) We're currently holding the inode alloc lock, so no 406 * 1) We're currently holding the inode alloc lock, so no
406 * nodes can change it underneath us. 407 * nodes can change it underneath us.
407 * 408 *
408 * 2) We've had to take the metadata lock at least once 409 * 2) We've had to take the metadata lock at least once
409 * already to check for extending writes, hence insuring 410 * already to check for extending writes, suid removal, etc.
410 * that our current copy is also up to date. 411 * The meta data update code then ensures that we don't get a
412 * stale inode allocation image (i_size, i_clusters, etc).
411 */ 413 */
412 new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
413 if (new_i_size > i_size_read(inode)) {
414 extending = 1;
415 locklevel = 1;
416 }
417 414
418 ret = ocfs2_meta_lock_with_page(inode, NULL, &di_bh, locklevel, page); 415 ret = ocfs2_meta_lock_with_page(inode, NULL, &di_bh, 1, page);
419 if (ret != 0) { 416 if (ret != 0) {
420 mlog_errno(ret); 417 mlog_errno(ret);
421 goto out; 418 goto out;
@@ -427,23 +424,20 @@ static int ocfs2_commit_write(struct file *file, struct page *page,
427 goto out_unlock_meta; 424 goto out_unlock_meta;
428 } 425 }
429 426
430 if (extending) { 427 handle = ocfs2_start_walk_page_trans(inode, page, from, to);
431 handle = ocfs2_start_walk_page_trans(inode, page, from, to); 428 if (IS_ERR(handle)) {
432 if (IS_ERR(handle)) { 429 ret = PTR_ERR(handle);
433 ret = PTR_ERR(handle); 430 goto out_unlock_data;
434 handle = NULL; 431 }
435 goto out_unlock_data;
436 }
437 432
438 /* Mark our buffer early. We'd rather catch this error up here 433 /* Mark our buffer early. We'd rather catch this error up here
439 * as opposed to after a successful commit_write which would 434 * as opposed to after a successful commit_write which would
440 * require us to set back inode->i_size. */ 435 * require us to set back inode->i_size. */
441 ret = ocfs2_journal_access(handle, inode, di_bh, 436 ret = ocfs2_journal_access(handle, inode, di_bh,
442 OCFS2_JOURNAL_ACCESS_WRITE); 437 OCFS2_JOURNAL_ACCESS_WRITE);
443 if (ret < 0) { 438 if (ret < 0) {
444 mlog_errno(ret); 439 mlog_errno(ret);
445 goto out_commit; 440 goto out_commit;
446 }
447 } 441 }
448 442
449 /* might update i_size */ 443 /* might update i_size */
@@ -453,37 +447,28 @@ static int ocfs2_commit_write(struct file *file, struct page *page,
453 goto out_commit; 447 goto out_commit;
454 } 448 }
455 449
456 if (extending) { 450 di = (struct ocfs2_dinode *)di_bh->b_data;
457 loff_t size = (u64) i_size_read(inode);
458 struct ocfs2_dinode *di =
459 (struct ocfs2_dinode *)di_bh->b_data;
460 451
461 /* ocfs2_mark_inode_dirty is too heavy to use here. */ 452 /* ocfs2_mark_inode_dirty() is too heavy to use here. */
462 inode->i_blocks = ocfs2_align_bytes_to_sectors(size); 453 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
463 inode->i_ctime = inode->i_mtime = CURRENT_TIME; 454 di->i_mtime = di->i_ctime = cpu_to_le64(inode->i_mtime.tv_sec);
455 di->i_mtime_nsec = di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
464 456
465 di->i_size = cpu_to_le64(size); 457 inode->i_blocks = ocfs2_align_bytes_to_sectors((u64)(i_size_read(inode)));
466 di->i_ctime = di->i_mtime = 458 di->i_size = cpu_to_le64((u64)i_size_read(inode));
467 cpu_to_le64(inode->i_mtime.tv_sec);
468 di->i_ctime_nsec = di->i_mtime_nsec =
469 cpu_to_le32(inode->i_mtime.tv_nsec);
470 459
471 ret = ocfs2_journal_dirty(handle, di_bh); 460 ret = ocfs2_journal_dirty(handle, di_bh);
472 if (ret < 0) { 461 if (ret < 0) {
473 mlog_errno(ret); 462 mlog_errno(ret);
474 goto out_commit; 463 goto out_commit;
475 }
476 } 464 }
477 465
478 BUG_ON(extending && (i_size_read(inode) != new_i_size));
479
480out_commit: 466out_commit:
481 if (handle) 467 ocfs2_commit_trans(handle);
482 ocfs2_commit_trans(handle);
483out_unlock_data: 468out_unlock_data:
484 ocfs2_data_unlock(inode, 1); 469 ocfs2_data_unlock(inode, 1);
485out_unlock_meta: 470out_unlock_meta:
486 ocfs2_meta_unlock(inode, locklevel); 471 ocfs2_meta_unlock(inode, 1);
487out: 472out:
488 if (di_bh) 473 if (di_bh)
489 brelse(di_bh); 474 brelse(di_bh);
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c
index 9a24adf9be6e..c9037414f4f6 100644
--- a/fs/ocfs2/buffer_head_io.c
+++ b/fs/ocfs2/buffer_head_io.c
@@ -100,6 +100,9 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
100 mlog_entry("(block=(%llu), nr=(%d), flags=%d, inode=%p)\n", 100 mlog_entry("(block=(%llu), nr=(%d), flags=%d, inode=%p)\n",
101 (unsigned long long)block, nr, flags, inode); 101 (unsigned long long)block, nr, flags, inode);
102 102
103 BUG_ON((flags & OCFS2_BH_READAHEAD) &&
104 (!inode || !(flags & OCFS2_BH_CACHED)));
105
103 if (osb == NULL || osb->sb == NULL || bhs == NULL) { 106 if (osb == NULL || osb->sb == NULL || bhs == NULL) {
104 status = -EINVAL; 107 status = -EINVAL;
105 mlog_errno(status); 108 mlog_errno(status);
@@ -140,6 +143,30 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
140 bh = bhs[i]; 143 bh = bhs[i];
141 ignore_cache = 0; 144 ignore_cache = 0;
142 145
146 /* There are three read-ahead cases here which we need to
147 * be concerned with. All three assume a buffer has
148 * previously been submitted with OCFS2_BH_READAHEAD
149 * and it hasn't yet completed I/O.
150 *
151 * 1) The current request is sync to disk. This rarely
152 * happens these days, and never when performance
153 * matters - the code can just wait on the buffer
154 * lock and re-submit.
155 *
156 * 2) The current request is cached, but not
157 * readahead. ocfs2_buffer_uptodate() will return
158 * false anyway, so we'll wind up waiting on the
159 * buffer lock to do I/O. We re-check the request
160 * with after getting the lock to avoid a re-submit.
161 *
162 * 3) The current request is readahead (and so must
163 * also be a caching one). We short circuit if the
164 * buffer is locked (under I/O) and if it's in the
165 * uptodate cache. The re-check from #2 catches the
166 * case that the previous read-ahead completes just
167 * before our is-it-in-flight check.
168 */
169
143 if (flags & OCFS2_BH_CACHED && 170 if (flags & OCFS2_BH_CACHED &&
144 !ocfs2_buffer_uptodate(inode, bh)) { 171 !ocfs2_buffer_uptodate(inode, bh)) {
145 mlog(ML_UPTODATE, 172 mlog(ML_UPTODATE,
@@ -169,6 +196,14 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
169 continue; 196 continue;
170 } 197 }
171 198
199 /* A read-ahead request was made - if the
200 * buffer is already under read-ahead from a
201 * previously submitted request than we are
202 * done here. */
203 if ((flags & OCFS2_BH_READAHEAD)
204 && ocfs2_buffer_read_ahead(inode, bh))
205 continue;
206
172 lock_buffer(bh); 207 lock_buffer(bh);
173 if (buffer_jbd(bh)) { 208 if (buffer_jbd(bh)) {
174#ifdef CATCH_BH_JBD_RACES 209#ifdef CATCH_BH_JBD_RACES
@@ -181,13 +216,22 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
181 continue; 216 continue;
182#endif 217#endif
183 } 218 }
219
220 /* Re-check ocfs2_buffer_uptodate() as a
221 * previously read-ahead buffer may have
222 * completed I/O while we were waiting for the
223 * buffer lock. */
224 if ((flags & OCFS2_BH_CACHED)
225 && !(flags & OCFS2_BH_READAHEAD)
226 && ocfs2_buffer_uptodate(inode, bh)) {
227 unlock_buffer(bh);
228 continue;
229 }
230
184 clear_buffer_uptodate(bh); 231 clear_buffer_uptodate(bh);
185 get_bh(bh); /* for end_buffer_read_sync() */ 232 get_bh(bh); /* for end_buffer_read_sync() */
186 bh->b_end_io = end_buffer_read_sync; 233 bh->b_end_io = end_buffer_read_sync;
187 if (flags & OCFS2_BH_READAHEAD) 234 submit_bh(READ, bh);
188 submit_bh(READA, bh);
189 else
190 submit_bh(READ, bh);
191 continue; 235 continue;
192 } 236 }
193 } 237 }
@@ -197,34 +241,39 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
197 for (i = (nr - 1); i >= 0; i--) { 241 for (i = (nr - 1); i >= 0; i--) {
198 bh = bhs[i]; 242 bh = bhs[i];
199 243
200 /* We know this can't have changed as we hold the 244 if (!(flags & OCFS2_BH_READAHEAD)) {
201 * inode sem. Avoid doing any work on the bh if the 245 /* We know this can't have changed as we hold the
202 * journal has it. */ 246 * inode sem. Avoid doing any work on the bh if the
203 if (!buffer_jbd(bh)) 247 * journal has it. */
204 wait_on_buffer(bh); 248 if (!buffer_jbd(bh))
205 249 wait_on_buffer(bh);
206 if (!buffer_uptodate(bh)) { 250
207 /* Status won't be cleared from here on out, 251 if (!buffer_uptodate(bh)) {
208 * so we can safely record this and loop back 252 /* Status won't be cleared from here on out,
209 * to cleanup the other buffers. Don't need to 253 * so we can safely record this and loop back
210 * remove the clustered uptodate information 254 * to cleanup the other buffers. Don't need to
211 * for this bh as it's not marked locally 255 * remove the clustered uptodate information
212 * uptodate. */ 256 * for this bh as it's not marked locally
213 status = -EIO; 257 * uptodate. */
214 brelse(bh); 258 status = -EIO;
215 bhs[i] = NULL; 259 brelse(bh);
216 continue; 260 bhs[i] = NULL;
261 continue;
262 }
217 } 263 }
218 264
265 /* Always set the buffer in the cache, even if it was
266 * a forced read, or read-ahead which hasn't yet
267 * completed. */
219 if (inode) 268 if (inode)
220 ocfs2_set_buffer_uptodate(inode, bh); 269 ocfs2_set_buffer_uptodate(inode, bh);
221 } 270 }
222 if (inode) 271 if (inode)
223 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); 272 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
224 273
225 mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s\n", 274 mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s, flags=0x%x\n",
226 (unsigned long long)block, nr, 275 (unsigned long long)block, nr,
227 (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes"); 276 (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes", flags);
228 277
229bail: 278bail:
230 279
diff --git a/fs/ocfs2/buffer_head_io.h b/fs/ocfs2/buffer_head_io.h
index 6ecb90937b68..6cc20930fac3 100644
--- a/fs/ocfs2/buffer_head_io.h
+++ b/fs/ocfs2/buffer_head_io.h
@@ -49,7 +49,7 @@ int ocfs2_read_blocks(struct ocfs2_super *osb,
49 49
50 50
51#define OCFS2_BH_CACHED 1 51#define OCFS2_BH_CACHED 1
52#define OCFS2_BH_READAHEAD 8 /* use this to pass READA down to submit_bh */ 52#define OCFS2_BH_READAHEAD 8
53 53
54static inline int ocfs2_read_block(struct ocfs2_super * osb, u64 off, 54static inline int ocfs2_read_block(struct ocfs2_super * osb, u64 off,
55 struct buffer_head **bh, int flags, 55 struct buffer_head **bh, int flags,
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 504595d6cf65..305cba3681fe 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -320,8 +320,12 @@ static int compute_max_sectors(struct block_device *bdev)
320 max_pages = q->max_hw_segments; 320 max_pages = q->max_hw_segments;
321 max_pages--; /* Handle I/Os that straddle a page */ 321 max_pages--; /* Handle I/Os that straddle a page */
322 322
323 max_sectors = max_pages << (PAGE_SHIFT - 9); 323 if (max_pages) {
324 324 max_sectors = max_pages << (PAGE_SHIFT - 9);
325 } else {
326 /* If BIO contains 1 or less than 1 page. */
327 max_sectors = q->max_sectors;
328 }
325 /* Why is fls() 1-based???? */ 329 /* Why is fls() 1-based???? */
326 pow_two_sectors = 1 << (fls(max_sectors) - 1); 330 pow_two_sectors = 1 << (fls(max_sectors) - 1);
327 331
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 3d494d1a5f36..04e01915b86e 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -74,14 +74,14 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
74int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) 74int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
75{ 75{
76 int error = 0; 76 int error = 0;
77 unsigned long offset, blk; 77 unsigned long offset, blk, last_ra_blk = 0;
78 int i, num, stored; 78 int i, stored;
79 struct buffer_head * bh, * tmp; 79 struct buffer_head * bh, * tmp;
80 struct ocfs2_dir_entry * de; 80 struct ocfs2_dir_entry * de;
81 int err; 81 int err;
82 struct inode *inode = filp->f_dentry->d_inode; 82 struct inode *inode = filp->f_dentry->d_inode;
83 struct super_block * sb = inode->i_sb; 83 struct super_block * sb = inode->i_sb;
84 int have_disk_lock = 0; 84 unsigned int ra_sectors = 16;
85 85
86 mlog_entry("dirino=%llu\n", 86 mlog_entry("dirino=%llu\n",
87 (unsigned long long)OCFS2_I(inode)->ip_blkno); 87 (unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -95,9 +95,8 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
95 mlog_errno(error); 95 mlog_errno(error);
96 /* we haven't got any yet, so propagate the error. */ 96 /* we haven't got any yet, so propagate the error. */
97 stored = error; 97 stored = error;
98 goto bail; 98 goto bail_nolock;
99 } 99 }
100 have_disk_lock = 1;
101 100
102 offset = filp->f_pos & (sb->s_blocksize - 1); 101 offset = filp->f_pos & (sb->s_blocksize - 1);
103 102
@@ -113,16 +112,21 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
113 continue; 112 continue;
114 } 113 }
115 114
116 /* 115 /* The idea here is to begin with 8k read-ahead and to stay
117 * Do the readahead (8k) 116 * 4k ahead of our current position.
118 */ 117 *
119 if (!offset) { 118 * TODO: Use the pagecache for this. We just need to
120 for (i = 16 >> (sb->s_blocksize_bits - 9), num = 0; 119 * make sure it's cluster-safe... */
120 if (!last_ra_blk
121 || (((last_ra_blk - blk) << 9) <= (ra_sectors / 2))) {
122 for (i = ra_sectors >> (sb->s_blocksize_bits - 9);
121 i > 0; i--) { 123 i > 0; i--) {
122 tmp = ocfs2_bread(inode, ++blk, &err, 1); 124 tmp = ocfs2_bread(inode, ++blk, &err, 1);
123 if (tmp) 125 if (tmp)
124 brelse(tmp); 126 brelse(tmp);
125 } 127 }
128 last_ra_blk = blk;
129 ra_sectors = 8;
126 } 130 }
127 131
128revalidate: 132revalidate:
@@ -194,9 +198,9 @@ revalidate:
194 198
195 stored = 0; 199 stored = 0;
196bail: 200bail:
197 if (have_disk_lock) 201 ocfs2_meta_unlock(inode, 0);
198 ocfs2_meta_unlock(inode, 0);
199 202
203bail_nolock:
200 mlog_exit(stored); 204 mlog_exit(stored);
201 205
202 return stored; 206 return stored;
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c
index 42775e2bbe2c..f13a4bac41f0 100644
--- a/fs/ocfs2/dlm/dlmast.c
+++ b/fs/ocfs2/dlm/dlmast.c
@@ -367,12 +367,10 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data)
367 goto do_ast; 367 goto do_ast;
368 } 368 }
369 369
370 mlog(ML_ERROR, "got %sast for unknown lock! cookie=%u:%llu, " 370 mlog(0, "got %sast for unknown lock! cookie=%u:%llu, "
371 "name=%.*s, namelen=%u\n", 371 "name=%.*s, namelen=%u\n", past->type == DLM_AST ? "" : "b",
372 past->type == DLM_AST ? "" : "b", 372 dlm_get_lock_cookie_node(cookie), dlm_get_lock_cookie_seq(cookie),
373 dlm_get_lock_cookie_node(cookie), 373 locklen, name, locklen);
374 dlm_get_lock_cookie_seq(cookie),
375 locklen, name, locklen);
376 374
377 ret = DLM_NORMAL; 375 ret = DLM_NORMAL;
378unlock_out: 376unlock_out:
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 762eb1fbb34d..151b41781eab 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -1330,6 +1330,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
1330 cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime)); 1330 cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime));
1331 lvb->lvb_imtime_packed = 1331 lvb->lvb_imtime_packed =
1332 cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime)); 1332 cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
1333 lvb->lvb_iattr = cpu_to_be32(oi->ip_attr);
1333 1334
1334 mlog_meta_lvb(0, lockres); 1335 mlog_meta_lvb(0, lockres);
1335 1336
@@ -1360,6 +1361,9 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
1360 oi->ip_clusters = be32_to_cpu(lvb->lvb_iclusters); 1361 oi->ip_clusters = be32_to_cpu(lvb->lvb_iclusters);
1361 i_size_write(inode, be64_to_cpu(lvb->lvb_isize)); 1362 i_size_write(inode, be64_to_cpu(lvb->lvb_isize));
1362 1363
1364 oi->ip_attr = be32_to_cpu(lvb->lvb_iattr);
1365 ocfs2_set_inode_flags(inode);
1366
1363 /* fast-symlinks are a special case */ 1367 /* fast-symlinks are a special case */
1364 if (S_ISLNK(inode->i_mode) && !oi->ip_clusters) 1368 if (S_ISLNK(inode->i_mode) && !oi->ip_clusters)
1365 inode->i_blocks = 0; 1369 inode->i_blocks = 0;
@@ -2899,8 +2903,9 @@ void ocfs2_dump_meta_lvb_info(u64 level,
2899 be32_to_cpu(lvb->lvb_iuid), be32_to_cpu(lvb->lvb_igid), 2903 be32_to_cpu(lvb->lvb_iuid), be32_to_cpu(lvb->lvb_igid),
2900 be16_to_cpu(lvb->lvb_imode)); 2904 be16_to_cpu(lvb->lvb_imode));
2901 mlog(level, "nlink %u, atime_packed 0x%llx, ctime_packed 0x%llx, " 2905 mlog(level, "nlink %u, atime_packed 0x%llx, ctime_packed 0x%llx, "
2902 "mtime_packed 0x%llx\n", be16_to_cpu(lvb->lvb_inlink), 2906 "mtime_packed 0x%llx iattr 0x%x\n", be16_to_cpu(lvb->lvb_inlink),
2903 (long long)be64_to_cpu(lvb->lvb_iatime_packed), 2907 (long long)be64_to_cpu(lvb->lvb_iatime_packed),
2904 (long long)be64_to_cpu(lvb->lvb_ictime_packed), 2908 (long long)be64_to_cpu(lvb->lvb_ictime_packed),
2905 (long long)be64_to_cpu(lvb->lvb_imtime_packed)); 2909 (long long)be64_to_cpu(lvb->lvb_imtime_packed),
2910 be32_to_cpu(lvb->lvb_iattr));
2906} 2911}
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
index 8f2d1db2d9ea..243ae862ece5 100644
--- a/fs/ocfs2/dlmglue.h
+++ b/fs/ocfs2/dlmglue.h
@@ -27,7 +27,7 @@
27#ifndef DLMGLUE_H 27#ifndef DLMGLUE_H
28#define DLMGLUE_H 28#define DLMGLUE_H
29 29
30#define OCFS2_LVB_VERSION 2 30#define OCFS2_LVB_VERSION 3
31 31
32struct ocfs2_meta_lvb { 32struct ocfs2_meta_lvb {
33 __be32 lvb_version; 33 __be32 lvb_version;
@@ -40,7 +40,8 @@ struct ocfs2_meta_lvb {
40 __be64 lvb_isize; 40 __be64 lvb_isize;
41 __be16 lvb_imode; 41 __be16 lvb_imode;
42 __be16 lvb_inlink; 42 __be16 lvb_inlink;
43 __be32 lvb_reserved[3]; 43 __be32 lvb_iattr;
44 __be32 lvb_reserved[2];
44}; 45};
45 46
46/* ocfs2_meta_lock_full() and ocfs2_data_lock_full() 'arg_flags' flags */ 47/* ocfs2_meta_lock_full() and ocfs2_data_lock_full() 'arg_flags' flags */
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index a9559c874530..2bbfa17090cf 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -44,6 +44,7 @@
44#include "file.h" 44#include "file.h"
45#include "sysfile.h" 45#include "sysfile.h"
46#include "inode.h" 46#include "inode.h"
47#include "ioctl.h"
47#include "journal.h" 48#include "journal.h"
48#include "mmap.h" 49#include "mmap.h"
49#include "suballoc.h" 50#include "suballoc.h"
@@ -1227,10 +1228,12 @@ const struct file_operations ocfs2_fops = {
1227 .open = ocfs2_file_open, 1228 .open = ocfs2_file_open,
1228 .aio_read = ocfs2_file_aio_read, 1229 .aio_read = ocfs2_file_aio_read,
1229 .aio_write = ocfs2_file_aio_write, 1230 .aio_write = ocfs2_file_aio_write,
1231 .ioctl = ocfs2_ioctl,
1230}; 1232};
1231 1233
1232const struct file_operations ocfs2_dops = { 1234const struct file_operations ocfs2_dops = {
1233 .read = generic_read_dir, 1235 .read = generic_read_dir,
1234 .readdir = ocfs2_readdir, 1236 .readdir = ocfs2_readdir,
1235 .fsync = ocfs2_sync_file, 1237 .fsync = ocfs2_sync_file,
1238 .ioctl = ocfs2_ioctl,
1236}; 1239};
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 327a5b7b86ed..7bcf69154592 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -71,6 +71,26 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
71 struct inode *inode, 71 struct inode *inode,
72 struct buffer_head *fe_bh); 72 struct buffer_head *fe_bh);
73 73
74void ocfs2_set_inode_flags(struct inode *inode)
75{
76 unsigned int flags = OCFS2_I(inode)->ip_attr;
77
78 inode->i_flags &= ~(S_IMMUTABLE |
79 S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
80
81 if (flags & OCFS2_IMMUTABLE_FL)
82 inode->i_flags |= S_IMMUTABLE;
83
84 if (flags & OCFS2_SYNC_FL)
85 inode->i_flags |= S_SYNC;
86 if (flags & OCFS2_APPEND_FL)
87 inode->i_flags |= S_APPEND;
88 if (flags & OCFS2_NOATIME_FL)
89 inode->i_flags |= S_NOATIME;
90 if (flags & OCFS2_DIRSYNC_FL)
91 inode->i_flags |= S_DIRSYNC;
92}
93
74struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb, 94struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
75 u64 blkno, 95 u64 blkno,
76 int delete_vote) 96 int delete_vote)
@@ -260,7 +280,6 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
260 inode->i_blocks = 280 inode->i_blocks =
261 ocfs2_align_bytes_to_sectors(le64_to_cpu(fe->i_size)); 281 ocfs2_align_bytes_to_sectors(le64_to_cpu(fe->i_size));
262 inode->i_mapping->a_ops = &ocfs2_aops; 282 inode->i_mapping->a_ops = &ocfs2_aops;
263 inode->i_flags |= S_NOATIME;
264 inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime); 283 inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
265 inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec); 284 inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
266 inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime); 285 inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
@@ -276,6 +295,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
276 295
277 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); 296 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
278 OCFS2_I(inode)->ip_orphaned_slot = OCFS2_INVALID_SLOT; 297 OCFS2_I(inode)->ip_orphaned_slot = OCFS2_INVALID_SLOT;
298 OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
279 299
280 if (create_ino) 300 if (create_ino)
281 inode->i_ino = ino_from_blkno(inode->i_sb, 301 inode->i_ino = ino_from_blkno(inode->i_sb,
@@ -330,6 +350,9 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
330 ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_data_lockres, 350 ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_data_lockres,
331 OCFS2_LOCK_TYPE_DATA, inode); 351 OCFS2_LOCK_TYPE_DATA, inode);
332 352
353 ocfs2_set_inode_flags(inode);
354 inode->i_flags |= S_NOATIME;
355
333 status = 0; 356 status = 0;
334bail: 357bail:
335 mlog_exit(status); 358 mlog_exit(status);
@@ -1027,12 +1050,8 @@ struct buffer_head *ocfs2_bread(struct inode *inode,
1027 u64 p_blkno; 1050 u64 p_blkno;
1028 int readflags = OCFS2_BH_CACHED; 1051 int readflags = OCFS2_BH_CACHED;
1029 1052
1030#if 0
1031 /* only turn this on if we know we can deal with read_block
1032 * returning nothing */
1033 if (reada) 1053 if (reada)
1034 readflags |= OCFS2_BH_READAHEAD; 1054 readflags |= OCFS2_BH_READAHEAD;
1035#endif
1036 1055
1037 if (((u64)block << inode->i_sb->s_blocksize_bits) >= 1056 if (((u64)block << inode->i_sb->s_blocksize_bits) >=
1038 i_size_read(inode)) { 1057 i_size_read(inode)) {
@@ -1131,6 +1150,7 @@ int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle,
1131 1150
1132 spin_lock(&OCFS2_I(inode)->ip_lock); 1151 spin_lock(&OCFS2_I(inode)->ip_lock);
1133 fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters); 1152 fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
1153 fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr);
1134 spin_unlock(&OCFS2_I(inode)->ip_lock); 1154 spin_unlock(&OCFS2_I(inode)->ip_lock);
1135 1155
1136 fe->i_size = cpu_to_le64(i_size_read(inode)); 1156 fe->i_size = cpu_to_le64(i_size_read(inode));
@@ -1169,6 +1189,8 @@ void ocfs2_refresh_inode(struct inode *inode,
1169 spin_lock(&OCFS2_I(inode)->ip_lock); 1189 spin_lock(&OCFS2_I(inode)->ip_lock);
1170 1190
1171 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); 1191 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
1192 OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
1193 ocfs2_set_inode_flags(inode);
1172 i_size_write(inode, le64_to_cpu(fe->i_size)); 1194 i_size_write(inode, le64_to_cpu(fe->i_size));
1173 inode->i_nlink = le16_to_cpu(fe->i_links_count); 1195 inode->i_nlink = le16_to_cpu(fe->i_links_count);
1174 inode->i_uid = le32_to_cpu(fe->i_uid); 1196 inode->i_uid = le32_to_cpu(fe->i_uid);
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index 35140f6cf840..4d1e53992566 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -56,6 +56,7 @@ struct ocfs2_inode_info
56 struct ocfs2_journal_handle *ip_handle; 56 struct ocfs2_journal_handle *ip_handle;
57 57
58 u32 ip_flags; /* see below */ 58 u32 ip_flags; /* see below */
59 u32 ip_attr; /* inode attributes */
59 60
60 /* protected by recovery_lock. */ 61 /* protected by recovery_lock. */
61 struct inode *ip_next_orphan; 62 struct inode *ip_next_orphan;
@@ -142,4 +143,6 @@ int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle,
142int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb); 143int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb);
143int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb); 144int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb);
144 145
146void ocfs2_set_inode_flags(struct inode *inode);
147
145#endif /* OCFS2_INODE_H */ 148#endif /* OCFS2_INODE_H */
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
new file mode 100644
index 000000000000..3663cef80689
--- /dev/null
+++ b/fs/ocfs2/ioctl.c
@@ -0,0 +1,136 @@
1/*
2 * linux/fs/ocfs2/ioctl.c
3 *
4 * Copyright (C) 2006 Herbert Poetzl
5 * adapted from Remy Card's ext2/ioctl.c
6 */
7
8#include <linux/fs.h>
9#include <linux/mount.h>
10
11#define MLOG_MASK_PREFIX ML_INODE
12#include <cluster/masklog.h>
13
14#include "ocfs2.h"
15#include "alloc.h"
16#include "dlmglue.h"
17#include "inode.h"
18#include "journal.h"
19
20#include "ocfs2_fs.h"
21#include "ioctl.h"
22
23#include <linux/ext2_fs.h>
24
25static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
26{
27 int status;
28
29 status = ocfs2_meta_lock(inode, NULL, NULL, 0);
30 if (status < 0) {
31 mlog_errno(status);
32 return status;
33 }
34 *flags = OCFS2_I(inode)->ip_attr;
35 ocfs2_meta_unlock(inode, 0);
36
37 mlog_exit(status);
38 return status;
39}
40
41static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
42 unsigned mask)
43{
44 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
45 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
46 struct ocfs2_journal_handle *handle = NULL;
47 struct buffer_head *bh = NULL;
48 unsigned oldflags;
49 int status;
50
51 mutex_lock(&inode->i_mutex);
52
53 status = ocfs2_meta_lock(inode, NULL, &bh, 1);
54 if (status < 0) {
55 mlog_errno(status);
56 goto bail;
57 }
58
59 status = -EROFS;
60 if (IS_RDONLY(inode))
61 goto bail_unlock;
62
63 status = -EACCES;
64 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
65 goto bail_unlock;
66
67 if (!S_ISDIR(inode->i_mode))
68 flags &= ~OCFS2_DIRSYNC_FL;
69
70 handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS);
71 if (IS_ERR(handle)) {
72 status = PTR_ERR(handle);
73 mlog_errno(status);
74 goto bail_unlock;
75 }
76
77 oldflags = ocfs2_inode->ip_attr;
78 flags = flags & mask;
79 flags |= oldflags & ~mask;
80
81 /*
82 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
83 * the relevant capability.
84 */
85 status = -EPERM;
86 if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) &
87 (OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) {
88 if (!capable(CAP_LINUX_IMMUTABLE))
89 goto bail_unlock;
90 }
91
92 ocfs2_inode->ip_attr = flags;
93 ocfs2_set_inode_flags(inode);
94
95 status = ocfs2_mark_inode_dirty(handle, inode, bh);
96 if (status < 0)
97 mlog_errno(status);
98
99 ocfs2_commit_trans(handle);
100bail_unlock:
101 ocfs2_meta_unlock(inode, 1);
102bail:
103 mutex_unlock(&inode->i_mutex);
104
105 if (bh)
106 brelse(bh);
107
108 mlog_exit(status);
109 return status;
110}
111
112int ocfs2_ioctl(struct inode * inode, struct file * filp,
113 unsigned int cmd, unsigned long arg)
114{
115 unsigned int flags;
116 int status;
117
118 switch (cmd) {
119 case OCFS2_IOC_GETFLAGS:
120 status = ocfs2_get_inode_attr(inode, &flags);
121 if (status < 0)
122 return status;
123
124 flags &= OCFS2_FL_VISIBLE;
125 return put_user(flags, (int __user *) arg);
126 case OCFS2_IOC_SETFLAGS:
127 if (get_user(flags, (int __user *) arg))
128 return -EFAULT;
129
130 return ocfs2_set_inode_attr(inode, flags,
131 OCFS2_FL_MODIFIABLE);
132 default:
133 return -ENOTTY;
134 }
135}
136
diff --git a/fs/ocfs2/ioctl.h b/fs/ocfs2/ioctl.h
new file mode 100644
index 000000000000..4a7c82931dba
--- /dev/null
+++ b/fs/ocfs2/ioctl.h
@@ -0,0 +1,16 @@
1/*
2 * ioctl.h
3 *
4 * Function prototypes
5 *
6 * Copyright (C) 2006 Herbert Poetzl
7 *
8 */
9
10#ifndef OCFS2_IOCTL_H
11#define OCFS2_IOCTL_H
12
13int ocfs2_ioctl(struct inode * inode, struct file * filp,
14 unsigned int cmd, unsigned long arg);
15
16#endif /* OCFS2_IOCTL_H */
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 0673862c8bdd..0d3e939b1f56 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -56,6 +56,7 @@
56#include "journal.h" 56#include "journal.h"
57#include "namei.h" 57#include "namei.h"
58#include "suballoc.h" 58#include "suballoc.h"
59#include "super.h"
59#include "symlink.h" 60#include "symlink.h"
60#include "sysfile.h" 61#include "sysfile.h"
61#include "uptodate.h" 62#include "uptodate.h"
@@ -310,13 +311,6 @@ static int ocfs2_mknod(struct inode *dir,
310 /* get our super block */ 311 /* get our super block */
311 osb = OCFS2_SB(dir->i_sb); 312 osb = OCFS2_SB(dir->i_sb);
312 313
313 if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
314 mlog(ML_ERROR, "inode %llu has i_nlink of %u\n",
315 (unsigned long long)OCFS2_I(dir)->ip_blkno, dir->i_nlink);
316 status = -EMLINK;
317 goto leave;
318 }
319
320 handle = ocfs2_alloc_handle(osb); 314 handle = ocfs2_alloc_handle(osb);
321 if (handle == NULL) { 315 if (handle == NULL) {
322 status = -ENOMEM; 316 status = -ENOMEM;
@@ -331,6 +325,11 @@ static int ocfs2_mknod(struct inode *dir,
331 goto leave; 325 goto leave;
332 } 326 }
333 327
328 if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
329 status = -EMLINK;
330 goto leave;
331 }
332
334 dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; 333 dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
335 if (!dirfe->i_links_count) { 334 if (!dirfe->i_links_count) {
336 /* can't make a file in a deleted directory. */ 335 /* can't make a file in a deleted directory. */
@@ -643,11 +642,6 @@ static int ocfs2_link(struct dentry *old_dentry,
643 goto bail; 642 goto bail;
644 } 643 }
645 644
646 if (inode->i_nlink >= OCFS2_LINK_MAX) {
647 err = -EMLINK;
648 goto bail;
649 }
650
651 handle = ocfs2_alloc_handle(osb); 645 handle = ocfs2_alloc_handle(osb);
652 if (handle == NULL) { 646 if (handle == NULL) {
653 err = -ENOMEM; 647 err = -ENOMEM;
@@ -661,6 +655,11 @@ static int ocfs2_link(struct dentry *old_dentry,
661 goto bail; 655 goto bail;
662 } 656 }
663 657
658 if (!dir->i_nlink) {
659 err = -ENOENT;
660 goto bail;
661 }
662
664 err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, 663 err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
665 dentry->d_name.len); 664 dentry->d_name.len);
666 if (err) 665 if (err)
@@ -1964,13 +1963,8 @@ restart:
1964 } 1963 }
1965 num++; 1964 num++;
1966 1965
1967 /* XXX: questionable readahead stuff here */
1968 bh = ocfs2_bread(dir, b++, &err, 1); 1966 bh = ocfs2_bread(dir, b++, &err, 1);
1969 bh_use[ra_max] = bh; 1967 bh_use[ra_max] = bh;
1970#if 0 // ???
1971 if (bh)
1972 ll_rw_block(READ, 1, &bh);
1973#endif
1974 } 1968 }
1975 } 1969 }
1976 if ((bh = bh_use[ra_ptr++]) == NULL) 1970 if ((bh = bh_use[ra_ptr++]) == NULL)
@@ -1978,6 +1972,10 @@ restart:
1978 wait_on_buffer(bh); 1972 wait_on_buffer(bh);
1979 if (!buffer_uptodate(bh)) { 1973 if (!buffer_uptodate(bh)) {
1980 /* read error, skip block & hope for the best */ 1974 /* read error, skip block & hope for the best */
1975 ocfs2_error(dir->i_sb, "reading directory %llu, "
1976 "offset %lu\n",
1977 (unsigned long long)OCFS2_I(dir)->ip_blkno,
1978 block);
1981 brelse(bh); 1979 brelse(bh);
1982 goto next; 1980 goto next;
1983 } 1981 }
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index c5b1ac547c15..3330a5dc6be2 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -114,6 +114,26 @@
114#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */ 114#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */
115#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */ 115#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */
116 116
117/* Inode attributes, keep in sync with EXT2 */
118#define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */
119#define OCFS2_UNRM_FL (0x00000002) /* Undelete */
120#define OCFS2_COMPR_FL (0x00000004) /* Compress file */
121#define OCFS2_SYNC_FL (0x00000008) /* Synchronous updates */
122#define OCFS2_IMMUTABLE_FL (0x00000010) /* Immutable file */
123#define OCFS2_APPEND_FL (0x00000020) /* writes to file may only append */
124#define OCFS2_NODUMP_FL (0x00000040) /* do not dump file */
125#define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */
126#define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */
127
128#define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */
129#define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */
130
131/*
132 * ioctl commands
133 */
134#define OCFS2_IOC_GETFLAGS _IOR('f', 1, long)
135#define OCFS2_IOC_SETFLAGS _IOW('f', 2, long)
136
117/* 137/*
118 * Journal Flags (ocfs2_dinode.id1.journal1.i_flags) 138 * Journal Flags (ocfs2_dinode.id1.journal1.i_flags)
119 */ 139 */
@@ -399,7 +419,9 @@ struct ocfs2_dinode {
399 __le32 i_atime_nsec; 419 __le32 i_atime_nsec;
400 __le32 i_ctime_nsec; 420 __le32 i_ctime_nsec;
401 __le32 i_mtime_nsec; 421 __le32 i_mtime_nsec;
402/*70*/ __le64 i_reserved1[9]; 422 __le32 i_attr;
423 __le32 i_reserved1;
424/*70*/ __le64 i_reserved2[8];
403/*B8*/ union { 425/*B8*/ union {
404 __le64 i_pad1; /* Generic way to refer to this 426 __le64 i_pad1; /* Generic way to refer to this
405 64bit union */ 427 64bit union */
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c
index b8a00a793326..9707ed7a3206 100644
--- a/fs/ocfs2/uptodate.c
+++ b/fs/ocfs2/uptodate.c
@@ -206,7 +206,10 @@ static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi,
206} 206}
207 207
208/* Warning: even if it returns true, this does *not* guarantee that 208/* Warning: even if it returns true, this does *not* guarantee that
209 * the block is stored in our inode metadata cache. */ 209 * the block is stored in our inode metadata cache.
210 *
211 * This can be called under lock_buffer()
212 */
210int ocfs2_buffer_uptodate(struct inode *inode, 213int ocfs2_buffer_uptodate(struct inode *inode,
211 struct buffer_head *bh) 214 struct buffer_head *bh)
212{ 215{
@@ -226,6 +229,16 @@ int ocfs2_buffer_uptodate(struct inode *inode,
226 return ocfs2_buffer_cached(OCFS2_I(inode), bh); 229 return ocfs2_buffer_cached(OCFS2_I(inode), bh);
227} 230}
228 231
232/*
233 * Determine whether a buffer is currently out on a read-ahead request.
234 * ip_io_sem should be held to serialize submitters with the logic here.
235 */
236int ocfs2_buffer_read_ahead(struct inode *inode,
237 struct buffer_head *bh)
238{
239 return buffer_locked(bh) && ocfs2_buffer_cached(OCFS2_I(inode), bh);
240}
241
229/* Requires ip_lock */ 242/* Requires ip_lock */
230static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci, 243static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci,
231 sector_t block) 244 sector_t block)
@@ -403,7 +416,11 @@ out_free:
403 * 416 *
404 * Note that this function may actually fail to insert the block if 417 * Note that this function may actually fail to insert the block if
405 * memory cannot be allocated. This is not fatal however (but may 418 * memory cannot be allocated. This is not fatal however (but may
406 * result in a performance penalty) */ 419 * result in a performance penalty)
420 *
421 * Readahead buffers can be passed in here before the I/O request is
422 * completed.
423 */
407void ocfs2_set_buffer_uptodate(struct inode *inode, 424void ocfs2_set_buffer_uptodate(struct inode *inode,
408 struct buffer_head *bh) 425 struct buffer_head *bh)
409{ 426{
diff --git a/fs/ocfs2/uptodate.h b/fs/ocfs2/uptodate.h
index 01cd32d26b06..2e73206059a8 100644
--- a/fs/ocfs2/uptodate.h
+++ b/fs/ocfs2/uptodate.h
@@ -40,5 +40,7 @@ void ocfs2_set_new_buffer_uptodate(struct inode *inode,
40 struct buffer_head *bh); 40 struct buffer_head *bh);
41void ocfs2_remove_from_cache(struct inode *inode, 41void ocfs2_remove_from_cache(struct inode *inode,
42 struct buffer_head *bh); 42 struct buffer_head *bh);
43int ocfs2_buffer_read_ahead(struct inode *inode,
44 struct buffer_head *bh);
43 45
44#endif /* OCFS2_UPTODATE_H */ 46#endif /* OCFS2_UPTODATE_H */
diff --git a/include/Kbuild b/include/Kbuild
index cb2534800b19..2d03f995865f 100644
--- a/include/Kbuild
+++ b/include/Kbuild
@@ -1,2 +1,9 @@
1header-y += asm-generic/ linux/ scsi/ sound/ mtd/ rdma/ video/ 1header-y += asm-generic/
2header-y += asm-$(ARCH)/ 2header-y += linux/
3header-y += scsi/
4header-y += sound/
5header-y += mtd/
6header-y += rdma/
7header-y += video/
8
9header-y += asm-$(ARCH)/
diff --git a/include/asm-alpha/Kbuild b/include/asm-alpha/Kbuild
index 2b06b3bad5ff..b7c8f188b313 100644
--- a/include/asm-alpha/Kbuild
+++ b/include/asm-alpha/Kbuild
@@ -1,5 +1,11 @@
1include include/asm-generic/Kbuild.asm 1include include/asm-generic/Kbuild.asm
2 2
3unifdef-y += console.h fpu.h sysinfo.h compiler.h 3header-y += gentrap.h
4header-y += regdef.h
5header-y += pal.h
6header-y += reg.h
4 7
5header-y += gentrap.h regdef.h pal.h reg.h 8unifdef-y += console.h
9unifdef-y += fpu.h
10unifdef-y += sysinfo.h
11unifdef-y += compiler.h
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index 70594b275a6e..3c06be381701 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -1,3 +1,12 @@
1header-y += atomic.h errno-base.h errno.h fcntl.h ioctl.h ipc.h mman.h \ 1header-y += atomic.h
2 signal.h statfs.h 2header-y += errno-base.h
3unifdef-y := resource.h siginfo.h 3header-y += errno.h
4header-y += fcntl.h
5header-y += ioctl.h
6header-y += ipc.h
7header-y += mman.h
8header-y += signal.h
9header-y += statfs.h
10
11unifdef-y += resource.h
12unifdef-y += siginfo.h
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
index c00de6028fa8..a84c3d88a189 100644
--- a/include/asm-generic/Kbuild.asm
+++ b/include/asm-generic/Kbuild.asm
@@ -1,8 +1,34 @@
1unifdef-y += a.out.h auxvec.h byteorder.h errno.h fcntl.h ioctl.h \ 1unifdef-y += a.out.h
2 ioctls.h ipcbuf.h mman.h msgbuf.h param.h poll.h \ 2unifdef-y += auxvec.h
3 posix_types.h ptrace.h resource.h sembuf.h shmbuf.h shmparam.h \ 3unifdef-y += byteorder.h
4 sigcontext.h siginfo.h signal.h socket.h sockios.h stat.h \ 4unifdef-y += errno.h
5 statfs.h termbits.h termios.h types.h unistd.h user.h 5unifdef-y += fcntl.h
6unifdef-y += ioctl.h
7unifdef-y += ioctls.h
8unifdef-y += ipcbuf.h
9unifdef-y += mman.h
10unifdef-y += msgbuf.h
11unifdef-y += param.h
12unifdef-y += poll.h
13unifdef-y += posix_types.h
14unifdef-y += ptrace.h
15unifdef-y += resource.h
16unifdef-y += sembuf.h
17unifdef-y += shmbuf.h
18unifdef-y += sigcontext.h
19unifdef-y += siginfo.h
20unifdef-y += signal.h
21unifdef-y += socket.h
22unifdef-y += sockios.h
23unifdef-y += stat.h
24unifdef-y += statfs.h
25unifdef-y += termbits.h
26unifdef-y += termios.h
27unifdef-y += types.h
28unifdef-y += unistd.h
29unifdef-y += user.h
6 30
7# These probably shouldn't be exported 31# These probably shouldn't be exported
8unifdef-y += elf.h page.h 32unifdef-y += shmparam.h
33unifdef-y += elf.h
34unifdef-y += page.h
diff --git a/include/asm-i386/Kbuild b/include/asm-i386/Kbuild
index 2308190321da..b75a348d0c1c 100644
--- a/include/asm-i386/Kbuild
+++ b/include/asm-i386/Kbuild
@@ -1,5 +1,10 @@
1include include/asm-generic/Kbuild.asm 1include include/asm-generic/Kbuild.asm
2 2
3header-y += boot.h debugreg.h ldt.h ucontext.h 3header-y += boot.h
4header-y += debugreg.h
5header-y += ldt.h
6header-y += ucontext.h
4 7
5unifdef-y += mtrr.h setup.h vm86.h 8unifdef-y += mtrr.h
9unifdef-y += setup.h
10unifdef-y += vm86.h
diff --git a/include/asm-ia64/Kbuild b/include/asm-ia64/Kbuild
index f1cb00f39c22..15818a18bc52 100644
--- a/include/asm-ia64/Kbuild
+++ b/include/asm-ia64/Kbuild
@@ -1,7 +1,17 @@
1include include/asm-generic/Kbuild.asm 1include include/asm-generic/Kbuild.asm
2 2
3header-y += break.h fpu.h fpswa.h gcc_intrin.h ia64regs.h \ 3header-y += break.h
4 intel_intrin.h intrinsics.h perfmon_default_smpl.h \ 4header-y += fpu.h
5 ptrace_offsets.h rse.h setup.h ucontext.h 5header-y += fpswa.h
6header-y += gcc_intrin.h
7header-y += ia64regs.h
8header-y += intel_intrin.h
9header-y += intrinsics.h
10header-y += perfmon_default_smpl.h
11header-y += ptrace_offsets.h
12header-y += rse.h
13header-y += setup.h
14header-y += ucontext.h
6 15
7unifdef-y += perfmon.h ustack.h 16unifdef-y += perfmon.h
17unifdef-y += ustack.h
diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild
index ac61d7eb6021..9827849953a3 100644
--- a/include/asm-powerpc/Kbuild
+++ b/include/asm-powerpc/Kbuild
@@ -1,10 +1,41 @@
1include include/asm-generic/Kbuild.asm 1include include/asm-generic/Kbuild.asm
2 2
3unifdef-y += a.out.h asm-compat.h bootx.h byteorder.h cputable.h elf.h \ 3header-y += auxvec.h
4 nvram.h param.h posix_types.h ptrace.h seccomp.h signal.h \ 4header-y += ioctls.h
5 termios.h types.h unistd.h 5header-y += mman.h
6header-y += sembuf.h
7header-y += siginfo.h
8header-y += stat.h
9header-y += errno.h
10header-y += ipcbuf.h
11header-y += msgbuf.h
12header-y += shmbuf.h
13header-y += socket.h
14header-y += termbits.h
15header-y += fcntl.h
16header-y += ipc.h
17header-y += poll.h
18header-y += shmparam.h
19header-y += sockios.h
20header-y += ucontext.h
21header-y += ioctl.h
22header-y += linkage.h
23header-y += resource.h
24header-y += sigcontext.h
25header-y += statfs.h
6 26
7header-y += auxvec.h ioctls.h mman.h sembuf.h siginfo.h stat.h errno.h \ 27unifdef-y += a.out.h
8 ipcbuf.h msgbuf.h shmbuf.h socket.h termbits.h fcntl.h ipc.h \ 28unifdef-y += asm-compat.h
9 poll.h shmparam.h sockios.h ucontext.h ioctl.h linkage.h \ 29unifdef-y += bootx.h
10 resource.h sigcontext.h statfs.h 30unifdef-y += byteorder.h
31unifdef-y += cputable.h
32unifdef-y += elf.h
33unifdef-y += nvram.h
34unifdef-y += param.h
35unifdef-y += posix_types.h
36unifdef-y += ptrace.h
37unifdef-y += seccomp.h
38unifdef-y += signal.h
39unifdef-y += termios.h
40unifdef-y += types.h
41unifdef-y += unistd.h
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 1ba3c9983614..12707ab9dc98 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -23,6 +23,7 @@
23#define PPC_FEATURE_SMT 0x00004000 23#define PPC_FEATURE_SMT 0x00004000
24#define PPC_FEATURE_ICACHE_SNOOP 0x00002000 24#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
25#define PPC_FEATURE_ARCH_2_05 0x00001000 25#define PPC_FEATURE_ARCH_2_05 0x00001000
26#define PPC_FEATURE_PA6T 0x00000800
26 27
27#define PPC_FEATURE_TRUE_LE 0x00000002 28#define PPC_FEATURE_TRUE_LE 0x00000002
28#define PPC_FEATURE_PPC_LE 0x00000001 29#define PPC_FEATURE_PPC_LE 0x00000001
@@ -36,6 +37,7 @@
36struct cpu_spec; 37struct cpu_spec;
37 38
38typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); 39typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
40typedef void (*cpu_restore_t)(void);
39 41
40enum powerpc_oprofile_type { 42enum powerpc_oprofile_type {
41 PPC_OPROFILE_INVALID = 0, 43 PPC_OPROFILE_INVALID = 0,
@@ -65,6 +67,8 @@ struct cpu_spec {
65 * BHT, SPD, etc... from head.S before branching to identify_machine 67 * BHT, SPD, etc... from head.S before branching to identify_machine
66 */ 68 */
67 cpu_setup_t cpu_setup; 69 cpu_setup_t cpu_setup;
70 /* Used to restore cpu setup on secondary processors and at resume */
71 cpu_restore_t cpu_restore;
68 72
69 /* Used by oprofile userspace to select the right counters */ 73 /* Used by oprofile userspace to select the right counters */
70 char *oprofile_cpu_type; 74 char *oprofile_cpu_type;
@@ -145,7 +149,7 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
145 149
146#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \ 150#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
147 CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \ 151 CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
148 CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL) 152 CPU_FTR_NODSISRALIGN)
149 153
150/* iSeries doesn't support large pages */ 154/* iSeries doesn't support large pages */
151#ifdef CONFIG_PPC_ISERIES 155#ifdef CONFIG_PPC_ISERIES
@@ -310,24 +314,29 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
310 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \ 314 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \
311 CPU_FTR_MMCRA | CPU_FTR_CTRL) 315 CPU_FTR_MMCRA | CPU_FTR_CTRL)
312#define CPU_FTRS_POWER4 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 316#define CPU_FTRS_POWER4 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
313 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA) 317 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
318 CPU_FTR_MMCRA)
314#define CPU_FTRS_PPC970 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 319#define CPU_FTRS_PPC970 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
315 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ 320 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
316 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA) 321 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA)
317#define CPU_FTRS_POWER5 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 322#define CPU_FTRS_POWER5 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
318 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ 323 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
319 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 324 CPU_FTR_MMCRA | CPU_FTR_SMT | \
320 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 325 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
321 CPU_FTR_PURR) 326 CPU_FTR_PURR)
322#define CPU_FTRS_POWER6 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 327#define CPU_FTRS_POWER6 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
323 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ 328 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
324 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 329 CPU_FTR_MMCRA | CPU_FTR_SMT | \
325 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 330 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
326 CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_REAL_LE) 331 CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_REAL_LE)
327#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 332#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
328 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ 333 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
329 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ 334 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
330 CPU_FTR_CTRL | CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE) 335 CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE)
336#define CPU_FTRS_PA6T (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
337 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
338 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
339 CPU_FTR_PURR | CPU_FTR_REAL_LE)
331#define CPU_FTRS_COMPATIBLE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 340#define CPU_FTRS_COMPATIBLE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
332 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2) 341 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
333#endif 342#endif
@@ -336,7 +345,7 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
336#define CPU_FTRS_POSSIBLE \ 345#define CPU_FTRS_POSSIBLE \
337 (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \ 346 (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
338 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \ 347 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \
339 CPU_FTRS_CELL | CPU_FTR_CI_LARGE_PAGE) 348 CPU_FTRS_CELL | CPU_FTRS_PA6T)
340#else 349#else
341enum { 350enum {
342 CPU_FTRS_POSSIBLE = 351 CPU_FTRS_POSSIBLE =
@@ -375,7 +384,7 @@ enum {
375#define CPU_FTRS_ALWAYS \ 384#define CPU_FTRS_ALWAYS \
376 (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \ 385 (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \
377 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_POWER6 & \ 386 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_POWER6 & \
378 CPU_FTRS_CELL & CPU_FTRS_POSSIBLE) 387 CPU_FTRS_CELL & CPU_FTRS_PA6T & CPU_FTRS_POSSIBLE)
379#else 388#else
380enum { 389enum {
381 CPU_FTRS_ALWAYS = 390 CPU_FTRS_ALWAYS =
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
index 0d3c4e85711a..257d1cecb8c9 100644
--- a/include/asm-powerpc/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -164,9 +164,15 @@
164#define H_VIO_SIGNAL 0x104 164#define H_VIO_SIGNAL 0x104
165#define H_SEND_CRQ 0x108 165#define H_SEND_CRQ 0x108
166#define H_COPY_RDMA 0x110 166#define H_COPY_RDMA 0x110
167#define H_REGISTER_LOGICAL_LAN 0x114
168#define H_FREE_LOGICAL_LAN 0x118
169#define H_ADD_LOGICAL_LAN_BUFFER 0x11C
170#define H_SEND_LOGICAL_LAN 0x120
171#define H_MULTICAST_CTRL 0x130
167#define H_SET_XDABR 0x134 172#define H_SET_XDABR 0x134
168#define H_STUFF_TCE 0x138 173#define H_STUFF_TCE 0x138
169#define H_PUT_TCE_INDIRECT 0x13C 174#define H_PUT_TCE_INDIRECT 0x13C
175#define H_CHANGE_LOGICAL_LAN_MAC 0x14C
170#define H_VTERM_PARTNER_INFO 0x150 176#define H_VTERM_PARTNER_INFO 0x150
171#define H_REGISTER_VTERM 0x154 177#define H_REGISTER_VTERM 0x154
172#define H_FREE_VTERM 0x158 178#define H_FREE_VTERM 0x158
@@ -196,102 +202,59 @@
196#define H_GET_HCA_INFO 0x1B8 202#define H_GET_HCA_INFO 0x1B8
197#define H_GET_PERF_COUNT 0x1BC 203#define H_GET_PERF_COUNT 0x1BC
198#define H_MANAGE_TRACE 0x1C0 204#define H_MANAGE_TRACE 0x1C0
205#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
199#define H_QUERY_INT_STATE 0x1E4 206#define H_QUERY_INT_STATE 0x1E4
200#define H_POLL_PENDING 0x1D8 207#define H_POLL_PENDING 0x1D8
201#define H_JOIN 0x298 208#define H_JOIN 0x298
202#define H_VASI_STATE 0x2A4 209#define H_VASI_STATE 0x2A4
203#define H_ENABLE_CRQ 0x2B0 210#define H_ENABLE_CRQ 0x2B0
211#define MAX_HCALL_OPCODE H_ENABLE_CRQ
204 212
205#ifndef __ASSEMBLY__ 213#ifndef __ASSEMBLY__
206 214
207/* plpar_hcall() -- Generic call interface using above opcodes 215/**
216 * plpar_hcall_norets: - Make a pseries hypervisor call with no return arguments
217 * @opcode: The hypervisor call to make.
208 * 218 *
209 * The actual call interface is a hypervisor call instruction with 219 * This call supports up to 7 arguments and only returns the status of
210 * the opcode in R3 and input args in R4-R7. 220 * the hcall. Use this version where possible, its slightly faster than
211 * Status is returned in R3 with variable output values in R4-R11. 221 * the other plpar_hcalls.
212 * Only H_PTE_READ with H_READ_4 uses R6-R11 so we ignore it for now
213 * and return only two out args which MUST ALWAYS BE PROVIDED.
214 */
215long plpar_hcall(unsigned long opcode,
216 unsigned long arg1,
217 unsigned long arg2,
218 unsigned long arg3,
219 unsigned long arg4,
220 unsigned long *out1,
221 unsigned long *out2,
222 unsigned long *out3);
223
224/* Same as plpar_hcall but for those opcodes that return no values
225 * other than status. Slightly more efficient.
226 */ 222 */
227long plpar_hcall_norets(unsigned long opcode, ...); 223long plpar_hcall_norets(unsigned long opcode, ...);
228 224
229/* 225/**
230 * Special hcall interface for ibmveth support. 226 * plpar_hcall: - Make a pseries hypervisor call
231 * Takes 8 input parms. Returns a rc and stores the 227 * @opcode: The hypervisor call to make.
232 * R4 return value in *out1. 228 * @retbuf: Buffer to store up to 4 return arguments in.
233 */
234long plpar_hcall_8arg_2ret(unsigned long opcode,
235 unsigned long arg1,
236 unsigned long arg2,
237 unsigned long arg3,
238 unsigned long arg4,
239 unsigned long arg5,
240 unsigned long arg6,
241 unsigned long arg7,
242 unsigned long arg8,
243 unsigned long *out1);
244
245/* plpar_hcall_4out()
246 * 229 *
247 * same as plpar_hcall except with 4 output arguments. 230 * This call supports up to 6 arguments and 4 return arguments. Use
231 * PLPAR_HCALL_BUFSIZE to size the return argument buffer.
248 * 232 *
233 * Used for all but the craziest of phyp interfaces (see plpar_hcall9)
249 */ 234 */
250long plpar_hcall_4out(unsigned long opcode, 235#define PLPAR_HCALL_BUFSIZE 4
251 unsigned long arg1, 236long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...);
252 unsigned long arg2,
253 unsigned long arg3,
254 unsigned long arg4,
255 unsigned long *out1,
256 unsigned long *out2,
257 unsigned long *out3,
258 unsigned long *out4);
259 237
260long plpar_hcall_7arg_7ret(unsigned long opcode, 238/**
261 unsigned long arg1, 239 * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments
262 unsigned long arg2, 240 * @opcode: The hypervisor call to make.
263 unsigned long arg3, 241 * @retbuf: Buffer to store up to 9 return arguments in.
264 unsigned long arg4, 242 *
265 unsigned long arg5, 243 * This call supports up to 9 arguments and 9 return arguments. Use
266 unsigned long arg6, 244 * PLPAR_HCALL9_BUFSIZE to size the return argument buffer.
267 unsigned long arg7, 245 */
268 unsigned long *out1, 246#define PLPAR_HCALL9_BUFSIZE 9
269 unsigned long *out2, 247long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...);
270 unsigned long *out3,
271 unsigned long *out4,
272 unsigned long *out5,
273 unsigned long *out6,
274 unsigned long *out7);
275 248
276long plpar_hcall_9arg_9ret(unsigned long opcode, 249/* For hcall instrumentation. One structure per-hcall, per-CPU */
277 unsigned long arg1, 250struct hcall_stats {
278 unsigned long arg2, 251 unsigned long num_calls; /* number of calls (on this CPU) */
279 unsigned long arg3, 252 unsigned long tb_total; /* total wall time (mftb) of calls. */
280 unsigned long arg4, 253 unsigned long purr_total; /* total cpu time (PURR) of calls. */
281 unsigned long arg5, 254};
282 unsigned long arg6, 255void update_hcall_stats(unsigned long opcode, unsigned long tb_delta,
283 unsigned long arg7, 256 unsigned long purr_delta);
284 unsigned long arg8, 257#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1)
285 unsigned long arg9,
286 unsigned long *out1,
287 unsigned long *out2,
288 unsigned long *out3,
289 unsigned long *out4,
290 unsigned long *out5,
291 unsigned long *out6,
292 unsigned long *out7,
293 unsigned long *out8,
294 unsigned long *out9);
295 258
296#endif /* __ASSEMBLY__ */ 259#endif /* __ASSEMBLY__ */
297#endif /* __KERNEL__ */ 260#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/ibmebus.h b/include/asm-powerpc/ibmebus.h
index 7a42723d107c..7ab195a27888 100644
--- a/include/asm-powerpc/ibmebus.h
+++ b/include/asm-powerpc/ibmebus.h
@@ -48,7 +48,7 @@ extern struct dma_mapping_ops ibmebus_dma_ops;
48extern struct bus_type ibmebus_bus_type; 48extern struct bus_type ibmebus_bus_type;
49 49
50struct ibmebus_dev { 50struct ibmebus_dev {
51 char *name; 51 const char *name;
52 struct of_device ofdev; 52 struct of_device ofdev;
53}; 53};
54 54
diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h
index b09b42af6a1e..c8390f9485de 100644
--- a/include/asm-powerpc/ide.h
+++ b/include/asm-powerpc/ide.h
@@ -12,6 +12,7 @@
12#include <linux/sched.h> 12#include <linux/sched.h>
13#include <asm/mpc8xx.h> 13#include <asm/mpc8xx.h>
14#endif 14#endif
15#include <asm/io.h>
15 16
16#ifndef MAX_HWIFS 17#ifndef MAX_HWIFS
17#ifdef __powerpc64__ 18#ifdef __powerpc64__
@@ -21,15 +22,14 @@
21#endif 22#endif
22#endif 23#endif
23 24
25#define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 __iomem *)(p), (a), (c))
26#define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 __iomem *)(p), (a), (c))
27#define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 __iomem *)(p), (a), (c))
28#define __ide_mm_outsl(p, a, c) _outsl_ns((volatile u32 __iomem *)(p), (a), (c))
29
24#ifndef __powerpc64__ 30#ifndef __powerpc64__
25#include <linux/hdreg.h> 31#include <linux/hdreg.h>
26#include <linux/ioport.h> 32#include <linux/ioport.h>
27#include <asm/io.h>
28
29extern void __ide_mm_insw(void __iomem *port, void *addr, u32 count);
30extern void __ide_mm_outsw(void __iomem *port, void *addr, u32 count);
31extern void __ide_mm_insl(void __iomem *port, void *addr, u32 count);
32extern void __ide_mm_outsl(void __iomem *port, void *addr, u32 count);
33 33
34struct ide_machdep_calls { 34struct ide_machdep_calls {
35 int (*default_irq)(unsigned long base); 35 int (*default_irq)(unsigned long base);
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 212428db0d8b..46bae1cf385b 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -20,20 +20,11 @@ extern int check_legacy_ioport(unsigned long base_port);
20#include <asm/page.h> 20#include <asm/page.h>
21#include <asm/byteorder.h> 21#include <asm/byteorder.h>
22#include <asm/paca.h> 22#include <asm/paca.h>
23#ifdef CONFIG_PPC_ISERIES
24#include <asm/iseries/iseries_io.h>
25#endif
26#include <asm/synch.h> 23#include <asm/synch.h>
27#include <asm/delay.h> 24#include <asm/delay.h>
28 25
29#include <asm-generic/iomap.h> 26#include <asm-generic/iomap.h>
30 27
31#define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 __iomem *)(p), (a), (c))
32#define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 __iomem *)(p), (a), (c))
33#define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 __iomem *)(p), (a), (c))
34#define __ide_mm_outsl(p, a, c) _outsl_ns((volatile u32 __iomem *)(p), (a), (c))
35
36
37#define SIO_CONFIG_RA 0x398 28#define SIO_CONFIG_RA 0x398
38#define SIO_CONFIG_RD 0x399 29#define SIO_CONFIG_RD 0x399
39 30
@@ -43,42 +34,53 @@ extern unsigned long isa_io_base;
43extern unsigned long pci_io_base; 34extern unsigned long pci_io_base;
44 35
45#ifdef CONFIG_PPC_ISERIES 36#ifdef CONFIG_PPC_ISERIES
46/* __raw_* accessors aren't supported on iSeries */ 37
47#define __raw_readb(addr) { BUG(); 0; } 38extern int in_8(const volatile unsigned char __iomem *addr);
48#define __raw_readw(addr) { BUG(); 0; } 39extern void out_8(volatile unsigned char __iomem *addr, int val);
49#define __raw_readl(addr) { BUG(); 0; } 40extern int in_le16(const volatile unsigned short __iomem *addr);
50#define __raw_readq(addr) { BUG(); 0; } 41extern int in_be16(const volatile unsigned short __iomem *addr);
51#define __raw_writeb(v, addr) { BUG(); 0; } 42extern void out_le16(volatile unsigned short __iomem *addr, int val);
52#define __raw_writew(v, addr) { BUG(); 0; } 43extern void out_be16(volatile unsigned short __iomem *addr, int val);
53#define __raw_writel(v, addr) { BUG(); 0; } 44extern unsigned in_le32(const volatile unsigned __iomem *addr);
54#define __raw_writeq(v, addr) { BUG(); 0; } 45extern unsigned in_be32(const volatile unsigned __iomem *addr);
55#define readb(addr) iSeries_Read_Byte(addr) 46extern void out_le32(volatile unsigned __iomem *addr, int val);
56#define readw(addr) iSeries_Read_Word(addr) 47extern void out_be32(volatile unsigned __iomem *addr, int val);
57#define readl(addr) iSeries_Read_Long(addr) 48extern unsigned long in_le64(const volatile unsigned long __iomem *addr);
58#define writeb(data, addr) iSeries_Write_Byte((data),(addr)) 49extern unsigned long in_be64(const volatile unsigned long __iomem *addr);
59#define writew(data, addr) iSeries_Write_Word((data),(addr)) 50extern void out_le64(volatile unsigned long __iomem *addr, unsigned long val);
60#define writel(data, addr) iSeries_Write_Long((data),(addr)) 51extern void out_be64(volatile unsigned long __iomem *addr, unsigned long val);
61#define memset_io(a,b,c) iSeries_memset_io((a),(b),(c)) 52
62#define memcpy_fromio(a,b,c) iSeries_memcpy_fromio((a), (b), (c)) 53extern unsigned char __raw_readb(const volatile void __iomem *addr);
63#define memcpy_toio(a,b,c) iSeries_memcpy_toio((a), (b), (c)) 54extern unsigned short __raw_readw(const volatile void __iomem *addr);
64 55extern unsigned int __raw_readl(const volatile void __iomem *addr);
65#define inb(addr) readb(((void __iomem *)(long)(addr))) 56extern unsigned long __raw_readq(const volatile void __iomem *addr);
66#define inw(addr) readw(((void __iomem *)(long)(addr))) 57extern void __raw_writeb(unsigned char v, volatile void __iomem *addr);
67#define inl(addr) readl(((void __iomem *)(long)(addr))) 58extern void __raw_writew(unsigned short v, volatile void __iomem *addr);
68#define outb(data,addr) writeb(data,((void __iomem *)(long)(addr))) 59extern void __raw_writel(unsigned int v, volatile void __iomem *addr);
69#define outw(data,addr) writew(data,((void __iomem *)(long)(addr))) 60extern void __raw_writeq(unsigned long v, volatile void __iomem *addr);
70#define outl(data,addr) writel(data,((void __iomem *)(long)(addr))) 61
71/* 62extern void memset_io(volatile void __iomem *addr, int c, unsigned long n);
72 * The *_ns versions below don't do byte-swapping. 63extern void memcpy_fromio(void *dest, const volatile void __iomem *src,
73 * Neither do the standard versions now, these are just here 64 unsigned long n);
74 * for older code. 65extern void memcpy_toio(volatile void __iomem *dest, const void *src,
75 */ 66 unsigned long n);
76#define insb(port, buf, ns) _insb((u8 __iomem *)((port)+pci_io_base), (buf), (ns)) 67
77#define insw(port, buf, ns) _insw_ns((u8 __iomem *)((port)+pci_io_base), (buf), (ns)) 68#else /* CONFIG_PPC_ISERIES */
78#define insl(port, buf, nl) _insl_ns((u8 __iomem *)((port)+pci_io_base), (buf), (nl)) 69
79#define insw_ns(port, buf, ns) _insw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns)) 70#define in_8(addr) __in_8((addr))
80#define insl_ns(port, buf, nl) _insl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl)) 71#define out_8(addr, val) __out_8((addr), (val))
81#else 72#define in_le16(addr) __in_le16((addr))
73#define in_be16(addr) __in_be16((addr))
74#define out_le16(addr, val) __out_le16((addr), (val))
75#define out_be16(addr, val) __out_be16((addr), (val))
76#define in_le32(addr) __in_le32((addr))
77#define in_be32(addr) __in_be32((addr))
78#define out_le32(addr, val) __out_le32((addr), (val))
79#define out_be32(addr, val) __out_be32((addr), (val))
80#define in_le64(addr) __in_le64((addr))
81#define in_be64(addr) __in_be64((addr))
82#define out_le64(addr, val) __out_le64((addr), (val))
83#define out_be64(addr, val) __out_be64((addr), (val))
82 84
83static inline unsigned char __raw_readb(const volatile void __iomem *addr) 85static inline unsigned char __raw_readb(const volatile void __iomem *addr)
84{ 86{
@@ -112,23 +114,11 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
112{ 114{
113 *(volatile unsigned long __force *)addr = v; 115 *(volatile unsigned long __force *)addr = v;
114} 116}
115#define readb(addr) eeh_readb(addr)
116#define readw(addr) eeh_readw(addr)
117#define readl(addr) eeh_readl(addr)
118#define readq(addr) eeh_readq(addr)
119#define writeb(data, addr) eeh_writeb((data), (addr))
120#define writew(data, addr) eeh_writew((data), (addr))
121#define writel(data, addr) eeh_writel((data), (addr))
122#define writeq(data, addr) eeh_writeq((data), (addr))
123#define memset_io(a,b,c) eeh_memset_io((a),(b),(c)) 117#define memset_io(a,b,c) eeh_memset_io((a),(b),(c))
124#define memcpy_fromio(a,b,c) eeh_memcpy_fromio((a),(b),(c)) 118#define memcpy_fromio(a,b,c) eeh_memcpy_fromio((a),(b),(c))
125#define memcpy_toio(a,b,c) eeh_memcpy_toio((a),(b),(c)) 119#define memcpy_toio(a,b,c) eeh_memcpy_toio((a),(b),(c))
126#define inb(port) eeh_inb((unsigned long)port) 120
127#define outb(val, port) eeh_outb(val, (unsigned long)port) 121#endif /* CONFIG_PPC_ISERIES */
128#define inw(port) eeh_inw((unsigned long)port)
129#define outw(val, port) eeh_outw(val, (unsigned long)port)
130#define inl(port) eeh_inl((unsigned long)port)
131#define outl(val, port) eeh_outl(val, (unsigned long)port)
132 122
133/* 123/*
134 * The insw/outsw/insl/outsl macros don't do byte-swapping. 124 * The insw/outsw/insl/outsl macros don't do byte-swapping.
@@ -138,30 +128,37 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
138#define insb(port, buf, ns) eeh_insb((port), (buf), (ns)) 128#define insb(port, buf, ns) eeh_insb((port), (buf), (ns))
139#define insw(port, buf, ns) eeh_insw_ns((port), (buf), (ns)) 129#define insw(port, buf, ns) eeh_insw_ns((port), (buf), (ns))
140#define insl(port, buf, nl) eeh_insl_ns((port), (buf), (nl)) 130#define insl(port, buf, nl) eeh_insl_ns((port), (buf), (nl))
141#define insw_ns(port, buf, ns) eeh_insw_ns((port), (buf), (ns))
142#define insl_ns(port, buf, nl) eeh_insl_ns((port), (buf), (nl))
143
144#endif
145 131
146#define outsb(port, buf, ns) _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns)) 132#define outsb(port, buf, ns) _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns))
147#define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns)) 133#define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
148#define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl)) 134#define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
149 135
136#define readb(addr) eeh_readb(addr)
137#define readw(addr) eeh_readw(addr)
138#define readl(addr) eeh_readl(addr)
139#define readq(addr) eeh_readq(addr)
140#define writeb(data, addr) eeh_writeb((data), (addr))
141#define writew(data, addr) eeh_writew((data), (addr))
142#define writel(data, addr) eeh_writel((data), (addr))
143#define writeq(data, addr) eeh_writeq((data), (addr))
144#define inb(port) eeh_inb((unsigned long)port)
145#define outb(val, port) eeh_outb(val, (unsigned long)port)
146#define inw(port) eeh_inw((unsigned long)port)
147#define outw(val, port) eeh_outw(val, (unsigned long)port)
148#define inl(port) eeh_inl((unsigned long)port)
149#define outl(val, port) eeh_outl(val, (unsigned long)port)
150
150#define readb_relaxed(addr) readb(addr) 151#define readb_relaxed(addr) readb(addr)
151#define readw_relaxed(addr) readw(addr) 152#define readw_relaxed(addr) readw(addr)
152#define readl_relaxed(addr) readl(addr) 153#define readl_relaxed(addr) readl(addr)
153#define readq_relaxed(addr) readq(addr) 154#define readq_relaxed(addr) readq(addr)
154 155
155extern void _insb(volatile u8 __iomem *port, void *buf, int ns); 156extern void _insb(volatile u8 __iomem *port, void *buf, long count);
156extern void _outsb(volatile u8 __iomem *port, const void *buf, int ns); 157extern void _outsb(volatile u8 __iomem *port, const void *buf, long count);
157extern void _insw(volatile u16 __iomem *port, void *buf, int ns); 158extern void _insw_ns(volatile u16 __iomem *port, void *buf, long count);
158extern void _outsw(volatile u16 __iomem *port, const void *buf, int ns); 159extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count);
159extern void _insl(volatile u32 __iomem *port, void *buf, int nl); 160extern void _insl_ns(volatile u32 __iomem *port, void *buf, long count);
160extern void _outsl(volatile u32 __iomem *port, const void *buf, int nl); 161extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count);
161extern void _insw_ns(volatile u16 __iomem *port, void *buf, int ns);
162extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, int ns);
163extern void _insl_ns(volatile u32 __iomem *port, void *buf, int nl);
164extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, int nl);
165 162
166static inline void mmiowb(void) 163static inline void mmiowb(void)
167{ 164{
@@ -180,14 +177,6 @@ static inline void mmiowb(void)
180#define inl_p(port) inl(port) 177#define inl_p(port) inl(port)
181#define outl_p(val, port) (udelay(1), outl((val), (port))) 178#define outl_p(val, port) (udelay(1), outl((val), (port)))
182 179
183/*
184 * The *_ns versions below don't do byte-swapping.
185 * Neither do the standard versions now, these are just here
186 * for older code.
187 */
188#define outsw_ns(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
189#define outsl_ns(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
190
191 180
192#define IO_SPACE_LIMIT ~(0UL) 181#define IO_SPACE_LIMIT ~(0UL)
193 182
@@ -279,7 +268,7 @@ static inline void iosync(void)
279 * and should not be used directly by device drivers. Use inb/readb 268 * and should not be used directly by device drivers. Use inb/readb
280 * instead. 269 * instead.
281 */ 270 */
282static inline int in_8(const volatile unsigned char __iomem *addr) 271static inline int __in_8(const volatile unsigned char __iomem *addr)
283{ 272{
284 int ret; 273 int ret;
285 274
@@ -288,14 +277,14 @@ static inline int in_8(const volatile unsigned char __iomem *addr)
288 return ret; 277 return ret;
289} 278}
290 279
291static inline void out_8(volatile unsigned char __iomem *addr, int val) 280static inline void __out_8(volatile unsigned char __iomem *addr, int val)
292{ 281{
293 __asm__ __volatile__("sync; stb%U0%X0 %1,%0" 282 __asm__ __volatile__("sync; stb%U0%X0 %1,%0"
294 : "=m" (*addr) : "r" (val)); 283 : "=m" (*addr) : "r" (val));
295 get_paca()->io_sync = 1; 284 get_paca()->io_sync = 1;
296} 285}
297 286
298static inline int in_le16(const volatile unsigned short __iomem *addr) 287static inline int __in_le16(const volatile unsigned short __iomem *addr)
299{ 288{
300 int ret; 289 int ret;
301 290
@@ -304,7 +293,7 @@ static inline int in_le16(const volatile unsigned short __iomem *addr)
304 return ret; 293 return ret;
305} 294}
306 295
307static inline int in_be16(const volatile unsigned short __iomem *addr) 296static inline int __in_be16(const volatile unsigned short __iomem *addr)
308{ 297{
309 int ret; 298 int ret;
310 299
@@ -313,21 +302,21 @@ static inline int in_be16(const volatile unsigned short __iomem *addr)
313 return ret; 302 return ret;
314} 303}
315 304
316static inline void out_le16(volatile unsigned short __iomem *addr, int val) 305static inline void __out_le16(volatile unsigned short __iomem *addr, int val)
317{ 306{
318 __asm__ __volatile__("sync; sthbrx %1,0,%2" 307 __asm__ __volatile__("sync; sthbrx %1,0,%2"
319 : "=m" (*addr) : "r" (val), "r" (addr)); 308 : "=m" (*addr) : "r" (val), "r" (addr));
320 get_paca()->io_sync = 1; 309 get_paca()->io_sync = 1;
321} 310}
322 311
323static inline void out_be16(volatile unsigned short __iomem *addr, int val) 312static inline void __out_be16(volatile unsigned short __iomem *addr, int val)
324{ 313{
325 __asm__ __volatile__("sync; sth%U0%X0 %1,%0" 314 __asm__ __volatile__("sync; sth%U0%X0 %1,%0"
326 : "=m" (*addr) : "r" (val)); 315 : "=m" (*addr) : "r" (val));
327 get_paca()->io_sync = 1; 316 get_paca()->io_sync = 1;
328} 317}
329 318
330static inline unsigned in_le32(const volatile unsigned __iomem *addr) 319static inline unsigned __in_le32(const volatile unsigned __iomem *addr)
331{ 320{
332 unsigned ret; 321 unsigned ret;
333 322
@@ -336,7 +325,7 @@ static inline unsigned in_le32(const volatile unsigned __iomem *addr)
336 return ret; 325 return ret;
337} 326}
338 327
339static inline unsigned in_be32(const volatile unsigned __iomem *addr) 328static inline unsigned __in_be32(const volatile unsigned __iomem *addr)
340{ 329{
341 unsigned ret; 330 unsigned ret;
342 331
@@ -345,21 +334,21 @@ static inline unsigned in_be32(const volatile unsigned __iomem *addr)
345 return ret; 334 return ret;
346} 335}
347 336
348static inline void out_le32(volatile unsigned __iomem *addr, int val) 337static inline void __out_le32(volatile unsigned __iomem *addr, int val)
349{ 338{
350 __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr) 339 __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr)
351 : "r" (val), "r" (addr)); 340 : "r" (val), "r" (addr));
352 get_paca()->io_sync = 1; 341 get_paca()->io_sync = 1;
353} 342}
354 343
355static inline void out_be32(volatile unsigned __iomem *addr, int val) 344static inline void __out_be32(volatile unsigned __iomem *addr, int val)
356{ 345{
357 __asm__ __volatile__("sync; stw%U0%X0 %1,%0" 346 __asm__ __volatile__("sync; stw%U0%X0 %1,%0"
358 : "=m" (*addr) : "r" (val)); 347 : "=m" (*addr) : "r" (val));
359 get_paca()->io_sync = 1; 348 get_paca()->io_sync = 1;
360} 349}
361 350
362static inline unsigned long in_le64(const volatile unsigned long __iomem *addr) 351static inline unsigned long __in_le64(const volatile unsigned long __iomem *addr)
363{ 352{
364 unsigned long tmp, ret; 353 unsigned long tmp, ret;
365 354
@@ -379,7 +368,7 @@ static inline unsigned long in_le64(const volatile unsigned long __iomem *addr)
379 return ret; 368 return ret;
380} 369}
381 370
382static inline unsigned long in_be64(const volatile unsigned long __iomem *addr) 371static inline unsigned long __in_be64(const volatile unsigned long __iomem *addr)
383{ 372{
384 unsigned long ret; 373 unsigned long ret;
385 374
@@ -388,7 +377,7 @@ static inline unsigned long in_be64(const volatile unsigned long __iomem *addr)
388 return ret; 377 return ret;
389} 378}
390 379
391static inline void out_le64(volatile unsigned long __iomem *addr, unsigned long val) 380static inline void __out_le64(volatile unsigned long __iomem *addr, unsigned long val)
392{ 381{
393 unsigned long tmp; 382 unsigned long tmp;
394 383
@@ -406,15 +395,13 @@ static inline void out_le64(volatile unsigned long __iomem *addr, unsigned long
406 get_paca()->io_sync = 1; 395 get_paca()->io_sync = 1;
407} 396}
408 397
409static inline void out_be64(volatile unsigned long __iomem *addr, unsigned long val) 398static inline void __out_be64(volatile unsigned long __iomem *addr, unsigned long val)
410{ 399{
411 __asm__ __volatile__("sync; std%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); 400 __asm__ __volatile__("sync; std%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
412 get_paca()->io_sync = 1; 401 get_paca()->io_sync = 1;
413} 402}
414 403
415#ifndef CONFIG_PPC_ISERIES
416#include <asm/eeh.h> 404#include <asm/eeh.h>
417#endif
418 405
419/** 406/**
420 * check_signature - find BIOS signatures 407 * check_signature - find BIOS signatures
@@ -430,7 +417,6 @@ static inline int check_signature(const volatile void __iomem * io_addr,
430 const unsigned char *signature, int length) 417 const unsigned char *signature, int length)
431{ 418{
432 int retval = 0; 419 int retval = 0;
433#ifndef CONFIG_PPC_ISERIES
434 do { 420 do {
435 if (readb(io_addr) != *signature) 421 if (readb(io_addr) != *signature)
436 goto out; 422 goto out;
@@ -440,7 +426,6 @@ static inline int check_signature(const volatile void __iomem * io_addr,
440 } while (length); 426 } while (length);
441 retval = 1; 427 retval = 1;
442out: 428out:
443#endif
444 return retval; 429 return retval;
445} 430}
446 431
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index d903a62959da..4da41efb1319 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -137,7 +137,7 @@ struct irq_map_entry {
137extern struct irq_map_entry irq_map[NR_IRQS]; 137extern struct irq_map_entry irq_map[NR_IRQS];
138 138
139 139
140/*** 140/**
141 * irq_alloc_host - Allocate a new irq_host data structure 141 * irq_alloc_host - Allocate a new irq_host data structure
142 * @node: device-tree node of the interrupt controller 142 * @node: device-tree node of the interrupt controller
143 * @revmap_type: type of reverse mapping to use 143 * @revmap_type: type of reverse mapping to use
@@ -159,14 +159,14 @@ extern struct irq_host *irq_alloc_host(unsigned int revmap_type,
159 irq_hw_number_t inval_irq); 159 irq_hw_number_t inval_irq);
160 160
161 161
162/*** 162/**
163 * irq_find_host - Locates a host for a given device node 163 * irq_find_host - Locates a host for a given device node
164 * @node: device-tree node of the interrupt controller 164 * @node: device-tree node of the interrupt controller
165 */ 165 */
166extern struct irq_host *irq_find_host(struct device_node *node); 166extern struct irq_host *irq_find_host(struct device_node *node);
167 167
168 168
169/*** 169/**
170 * irq_set_default_host - Set a "default" host 170 * irq_set_default_host - Set a "default" host
171 * @host: default host pointer 171 * @host: default host pointer
172 * 172 *
@@ -178,7 +178,7 @@ extern struct irq_host *irq_find_host(struct device_node *node);
178extern void irq_set_default_host(struct irq_host *host); 178extern void irq_set_default_host(struct irq_host *host);
179 179
180 180
181/*** 181/**
182 * irq_set_virq_count - Set the maximum number of virt irqs 182 * irq_set_virq_count - Set the maximum number of virt irqs
183 * @count: number of linux virtual irqs, capped with NR_IRQS 183 * @count: number of linux virtual irqs, capped with NR_IRQS
184 * 184 *
@@ -188,7 +188,7 @@ extern void irq_set_default_host(struct irq_host *host);
188extern void irq_set_virq_count(unsigned int count); 188extern void irq_set_virq_count(unsigned int count);
189 189
190 190
191/*** 191/**
192 * irq_create_mapping - Map a hardware interrupt into linux virq space 192 * irq_create_mapping - Map a hardware interrupt into linux virq space
193 * @host: host owning this hardware interrupt or NULL for default host 193 * @host: host owning this hardware interrupt or NULL for default host
194 * @hwirq: hardware irq number in that host space 194 * @hwirq: hardware irq number in that host space
@@ -202,13 +202,13 @@ extern unsigned int irq_create_mapping(struct irq_host *host,
202 irq_hw_number_t hwirq); 202 irq_hw_number_t hwirq);
203 203
204 204
205/*** 205/**
206 * irq_dispose_mapping - Unmap an interrupt 206 * irq_dispose_mapping - Unmap an interrupt
207 * @virq: linux virq number of the interrupt to unmap 207 * @virq: linux virq number of the interrupt to unmap
208 */ 208 */
209extern void irq_dispose_mapping(unsigned int virq); 209extern void irq_dispose_mapping(unsigned int virq);
210 210
211/*** 211/**
212 * irq_find_mapping - Find a linux virq from an hw irq number. 212 * irq_find_mapping - Find a linux virq from an hw irq number.
213 * @host: host owning this hardware interrupt 213 * @host: host owning this hardware interrupt
214 * @hwirq: hardware irq number in that host space 214 * @hwirq: hardware irq number in that host space
@@ -221,7 +221,7 @@ extern unsigned int irq_find_mapping(struct irq_host *host,
221 irq_hw_number_t hwirq); 221 irq_hw_number_t hwirq);
222 222
223 223
224/*** 224/**
225 * irq_radix_revmap - Find a linux virq from a hw irq number. 225 * irq_radix_revmap - Find a linux virq from a hw irq number.
226 * @host: host owning this hardware interrupt 226 * @host: host owning this hardware interrupt
227 * @hwirq: hardware irq number in that host space 227 * @hwirq: hardware irq number in that host space
@@ -232,7 +232,7 @@ extern unsigned int irq_find_mapping(struct irq_host *host,
232extern unsigned int irq_radix_revmap(struct irq_host *host, 232extern unsigned int irq_radix_revmap(struct irq_host *host,
233 irq_hw_number_t hwirq); 233 irq_hw_number_t hwirq);
234 234
235/*** 235/**
236 * irq_linear_revmap - Find a linux virq from a hw irq number. 236 * irq_linear_revmap - Find a linux virq from a hw irq number.
237 * @host: host owning this hardware interrupt 237 * @host: host owning this hardware interrupt
238 * @hwirq: hardware irq number in that host space 238 * @hwirq: hardware irq number in that host space
@@ -247,7 +247,7 @@ extern unsigned int irq_linear_revmap(struct irq_host *host,
247 247
248 248
249 249
250/*** 250/**
251 * irq_alloc_virt - Allocate virtual irq numbers 251 * irq_alloc_virt - Allocate virtual irq numbers
252 * @host: host owning these new virtual irqs 252 * @host: host owning these new virtual irqs
253 * @count: number of consecutive numbers to allocate 253 * @count: number of consecutive numbers to allocate
@@ -261,7 +261,7 @@ extern unsigned int irq_alloc_virt(struct irq_host *host,
261 unsigned int count, 261 unsigned int count,
262 unsigned int hint); 262 unsigned int hint);
263 263
264/*** 264/**
265 * irq_free_virt - Free virtual irq numbers 265 * irq_free_virt - Free virtual irq numbers
266 * @virq: virtual irq number of the first interrupt to free 266 * @virq: virtual irq number of the first interrupt to free
267 * @count: number of interrupts to free 267 * @count: number of interrupts to free
@@ -300,7 +300,7 @@ extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
300 300
301/* -- End OF helpers -- */ 301/* -- End OF helpers -- */
302 302
303/*** 303/**
304 * irq_early_init - Init irq remapping subsystem 304 * irq_early_init - Init irq remapping subsystem
305 */ 305 */
306extern void irq_early_init(void); 306extern void irq_early_init(void);
diff --git a/include/asm-powerpc/iseries/hv_call_xm.h b/include/asm-powerpc/iseries/hv_call_xm.h
index ca9202cb01ed..392ac3f54df0 100644
--- a/include/asm-powerpc/iseries/hv_call_xm.h
+++ b/include/asm-powerpc/iseries/hv_call_xm.h
@@ -16,23 +16,6 @@
16#define HvCallXmSetTce HvCallXm + 11 16#define HvCallXmSetTce HvCallXm + 11
17#define HvCallXmSetTces HvCallXm + 13 17#define HvCallXmSetTces HvCallXm + 13
18 18
19/*
20 * Structure passed to HvCallXm_getTceTableParms
21 */
22struct iommu_table_cb {
23 unsigned long itc_busno; /* Bus number for this tce table */
24 unsigned long itc_start; /* Will be NULL for secondary */
25 unsigned long itc_totalsize; /* Size (in pages) of whole table */
26 unsigned long itc_offset; /* Index into real tce table of the
27 start of our section */
28 unsigned long itc_size; /* Size (in pages) of our section */
29 unsigned long itc_index; /* Index of this tce table */
30 unsigned short itc_maxtables; /* Max num of tables for partition */
31 unsigned char itc_virtbus; /* Flag to indicate virtual bus */
32 unsigned char itc_slotno; /* IOA Tce Slot Index */
33 unsigned char itc_rsvd[4];
34};
35
36static inline void HvCallXm_getTceTableParms(u64 cb) 19static inline void HvCallXm_getTceTableParms(u64 cb)
37{ 20{
38 HvCall1(HvCallXmGetTceTableParms, cb); 21 HvCall1(HvCallXmGetTceTableParms, cb);
diff --git a/include/asm-powerpc/iseries/hv_lp_config.h b/include/asm-powerpc/iseries/hv_lp_config.h
index df8b20739719..a006fd1e4a2c 100644
--- a/include/asm-powerpc/iseries/hv_lp_config.h
+++ b/include/asm-powerpc/iseries/hv_lp_config.h
@@ -25,7 +25,6 @@
25 25
26#include <asm/iseries/hv_call_sc.h> 26#include <asm/iseries/hv_call_sc.h>
27#include <asm/iseries/hv_types.h> 27#include <asm/iseries/hv_types.h>
28#include <asm/iseries/it_lp_naca.h>
29 28
30enum { 29enum {
31 HvCallCfg_Cur = 0, 30 HvCallCfg_Cur = 0,
@@ -44,16 +43,8 @@ enum {
44#define HvCallCfgGetHostingLpIndex HvCallCfg + 32 43#define HvCallCfgGetHostingLpIndex HvCallCfg + 32
45 44
46extern HvLpIndex HvLpConfig_getLpIndex_outline(void); 45extern HvLpIndex HvLpConfig_getLpIndex_outline(void);
47 46extern HvLpIndex HvLpConfig_getLpIndex(void);
48static inline HvLpIndex HvLpConfig_getLpIndex(void) 47extern HvLpIndex HvLpConfig_getPrimaryLpIndex(void);
49{
50 return itLpNaca.xLpIndex;
51}
52
53static inline HvLpIndex HvLpConfig_getPrimaryLpIndex(void)
54{
55 return itLpNaca.xPrimaryLpIndex;
56}
57 48
58static inline u64 HvLpConfig_getMsChunks(void) 49static inline u64 HvLpConfig_getMsChunks(void)
59{ 50{
diff --git a/include/asm-powerpc/iseries/iseries_io.h b/include/asm-powerpc/iseries/iseries_io.h
deleted file mode 100644
index f29009bd63c9..000000000000
--- a/include/asm-powerpc/iseries/iseries_io.h
+++ /dev/null
@@ -1,60 +0,0 @@
1#ifndef _ASM_POWERPC_ISERIES_ISERIES_IO_H
2#define _ASM_POWERPC_ISERIES_ISERIES_IO_H
3
4
5#ifdef CONFIG_PPC_ISERIES
6#include <linux/types.h>
7/*
8 * Created by Allan Trautman on Thu Dec 28 2000.
9 *
10 * Remaps the io.h for the iSeries Io
11 * Copyright (C) 2000 Allan H Trautman, IBM Corporation
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the:
25 * Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330,
27 * Boston, MA 02111-1307 USA
28 *
29 * Change Activity:
30 * Created December 28, 2000
31 * End Change Activity
32 */
33
34#ifdef CONFIG_PCI
35extern u8 iSeries_Read_Byte(const volatile void __iomem * IoAddress);
36extern u16 iSeries_Read_Word(const volatile void __iomem * IoAddress);
37extern u32 iSeries_Read_Long(const volatile void __iomem * IoAddress);
38extern void iSeries_Write_Byte(u8 IoData, volatile void __iomem * IoAddress);
39extern void iSeries_Write_Word(u16 IoData, volatile void __iomem * IoAddress);
40extern void iSeries_Write_Long(u32 IoData, volatile void __iomem * IoAddress);
41
42extern void iSeries_memset_io(volatile void __iomem *dest, char x, size_t n);
43extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source,
44 size_t n);
45extern void iSeries_memcpy_fromio(void *dest,
46 const volatile void __iomem *source, size_t n);
47#else
48static inline u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
49{
50 return 0xff;
51}
52
53static inline void iSeries_Write_Byte(u8 IoData,
54 volatile void __iomem *IoAddress)
55{
56}
57#endif /* CONFIG_PCI */
58
59#endif /* CONFIG_PPC_ISERIES */
60#endif /* _ASM_POWERPC_ISERIES_ISERIES_IO_H */
diff --git a/include/asm-powerpc/iseries/it_lp_queue.h b/include/asm-powerpc/iseries/it_lp_queue.h
index 284c5a7db3ac..3f6814769295 100644
--- a/include/asm-powerpc/iseries/it_lp_queue.h
+++ b/include/asm-powerpc/iseries/it_lp_queue.h
@@ -27,8 +27,6 @@
27#include <asm/types.h> 27#include <asm/types.h>
28#include <asm/ptrace.h> 28#include <asm/ptrace.h>
29 29
30struct HvLpEvent;
31
32#define IT_LP_MAX_QUEUES 8 30#define IT_LP_MAX_QUEUES 8
33 31
34#define IT_LP_NOT_USED 0 /* Queue will not be used by PLIC */ 32#define IT_LP_NOT_USED 0 /* Queue will not be used by PLIC */
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 72a97d37aac3..7a95d296abd1 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -122,6 +122,34 @@ enum viorc {
122 viorc_openRejected = 0x0301 122 viorc_openRejected = 0x0301
123}; 123};
124 124
125/*
126 * The structure of the events that flow between us and OS/400 for chario
127 * events. You can't mess with this unless the OS/400 side changes too.
128 */
129struct viocharlpevent {
130 struct HvLpEvent event;
131 u32 reserved;
132 u16 version;
133 u16 subtype_result_code;
134 u8 virtual_device;
135 u8 len;
136 u8 data[VIOCHAR_MAX_DATA];
137};
138
139#define VIOCHAR_WINDOW 10
140
141enum viocharsubtype {
142 viocharopen = 0x0001,
143 viocharclose = 0x0002,
144 viochardata = 0x0003,
145 viocharack = 0x0004,
146 viocharconfig = 0x0005
147};
148
149enum viochar_rc {
150 viochar_rc_ebusy = 1
151};
152
125struct device; 153struct device;
126 154
127extern struct device *iSeries_vio_dev; 155extern struct device *iSeries_vio_dev;
diff --git a/include/asm-powerpc/lppaca.h b/include/asm-powerpc/lppaca.h
index 4dc514aabfe7..821ea0c512b4 100644
--- a/include/asm-powerpc/lppaca.h
+++ b/include/asm-powerpc/lppaca.h
@@ -27,7 +27,9 @@
27// 27//
28// 28//
29//---------------------------------------------------------------------------- 29//----------------------------------------------------------------------------
30#include <linux/cache.h>
30#include <asm/types.h> 31#include <asm/types.h>
32#include <asm/mmu.h>
31 33
32/* The Hypervisor barfs if the lppaca crosses a page boundary. A 1k 34/* The Hypervisor barfs if the lppaca crosses a page boundary. A 1k
33 * alignment is sufficient to prevent this */ 35 * alignment is sufficient to prevent this */
@@ -114,7 +116,7 @@ struct lppaca {
114 116
115 117
116//============================================================================= 118//=============================================================================
117// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors 119// CACHE_LINE_3 0x0100 - 0x017F: This line is shared with other processors
118//============================================================================= 120//=============================================================================
119 // This is the yield_count. An "odd" value (low bit on) means that 121 // This is the yield_count. An "odd" value (low bit on) means that
120 // the processor is yielded (either because of an OS yield or a PLIC 122 // the processor is yielded (either because of an OS yield or a PLIC
@@ -126,12 +128,29 @@ struct lppaca {
126 u8 reserved6[124]; // Reserved x04-x7F 128 u8 reserved6[124]; // Reserved x04-x7F
127 129
128//============================================================================= 130//=============================================================================
129// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data 131// CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data
130//============================================================================= 132//=============================================================================
131 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF 133 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF
132} __attribute__((__aligned__(0x400))); 134} __attribute__((__aligned__(0x400)));
133 135
134extern struct lppaca lppaca[]; 136extern struct lppaca lppaca[];
135 137
138/*
139 * SLB shadow buffer structure as defined in the PAPR. The save_area
140 * contains adjacent ESID and VSID pairs for each shadowed SLB. The
141 * ESID is stored in the lower 64bits, then the VSID.
142 */
143struct slb_shadow {
144 u32 persistent; // Number of persistent SLBs x00-x03
145 u32 buffer_length; // Total shadow buffer length x04-x07
146 u64 reserved; // Alignment x08-x0f
147 struct {
148 u64 esid;
149 u64 vsid;
150 } save_area[SLB_NUM_BOLTED]; // x10-x40
151} ____cacheline_aligned;
152
153extern struct slb_shadow slb_shadow[];
154
136#endif /* __KERNEL__ */ 155#endif /* __KERNEL__ */
137#endif /* _ASM_POWERPC_LPPACA_H */ 156#endif /* _ASM_POWERPC_LPPACA_H */
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index 3d5d590bc4b0..0a4e5c93e8e6 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -23,6 +23,7 @@
23register struct paca_struct *local_paca asm("r13"); 23register struct paca_struct *local_paca asm("r13");
24#define get_paca() local_paca 24#define get_paca() local_paca
25#define get_lppaca() (get_paca()->lppaca_ptr) 25#define get_lppaca() (get_paca()->lppaca_ptr)
26#define get_slb_shadow() (get_paca()->slb_shadow_ptr)
26 27
27struct task_struct; 28struct task_struct;
28 29
@@ -99,6 +100,8 @@ struct paca_struct {
99 u64 user_time; /* accumulated usermode TB ticks */ 100 u64 user_time; /* accumulated usermode TB ticks */
100 u64 system_time; /* accumulated system TB ticks */ 101 u64 system_time; /* accumulated system TB ticks */
101 u64 startpurr; /* PURR/TB value snapshot */ 102 u64 startpurr; /* PURR/TB value snapshot */
103
104 struct slb_shadow *slb_shadow_ptr;
102}; 105};
103 106
104extern struct paca_struct paca[]; 107extern struct paca_struct paca[];
diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
index fb597b37c2a2..b4d38b0b15f8 100644
--- a/include/asm-powerpc/page.h
+++ b/include/asm-powerpc/page.h
@@ -55,12 +55,6 @@
55#define PAGE_OFFSET ASM_CONST(CONFIG_KERNEL_START) 55#define PAGE_OFFSET ASM_CONST(CONFIG_KERNEL_START)
56#define KERNELBASE (PAGE_OFFSET + PHYSICAL_START) 56#define KERNELBASE (PAGE_OFFSET + PHYSICAL_START)
57 57
58#ifdef CONFIG_DISCONTIGMEM
59#define page_to_pfn(page) discontigmem_page_to_pfn(page)
60#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
61#define pfn_valid(pfn) discontigmem_pfn_valid(pfn)
62#endif
63
64#ifdef CONFIG_FLATMEM 58#ifdef CONFIG_FLATMEM
65#define pfn_valid(pfn) ((pfn) < max_mapnr) 59#define pfn_valid(pfn) ((pfn) < max_mapnr)
66#endif 60#endif
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index cf79bc7ebb55..1115756c79f9 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -69,6 +69,17 @@ struct pci_dev *pci_get_device_by_addr(unsigned long addr);
69void eeh_slot_error_detail (struct pci_dn *pdn, int severity); 69void eeh_slot_error_detail (struct pci_dn *pdn, int severity);
70 70
71/** 71/**
72 * rtas_pci_enableo - enable IO transfers for this slot
73 * @pdn: pci device node
74 * @function: either EEH_THAW_MMIO or EEH_THAW_DMA
75 *
76 * Enable I/O transfers to this slot
77 */
78#define EEH_THAW_MMIO 2
79#define EEH_THAW_DMA 3
80int rtas_pci_enable(struct pci_dn *pdn, int function);
81
82/**
72 * rtas_set_slot_reset -- unfreeze a frozen slot 83 * rtas_set_slot_reset -- unfreeze a frozen slot
73 * 84 *
74 * Clear the EEH-frozen condition on a slot. This routine 85 * Clear the EEH-frozen condition on a slot. This routine
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index 22e54a2a6604..6cb6fb19e57f 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -32,6 +32,7 @@
32#define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ 32#define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */
33#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ 33#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */
34#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ 34#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */
35#define _CHRP_briq 0x07 /* TotalImpact's briQ */
35 36
36#if defined(__KERNEL__) && defined(CONFIG_PPC32) 37#if defined(__KERNEL__) && defined(CONFIG_PPC32)
37 38
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index d0fa1b9aed35..524629769336 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -72,8 +72,8 @@ struct property {
72}; 72};
73 73
74struct device_node { 74struct device_node {
75 char *name; 75 const char *name;
76 char *type; 76 const char *type;
77 phandle node; 77 phandle node;
78 phandle linux_phandle; 78 phandle linux_phandle;
79 char *full_name; 79 char *full_name;
@@ -160,7 +160,7 @@ extern void unflatten_device_tree(void);
160extern void early_init_devtree(void *); 160extern void early_init_devtree(void *);
161extern int device_is_compatible(struct device_node *device, const char *); 161extern int device_is_compatible(struct device_node *device, const char *);
162extern int machine_is_compatible(const char *compat); 162extern int machine_is_compatible(const char *compat);
163extern void *get_property(struct device_node *node, const char *name, 163extern const void *get_property(struct device_node *node, const char *name,
164 int *lenp); 164 int *lenp);
165extern void print_properties(struct device_node *node); 165extern void print_properties(struct device_node *node);
166extern int prom_n_addr_cells(struct device_node* np); 166extern int prom_n_addr_cells(struct device_node* np);
@@ -197,8 +197,8 @@ extern int release_OF_resource(struct device_node* node, int index);
197 */ 197 */
198 198
199 199
200/* Helper to read a big number */ 200/* Helper to read a big number; size is in cells (not bytes) */
201static inline u64 of_read_number(u32 *cell, int size) 201static inline u64 of_read_number(const u32 *cell, int size)
202{ 202{
203 u64 r = 0; 203 u64 r = 0;
204 while (size--) 204 while (size--)
@@ -206,18 +206,28 @@ static inline u64 of_read_number(u32 *cell, int size)
206 return r; 206 return r;
207} 207}
208 208
209/* Like of_read_number, but we want an unsigned long result */
210#ifdef CONFIG_PPC32
211static inline unsigned long of_read_ulong(const u32 *cell, int size)
212{
213 return cell[size-1];
214}
215#else
216#define of_read_ulong(cell, size) of_read_number(cell, size)
217#endif
218
209/* Translate an OF address block into a CPU physical address 219/* Translate an OF address block into a CPU physical address
210 */ 220 */
211#define OF_BAD_ADDR ((u64)-1) 221#define OF_BAD_ADDR ((u64)-1)
212extern u64 of_translate_address(struct device_node *np, u32 *addr); 222extern u64 of_translate_address(struct device_node *np, const u32 *addr);
213 223
214/* Extract an address from a device, returns the region size and 224/* Extract an address from a device, returns the region size and
215 * the address space flags too. The PCI version uses a BAR number 225 * the address space flags too. The PCI version uses a BAR number
216 * instead of an absolute index 226 * instead of an absolute index
217 */ 227 */
218extern u32 *of_get_address(struct device_node *dev, int index, 228extern const u32 *of_get_address(struct device_node *dev, int index,
219 u64 *size, unsigned int *flags); 229 u64 *size, unsigned int *flags);
220extern u32 *of_get_pci_address(struct device_node *dev, int bar_no, 230extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
221 u64 *size, unsigned int *flags); 231 u64 *size, unsigned int *flags);
222 232
223/* Get an address as a resource. Note that if your address is 233/* Get an address as a resource. Note that if your address is
@@ -234,7 +244,7 @@ extern int of_pci_address_to_resource(struct device_node *dev, int bar,
234/* Parse the ibm,dma-window property of an OF node into the busno, phys and 244/* Parse the ibm,dma-window property of an OF node into the busno, phys and
235 * size parameters. 245 * size parameters.
236 */ 246 */
237void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop, 247void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
238 unsigned long *busno, unsigned long *phys, unsigned long *size); 248 unsigned long *busno, unsigned long *phys, unsigned long *size);
239 249
240extern void kdump_move_device_tree(void); 250extern void kdump_move_device_tree(void);
@@ -259,7 +269,7 @@ struct of_irq {
259 u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ 269 u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
260}; 270};
261 271
262/*** 272/**
263 * of_irq_map_init - Initialize the irq remapper 273 * of_irq_map_init - Initialize the irq remapper
264 * @flags: flags defining workarounds to enable 274 * @flags: flags defining workarounds to enable
265 * 275 *
@@ -272,7 +282,7 @@ struct of_irq {
272 282
273extern void of_irq_map_init(unsigned int flags); 283extern void of_irq_map_init(unsigned int flags);
274 284
275/*** 285/**
276 * of_irq_map_raw - Low level interrupt tree parsing 286 * of_irq_map_raw - Low level interrupt tree parsing
277 * @parent: the device interrupt parent 287 * @parent: the device interrupt parent
278 * @intspec: interrupt specifier ("interrupts" property of the device) 288 * @intspec: interrupt specifier ("interrupts" property of the device)
@@ -289,12 +299,12 @@ extern void of_irq_map_init(unsigned int flags);
289 * 299 *
290 */ 300 */
291 301
292extern int of_irq_map_raw(struct device_node *parent, u32 *intspec, 302extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
293 u32 ointsize, u32 *addr, 303 u32 ointsize, const u32 *addr,
294 struct of_irq *out_irq); 304 struct of_irq *out_irq);
295 305
296 306
297/*** 307/**
298 * of_irq_map_one - Resolve an interrupt for a device 308 * of_irq_map_one - Resolve an interrupt for a device
299 * @device: the device whose interrupt is to be resolved 309 * @device: the device whose interrupt is to be resolved
300 * @index: index of the interrupt to resolve 310 * @index: index of the interrupt to resolve
@@ -307,7 +317,7 @@ extern int of_irq_map_raw(struct device_node *parent, u32 *intspec,
307extern int of_irq_map_one(struct device_node *device, int index, 317extern int of_irq_map_one(struct device_node *device, int index,
308 struct of_irq *out_irq); 318 struct of_irq *out_irq);
309 319
310/*** 320/**
311 * of_irq_map_pci - Resolve the interrupt for a PCI device 321 * of_irq_map_pci - Resolve the interrupt for a PCI device
312 * @pdev: the device whose interrupt is to be resolved 322 * @pdev: the device whose interrupt is to be resolved
313 * @out_irq: structure of_irq filled by this function 323 * @out_irq: structure of_irq filled by this function
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index dc4cb9cc73a1..4435efe85d0e 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -215,12 +215,10 @@ do { \
215#define PTRACE_GETVRREGS 18 215#define PTRACE_GETVRREGS 18
216#define PTRACE_SETVRREGS 19 216#define PTRACE_SETVRREGS 19
217 217
218#ifndef __powerpc64__
219/* Get/set all the upper 32-bits of the SPE registers, accumulator, and 218/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
220 * spefscr, in one go */ 219 * spefscr, in one go */
221#define PTRACE_GETEVRREGS 20 220#define PTRACE_GETEVRREGS 20
222#define PTRACE_SETEVRREGS 21 221#define PTRACE_SETEVRREGS 21
223#endif /* __powerpc64__ */
224 222
225/* 223/*
226 * Get or set a debug register. The first 16 are DABR registers and the 224 * Get or set a debug register. The first 16 are DABR registers and the
@@ -235,7 +233,6 @@ do { \
235#define PPC_PTRACE_GETFPREGS 0x97 /* Get FPRs 0 - 31 */ 233#define PPC_PTRACE_GETFPREGS 0x97 /* Get FPRs 0 - 31 */
236#define PPC_PTRACE_SETFPREGS 0x96 /* Set FPRs 0 - 31 */ 234#define PPC_PTRACE_SETFPREGS 0x96 /* Set FPRs 0 - 31 */
237 235
238#ifdef __powerpc64__
239/* Calls to trace a 64bit program from a 32bit program */ 236/* Calls to trace a 64bit program from a 32bit program */
240#define PPC_PTRACE_PEEKTEXT_3264 0x95 237#define PPC_PTRACE_PEEKTEXT_3264 0x95
241#define PPC_PTRACE_PEEKDATA_3264 0x94 238#define PPC_PTRACE_PEEKDATA_3264 0x94
@@ -243,6 +240,5 @@ do { \
243#define PPC_PTRACE_POKEDATA_3264 0x92 240#define PPC_PTRACE_POKEDATA_3264 0x92
244#define PPC_PTRACE_PEEKUSR_3264 0x91 241#define PPC_PTRACE_PEEKUSR_3264 0x91
245#define PPC_PTRACE_POKEUSR_3264 0x90 242#define PPC_PTRACE_POKEUSR_3264 0x90
246#endif /* __powerpc64__ */
247 243
248#endif /* _ASM_POWERPC_PTRACE_H */ 244#endif /* _ASM_POWERPC_PTRACE_H */
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index cf73475a0c69..3a9fcc15811b 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -592,6 +592,7 @@
592#define PV_630p 0x0041 592#define PV_630p 0x0041
593#define PV_970MP 0x0044 593#define PV_970MP 0x0044
594#define PV_BE 0x0070 594#define PV_BE 0x0070
595#define PV_PA6T 0x0090
595 596
596/* 597/*
597 * Number of entries in the SLB. If this ever changes we should handle 598 * Number of entries in the SLB. If this ever changes we should handle
diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h
index 82a27e9a041f..d34f9e1f242c 100644
--- a/include/asm-powerpc/rtas.h
+++ b/include/asm-powerpc/rtas.h
@@ -230,5 +230,21 @@ extern unsigned long rtas_rmo_buf;
230 230
231#define GLOBAL_INTERRUPT_QUEUE 9005 231#define GLOBAL_INTERRUPT_QUEUE 9005
232 232
233/**
234 * rtas_config_addr - Format a busno, devfn and reg for RTAS.
235 * @busno: The bus number.
236 * @devfn: The device and function number as encoded by PCI_DEVFN().
237 * @reg: The register number.
238 *
239 * This function encodes the given busno, devfn and register number as
240 * required for RTAS calls that take a "config_addr" parameter.
241 * See PAPR requirement 7.3.4-1 for more info.
242 */
243static inline u32 rtas_config_addr(int busno, int devfn, int reg)
244{
245 return ((reg & 0xf00) << 20) | ((busno & 0xff) << 16) |
246 (devfn << 8) | (reg & 0xff);
247}
248
233#endif /* __KERNEL__ */ 249#endif /* __KERNEL__ */
234#endif /* _POWERPC_RTAS_H */ 250#endif /* _POWERPC_RTAS_H */
diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h
index 51e65fc46a03..e49f644ca63a 100644
--- a/include/asm-powerpc/smu.h
+++ b/include/asm-powerpc/smu.h
@@ -517,7 +517,7 @@ struct smu_sdbp_cpupiddata {
517 * This returns the pointer to an SMU "sdb" partition data or NULL 517 * This returns the pointer to an SMU "sdb" partition data or NULL
518 * if not found. The data format is described below 518 * if not found. The data format is described below
519 */ 519 */
520extern struct smu_sdbp_header *smu_get_sdb_partition(int id, 520extern const struct smu_sdbp_header *smu_get_sdb_partition(int id,
521 unsigned int *size); 521 unsigned int *size);
522 522
523/* Get "sdb" partition data from an SMU satellite */ 523/* Get "sdb" partition data from an SMU satellite */
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index c02d105d8294..b42b53c40f5d 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -106,7 +106,7 @@ struct spu_context;
106struct spu_runqueue; 106struct spu_runqueue;
107 107
108struct spu { 108struct spu {
109 char *name; 109 const char *name;
110 unsigned long local_store_phys; 110 unsigned long local_store_phys;
111 u8 *local_store; 111 u8 *local_store;
112 unsigned long problem_phys; 112 unsigned long problem_phys;
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 4c9f5229e833..4b41deaa8d8d 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -177,11 +177,6 @@ extern u32 booke_wdt_enabled;
177extern u32 booke_wdt_period; 177extern u32 booke_wdt_period;
178#endif /* CONFIG_BOOKE_WDT */ 178#endif /* CONFIG_BOOKE_WDT */
179 179
180/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
181extern unsigned char e2a(unsigned char);
182extern unsigned char* strne2a(unsigned char *dest,
183 const unsigned char *src, size_t n);
184
185struct device_node; 180struct device_node;
186extern void note_scsi_host(struct device_node *, void *); 181extern void note_scsi_host(struct device_node *, void *);
187 182
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index dc9bd101ca14..4b51d42e1419 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -46,8 +46,8 @@ struct iommu_table;
46 */ 46 */
47struct vio_dev { 47struct vio_dev {
48 struct iommu_table *iommu_table; /* vio_map_* uses this */ 48 struct iommu_table *iommu_table; /* vio_map_* uses this */
49 char *name; 49 const char *name;
50 char *type; 50 const char *type;
51 uint32_t unit_address; 51 uint32_t unit_address;
52 unsigned int irq; 52 unsigned int irq;
53 struct device dev; 53 struct device dev;
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 680555be22ec..3d9a9e6f3321 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -327,26 +327,12 @@ __do_out_asm(outl, "stwbrx")
327#define inl_p(port) inl((port)) 327#define inl_p(port) inl((port))
328#define outl_p(val, port) outl((val), (port)) 328#define outl_p(val, port) outl((val), (port))
329 329
330extern void _insb(volatile u8 __iomem *port, void *buf, int ns); 330extern void _insb(volatile u8 __iomem *port, void *buf, long count);
331extern void _outsb(volatile u8 __iomem *port, const void *buf, int ns); 331extern void _outsb(volatile u8 __iomem *port, const void *buf, long count);
332extern void _insw(volatile u16 __iomem *port, void *buf, int ns); 332extern void _insw_ns(volatile u16 __iomem *port, void *buf, long count);
333extern void _outsw(volatile u16 __iomem *port, const void *buf, int ns); 333extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count);
334extern void _insl(volatile u32 __iomem *port, void *buf, int nl); 334extern void _insl_ns(volatile u32 __iomem *port, void *buf, long count);
335extern void _outsl(volatile u32 __iomem *port, const void *buf, int nl); 335extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count);
336extern void _insw_ns(volatile u16 __iomem *port, void *buf, int ns);
337extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, int ns);
338extern void _insl_ns(volatile u32 __iomem *port, void *buf, int nl);
339extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, int nl);
340
341/*
342 * The *_ns versions below don't do byte-swapping.
343 * Neither do the standard versions now, these are just here
344 * for older code.
345 */
346#define insw_ns(port, buf, ns) _insw_ns((port)+___IO_BASE, (buf), (ns))
347#define outsw_ns(port, buf, ns) _outsw_ns((port)+___IO_BASE, (buf), (ns))
348#define insl_ns(port, buf, nl) _insl_ns((port)+___IO_BASE, (buf), (nl))
349#define outsl_ns(port, buf, nl) _outsl_ns((port)+___IO_BASE, (buf), (nl))
350 336
351 337
352#define IO_SPACE_LIMIT ~0 338#define IO_SPACE_LIMIT ~0
diff --git a/include/asm-ppc/mpc8260_pci9.h b/include/asm-ppc/mpc8260_pci9.h
index 26b3f6e787bc..9f7176881c56 100644
--- a/include/asm-ppc/mpc8260_pci9.h
+++ b/include/asm-ppc/mpc8260_pci9.h
@@ -30,8 +30,6 @@
30#undef inb 30#undef inb
31#undef inw 31#undef inw
32#undef inl 32#undef inl
33#undef insw_ns
34#undef insl_ns
35#undef memcpy_fromio 33#undef memcpy_fromio
36 34
37extern int readb(volatile unsigned char *addr); 35extern int readb(volatile unsigned char *addr);
@@ -43,8 +41,6 @@ extern void insl(unsigned port, void *buf, int nl);
43extern int inb(unsigned port); 41extern int inb(unsigned port);
44extern int inw(unsigned port); 42extern int inw(unsigned port);
45extern unsigned inl(unsigned port); 43extern unsigned inl(unsigned port);
46extern void insw_ns(unsigned port, void *buf, int ns);
47extern void insl_ns(unsigned port, void *buf, int nl);
48extern void *memcpy_fromio(void *dest, unsigned long src, size_t count); 44extern void *memcpy_fromio(void *dest, unsigned long src, size_t count);
49 45
50#endif /* !__CONFIG_8260_PCI9_DEFS */ 46#endif /* !__CONFIG_8260_PCI9_DEFS */
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h
index 4944c0fb8bea..602fbadeaf48 100644
--- a/include/asm-ppc/reg_booke.h
+++ b/include/asm-ppc/reg_booke.h
@@ -300,14 +300,14 @@ do { \
300#define DBSR_IC 0x80000000 /* Instruction Completion */ 300#define DBSR_IC 0x80000000 /* Instruction Completion */
301#define DBSR_BT 0x40000000 /* Branch taken */ 301#define DBSR_BT 0x40000000 /* Branch taken */
302#define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */ 302#define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */
303#define DBSR_IAC1 0x00800000 /* Instruction Address Compare 1 Event */ 303#define DBSR_IAC1 0x04000000 /* Instruction Address Compare 1 Event */
304#define DBSR_IAC2 0x00400000 /* Instruction Address Compare 2 Event */ 304#define DBSR_IAC2 0x02000000 /* Instruction Address Compare 2 Event */
305#define DBSR_IAC3 0x00200000 /* Instruction Address Compare 3 Event */ 305#define DBSR_IAC3 0x00080000 /* Instruction Address Compare 3 Event */
306#define DBSR_IAC4 0x00100000 /* Instruction Address Compare 4 Event */ 306#define DBSR_IAC4 0x00040000 /* Instruction Address Compare 4 Event */
307#define DBSR_DAC1R 0x00080000 /* Data Address Compare 1 Read Event */ 307#define DBSR_DAC1R 0x01000000 /* Data Address Compare 1 Read Event */
308#define DBSR_DAC1W 0x00040000 /* Data Address Compare 1 Write Event */ 308#define DBSR_DAC1W 0x00800000 /* Data Address Compare 1 Write Event */
309#define DBSR_DAC2R 0x00020000 /* Data Address Compare 2 Read Event */ 309#define DBSR_DAC2R 0x00400000 /* Data Address Compare 2 Read Event */
310#define DBSR_DAC2W 0x00010000 /* Data Address Compare 2 Write Event */ 310#define DBSR_DAC2W 0x00200000 /* Data Address Compare 2 Write Event */
311#endif 311#endif
312 312
313/* Bit definitions related to the ESR. */ 313/* Bit definitions related to the ESR. */
diff --git a/include/asm-s390/Kbuild b/include/asm-s390/Kbuild
index ed8955f49e47..088969d55e72 100644
--- a/include/asm-s390/Kbuild
+++ b/include/asm-s390/Kbuild
@@ -1,4 +1,12 @@
1include include/asm-generic/Kbuild.asm 1include include/asm-generic/Kbuild.asm
2 2
3unifdef-y += cmb.h debug.h 3header-y += dasd.h
4header-y += dasd.h qeth.h tape390.h ucontext.h vtoc.h z90crypt.h 4header-y += monwriter.h
5header-y += qeth.h
6header-y += tape390.h
7header-y += ucontext.h
8header-y += vtoc.h
9header-y += z90crypt.h
10
11unifdef-y += cmb.h
12unifdef-y += debug.h
diff --git a/include/asm-s390/appldata.h b/include/asm-s390/appldata.h
new file mode 100644
index 000000000000..b1770703b706
--- /dev/null
+++ b/include/asm-s390/appldata.h
@@ -0,0 +1,90 @@
1/*
2 * include/asm-s390/appldata.h
3 *
4 * Copyright (C) IBM Corp. 2006
5 *
6 * Author(s): Melissa Howland <melissah@us.ibm.com>
7 */
8
9#ifndef _ASM_S390_APPLDATA_H
10#define _ASM_S390_APPLDATA_H
11
12#include <asm/io.h>
13
14#ifndef CONFIG_64BIT
15
16#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */
17#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */
18#define APPLDATA_GEN_EVENT_REC 0x02
19#define APPLDATA_START_CONFIG_REC 0x03
20
21/*
22 * Parameter list for DIAGNOSE X'DC'
23 */
24struct appldata_parameter_list {
25 u16 diag; /* The DIAGNOSE code X'00DC' */
26 u8 function; /* The function code for the DIAGNOSE */
27 u8 parlist_length; /* Length of the parameter list */
28 u32 product_id_addr; /* Address of the 16-byte product ID */
29 u16 reserved;
30 u16 buffer_length; /* Length of the application data buffer */
31 u32 buffer_addr; /* Address of the application data buffer */
32} __attribute__ ((packed));
33
34#else /* CONFIG_64BIT */
35
36#define APPLDATA_START_INTERVAL_REC 0x80
37#define APPLDATA_STOP_REC 0x81
38#define APPLDATA_GEN_EVENT_REC 0x82
39#define APPLDATA_START_CONFIG_REC 0x83
40
41/*
42 * Parameter list for DIAGNOSE X'DC'
43 */
44struct appldata_parameter_list {
45 u16 diag;
46 u8 function;
47 u8 parlist_length;
48 u32 unused01;
49 u16 reserved;
50 u16 buffer_length;
51 u32 unused02;
52 u64 product_id_addr;
53 u64 buffer_addr;
54} __attribute__ ((packed));
55
56#endif /* CONFIG_64BIT */
57
58struct appldata_product_id {
59 char prod_nr[7]; /* product number */
60 u16 prod_fn; /* product function */
61 u8 record_nr; /* record number */
62 u16 version_nr; /* version */
63 u16 release_nr; /* release */
64 u16 mod_lvl; /* modification level */
65} __attribute__ ((packed));
66
67static inline int appldata_asm(struct appldata_product_id *id,
68 unsigned short fn, void *buffer,
69 unsigned short length)
70{
71 struct appldata_parameter_list parm_list;
72 int ry;
73
74 if (!MACHINE_IS_VM)
75 return -ENOSYS;
76 parm_list.diag = 0xdc;
77 parm_list.function = fn;
78 parm_list.parlist_length = sizeof(parm_list);
79 parm_list.buffer_length = length;
80 parm_list.product_id_addr = (unsigned long) id;
81 parm_list.buffer_addr = virt_to_phys(buffer);
82 asm volatile(
83 "diag %1,%0,0xdc"
84 : "=d" (ry)
85 : "d" (&parm_list), "m" (parm_list), "m" (*id)
86 : "cc");
87 return ry;
88}
89
90#endif /* _ASM_S390_APPLDATA_H */
diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h
index 28fdd6e2b8ba..da063cd5f0a0 100644
--- a/include/asm-s390/cio.h
+++ b/include/asm-s390/cio.h
@@ -270,6 +270,11 @@ struct diag210 {
270 __u32 vrdccrft : 8; /* real device feature (output) */ 270 __u32 vrdccrft : 8; /* real device feature (output) */
271} __attribute__ ((packed,aligned(4))); 271} __attribute__ ((packed,aligned(4)));
272 272
273struct ccw_dev_id {
274 u8 ssid;
275 u16 devno;
276};
277
273extern int diag210(struct diag210 *addr); 278extern int diag210(struct diag210 *addr);
274 279
275extern void wait_cons_dev(void); 280extern void wait_cons_dev(void);
@@ -280,6 +285,8 @@ extern void cio_reset_channel_paths(void);
280 285
281extern void css_schedule_reprobe(void); 286extern void css_schedule_reprobe(void);
282 287
288extern void reipl_ccw_dev(struct ccw_dev_id *id);
289
283#endif 290#endif
284 291
285#endif 292#endif
diff --git a/include/asm-s390/dma.h b/include/asm-s390/dma.h
index 02720c449cd8..7425c6af6cd4 100644
--- a/include/asm-s390/dma.h
+++ b/include/asm-s390/dma.h
@@ -11,6 +11,6 @@
11 11
12#define MAX_DMA_ADDRESS 0x80000000 12#define MAX_DMA_ADDRESS 0x80000000
13 13
14#define free_dma(x) 14#define free_dma(x) do { } while (0)
15 15
16#endif /* _ASM_DMA_H */ 16#endif /* _ASM_DMA_H */
diff --git a/include/asm-s390/futex.h b/include/asm-s390/futex.h
index ffedf14f89f6..5e261e1de671 100644
--- a/include/asm-s390/futex.h
+++ b/include/asm-s390/futex.h
@@ -7,75 +7,21 @@
7#include <asm/errno.h> 7#include <asm/errno.h>
8#include <asm/uaccess.h> 8#include <asm/uaccess.h>
9 9
10#ifndef __s390x__
11#define __futex_atomic_fixup \
12 ".section __ex_table,\"a\"\n" \
13 " .align 4\n" \
14 " .long 0b,4b,2b,4b,3b,4b\n" \
15 ".previous"
16#else /* __s390x__ */
17#define __futex_atomic_fixup \
18 ".section __ex_table,\"a\"\n" \
19 " .align 8\n" \
20 " .quad 0b,4b,2b,4b,3b,4b\n" \
21 ".previous"
22#endif /* __s390x__ */
23
24#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \
25 asm volatile(" sacf 256\n" \
26 "0: l %1,0(%6)\n" \
27 "1: " insn \
28 "2: cs %1,%2,0(%6)\n" \
29 "3: jl 1b\n" \
30 " lhi %0,0\n" \
31 "4: sacf 0\n" \
32 __futex_atomic_fixup \
33 : "=d" (ret), "=&d" (oldval), "=&d" (newval), \
34 "=m" (*uaddr) \
35 : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
36 "m" (*uaddr) : "cc" );
37
38static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) 10static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
39{ 11{
40 int op = (encoded_op >> 28) & 7; 12 int op = (encoded_op >> 28) & 7;
41 int cmp = (encoded_op >> 24) & 15; 13 int cmp = (encoded_op >> 24) & 15;
42 int oparg = (encoded_op << 8) >> 20; 14 int oparg = (encoded_op << 8) >> 20;
43 int cmparg = (encoded_op << 20) >> 20; 15 int cmparg = (encoded_op << 20) >> 20;
44 int oldval = 0, newval, ret; 16 int oldval, ret;
17
45 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) 18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
46 oparg = 1 << oparg; 19 oparg = 1 << oparg;
47 20
48 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) 21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
49 return -EFAULT; 22 return -EFAULT;
50 23
51 inc_preempt_count(); 24 ret = uaccess.futex_atomic_op(op, uaddr, oparg, &oldval);
52
53 switch (op) {
54 case FUTEX_OP_SET:
55 __futex_atomic_op("lr %2,%5\n",
56 ret, oldval, newval, uaddr, oparg);
57 break;
58 case FUTEX_OP_ADD:
59 __futex_atomic_op("lr %2,%1\nar %2,%5\n",
60 ret, oldval, newval, uaddr, oparg);
61 break;
62 case FUTEX_OP_OR:
63 __futex_atomic_op("lr %2,%1\nor %2,%5\n",
64 ret, oldval, newval, uaddr, oparg);
65 break;
66 case FUTEX_OP_ANDN:
67 __futex_atomic_op("lr %2,%1\nnr %2,%5\n",
68 ret, oldval, newval, uaddr, oparg);
69 break;
70 case FUTEX_OP_XOR:
71 __futex_atomic_op("lr %2,%1\nxr %2,%5\n",
72 ret, oldval, newval, uaddr, oparg);
73 break;
74 default:
75 ret = -ENOSYS;
76 }
77
78 dec_preempt_count();
79 25
80 if (!ret) { 26 if (!ret) {
81 switch (cmp) { 27 switch (cmp) {
@@ -91,32 +37,13 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
91 return ret; 37 return ret;
92} 38}
93 39
94static inline int 40static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr,
95futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) 41 int oldval, int newval)
96{ 42{
97 int ret;
98
99 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) 43 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
100 return -EFAULT; 44 return -EFAULT;
101 asm volatile(" sacf 256\n" 45
102 " cs %1,%4,0(%5)\n" 46 return uaccess.futex_atomic_cmpxchg(uaddr, oldval, newval);
103 "0: lr %0,%1\n"
104 "1: sacf 0\n"
105#ifndef __s390x__
106 ".section __ex_table,\"a\"\n"
107 " .align 4\n"
108 " .long 0b,1b\n"
109 ".previous"
110#else /* __s390x__ */
111 ".section __ex_table,\"a\"\n"
112 " .align 8\n"
113 " .quad 0b,1b\n"
114 ".previous"
115#endif /* __s390x__ */
116 : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
117 : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
118 : "cc", "memory" );
119 return oldval;
120} 47}
121 48
122#endif /* __KERNEL__ */ 49#endif /* __KERNEL__ */
diff --git a/include/asm-s390/io.h b/include/asm-s390/io.h
index d4614b35f423..a6cc27e77007 100644
--- a/include/asm-s390/io.h
+++ b/include/asm-s390/io.h
@@ -116,7 +116,7 @@ extern void iounmap(void *addr);
116#define outb(x,addr) ((void) writeb(x,addr)) 116#define outb(x,addr) ((void) writeb(x,addr))
117#define outb_p(x,addr) outb(x,addr) 117#define outb_p(x,addr) outb(x,addr)
118 118
119#define mmiowb() 119#define mmiowb() do { } while (0)
120 120
121/* 121/*
122 * Convert a physical pointer to a virtual kernel pointer for /dev/mem 122 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/include/asm-s390/kdebug.h b/include/asm-s390/kdebug.h
new file mode 100644
index 000000000000..40cc68025e01
--- /dev/null
+++ b/include/asm-s390/kdebug.h
@@ -0,0 +1,59 @@
1#ifndef _S390_KDEBUG_H
2#define _S390_KDEBUG_H
3
4/*
5 * Feb 2006 Ported to s390 <grundym@us.ibm.com>
6 */
7#include <linux/notifier.h>
8
9struct pt_regs;
10
11struct die_args {
12 struct pt_regs *regs;
13 const char *str;
14 long err;
15 int trapnr;
16 int signr;
17};
18
19/* Note - you should never unregister because that can race with NMIs.
20 * If you really want to do it first unregister - then synchronize_sched
21 * - then free.
22 */
23extern int register_die_notifier(struct notifier_block *);
24extern int unregister_die_notifier(struct notifier_block *);
25extern int register_page_fault_notifier(struct notifier_block *);
26extern int unregister_page_fault_notifier(struct notifier_block *);
27extern struct atomic_notifier_head s390die_chain;
28
29
30enum die_val {
31 DIE_OOPS = 1,
32 DIE_BPT,
33 DIE_SSTEP,
34 DIE_PANIC,
35 DIE_NMI,
36 DIE_DIE,
37 DIE_NMIWATCHDOG,
38 DIE_KERNELDEBUG,
39 DIE_TRAP,
40 DIE_GPF,
41 DIE_CALL,
42 DIE_NMI_IPI,
43 DIE_PAGE_FAULT,
44};
45
46static inline int notify_die(enum die_val val, const char *str,
47 struct pt_regs *regs, long err, int trap, int sig)
48{
49 struct die_args args = {
50 .regs = regs,
51 .str = str,
52 .err = err,
53 .trapnr = trap,
54 .signr = sig
55 };
56 return atomic_notifier_call_chain(&s390die_chain, val, &args);
57}
58
59#endif
diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h
new file mode 100644
index 000000000000..b847ff0ec3fa
--- /dev/null
+++ b/include/asm-s390/kprobes.h
@@ -0,0 +1,114 @@
1#ifndef _ASM_S390_KPROBES_H
2#define _ASM_S390_KPROBES_H
3/*
4 * Kernel Probes (KProbes)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 * Copyright (C) IBM Corporation, 2002, 2006
21 *
22 * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
23 * Probes initial implementation ( includes suggestions from
24 * Rusty Russell).
25 * 2004-Nov Modified for PPC64 by Ananth N Mavinakayanahalli
26 * <ananth@in.ibm.com>
27 * 2005-Dec Used as a template for s390 by Mike Grundy
28 * <grundym@us.ibm.com>
29 */
30#include <linux/types.h>
31#include <linux/ptrace.h>
32#include <linux/percpu.h>
33
34#define __ARCH_WANT_KPROBES_INSN_SLOT
35struct pt_regs;
36struct kprobe;
37
38typedef u16 kprobe_opcode_t;
39#define BREAKPOINT_INSTRUCTION 0x0002
40
41/* Maximum instruction size is 3 (16bit) halfwords: */
42#define MAX_INSN_SIZE 0x0003
43#define MAX_STACK_SIZE 64
44#define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \
45 (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) \
46 ? (MAX_STACK_SIZE) \
47 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
48
49#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)(pentry)
50
51#define ARCH_SUPPORTS_KRETPROBES
52#define ARCH_INACTIVE_KPROBE_COUNT 0
53
54#define KPROBE_SWAP_INST 0x10
55
56#define FIXUP_PSW_NORMAL 0x08
57#define FIXUP_BRANCH_NOT_TAKEN 0x04
58#define FIXUP_RETURN_REGISTER 0x02
59#define FIXUP_NOT_REQUIRED 0x01
60
61/* Architecture specific copy of original instruction */
62struct arch_specific_insn {
63 /* copy of original instruction */
64 kprobe_opcode_t *insn;
65 int fixup;
66 int ilen;
67 int reg;
68};
69
70struct ins_replace_args {
71 kprobe_opcode_t *ptr;
72 kprobe_opcode_t old;
73 kprobe_opcode_t new;
74};
75struct prev_kprobe {
76 struct kprobe *kp;
77 unsigned long status;
78 unsigned long saved_psw;
79 unsigned long kprobe_saved_imask;
80 unsigned long kprobe_saved_ctl[3];
81};
82
83/* per-cpu kprobe control block */
84struct kprobe_ctlblk {
85 unsigned long kprobe_status;
86 unsigned long kprobe_saved_imask;
87 unsigned long kprobe_saved_ctl[3];
88 struct pt_regs jprobe_saved_regs;
89 unsigned long jprobe_saved_r14;
90 unsigned long jprobe_saved_r15;
91 struct prev_kprobe prev_kprobe;
92 kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
93};
94
95void arch_remove_kprobe(struct kprobe *p);
96void kretprobe_trampoline(void);
97int is_prohibited_opcode(kprobe_opcode_t *instruction);
98void get_instruction_type(struct arch_specific_insn *ainsn);
99
100#define flush_insn_slot(p) do { } while (0)
101
102#endif /* _ASM_S390_KPROBES_H */
103
104#ifdef CONFIG_KPROBES
105
106extern int kprobe_exceptions_notify(struct notifier_block *self,
107 unsigned long val, void *data);
108#else /* !CONFIG_KPROBES */
109static inline int kprobe_exceptions_notify(struct notifier_block *self,
110 unsigned long val, void *data)
111{
112 return 0;
113}
114#endif
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index 596c8b172104..18695d10dedf 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -35,6 +35,7 @@
35#define __LC_IO_NEW_PSW 0x01f0 35#define __LC_IO_NEW_PSW 0x01f0
36#endif /* !__s390x__ */ 36#endif /* !__s390x__ */
37 37
38#define __LC_IPL_PARMBLOCK_PTR 0x014
38#define __LC_EXT_PARAMS 0x080 39#define __LC_EXT_PARAMS 0x080
39#define __LC_CPU_ADDRESS 0x084 40#define __LC_CPU_ADDRESS 0x084
40#define __LC_EXT_INT_CODE 0x086 41#define __LC_EXT_INT_CODE 0x086
@@ -47,6 +48,7 @@
47#define __LC_PER_ATMID 0x096 48#define __LC_PER_ATMID 0x096
48#define __LC_PER_ADDRESS 0x098 49#define __LC_PER_ADDRESS 0x098
49#define __LC_PER_ACCESS_ID 0x0A1 50#define __LC_PER_ACCESS_ID 0x0A1
51#define __LC_AR_MODE_ID 0x0A3
50 52
51#define __LC_SUBCHANNEL_ID 0x0B8 53#define __LC_SUBCHANNEL_ID 0x0B8
52#define __LC_SUBCHANNEL_NR 0x0BA 54#define __LC_SUBCHANNEL_NR 0x0BA
@@ -106,18 +108,28 @@
106#define __LC_INT_CLOCK 0xDE8 108#define __LC_INT_CLOCK 0xDE8
107#endif /* __s390x__ */ 109#endif /* __s390x__ */
108 110
109#define __LC_PANIC_MAGIC 0xE00
110 111
112#define __LC_PANIC_MAGIC 0xE00
111#ifndef __s390x__ 113#ifndef __s390x__
112#define __LC_PFAULT_INTPARM 0x080 114#define __LC_PFAULT_INTPARM 0x080
113#define __LC_CPU_TIMER_SAVE_AREA 0x0D8 115#define __LC_CPU_TIMER_SAVE_AREA 0x0D8
116#define __LC_CLOCK_COMP_SAVE_AREA 0x0E0
117#define __LC_PSW_SAVE_AREA 0x100
118#define __LC_PREFIX_SAVE_AREA 0x108
114#define __LC_AREGS_SAVE_AREA 0x120 119#define __LC_AREGS_SAVE_AREA 0x120
120#define __LC_FPREGS_SAVE_AREA 0x160
115#define __LC_GPREGS_SAVE_AREA 0x180 121#define __LC_GPREGS_SAVE_AREA 0x180
116#define __LC_CREGS_SAVE_AREA 0x1C0 122#define __LC_CREGS_SAVE_AREA 0x1C0
117#else /* __s390x__ */ 123#else /* __s390x__ */
118#define __LC_PFAULT_INTPARM 0x11B8 124#define __LC_PFAULT_INTPARM 0x11B8
125#define __LC_FPREGS_SAVE_AREA 0x1200
119#define __LC_GPREGS_SAVE_AREA 0x1280 126#define __LC_GPREGS_SAVE_AREA 0x1280
127#define __LC_PSW_SAVE_AREA 0x1300
128#define __LC_PREFIX_SAVE_AREA 0x1318
129#define __LC_FP_CREG_SAVE_AREA 0x131C
130#define __LC_TODREG_SAVE_AREA 0x1324
120#define __LC_CPU_TIMER_SAVE_AREA 0x1328 131#define __LC_CPU_TIMER_SAVE_AREA 0x1328
132#define __LC_CLOCK_COMP_SAVE_AREA 0x1331
121#define __LC_AREGS_SAVE_AREA 0x1340 133#define __LC_AREGS_SAVE_AREA 0x1340
122#define __LC_CREGS_SAVE_AREA 0x1380 134#define __LC_CREGS_SAVE_AREA 0x1380
123#endif /* __s390x__ */ 135#endif /* __s390x__ */
diff --git a/include/asm-s390/monwriter.h b/include/asm-s390/monwriter.h
new file mode 100644
index 000000000000..f0cbf96c52e6
--- /dev/null
+++ b/include/asm-s390/monwriter.h
@@ -0,0 +1,33 @@
1/*
2 * include/asm-s390/monwriter.h
3 *
4 * Copyright (C) IBM Corp. 2006
5 * Character device driver for writing z/VM APPLDATA monitor records
6 * Version 1.0
7 * Author(s): Melissa Howland <melissah@us.ibm.com>
8 *
9 */
10
11#ifndef _ASM_390_MONWRITER_H
12#define _ASM_390_MONWRITER_H
13
14/* mon_function values */
15#define MONWRITE_START_INTERVAL 0x00 /* start interval recording */
16#define MONWRITE_STOP_INTERVAL 0x01 /* stop interval or config recording */
17#define MONWRITE_GEN_EVENT 0x02 /* generate event record */
18#define MONWRITE_START_CONFIG 0x03 /* start configuration recording */
19
20/* the header the app uses in its write() data */
21struct monwrite_hdr {
22 unsigned char mon_function;
23 unsigned short applid;
24 unsigned char record_num;
25 unsigned short version;
26 unsigned short release;
27 unsigned short mod_level;
28 unsigned short datalen;
29 unsigned char hdrlen;
30
31} __attribute__((packed));
32
33#endif /* _ASM_390_MONWRITER_H */
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h
index a78e853e0dd5..803bc7064418 100644
--- a/include/asm-s390/pgalloc.h
+++ b/include/asm-s390/pgalloc.h
@@ -22,6 +22,16 @@
22extern void diag10(unsigned long addr); 22extern void diag10(unsigned long addr);
23 23
24/* 24/*
25 * Page allocation orders.
26 */
27#ifndef __s390x__
28# define PGD_ALLOC_ORDER 1
29#else /* __s390x__ */
30# define PMD_ALLOC_ORDER 2
31# define PGD_ALLOC_ORDER 2
32#endif /* __s390x__ */
33
34/*
25 * Allocate and free page tables. The xxx_kernel() versions are 35 * Allocate and free page tables. The xxx_kernel() versions are
26 * used to allocate a kernel page table - this turns on ASN bits 36 * used to allocate a kernel page table - this turns on ASN bits
27 * if any. 37 * if any.
@@ -29,30 +39,23 @@ extern void diag10(unsigned long addr);
29 39
30static inline pgd_t *pgd_alloc(struct mm_struct *mm) 40static inline pgd_t *pgd_alloc(struct mm_struct *mm)
31{ 41{
32 pgd_t *pgd; 42 pgd_t *pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ALLOC_ORDER);
33 int i; 43 int i;
34 44
45 if (!pgd)
46 return NULL;
47 for (i = 0; i < PTRS_PER_PGD; i++)
35#ifndef __s390x__ 48#ifndef __s390x__
36 pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,1); 49 pmd_clear(pmd_offset(pgd + i, i*PGDIR_SIZE));
37 if (pgd != NULL) 50#else
38 for (i = 0; i < USER_PTRS_PER_PGD; i++) 51 pgd_clear(pgd + i);
39 pmd_clear(pmd_offset(pgd + i, i*PGDIR_SIZE)); 52#endif
40#else /* __s390x__ */
41 pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,2);
42 if (pgd != NULL)
43 for (i = 0; i < PTRS_PER_PGD; i++)
44 pgd_clear(pgd + i);
45#endif /* __s390x__ */
46 return pgd; 53 return pgd;
47} 54}
48 55
49static inline void pgd_free(pgd_t *pgd) 56static inline void pgd_free(pgd_t *pgd)
50{ 57{
51#ifndef __s390x__ 58 free_pages((unsigned long) pgd, PGD_ALLOC_ORDER);
52 free_pages((unsigned long) pgd, 1);
53#else /* __s390x__ */
54 free_pages((unsigned long) pgd, 2);
55#endif /* __s390x__ */
56} 59}
57 60
58#ifndef __s390x__ 61#ifndef __s390x__
@@ -68,20 +71,19 @@ static inline void pgd_free(pgd_t *pgd)
68#else /* __s390x__ */ 71#else /* __s390x__ */
69static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) 72static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
70{ 73{
71 pmd_t *pmd; 74 pmd_t *pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, PMD_ALLOC_ORDER);
72 int i; 75 int i;
73 76
74 pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 2); 77 if (!pmd)
75 if (pmd != NULL) { 78 return NULL;
76 for (i=0; i < PTRS_PER_PMD; i++) 79 for (i=0; i < PTRS_PER_PMD; i++)
77 pmd_clear(pmd+i); 80 pmd_clear(pmd + i);
78 }
79 return pmd; 81 return pmd;
80} 82}
81 83
82static inline void pmd_free (pmd_t *pmd) 84static inline void pmd_free (pmd_t *pmd)
83{ 85{
84 free_pages((unsigned long) pmd, 2); 86 free_pages((unsigned long) pmd, PMD_ALLOC_ORDER);
85} 87}
86 88
87#define __pmd_free_tlb(tlb,pmd) \ 89#define __pmd_free_tlb(tlb,pmd) \
@@ -123,15 +125,14 @@ pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page)
123static inline pte_t * 125static inline pte_t *
124pte_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr) 126pte_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr)
125{ 127{
126 pte_t *pte; 128 pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT);
127 int i; 129 int i;
128 130
129 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); 131 if (!pte)
130 if (pte != NULL) { 132 return NULL;
131 for (i=0; i < PTRS_PER_PTE; i++) { 133 for (i=0; i < PTRS_PER_PTE; i++) {
132 pte_clear(mm, vmaddr, pte+i); 134 pte_clear(mm, vmaddr, pte + i);
133 vmaddr += PAGE_SIZE; 135 vmaddr += PAGE_SIZE;
134 }
135 } 136 }
136 return pte; 137 return pte;
137} 138}
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 24312387fa24..1a07028d575e 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -89,19 +89,6 @@ extern char empty_zero_page[PAGE_SIZE];
89# define PTRS_PER_PGD 2048 89# define PTRS_PER_PGD 2048
90#endif /* __s390x__ */ 90#endif /* __s390x__ */
91 91
92/*
93 * pgd entries used up by user/kernel:
94 */
95#ifndef __s390x__
96# define USER_PTRS_PER_PGD 512
97# define USER_PGD_PTRS 512
98# define KERNEL_PGD_PTRS 512
99#else /* __s390x__ */
100# define USER_PTRS_PER_PGD 2048
101# define USER_PGD_PTRS 2048
102# define KERNEL_PGD_PTRS 2048
103#endif /* __s390x__ */
104
105#define FIRST_USER_ADDRESS 0 92#define FIRST_USER_ADDRESS 0
106 93
107#define pte_ERROR(e) \ 94#define pte_ERROR(e) \
@@ -216,12 +203,14 @@ extern char empty_zero_page[PAGE_SIZE];
216#define _PAGE_RO 0x200 /* HW read-only */ 203#define _PAGE_RO 0x200 /* HW read-only */
217#define _PAGE_INVALID 0x400 /* HW invalid */ 204#define _PAGE_INVALID 0x400 /* HW invalid */
218 205
219/* Mask and four different kinds of invalid pages. */ 206/* Mask and six different types of pages. */
220#define _PAGE_INVALID_MASK 0x601 207#define _PAGE_TYPE_MASK 0x601
221#define _PAGE_INVALID_EMPTY 0x400 208#define _PAGE_TYPE_EMPTY 0x400
222#define _PAGE_INVALID_NONE 0x401 209#define _PAGE_TYPE_NONE 0x401
223#define _PAGE_INVALID_SWAP 0x600 210#define _PAGE_TYPE_SWAP 0x600
224#define _PAGE_INVALID_FILE 0x601 211#define _PAGE_TYPE_FILE 0x601
212#define _PAGE_TYPE_RO 0x200
213#define _PAGE_TYPE_RW 0x000
225 214
226#ifndef __s390x__ 215#ifndef __s390x__
227 216
@@ -280,15 +269,14 @@ extern char empty_zero_page[PAGE_SIZE];
280#endif /* __s390x__ */ 269#endif /* __s390x__ */
281 270
282/* 271/*
283 * No mapping available 272 * Page protection definitions.
284 */ 273 */
285#define PAGE_NONE_SHARED __pgprot(_PAGE_INVALID_NONE) 274#define PAGE_NONE __pgprot(_PAGE_TYPE_NONE)
286#define PAGE_NONE_PRIVATE __pgprot(_PAGE_INVALID_NONE) 275#define PAGE_RO __pgprot(_PAGE_TYPE_RO)
287#define PAGE_RO_SHARED __pgprot(_PAGE_RO) 276#define PAGE_RW __pgprot(_PAGE_TYPE_RW)
288#define PAGE_RO_PRIVATE __pgprot(_PAGE_RO) 277
289#define PAGE_COPY __pgprot(_PAGE_RO) 278#define PAGE_KERNEL PAGE_RW
290#define PAGE_SHARED __pgprot(0) 279#define PAGE_COPY PAGE_RO
291#define PAGE_KERNEL __pgprot(0)
292 280
293/* 281/*
294 * The S390 can't do page protection for execute, and considers that the 282 * The S390 can't do page protection for execute, and considers that the
@@ -296,23 +284,23 @@ extern char empty_zero_page[PAGE_SIZE];
296 * the closest we can get.. 284 * the closest we can get..
297 */ 285 */
298 /*xwr*/ 286 /*xwr*/
299#define __P000 PAGE_NONE_PRIVATE 287#define __P000 PAGE_NONE
300#define __P001 PAGE_RO_PRIVATE 288#define __P001 PAGE_RO
301#define __P010 PAGE_COPY 289#define __P010 PAGE_RO
302#define __P011 PAGE_COPY 290#define __P011 PAGE_RO
303#define __P100 PAGE_RO_PRIVATE 291#define __P100 PAGE_RO
304#define __P101 PAGE_RO_PRIVATE 292#define __P101 PAGE_RO
305#define __P110 PAGE_COPY 293#define __P110 PAGE_RO
306#define __P111 PAGE_COPY 294#define __P111 PAGE_RO
307 295
308#define __S000 PAGE_NONE_SHARED 296#define __S000 PAGE_NONE
309#define __S001 PAGE_RO_SHARED 297#define __S001 PAGE_RO
310#define __S010 PAGE_SHARED 298#define __S010 PAGE_RW
311#define __S011 PAGE_SHARED 299#define __S011 PAGE_RW
312#define __S100 PAGE_RO_SHARED 300#define __S100 PAGE_RO
313#define __S101 PAGE_RO_SHARED 301#define __S101 PAGE_RO
314#define __S110 PAGE_SHARED 302#define __S110 PAGE_RW
315#define __S111 PAGE_SHARED 303#define __S111 PAGE_RW
316 304
317/* 305/*
318 * Certain architectures need to do special things when PTEs 306 * Certain architectures need to do special things when PTEs
@@ -377,18 +365,18 @@ static inline int pmd_bad(pmd_t pmd)
377 365
378static inline int pte_none(pte_t pte) 366static inline int pte_none(pte_t pte)
379{ 367{
380 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY; 368 return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_EMPTY;
381} 369}
382 370
383static inline int pte_present(pte_t pte) 371static inline int pte_present(pte_t pte)
384{ 372{
385 return !(pte_val(pte) & _PAGE_INVALID) || 373 return !(pte_val(pte) & _PAGE_INVALID) ||
386 (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE; 374 (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_NONE;
387} 375}
388 376
389static inline int pte_file(pte_t pte) 377static inline int pte_file(pte_t pte)
390{ 378{
391 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE; 379 return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_FILE;
392} 380}
393 381
394#define pte_same(a,b) (pte_val(a) == pte_val(b)) 382#define pte_same(a,b) (pte_val(a) == pte_val(b))
@@ -461,7 +449,7 @@ static inline void pmd_clear(pmd_t * pmdp)
461 449
462static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 450static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
463{ 451{
464 pte_val(*ptep) = _PAGE_INVALID_EMPTY; 452 pte_val(*ptep) = _PAGE_TYPE_EMPTY;
465} 453}
466 454
467/* 455/*
@@ -477,7 +465,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
477 465
478static inline pte_t pte_wrprotect(pte_t pte) 466static inline pte_t pte_wrprotect(pte_t pte)
479{ 467{
480 /* Do not clobber _PAGE_INVALID_NONE pages! */ 468 /* Do not clobber _PAGE_TYPE_NONE pages! */
481 if (!(pte_val(pte) & _PAGE_INVALID)) 469 if (!(pte_val(pte) & _PAGE_INVALID))
482 pte_val(pte) |= _PAGE_RO; 470 pte_val(pte) |= _PAGE_RO;
483 return pte; 471 return pte;
@@ -556,26 +544,30 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
556 return pte; 544 return pte;
557} 545}
558 546
559static inline pte_t 547static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
560ptep_clear_flush(struct vm_area_struct *vma,
561 unsigned long address, pte_t *ptep)
562{ 548{
563 pte_t pte = *ptep; 549 if (!(pte_val(*ptep) & _PAGE_INVALID)) {
564#ifndef __s390x__ 550#ifndef __s390x__
565 if (!(pte_val(pte) & _PAGE_INVALID)) {
566 /* S390 has 1mb segments, we are emulating 4MB segments */ 551 /* S390 has 1mb segments, we are emulating 4MB segments */
567 pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); 552 pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00);
568 __asm__ __volatile__ ("ipte %2,%3" 553#else
569 : "=m" (*ptep) : "m" (*ptep), 554 /* ipte in zarch mode can do the math */
570 "a" (pto), "a" (address) ); 555 pte_t *pto = ptep;
556#endif
557 asm volatile ("ipte %2,%3"
558 : "=m" (*ptep) : "m" (*ptep),
559 "a" (pto), "a" (address) );
571 } 560 }
572#else /* __s390x__ */ 561 pte_val(*ptep) = _PAGE_TYPE_EMPTY;
573 if (!(pte_val(pte) & _PAGE_INVALID)) 562}
574 __asm__ __volatile__ ("ipte %2,%3" 563
575 : "=m" (*ptep) : "m" (*ptep), 564static inline pte_t
576 "a" (ptep), "a" (address) ); 565ptep_clear_flush(struct vm_area_struct *vma,
577#endif /* __s390x__ */ 566 unsigned long address, pte_t *ptep)
578 pte_val(*ptep) = _PAGE_INVALID_EMPTY; 567{
568 pte_t pte = *ptep;
569
570 __ptep_ipte(address, ptep);
579 return pte; 571 return pte;
580} 572}
581 573
@@ -755,7 +747,7 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
755{ 747{
756 pte_t pte; 748 pte_t pte;
757 offset &= __SWP_OFFSET_MASK; 749 offset &= __SWP_OFFSET_MASK;
758 pte_val(pte) = _PAGE_INVALID_SWAP | ((type & 0x1f) << 2) | 750 pte_val(pte) = _PAGE_TYPE_SWAP | ((type & 0x1f) << 2) |
759 ((offset & 1UL) << 7) | ((offset & ~1UL) << 11); 751 ((offset & 1UL) << 7) | ((offset & ~1UL) << 11);
760 return pte; 752 return pte;
761} 753}
@@ -778,7 +770,7 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
778 770
779#define pgoff_to_pte(__off) \ 771#define pgoff_to_pte(__off) \
780 ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \ 772 ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \
781 | _PAGE_INVALID_FILE }) 773 | _PAGE_TYPE_FILE })
782 774
783#endif /* !__ASSEMBLY__ */ 775#endif /* !__ASSEMBLY__ */
784 776
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index 5b71d3731723..a3a4e5fd30d7 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -339,4 +339,21 @@ int unregister_idle_notifier(struct notifier_block *nb);
339 339
340#endif 340#endif
341 341
342/*
343 * Helper macro for exception table entries
344 */
345#ifndef __s390x__
346#define EX_TABLE(_fault,_target) \
347 ".section __ex_table,\"a\"\n" \
348 " .align 4\n" \
349 " .long " #_fault "," #_target "\n" \
350 ".previous\n"
351#else
352#define EX_TABLE(_fault,_target) \
353 ".section __ex_table,\"a\"\n" \
354 " .align 8\n" \
355 " .quad " #_fault "," #_target "\n" \
356 ".previous\n"
357#endif
358
342#endif /* __ASM_S390_PROCESSOR_H */ 359#endif /* __ASM_S390_PROCESSOR_H */
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
index 19e31979309a..f1959732b6fd 100644
--- a/include/asm-s390/setup.h
+++ b/include/asm-s390/setup.h
@@ -14,8 +14,6 @@
14 14
15#define PARMAREA 0x10400 15#define PARMAREA 0x10400
16#define COMMAND_LINE_SIZE 896 16#define COMMAND_LINE_SIZE 896
17#define RAMDISK_ORIGIN 0x800000
18#define RAMDISK_SIZE 0x800000
19#define MEMORY_CHUNKS 16 /* max 0x7fff */ 17#define MEMORY_CHUNKS 16 /* max 0x7fff */
20#define IPL_PARMBLOCK_ORIGIN 0x2000 18#define IPL_PARMBLOCK_ORIGIN 0x2000
21 19
@@ -46,10 +44,12 @@ extern unsigned long machine_flags;
46#define MACHINE_HAS_IEEE (machine_flags & 2) 44#define MACHINE_HAS_IEEE (machine_flags & 2)
47#define MACHINE_HAS_CSP (machine_flags & 8) 45#define MACHINE_HAS_CSP (machine_flags & 8)
48#define MACHINE_HAS_DIAG44 (1) 46#define MACHINE_HAS_DIAG44 (1)
47#define MACHINE_HAS_MVCOS (0)
49#else /* __s390x__ */ 48#else /* __s390x__ */
50#define MACHINE_HAS_IEEE (1) 49#define MACHINE_HAS_IEEE (1)
51#define MACHINE_HAS_CSP (1) 50#define MACHINE_HAS_CSP (1)
52#define MACHINE_HAS_DIAG44 (machine_flags & 32) 51#define MACHINE_HAS_DIAG44 (machine_flags & 32)
52#define MACHINE_HAS_MVCOS (machine_flags & 512)
53#endif /* __s390x__ */ 53#endif /* __s390x__ */
54 54
55 55
@@ -70,52 +70,76 @@ extern unsigned int console_irq;
70#define SET_CONSOLE_3215 do { console_mode = 2; } while (0) 70#define SET_CONSOLE_3215 do { console_mode = 2; } while (0)
71#define SET_CONSOLE_3270 do { console_mode = 3; } while (0) 71#define SET_CONSOLE_3270 do { console_mode = 3; } while (0)
72 72
73struct ipl_list_header { 73
74 u32 length; 74struct ipl_list_hdr {
75 u8 reserved[3]; 75 u32 len;
76 u8 reserved1[3];
76 u8 version; 77 u8 version;
78 u32 blk0_len;
79 u8 pbt;
80 u8 flags;
81 u16 reserved2;
77} __attribute__((packed)); 82} __attribute__((packed));
78 83
79struct ipl_block_fcp { 84struct ipl_block_fcp {
80 u32 length; 85 u8 reserved1[313-1];
81 u8 pbt; 86 u8 opt;
82 u8 reserved1[322-1]; 87 u8 reserved2[3];
88 u16 reserved3;
83 u16 devno; 89 u16 devno;
84 u8 reserved2[4]; 90 u8 reserved4[4];
85 u64 wwpn; 91 u64 wwpn;
86 u64 lun; 92 u64 lun;
87 u32 bootprog; 93 u32 bootprog;
88 u8 reserved3[12]; 94 u8 reserved5[12];
89 u64 br_lba; 95 u64 br_lba;
90 u32 scp_data_len; 96 u32 scp_data_len;
91 u8 reserved4[260]; 97 u8 reserved6[260];
92 u8 scp_data[]; 98 u8 scp_data[];
93} __attribute__((packed)); 99} __attribute__((packed));
94 100
101struct ipl_block_ccw {
102 u8 load_param[8];
103 u8 reserved1[84];
104 u8 reserved2[2];
105 u16 devno;
106 u8 vm_flags;
107 u8 reserved3[3];
108 u32 vm_parm_len;
109} __attribute__((packed));
110
95struct ipl_parameter_block { 111struct ipl_parameter_block {
112 struct ipl_list_hdr hdr;
96 union { 113 union {
97 u32 length; 114 struct ipl_block_fcp fcp;
98 struct ipl_list_header header; 115 struct ipl_block_ccw ccw;
99 } hdr; 116 } ipl_info;
100 struct ipl_block_fcp fcp;
101} __attribute__((packed)); 117} __attribute__((packed));
102 118
103#define IPL_MAX_SUPPORTED_VERSION (0) 119#define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \
120 sizeof(struct ipl_block_fcp))
104 121
105#define IPL_TYPE_FCP (0) 122#define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \
123 sizeof(struct ipl_block_ccw))
124
125#define IPL_MAX_SUPPORTED_VERSION (0)
106 126
107/* 127/*
108 * IPL validity flags and parameters as detected in head.S 128 * IPL validity flags and parameters as detected in head.S
109 */ 129 */
110extern u32 ipl_parameter_flags; 130extern u32 ipl_flags;
111extern u16 ipl_devno; 131extern u16 ipl_devno;
112 132
113#define IPL_DEVNO_VALID (ipl_parameter_flags & 1) 133void do_reipl(void);
114#define IPL_PARMBLOCK_VALID (ipl_parameter_flags & 2) 134
135enum {
136 IPL_DEVNO_VALID = 1,
137 IPL_PARMBLOCK_VALID = 2,
138};
115 139
116#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \ 140#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \
117 IPL_PARMBLOCK_ORIGIN) 141 IPL_PARMBLOCK_ORIGIN)
118#define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.length) 142#define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len)
119 143
120#else /* __ASSEMBLY__ */ 144#else /* __ASSEMBLY__ */
121 145
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
index 657646054c5e..9fb02e9779c9 100644
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -104,7 +104,7 @@ smp_call_function_on(void (*func) (void *info), void *info,
104#define smp_cpu_not_running(cpu) 1 104#define smp_cpu_not_running(cpu) 1
105#define smp_get_cpu(cpu) ({ 0; }) 105#define smp_get_cpu(cpu) ({ 0; })
106#define smp_put_cpu(cpu) ({ 0; }) 106#define smp_put_cpu(cpu) ({ 0; })
107#define smp_setup_cpu_possible_map() 107#define smp_setup_cpu_possible_map() do { } while (0)
108#endif 108#endif
109 109
110#endif 110#endif
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h
index 0b7c0ca4c3d7..e2047b0c9092 100644
--- a/include/asm-s390/uaccess.h
+++ b/include/asm-s390/uaccess.h
@@ -47,7 +47,7 @@
47 S390_lowcore.user_asce : S390_lowcore.kernel_asce; \ 47 S390_lowcore.user_asce : S390_lowcore.kernel_asce; \
48 asm volatile ("lctlg 7,7,%0" : : "m" (__pto) ); \ 48 asm volatile ("lctlg 7,7,%0" : : "m" (__pto) ); \
49}) 49})
50#else 50#else /* __s390x__ */
51#define set_fs(x) \ 51#define set_fs(x) \
52({ \ 52({ \
53 unsigned long __pto; \ 53 unsigned long __pto; \
@@ -56,7 +56,7 @@
56 S390_lowcore.user_asce : S390_lowcore.kernel_asce; \ 56 S390_lowcore.user_asce : S390_lowcore.kernel_asce; \
57 asm volatile ("lctl 7,7,%0" : : "m" (__pto) ); \ 57 asm volatile ("lctl 7,7,%0" : : "m" (__pto) ); \
58}) 58})
59#endif 59#endif /* __s390x__ */
60 60
61#define segment_eq(a,b) ((a).ar4 == (b).ar4) 61#define segment_eq(a,b) ((a).ar4 == (b).ar4)
62 62
@@ -85,76 +85,51 @@ struct exception_table_entry
85 unsigned long insn, fixup; 85 unsigned long insn, fixup;
86}; 86};
87 87
88#ifndef __s390x__ 88struct uaccess_ops {
89#define __uaccess_fixup \ 89 size_t (*copy_from_user)(size_t, const void __user *, void *);
90 ".section .fixup,\"ax\"\n" \ 90 size_t (*copy_from_user_small)(size_t, const void __user *, void *);
91 "2: lhi %0,%4\n" \ 91 size_t (*copy_to_user)(size_t, void __user *, const void *);
92 " bras 1,3f\n" \ 92 size_t (*copy_to_user_small)(size_t, void __user *, const void *);
93 " .long 1b\n" \ 93 size_t (*copy_in_user)(size_t, void __user *, const void __user *);
94 "3: l 1,0(1)\n" \ 94 size_t (*clear_user)(size_t, void __user *);
95 " br 1\n" \ 95 size_t (*strnlen_user)(size_t, const char __user *);
96 ".previous\n" \ 96 size_t (*strncpy_from_user)(size_t, const char __user *, char *);
97 ".section __ex_table,\"a\"\n" \ 97 int (*futex_atomic_op)(int op, int __user *, int oparg, int *old);
98 " .align 4\n" \ 98 int (*futex_atomic_cmpxchg)(int __user *, int old, int new);
99 " .long 0b,2b\n" \ 99};
100 ".previous" 100
101#define __uaccess_clobber "cc", "1" 101extern struct uaccess_ops uaccess;
102#else /* __s390x__ */ 102extern struct uaccess_ops uaccess_std;
103#define __uaccess_fixup \ 103extern struct uaccess_ops uaccess_mvcos;
104 ".section .fixup,\"ax\"\n" \ 104
105 "2: lghi %0,%4\n" \ 105static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
106 " jg 1b\n" \ 106{
107 ".previous\n" \ 107 size = uaccess.copy_to_user_small(size, ptr, x);
108 ".section __ex_table,\"a\"\n" \ 108 return size ? -EFAULT : size;
109 " .align 8\n" \ 109}
110 " .quad 0b,2b\n" \ 110
111 ".previous" 111static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
112#define __uaccess_clobber "cc" 112{
113#endif /* __s390x__ */ 113 size = uaccess.copy_from_user_small(size, ptr, x);
114 return size ? -EFAULT : size;
115}
114 116
115/* 117/*
116 * These are the main single-value transfer routines. They automatically 118 * These are the main single-value transfer routines. They automatically
117 * use the right size if we just have the right pointer type. 119 * use the right size if we just have the right pointer type.
118 */ 120 */
119#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
120#define __put_user_asm(x, ptr, err) \
121({ \
122 err = 0; \
123 asm volatile( \
124 "0: mvcs 0(%1,%2),%3,%0\n" \
125 "1:\n" \
126 __uaccess_fixup \
127 : "+&d" (err) \
128 : "d" (sizeof(*(ptr))), "a" (ptr), "Q" (x), \
129 "K" (-EFAULT) \
130 : __uaccess_clobber ); \
131})
132#else
133#define __put_user_asm(x, ptr, err) \
134({ \
135 err = 0; \
136 asm volatile( \
137 "0: mvcs 0(%1,%2),0(%3),%0\n" \
138 "1:\n" \
139 __uaccess_fixup \
140 : "+&d" (err) \
141 : "d" (sizeof(*(ptr))), "a" (ptr), "a" (&(x)), \
142 "K" (-EFAULT), "m" (x) \
143 : __uaccess_clobber ); \
144})
145#endif
146
147#define __put_user(x, ptr) \ 121#define __put_user(x, ptr) \
148({ \ 122({ \
149 __typeof__(*(ptr)) __x = (x); \ 123 __typeof__(*(ptr)) __x = (x); \
150 int __pu_err; \ 124 int __pu_err = -EFAULT; \
151 __chk_user_ptr(ptr); \ 125 __chk_user_ptr(ptr); \
152 switch (sizeof (*(ptr))) { \ 126 switch (sizeof (*(ptr))) { \
153 case 1: \ 127 case 1: \
154 case 2: \ 128 case 2: \
155 case 4: \ 129 case 4: \
156 case 8: \ 130 case 8: \
157 __put_user_asm(__x, ptr, __pu_err); \ 131 __pu_err = __put_user_fn(sizeof (*(ptr)), \
132 ptr, &__x); \
158 break; \ 133 break; \
159 default: \ 134 default: \
160 __put_user_bad(); \ 135 __put_user_bad(); \
@@ -172,60 +147,36 @@ struct exception_table_entry
172 147
173extern int __put_user_bad(void) __attribute__((noreturn)); 148extern int __put_user_bad(void) __attribute__((noreturn));
174 149
175#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
176#define __get_user_asm(x, ptr, err) \
177({ \
178 err = 0; \
179 asm volatile ( \
180 "0: mvcp %O1(%2,%R1),0(%3),%0\n" \
181 "1:\n" \
182 __uaccess_fixup \
183 : "+&d" (err), "=Q" (x) \
184 : "d" (sizeof(*(ptr))), "a" (ptr), \
185 "K" (-EFAULT) \
186 : __uaccess_clobber ); \
187})
188#else
189#define __get_user_asm(x, ptr, err) \
190({ \
191 err = 0; \
192 asm volatile ( \
193 "0: mvcp 0(%2,%5),0(%3),%0\n" \
194 "1:\n" \
195 __uaccess_fixup \
196 : "+&d" (err), "=m" (x) \
197 : "d" (sizeof(*(ptr))), "a" (ptr), \
198 "K" (-EFAULT), "a" (&(x)) \
199 : __uaccess_clobber ); \
200})
201#endif
202
203#define __get_user(x, ptr) \ 150#define __get_user(x, ptr) \
204({ \ 151({ \
205 int __gu_err; \ 152 int __gu_err = -EFAULT; \
206 __chk_user_ptr(ptr); \ 153 __chk_user_ptr(ptr); \
207 switch (sizeof(*(ptr))) { \ 154 switch (sizeof(*(ptr))) { \
208 case 1: { \ 155 case 1: { \
209 unsigned char __x; \ 156 unsigned char __x; \
210 __get_user_asm(__x, ptr, __gu_err); \ 157 __gu_err = __get_user_fn(sizeof (*(ptr)), \
158 ptr, &__x); \
211 (x) = *(__force __typeof__(*(ptr)) *) &__x; \ 159 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
212 break; \ 160 break; \
213 }; \ 161 }; \
214 case 2: { \ 162 case 2: { \
215 unsigned short __x; \ 163 unsigned short __x; \
216 __get_user_asm(__x, ptr, __gu_err); \ 164 __gu_err = __get_user_fn(sizeof (*(ptr)), \
165 ptr, &__x); \
217 (x) = *(__force __typeof__(*(ptr)) *) &__x; \ 166 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
218 break; \ 167 break; \
219 }; \ 168 }; \
220 case 4: { \ 169 case 4: { \
221 unsigned int __x; \ 170 unsigned int __x; \
222 __get_user_asm(__x, ptr, __gu_err); \ 171 __gu_err = __get_user_fn(sizeof (*(ptr)), \
172 ptr, &__x); \
223 (x) = *(__force __typeof__(*(ptr)) *) &__x; \ 173 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
224 break; \ 174 break; \
225 }; \ 175 }; \
226 case 8: { \ 176 case 8: { \
227 unsigned long long __x; \ 177 unsigned long long __x; \
228 __get_user_asm(__x, ptr, __gu_err); \ 178 __gu_err = __get_user_fn(sizeof (*(ptr)), \
179 ptr, &__x); \
229 (x) = *(__force __typeof__(*(ptr)) *) &__x; \ 180 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
230 break; \ 181 break; \
231 }; \ 182 }; \
@@ -247,8 +198,6 @@ extern int __get_user_bad(void) __attribute__((noreturn));
247#define __put_user_unaligned __put_user 198#define __put_user_unaligned __put_user
248#define __get_user_unaligned __get_user 199#define __get_user_unaligned __get_user
249 200
250extern long __copy_to_user_asm(const void *from, long n, void __user *to);
251
252/** 201/**
253 * __copy_to_user: - Copy a block of data into user space, with less checking. 202 * __copy_to_user: - Copy a block of data into user space, with less checking.
254 * @to: Destination address, in user space. 203 * @to: Destination address, in user space.
@@ -266,7 +215,10 @@ extern long __copy_to_user_asm(const void *from, long n, void __user *to);
266static inline unsigned long 215static inline unsigned long
267__copy_to_user(void __user *to, const void *from, unsigned long n) 216__copy_to_user(void __user *to, const void *from, unsigned long n)
268{ 217{
269 return __copy_to_user_asm(from, n, to); 218 if (__builtin_constant_p(n) && (n <= 256))
219 return uaccess.copy_to_user_small(n, to, from);
220 else
221 return uaccess.copy_to_user(n, to, from);
270} 222}
271 223
272#define __copy_to_user_inatomic __copy_to_user 224#define __copy_to_user_inatomic __copy_to_user
@@ -294,8 +246,6 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
294 return n; 246 return n;
295} 247}
296 248
297extern long __copy_from_user_asm(void *to, long n, const void __user *from);
298
299/** 249/**
300 * __copy_from_user: - Copy a block of data from user space, with less checking. 250 * __copy_from_user: - Copy a block of data from user space, with less checking.
301 * @to: Destination address, in kernel space. 251 * @to: Destination address, in kernel space.
@@ -316,7 +266,10 @@ extern long __copy_from_user_asm(void *to, long n, const void __user *from);
316static inline unsigned long 266static inline unsigned long
317__copy_from_user(void *to, const void __user *from, unsigned long n) 267__copy_from_user(void *to, const void __user *from, unsigned long n)
318{ 268{
319 return __copy_from_user_asm(to, n, from); 269 if (__builtin_constant_p(n) && (n <= 256))
270 return uaccess.copy_from_user_small(n, from, to);
271 else
272 return uaccess.copy_from_user(n, from, to);
320} 273}
321 274
322/** 275/**
@@ -346,13 +299,10 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
346 return n; 299 return n;
347} 300}
348 301
349extern unsigned long __copy_in_user_asm(const void __user *from, long n,
350 void __user *to);
351
352static inline unsigned long 302static inline unsigned long
353__copy_in_user(void __user *to, const void __user *from, unsigned long n) 303__copy_in_user(void __user *to, const void __user *from, unsigned long n)
354{ 304{
355 return __copy_in_user_asm(from, n, to); 305 return uaccess.copy_in_user(n, to, from);
356} 306}
357 307
358static inline unsigned long 308static inline unsigned long
@@ -360,34 +310,28 @@ copy_in_user(void __user *to, const void __user *from, unsigned long n)
360{ 310{
361 might_sleep(); 311 might_sleep();
362 if (__access_ok(from,n) && __access_ok(to,n)) 312 if (__access_ok(from,n) && __access_ok(to,n))
363 n = __copy_in_user_asm(from, n, to); 313 n = __copy_in_user(to, from, n);
364 return n; 314 return n;
365} 315}
366 316
367/* 317/*
368 * Copy a null terminated string from userspace. 318 * Copy a null terminated string from userspace.
369 */ 319 */
370extern long __strncpy_from_user_asm(long count, char *dst,
371 const char __user *src);
372
373static inline long 320static inline long
374strncpy_from_user(char *dst, const char __user *src, long count) 321strncpy_from_user(char *dst, const char __user *src, long count)
375{ 322{
376 long res = -EFAULT; 323 long res = -EFAULT;
377 might_sleep(); 324 might_sleep();
378 if (access_ok(VERIFY_READ, src, 1)) 325 if (access_ok(VERIFY_READ, src, 1))
379 res = __strncpy_from_user_asm(count, dst, src); 326 res = uaccess.strncpy_from_user(count, src, dst);
380 return res; 327 return res;
381} 328}
382 329
383
384extern long __strnlen_user_asm(long count, const char __user *src);
385
386static inline unsigned long 330static inline unsigned long
387strnlen_user(const char __user * src, unsigned long n) 331strnlen_user(const char __user * src, unsigned long n)
388{ 332{
389 might_sleep(); 333 might_sleep();
390 return __strnlen_user_asm(n, src); 334 return uaccess.strnlen_user(n, src);
391} 335}
392 336
393/** 337/**
@@ -410,12 +354,10 @@ strnlen_user(const char __user * src, unsigned long n)
410 * Zero Userspace 354 * Zero Userspace
411 */ 355 */
412 356
413extern long __clear_user_asm(void __user *to, long n);
414
415static inline unsigned long 357static inline unsigned long
416__clear_user(void __user *to, unsigned long n) 358__clear_user(void __user *to, unsigned long n)
417{ 359{
418 return __clear_user_asm(to, n); 360 return uaccess.clear_user(n, to);
419} 361}
420 362
421static inline unsigned long 363static inline unsigned long
@@ -423,7 +365,7 @@ clear_user(void __user *to, unsigned long n)
423{ 365{
424 might_sleep(); 366 might_sleep();
425 if (access_ok(VERIFY_WRITE, to, n)) 367 if (access_ok(VERIFY_WRITE, to, n))
426 n = __clear_user_asm(to, n); 368 n = uaccess.clear_user(n, to);
427 return n; 369 return n;
428} 370}
429 371
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index aa7a243862e1..02b942d85c37 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -25,17 +25,12 @@
25#define __NR_unlink 10 25#define __NR_unlink 10
26#define __NR_execve 11 26#define __NR_execve 11
27#define __NR_chdir 12 27#define __NR_chdir 12
28#define __NR_time 13
29#define __NR_mknod 14 28#define __NR_mknod 14
30#define __NR_chmod 15 29#define __NR_chmod 15
31#define __NR_lchown 16
32#define __NR_lseek 19 30#define __NR_lseek 19
33#define __NR_getpid 20 31#define __NR_getpid 20
34#define __NR_mount 21 32#define __NR_mount 21
35#define __NR_umount 22 33#define __NR_umount 22
36#define __NR_setuid 23
37#define __NR_getuid 24
38#define __NR_stime 25
39#define __NR_ptrace 26 34#define __NR_ptrace 26
40#define __NR_alarm 27 35#define __NR_alarm 27
41#define __NR_pause 29 36#define __NR_pause 29
@@ -51,11 +46,7 @@
51#define __NR_pipe 42 46#define __NR_pipe 42
52#define __NR_times 43 47#define __NR_times 43
53#define __NR_brk 45 48#define __NR_brk 45
54#define __NR_setgid 46
55#define __NR_getgid 47
56#define __NR_signal 48 49#define __NR_signal 48
57#define __NR_geteuid 49
58#define __NR_getegid 50
59#define __NR_acct 51 50#define __NR_acct 51
60#define __NR_umount2 52 51#define __NR_umount2 52
61#define __NR_ioctl 54 52#define __NR_ioctl 54
@@ -69,18 +60,13 @@
69#define __NR_getpgrp 65 60#define __NR_getpgrp 65
70#define __NR_setsid 66 61#define __NR_setsid 66
71#define __NR_sigaction 67 62#define __NR_sigaction 67
72#define __NR_setreuid 70
73#define __NR_setregid 71
74#define __NR_sigsuspend 72 63#define __NR_sigsuspend 72
75#define __NR_sigpending 73 64#define __NR_sigpending 73
76#define __NR_sethostname 74 65#define __NR_sethostname 74
77#define __NR_setrlimit 75 66#define __NR_setrlimit 75
78#define __NR_getrlimit 76
79#define __NR_getrusage 77 67#define __NR_getrusage 77
80#define __NR_gettimeofday 78 68#define __NR_gettimeofday 78
81#define __NR_settimeofday 79 69#define __NR_settimeofday 79
82#define __NR_getgroups 80
83#define __NR_setgroups 81
84#define __NR_symlink 83 70#define __NR_symlink 83
85#define __NR_readlink 85 71#define __NR_readlink 85
86#define __NR_uselib 86 72#define __NR_uselib 86
@@ -92,12 +78,10 @@
92#define __NR_truncate 92 78#define __NR_truncate 92
93#define __NR_ftruncate 93 79#define __NR_ftruncate 93
94#define __NR_fchmod 94 80#define __NR_fchmod 94
95#define __NR_fchown 95
96#define __NR_getpriority 96 81#define __NR_getpriority 96
97#define __NR_setpriority 97 82#define __NR_setpriority 97
98#define __NR_statfs 99 83#define __NR_statfs 99
99#define __NR_fstatfs 100 84#define __NR_fstatfs 100
100#define __NR_ioperm 101
101#define __NR_socketcall 102 85#define __NR_socketcall 102
102#define __NR_syslog 103 86#define __NR_syslog 103
103#define __NR_setitimer 104 87#define __NR_setitimer 104
@@ -131,11 +115,7 @@
131#define __NR_sysfs 135 115#define __NR_sysfs 135
132#define __NR_personality 136 116#define __NR_personality 136
133#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ 117#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
134#define __NR_setfsuid 138
135#define __NR_setfsgid 139
136#define __NR__llseek 140
137#define __NR_getdents 141 118#define __NR_getdents 141
138#define __NR__newselect 142
139#define __NR_flock 143 119#define __NR_flock 143
140#define __NR_msync 144 120#define __NR_msync 144
141#define __NR_readv 145 121#define __NR_readv 145
@@ -157,13 +137,9 @@
157#define __NR_sched_rr_get_interval 161 137#define __NR_sched_rr_get_interval 161
158#define __NR_nanosleep 162 138#define __NR_nanosleep 162
159#define __NR_mremap 163 139#define __NR_mremap 163
160#define __NR_setresuid 164
161#define __NR_getresuid 165
162#define __NR_query_module 167 140#define __NR_query_module 167
163#define __NR_poll 168 141#define __NR_poll 168
164#define __NR_nfsservctl 169 142#define __NR_nfsservctl 169
165#define __NR_setresgid 170
166#define __NR_getresgid 171
167#define __NR_prctl 172 143#define __NR_prctl 172
168#define __NR_rt_sigreturn 173 144#define __NR_rt_sigreturn 173
169#define __NR_rt_sigaction 174 145#define __NR_rt_sigaction 174
@@ -174,7 +150,6 @@
174#define __NR_rt_sigsuspend 179 150#define __NR_rt_sigsuspend 179
175#define __NR_pread64 180 151#define __NR_pread64 180
176#define __NR_pwrite64 181 152#define __NR_pwrite64 181
177#define __NR_chown 182
178#define __NR_getcwd 183 153#define __NR_getcwd 183
179#define __NR_capget 184 154#define __NR_capget 184
180#define __NR_capset 185 155#define __NR_capset 185
@@ -183,39 +158,11 @@
183#define __NR_getpmsg 188 158#define __NR_getpmsg 188
184#define __NR_putpmsg 189 159#define __NR_putpmsg 189
185#define __NR_vfork 190 160#define __NR_vfork 190
186#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
187#define __NR_mmap2 192
188#define __NR_truncate64 193
189#define __NR_ftruncate64 194
190#define __NR_stat64 195
191#define __NR_lstat64 196
192#define __NR_fstat64 197
193#define __NR_lchown32 198
194#define __NR_getuid32 199
195#define __NR_getgid32 200
196#define __NR_geteuid32 201
197#define __NR_getegid32 202
198#define __NR_setreuid32 203
199#define __NR_setregid32 204
200#define __NR_getgroups32 205
201#define __NR_setgroups32 206
202#define __NR_fchown32 207
203#define __NR_setresuid32 208
204#define __NR_getresuid32 209
205#define __NR_setresgid32 210
206#define __NR_getresgid32 211
207#define __NR_chown32 212
208#define __NR_setuid32 213
209#define __NR_setgid32 214
210#define __NR_setfsuid32 215
211#define __NR_setfsgid32 216
212#define __NR_pivot_root 217 161#define __NR_pivot_root 217
213#define __NR_mincore 218 162#define __NR_mincore 218
214#define __NR_madvise 219 163#define __NR_madvise 219
215#define __NR_getdents64 220 164#define __NR_getdents64 220
216#define __NR_fcntl64 221
217#define __NR_readahead 222 165#define __NR_readahead 222
218#define __NR_sendfile64 223
219#define __NR_setxattr 224 166#define __NR_setxattr 224
220#define __NR_lsetxattr 225 167#define __NR_lsetxattr 225
221#define __NR_fsetxattr 226 168#define __NR_fsetxattr 226
@@ -256,7 +203,6 @@
256#define __NR_clock_getres (__NR_timer_create+7) 203#define __NR_clock_getres (__NR_timer_create+7)
257#define __NR_clock_nanosleep (__NR_timer_create+8) 204#define __NR_clock_nanosleep (__NR_timer_create+8)
258/* Number 263 is reserved for vserver */ 205/* Number 263 is reserved for vserver */
259#define __NR_fadvise64_64 264
260#define __NR_statfs64 265 206#define __NR_statfs64 265
261#define __NR_fstatfs64 266 207#define __NR_fstatfs64 266
262#define __NR_remap_file_pages 267 208#define __NR_remap_file_pages 267
@@ -285,7 +231,6 @@
285#define __NR_mknodat 290 231#define __NR_mknodat 290
286#define __NR_fchownat 291 232#define __NR_fchownat 291
287#define __NR_futimesat 292 233#define __NR_futimesat 292
288#define __NR_fstatat64 293
289#define __NR_unlinkat 294 234#define __NR_unlinkat 294
290#define __NR_renameat 295 235#define __NR_renameat 295
291#define __NR_linkat 296 236#define __NR_linkat 296
@@ -310,62 +255,65 @@
310 * have a different name although they do the same (e.g. __NR_chown32 255 * have a different name although they do the same (e.g. __NR_chown32
311 * is __NR_chown on 64 bit). 256 * is __NR_chown on 64 bit).
312 */ 257 */
313#ifdef __s390x__ 258#ifndef __s390x__
314#undef __NR_time 259
315#undef __NR_lchown 260#define __NR_time 13
316#undef __NR_setuid 261#define __NR_lchown 16
317#undef __NR_getuid 262#define __NR_setuid 23
318#undef __NR_stime 263#define __NR_getuid 24
319#undef __NR_setgid 264#define __NR_stime 25
320#undef __NR_getgid 265#define __NR_setgid 46
321#undef __NR_geteuid 266#define __NR_getgid 47
322#undef __NR_getegid 267#define __NR_geteuid 49
323#undef __NR_setreuid 268#define __NR_getegid 50
324#undef __NR_setregid 269#define __NR_setreuid 70
325#undef __NR_getrlimit 270#define __NR_setregid 71
326#undef __NR_getgroups 271#define __NR_getrlimit 76
327#undef __NR_setgroups 272#define __NR_getgroups 80
328#undef __NR_fchown 273#define __NR_setgroups 81
329#undef __NR_ioperm 274#define __NR_fchown 95
330#undef __NR_setfsuid 275#define __NR_ioperm 101
331#undef __NR_setfsgid 276#define __NR_setfsuid 138
332#undef __NR__llseek 277#define __NR_setfsgid 139
333#undef __NR__newselect 278#define __NR__llseek 140
334#undef __NR_setresuid 279#define __NR__newselect 142
335#undef __NR_getresuid 280#define __NR_setresuid 164
336#undef __NR_setresgid 281#define __NR_getresuid 165
337#undef __NR_getresgid 282#define __NR_setresgid 170
338#undef __NR_chown 283#define __NR_getresgid 171
339#undef __NR_ugetrlimit 284#define __NR_chown 182
340#undef __NR_mmap2 285#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
341#undef __NR_truncate64 286#define __NR_mmap2 192
342#undef __NR_ftruncate64 287#define __NR_truncate64 193
343#undef __NR_stat64 288#define __NR_ftruncate64 194
344#undef __NR_lstat64 289#define __NR_stat64 195
345#undef __NR_fstat64 290#define __NR_lstat64 196
346#undef __NR_lchown32 291#define __NR_fstat64 197
347#undef __NR_getuid32 292#define __NR_lchown32 198
348#undef __NR_getgid32 293#define __NR_getuid32 199
349#undef __NR_geteuid32 294#define __NR_getgid32 200
350#undef __NR_getegid32 295#define __NR_geteuid32 201
351#undef __NR_setreuid32 296#define __NR_getegid32 202
352#undef __NR_setregid32 297#define __NR_setreuid32 203
353#undef __NR_getgroups32 298#define __NR_setregid32 204
354#undef __NR_setgroups32 299#define __NR_getgroups32 205
355#undef __NR_fchown32 300#define __NR_setgroups32 206
356#undef __NR_setresuid32 301#define __NR_fchown32 207
357#undef __NR_getresuid32 302#define __NR_setresuid32 208
358#undef __NR_setresgid32 303#define __NR_getresuid32 209
359#undef __NR_getresgid32 304#define __NR_setresgid32 210
360#undef __NR_chown32 305#define __NR_getresgid32 211
361#undef __NR_setuid32 306#define __NR_chown32 212
362#undef __NR_setgid32 307#define __NR_setuid32 213
363#undef __NR_setfsuid32 308#define __NR_setgid32 214
364#undef __NR_setfsgid32 309#define __NR_setfsuid32 215
365#undef __NR_fcntl64 310#define __NR_setfsgid32 216
366#undef __NR_sendfile64 311#define __NR_fcntl64 221
367#undef __NR_fadvise64_64 312#define __NR_sendfile64 223
368#undef __NR_fstatat64 313#define __NR_fadvise64_64 264
314#define __NR_fstatat64 293
315
316#else
369 317
370#define __NR_select 142 318#define __NR_select 142
371#define __NR_getrlimit 191 /* SuS compliant getrlimit */ 319#define __NR_getrlimit 191 /* SuS compliant getrlimit */
diff --git a/include/asm-s390/z90crypt.h b/include/asm-s390/z90crypt.h
deleted file mode 100644
index 31a2439b07bd..000000000000
--- a/include/asm-s390/z90crypt.h
+++ /dev/null
@@ -1,212 +0,0 @@
1/*
2 * include/asm-s390/z90crypt.h
3 *
4 * z90crypt 1.3.3 (user-visible header)
5 *
6 * Copyright (C) 2001, 2005 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#ifndef __ASM_S390_Z90CRYPT_H
28#define __ASM_S390_Z90CRYPT_H
29#include <linux/ioctl.h>
30
31#define z90crypt_VERSION 1
32#define z90crypt_RELEASE 3 // 2 = PCIXCC, 3 = rewrite for coding standards
33#define z90crypt_VARIANT 3 // 3 = CEX2A support
34
35/**
36 * struct ica_rsa_modexpo
37 *
38 * Requirements:
39 * - outputdatalength is at least as large as inputdatalength.
40 * - All key parts are right justified in their fields, padded on
41 * the left with zeroes.
42 * - length(b_key) = inputdatalength
43 * - length(n_modulus) = inputdatalength
44 */
45struct ica_rsa_modexpo {
46 char __user * inputdata;
47 unsigned int inputdatalength;
48 char __user * outputdata;
49 unsigned int outputdatalength;
50 char __user * b_key;
51 char __user * n_modulus;
52};
53
54/**
55 * struct ica_rsa_modexpo_crt
56 *
57 * Requirements:
58 * - inputdatalength is even.
59 * - outputdatalength is at least as large as inputdatalength.
60 * - All key parts are right justified in their fields, padded on
61 * the left with zeroes.
62 * - length(bp_key) = inputdatalength/2 + 8
63 * - length(bq_key) = inputdatalength/2
64 * - length(np_key) = inputdatalength/2 + 8
65 * - length(nq_key) = inputdatalength/2
66 * - length(u_mult_inv) = inputdatalength/2 + 8
67 */
68struct ica_rsa_modexpo_crt {
69 char __user * inputdata;
70 unsigned int inputdatalength;
71 char __user * outputdata;
72 unsigned int outputdatalength;
73 char __user * bp_key;
74 char __user * bq_key;
75 char __user * np_prime;
76 char __user * nq_prime;
77 char __user * u_mult_inv;
78};
79
80#define Z90_IOCTL_MAGIC 'z' // NOTE: Need to allocate from linux folks
81
82/**
83 * Interface notes:
84 *
85 * The ioctl()s which are implemented (along with relevant details)
86 * are:
87 *
88 * ICARSAMODEXPO
89 * Perform an RSA operation using a Modulus-Exponent pair
90 * This takes an ica_rsa_modexpo struct as its arg.
91 *
92 * NOTE: please refer to the comments preceding this structure
93 * for the implementation details for the contents of the
94 * block
95 *
96 * ICARSACRT
97 * Perform an RSA operation using a Chinese-Remainder Theorem key
98 * This takes an ica_rsa_modexpo_crt struct as its arg.
99 *
100 * NOTE: please refer to the comments preceding this structure
101 * for the implementation details for the contents of the
102 * block
103 *
104 * Z90STAT_TOTALCOUNT
105 * Return an integer count of all device types together.
106 *
107 * Z90STAT_PCICACOUNT
108 * Return an integer count of all PCICAs.
109 *
110 * Z90STAT_PCICCCOUNT
111 * Return an integer count of all PCICCs.
112 *
113 * Z90STAT_PCIXCCMCL2COUNT
114 * Return an integer count of all MCL2 PCIXCCs.
115 *
116 * Z90STAT_PCIXCCMCL3COUNT
117 * Return an integer count of all MCL3 PCIXCCs.
118 *
119 * Z90STAT_CEX2CCOUNT
120 * Return an integer count of all CEX2Cs.
121 *
122 * Z90STAT_CEX2ACOUNT
123 * Return an integer count of all CEX2As.
124 *
125 * Z90STAT_REQUESTQ_COUNT
126 * Return an integer count of the number of entries waiting to be
127 * sent to a device.
128 *
129 * Z90STAT_PENDINGQ_COUNT
130 * Return an integer count of the number of entries sent to a
131 * device awaiting the reply.
132 *
133 * Z90STAT_TOTALOPEN_COUNT
134 * Return an integer count of the number of open file handles.
135 *
136 * Z90STAT_DOMAIN_INDEX
137 * Return the integer value of the Cryptographic Domain.
138 *
139 * Z90STAT_STATUS_MASK
140 * Return an 64 element array of unsigned chars for the status of
141 * all devices.
142 * 0x01: PCICA
143 * 0x02: PCICC
144 * 0x03: PCIXCC_MCL2
145 * 0x04: PCIXCC_MCL3
146 * 0x05: CEX2C
147 * 0x06: CEX2A
148 * 0x0d: device is disabled via the proc filesystem
149 *
150 * Z90STAT_QDEPTH_MASK
151 * Return an 64 element array of unsigned chars for the queue
152 * depth of all devices.
153 *
154 * Z90STAT_PERDEV_REQCNT
155 * Return an 64 element array of unsigned integers for the number
156 * of successfully completed requests per device since the device
157 * was detected and made available.
158 *
159 * ICAZ90STATUS (deprecated)
160 * Return some device driver status in a ica_z90_status struct
161 * This takes an ica_z90_status struct as its arg.
162 *
163 * NOTE: this ioctl() is deprecated, and has been replaced with
164 * single ioctl()s for each type of status being requested
165 *
166 * Z90STAT_PCIXCCCOUNT (deprecated)
167 * Return an integer count of all PCIXCCs (MCL2 + MCL3).
168 * This is DEPRECATED now that MCL3 PCIXCCs are treated differently from
169 * MCL2 PCIXCCs.
170 *
171 * Z90QUIESCE (not recommended)
172 * Quiesce the driver. This is intended to stop all new
173 * requests from being processed. Its use is NOT recommended,
174 * except in circumstances where there is no other way to stop
175 * callers from accessing the driver. Its original use was to
176 * allow the driver to be "drained" of work in preparation for
177 * a system shutdown.
178 *
179 * NOTE: once issued, this ban on new work cannot be undone
180 * except by unloading and reloading the driver.
181 */
182
183/**
184 * Supported ioctl calls
185 */
186#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, Z90_IOCTL_MAGIC, 0x05, 0)
187#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, Z90_IOCTL_MAGIC, 0x06, 0)
188
189/* DEPRECATED status calls (bound for removal at some point) */
190#define ICAZ90STATUS _IOR(Z90_IOCTL_MAGIC, 0x10, struct ica_z90_status)
191#define Z90STAT_PCIXCCCOUNT _IOR(Z90_IOCTL_MAGIC, 0x43, int)
192
193/* unrelated to ICA callers */
194#define Z90QUIESCE _IO(Z90_IOCTL_MAGIC, 0x11)
195
196/* New status calls */
197#define Z90STAT_TOTALCOUNT _IOR(Z90_IOCTL_MAGIC, 0x40, int)
198#define Z90STAT_PCICACOUNT _IOR(Z90_IOCTL_MAGIC, 0x41, int)
199#define Z90STAT_PCICCCOUNT _IOR(Z90_IOCTL_MAGIC, 0x42, int)
200#define Z90STAT_PCIXCCMCL2COUNT _IOR(Z90_IOCTL_MAGIC, 0x4b, int)
201#define Z90STAT_PCIXCCMCL3COUNT _IOR(Z90_IOCTL_MAGIC, 0x4c, int)
202#define Z90STAT_CEX2CCOUNT _IOR(Z90_IOCTL_MAGIC, 0x4d, int)
203#define Z90STAT_CEX2ACOUNT _IOR(Z90_IOCTL_MAGIC, 0x4e, int)
204#define Z90STAT_REQUESTQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x44, int)
205#define Z90STAT_PENDINGQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x45, int)
206#define Z90STAT_TOTALOPEN_COUNT _IOR(Z90_IOCTL_MAGIC, 0x46, int)
207#define Z90STAT_DOMAIN_INDEX _IOR(Z90_IOCTL_MAGIC, 0x47, int)
208#define Z90STAT_STATUS_MASK _IOR(Z90_IOCTL_MAGIC, 0x48, char[64])
209#define Z90STAT_QDEPTH_MASK _IOR(Z90_IOCTL_MAGIC, 0x49, char[64])
210#define Z90STAT_PERDEV_REQCNT _IOR(Z90_IOCTL_MAGIC, 0x4a, int[64])
211
212#endif /* __ASM_S390_Z90CRYPT_H */
diff --git a/include/asm-s390/zcrypt.h b/include/asm-s390/zcrypt.h
new file mode 100644
index 000000000000..7244c68464f2
--- /dev/null
+++ b/include/asm-s390/zcrypt.h
@@ -0,0 +1,285 @@
1/*
2 * include/asm-s390/zcrypt.h
3 *
4 * zcrypt 2.1.0 (user-visible header)
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#ifndef __ASM_S390_ZCRYPT_H
28#define __ASM_S390_ZCRYPT_H
29
30#define ZCRYPT_VERSION 2
31#define ZCRYPT_RELEASE 1
32#define ZCRYPT_VARIANT 0
33
34#include <linux/ioctl.h>
35#include <linux/compiler.h>
36
37/**
38 * struct ica_rsa_modexpo
39 *
40 * Requirements:
41 * - outputdatalength is at least as large as inputdatalength.
42 * - All key parts are right justified in their fields, padded on
43 * the left with zeroes.
44 * - length(b_key) = inputdatalength
45 * - length(n_modulus) = inputdatalength
46 */
47struct ica_rsa_modexpo {
48 char __user * inputdata;
49 unsigned int inputdatalength;
50 char __user * outputdata;
51 unsigned int outputdatalength;
52 char __user * b_key;
53 char __user * n_modulus;
54};
55
56/**
57 * struct ica_rsa_modexpo_crt
58 *
59 * Requirements:
60 * - inputdatalength is even.
61 * - outputdatalength is at least as large as inputdatalength.
62 * - All key parts are right justified in their fields, padded on
63 * the left with zeroes.
64 * - length(bp_key) = inputdatalength/2 + 8
65 * - length(bq_key) = inputdatalength/2
66 * - length(np_key) = inputdatalength/2 + 8
67 * - length(nq_key) = inputdatalength/2
68 * - length(u_mult_inv) = inputdatalength/2 + 8
69 */
70struct ica_rsa_modexpo_crt {
71 char __user * inputdata;
72 unsigned int inputdatalength;
73 char __user * outputdata;
74 unsigned int outputdatalength;
75 char __user * bp_key;
76 char __user * bq_key;
77 char __user * np_prime;
78 char __user * nq_prime;
79 char __user * u_mult_inv;
80};
81
82/**
83 * CPRBX
84 * Note that all shorts and ints are big-endian.
85 * All pointer fields are 16 bytes long, and mean nothing.
86 *
87 * A request CPRB is followed by a request_parameter_block.
88 *
89 * The request (or reply) parameter block is organized thus:
90 * function code
91 * VUD block
92 * key block
93 */
94struct ica_CPRBX {
95 unsigned short cprb_len; /* CPRB length 220 */
96 unsigned char cprb_ver_id; /* CPRB version id. 0x02 */
97 unsigned char pad_000[3]; /* Alignment pad bytes */
98 unsigned char func_id[2]; /* function id 0x5432 */
99 unsigned char cprb_flags[4]; /* Flags */
100 unsigned int req_parml; /* request parameter buffer len */
101 unsigned int req_datal; /* request data buffer */
102 unsigned int rpl_msgbl; /* reply message block length */
103 unsigned int rpld_parml; /* replied parameter block len */
104 unsigned int rpl_datal; /* reply data block len */
105 unsigned int rpld_datal; /* replied data block len */
106 unsigned int req_extbl; /* request extension block len */
107 unsigned char pad_001[4]; /* reserved */
108 unsigned int rpld_extbl; /* replied extension block len */
109 unsigned char padx000[16 - sizeof (char *)];
110 unsigned char * req_parmb; /* request parm block 'address' */
111 unsigned char padx001[16 - sizeof (char *)];
112 unsigned char * req_datab; /* request data block 'address' */
113 unsigned char padx002[16 - sizeof (char *)];
114 unsigned char * rpl_parmb; /* reply parm block 'address' */
115 unsigned char padx003[16 - sizeof (char *)];
116 unsigned char * rpl_datab; /* reply data block 'address' */
117 unsigned char padx004[16 - sizeof (char *)];
118 unsigned char * req_extb; /* request extension block 'addr'*/
119 unsigned char padx005[16 - sizeof (char *)];
120 unsigned char * rpl_extb; /* reply extension block 'addres'*/
121 unsigned short ccp_rtcode; /* server return code */
122 unsigned short ccp_rscode; /* server reason code */
123 unsigned int mac_data_len; /* Mac Data Length */
124 unsigned char logon_id[8]; /* Logon Identifier */
125 unsigned char mac_value[8]; /* Mac Value */
126 unsigned char mac_content_flgs;/* Mac content flag byte */
127 unsigned char pad_002; /* Alignment */
128 unsigned short domain; /* Domain */
129 unsigned char usage_domain[4];/* Usage domain */
130 unsigned char cntrl_domain[4];/* Control domain */
131 unsigned char S390enf_mask[4];/* S/390 enforcement mask */
132 unsigned char pad_004[36]; /* reserved */
133};
134
135/**
136 * xcRB
137 */
138struct ica_xcRB {
139 unsigned short agent_ID;
140 unsigned int user_defined;
141 unsigned short request_ID;
142 unsigned int request_control_blk_length;
143 unsigned char padding1[16 - sizeof (char *)];
144 char __user * request_control_blk_addr;
145 unsigned int request_data_length;
146 char padding2[16 - sizeof (char *)];
147 char __user * request_data_address;
148 unsigned int reply_control_blk_length;
149 char padding3[16 - sizeof (char *)];
150 char __user * reply_control_blk_addr;
151 unsigned int reply_data_length;
152 char padding4[16 - sizeof (char *)];
153 char __user * reply_data_addr;
154 unsigned short priority_window;
155 unsigned int status;
156} __attribute__((packed));
157#define AUTOSELECT ((unsigned int)0xFFFFFFFF)
158
159#define ZCRYPT_IOCTL_MAGIC 'z'
160
161/**
162 * Interface notes:
163 *
164 * The ioctl()s which are implemented (along with relevant details)
165 * are:
166 *
167 * ICARSAMODEXPO
168 * Perform an RSA operation using a Modulus-Exponent pair
169 * This takes an ica_rsa_modexpo struct as its arg.
170 *
171 * NOTE: please refer to the comments preceding this structure
172 * for the implementation details for the contents of the
173 * block
174 *
175 * ICARSACRT
176 * Perform an RSA operation using a Chinese-Remainder Theorem key
177 * This takes an ica_rsa_modexpo_crt struct as its arg.
178 *
179 * NOTE: please refer to the comments preceding this structure
180 * for the implementation details for the contents of the
181 * block
182 *
183 * Z90STAT_TOTALCOUNT
184 * Return an integer count of all device types together.
185 *
186 * Z90STAT_PCICACOUNT
187 * Return an integer count of all PCICAs.
188 *
189 * Z90STAT_PCICCCOUNT
190 * Return an integer count of all PCICCs.
191 *
192 * Z90STAT_PCIXCCMCL2COUNT
193 * Return an integer count of all MCL2 PCIXCCs.
194 *
195 * Z90STAT_PCIXCCMCL3COUNT
196 * Return an integer count of all MCL3 PCIXCCs.
197 *
198 * Z90STAT_CEX2CCOUNT
199 * Return an integer count of all CEX2Cs.
200 *
201 * Z90STAT_CEX2ACOUNT
202 * Return an integer count of all CEX2As.
203 *
204 * Z90STAT_REQUESTQ_COUNT
205 * Return an integer count of the number of entries waiting to be
206 * sent to a device.
207 *
208 * Z90STAT_PENDINGQ_COUNT
209 * Return an integer count of the number of entries sent to a
210 * device awaiting the reply.
211 *
212 * Z90STAT_TOTALOPEN_COUNT
213 * Return an integer count of the number of open file handles.
214 *
215 * Z90STAT_DOMAIN_INDEX
216 * Return the integer value of the Cryptographic Domain.
217 *
218 * Z90STAT_STATUS_MASK
219 * Return an 64 element array of unsigned chars for the status of
220 * all devices.
221 * 0x01: PCICA
222 * 0x02: PCICC
223 * 0x03: PCIXCC_MCL2
224 * 0x04: PCIXCC_MCL3
225 * 0x05: CEX2C
226 * 0x06: CEX2A
227 * 0x0d: device is disabled via the proc filesystem
228 *
229 * Z90STAT_QDEPTH_MASK
230 * Return an 64 element array of unsigned chars for the queue
231 * depth of all devices.
232 *
233 * Z90STAT_PERDEV_REQCNT
234 * Return an 64 element array of unsigned integers for the number
235 * of successfully completed requests per device since the device
236 * was detected and made available.
237 *
238 * ICAZ90STATUS (deprecated)
239 * Return some device driver status in a ica_z90_status struct
240 * This takes an ica_z90_status struct as its arg.
241 *
242 * NOTE: this ioctl() is deprecated, and has been replaced with
243 * single ioctl()s for each type of status being requested
244 *
245 * Z90STAT_PCIXCCCOUNT (deprecated)
246 * Return an integer count of all PCIXCCs (MCL2 + MCL3).
247 * This is DEPRECATED now that MCL3 PCIXCCs are treated differently from
248 * MCL2 PCIXCCs.
249 *
250 * Z90QUIESCE (not recommended)
251 * Quiesce the driver. This is intended to stop all new
252 * requests from being processed. Its use is NOT recommended,
253 * except in circumstances where there is no other way to stop
254 * callers from accessing the driver. Its original use was to
255 * allow the driver to be "drained" of work in preparation for
256 * a system shutdown.
257 *
258 * NOTE: once issued, this ban on new work cannot be undone
259 * except by unloading and reloading the driver.
260 */
261
262/**
263 * Supported ioctl calls
264 */
265#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0)
266#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
267#define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
268
269/* New status calls */
270#define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int)
271#define Z90STAT_PCICACOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x41, int)
272#define Z90STAT_PCICCCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x42, int)
273#define Z90STAT_PCIXCCMCL2COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4b, int)
274#define Z90STAT_PCIXCCMCL3COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4c, int)
275#define Z90STAT_CEX2CCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4d, int)
276#define Z90STAT_CEX2ACOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4e, int)
277#define Z90STAT_REQUESTQ_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x44, int)
278#define Z90STAT_PENDINGQ_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x45, int)
279#define Z90STAT_TOTALOPEN_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x46, int)
280#define Z90STAT_DOMAIN_INDEX _IOR(ZCRYPT_IOCTL_MAGIC, 0x47, int)
281#define Z90STAT_STATUS_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x48, char[64])
282#define Z90STAT_QDEPTH_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x49, char[64])
283#define Z90STAT_PERDEV_REQCNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4a, int[64])
284
285#endif /* __ASM_S390_ZCRYPT_H */
diff --git a/include/asm-sparc/Kbuild b/include/asm-sparc/Kbuild
index e2a57fd7abfa..b22b67a64ecc 100644
--- a/include/asm-sparc/Kbuild
+++ b/include/asm-sparc/Kbuild
@@ -1,6 +1,22 @@
1include include/asm-generic/Kbuild.asm 1include include/asm-generic/Kbuild.asm
2 2
3unifdef-y += fbio.h perfctr.h psr.h 3header-y += apc.h
4header-y += apc.h asi.h auxio.h bpp.h head.h ipc.h jsflash.h \ 4header-y += asi.h
5 openpromio.h pbm.h pconf.h pgtsun4.h reg.h traps.h \ 5header-y += auxio.h
6 turbosparc.h vfc_ioctls.h winmacro.h 6header-y += bpp.h
7header-y += head.h
8header-y += ipc.h
9header-y += jsflash.h
10header-y += openpromio.h
11header-y += pbm.h
12header-y += pconf.h
13header-y += pgtsun4.h
14header-y += reg.h
15header-y += traps.h
16header-y += turbosparc.h
17header-y += vfc_ioctls.h
18header-y += winmacro.h
19
20unifdef-y += fbio.h
21unifdef-y += perfctr.h
22unifdef-y += psr.h
diff --git a/include/asm-sparc64/Kbuild b/include/asm-sparc64/Kbuild
index 9284c3cb27ec..4b59ce46cc2d 100644
--- a/include/asm-sparc64/Kbuild
+++ b/include/asm-sparc64/Kbuild
@@ -4,7 +4,26 @@ ALTARCH := sparc
4ARCHDEF := defined __sparc__ && defined __arch64__ 4ARCHDEF := defined __sparc__ && defined __arch64__
5ALTARCHDEF := defined __sparc__ && !defined __arch64__ 5ALTARCHDEF := defined __sparc__ && !defined __arch64__
6 6
7unifdef-y += fbio.h perfctr.h 7header-y += apb.h
8header-y += apb.h asi.h bbc.h bpp.h display7seg.h envctrl.h floppy.h \ 8header-y += asi.h
9 ipc.h kdebug.h mostek.h openprom.h openpromio.h parport.h \ 9header-y += bbc.h
10 pconf.h psrcompat.h pstate.h reg.h uctx.h utrap.h watchdog.h 10header-y += bpp.h
11header-y += display7seg.h
12header-y += envctrl.h
13header-y += floppy.h
14header-y += ipc.h
15header-y += kdebug.h
16header-y += mostek.h
17header-y += openprom.h
18header-y += openpromio.h
19header-y += parport.h
20header-y += pconf.h
21header-y += psrcompat.h
22header-y += pstate.h
23header-y += reg.h
24header-y += uctx.h
25header-y += utrap.h
26header-y += watchdog.h
27
28unifdef-y += fbio.h
29unifdef-y += perfctr.h
diff --git a/include/asm-x86_64/Kbuild b/include/asm-x86_64/Kbuild
index dc4d101e8a16..40f2f13fe174 100644
--- a/include/asm-x86_64/Kbuild
+++ b/include/asm-x86_64/Kbuild
@@ -4,8 +4,18 @@ ALTARCH := i386
4ARCHDEF := defined __x86_64__ 4ARCHDEF := defined __x86_64__
5ALTARCHDEF := defined __i386__ 5ALTARCHDEF := defined __i386__
6 6
7header-y += boot.h bootsetup.h cpufeature.h debugreg.h ldt.h \ 7header-y += boot.h
8 msr.h prctl.h setup.h sigcontext32.h ucontext.h \ 8header-y += bootsetup.h
9 vsyscall32.h 9header-y += cpufeature.h
10header-y += debugreg.h
11header-y += ldt.h
12header-y += msr.h
13header-y += prctl.h
14header-y += setup.h
15header-y += sigcontext32.h
16header-y += ucontext.h
17header-y += vsyscall32.h
10 18
11unifdef-y += mce.h mtrr.h vsyscall.h 19unifdef-y += mce.h
20unifdef-y += mtrr.h
21unifdef-y += vsyscall.h
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
new file mode 100644
index 000000000000..5748aecdb414
--- /dev/null
+++ b/include/crypto/algapi.h
@@ -0,0 +1,156 @@
1/*
2 * Cryptographic API for algorithms (i.e., low-level API).
3 *
4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 */
12#ifndef _CRYPTO_ALGAPI_H
13#define _CRYPTO_ALGAPI_H
14
15#include <linux/crypto.h>
16
17struct module;
18struct seq_file;
19
20struct crypto_type {
21 unsigned int (*ctxsize)(struct crypto_alg *alg);
22 int (*init)(struct crypto_tfm *tfm);
23 void (*exit)(struct crypto_tfm *tfm);
24 void (*show)(struct seq_file *m, struct crypto_alg *alg);
25};
26
27struct crypto_instance {
28 struct crypto_alg alg;
29
30 struct crypto_template *tmpl;
31 struct hlist_node list;
32
33 void *__ctx[] CRYPTO_MINALIGN_ATTR;
34};
35
36struct crypto_template {
37 struct list_head list;
38 struct hlist_head instances;
39 struct module *module;
40
41 struct crypto_instance *(*alloc)(void *param, unsigned int len);
42 void (*free)(struct crypto_instance *inst);
43
44 char name[CRYPTO_MAX_ALG_NAME];
45};
46
47struct crypto_spawn {
48 struct list_head list;
49 struct crypto_alg *alg;
50 struct crypto_instance *inst;
51};
52
53struct scatter_walk {
54 struct scatterlist *sg;
55 unsigned int offset;
56};
57
58struct blkcipher_walk {
59 union {
60 struct {
61 struct page *page;
62 unsigned long offset;
63 } phys;
64
65 struct {
66 u8 *page;
67 u8 *addr;
68 } virt;
69 } src, dst;
70
71 struct scatter_walk in;
72 unsigned int nbytes;
73
74 struct scatter_walk out;
75 unsigned int total;
76
77 void *page;
78 u8 *buffer;
79 u8 *iv;
80
81 int flags;
82};
83
84extern const struct crypto_type crypto_blkcipher_type;
85extern const struct crypto_type crypto_hash_type;
86
87void crypto_mod_put(struct crypto_alg *alg);
88
89int crypto_register_template(struct crypto_template *tmpl);
90void crypto_unregister_template(struct crypto_template *tmpl);
91struct crypto_template *crypto_lookup_template(const char *name);
92
93int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
94 struct crypto_instance *inst);
95void crypto_drop_spawn(struct crypto_spawn *spawn);
96struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn);
97
98struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len,
99 u32 type, u32 mask);
100struct crypto_instance *crypto_alloc_instance(const char *name,
101 struct crypto_alg *alg);
102
103int blkcipher_walk_done(struct blkcipher_desc *desc,
104 struct blkcipher_walk *walk, int err);
105int blkcipher_walk_virt(struct blkcipher_desc *desc,
106 struct blkcipher_walk *walk);
107int blkcipher_walk_phys(struct blkcipher_desc *desc,
108 struct blkcipher_walk *walk);
109
110static inline void *crypto_tfm_ctx_aligned(struct crypto_tfm *tfm)
111{
112 unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm);
113 unsigned long align = crypto_tfm_alg_alignmask(tfm);
114
115 if (align <= crypto_tfm_ctx_alignment())
116 align = 1;
117 return (void *)ALIGN(addr, align);
118}
119
120static inline void *crypto_instance_ctx(struct crypto_instance *inst)
121{
122 return inst->__ctx;
123}
124
125static inline void *crypto_blkcipher_ctx(struct crypto_blkcipher *tfm)
126{
127 return crypto_tfm_ctx(&tfm->base);
128}
129
130static inline void *crypto_blkcipher_ctx_aligned(struct crypto_blkcipher *tfm)
131{
132 return crypto_tfm_ctx_aligned(&tfm->base);
133}
134
135static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm)
136{
137 return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher;
138}
139
140static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm)
141{
142 return crypto_tfm_ctx_aligned(&tfm->base);
143}
144
145static inline void blkcipher_walk_init(struct blkcipher_walk *walk,
146 struct scatterlist *dst,
147 struct scatterlist *src,
148 unsigned int nbytes)
149{
150 walk->in.sg = src;
151 walk->out.sg = dst;
152 walk->total = nbytes;
153}
154
155#endif /* _CRYPTO_ALGAPI_H */
156
diff --git a/include/crypto/twofish.h b/include/crypto/twofish.h
new file mode 100644
index 000000000000..c408522595c6
--- /dev/null
+++ b/include/crypto/twofish.h
@@ -0,0 +1,22 @@
1#ifndef _CRYPTO_TWOFISH_H
2#define _CRYPTO_TWOFISH_H
3
4#include <linux/types.h>
5
6#define TF_MIN_KEY_SIZE 16
7#define TF_MAX_KEY_SIZE 32
8#define TF_BLOCK_SIZE 16
9
10struct crypto_tfm;
11
12/* Structure for an expanded Twofish key. s contains the key-dependent
13 * S-boxes composed with the MDS matrix; w contains the eight "whitening"
14 * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
15 * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
16struct twofish_ctx {
17 u32 s[4][256], w[8], k[32];
18};
19
20int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len);
21
22#endif
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 2b8a7d68fae3..7d076d97b2f7 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -1,63 +1,343 @@
1header-y := byteorder/ dvb/ hdlc/ isdn/ nfsd/ raid/ sunrpc/ tc_act/ \ 1header-y += byteorder/
2 netfilter/ netfilter_arp/ netfilter_bridge/ netfilter_ipv4/ \ 2header-y += dvb/
3 netfilter_ipv6/ 3header-y += hdlc/
4header-y += isdn/
5header-y += nfsd/
6header-y += raid/
7header-y += sunrpc/
8header-y += tc_act/
9header-y += netfilter/
10header-y += netfilter_arp/
11header-y += netfilter_bridge/
12header-y += netfilter_ipv4/
13header-y += netfilter_ipv6/
4 14
5header-y += affs_fs.h affs_hardblocks.h aio_abi.h a.out.h arcfb.h \ 15header-y += affs_fs.h
6 atmapi.h atmbr2684.h atmclip.h atm_eni.h atm_he.h \ 16header-y += affs_hardblocks.h
7 atm_idt77105.h atmioc.h atmlec.h atmmpc.h atm_nicstar.h \ 17header-y += aio_abi.h
8 atmppp.h atmsap.h atmsvc.h atm_zatm.h auto_fs4.h auxvec.h \ 18header-y += a.out.h
9 awe_voice.h ax25.h b1lli.h baycom.h bfs_fs.h blkpg.h \ 19header-y += arcfb.h
10 bpqether.h cdk.h chio.h coda_psdev.h coff.h comstats.h \ 20header-y += atmapi.h
11 consolemap.h cycx_cfm.h dm-ioctl.h dn.h dqblk_v1.h \ 21header-y += atmbr2684.h
12 dqblk_v2.h dqblk_xfs.h efs_fs_sb.h elf-fdpic.h elf.h elf-em.h \ 22header-y += atmclip.h
13 fadvise.h fd.h fdreg.h ftape-header-segment.h ftape-vendors.h \ 23header-y += atm_eni.h
14 fuse.h futex.h genetlink.h gen_stats.h gigaset_dev.h hdsmart.h \ 24header-y += atm_he.h
15 hpfs_fs.h hysdn_if.h i2c-dev.h i8k.h icmp.h \ 25header-y += atm_idt77105.h
16 if_arcnet.h if_arp.h if_bonding.h if_cablemodem.h if_fc.h \ 26header-y += atmioc.h
17 if_fddi.h if.h if_hippi.h if_infiniband.h if_packet.h \ 27header-y += atmlec.h
18 if_plip.h if_ppp.h if_slip.h if_strip.h if_tunnel.h in6.h \ 28header-y += atmmpc.h
19 in_route.h ioctl.h ip.h ipmi_msgdefs.h ip_mp_alg.h ipsec.h \ 29header-y += atm_nicstar.h
20 ipx.h irda.h isdn_divertif.h iso_fs.h ite_gpio.h ixjuser.h \ 30header-y += atmppp.h
21 jffs2.h keyctl.h limits.h major.h matroxfb.h meye.h minix_fs.h \ 31header-y += atmsap.h
22 mmtimer.h mqueue.h mtio.h ncp_no.h netfilter_arp.h netrom.h \ 32header-y += atmsvc.h
23 nfs2.h nfs4_mount.h nfs_mount.h openprom_fs.h param.h \ 33header-y += atm_zatm.h
24 pci_ids.h pci_regs.h personality.h pfkeyv2.h pg.h pkt_cls.h \ 34header-y += auto_fs4.h
25 pkt_sched.h posix_types.h ppdev.h prctl.h ps2esdi.h qic117.h \ 35header-y += auxvec.h
26 qnxtypes.h quotaio_v1.h quotaio_v2.h radeonfb.h raw.h \ 36header-y += awe_voice.h
27 resource.h rose.h sctp.h smbno.h snmp.h sockios.h som.h \ 37header-y += ax25.h
28 sound.h stddef.h synclink.h telephony.h termios.h ticable.h \ 38header-y += b1lli.h
29 times.h tiocl.h tipc.h toshiba.h ultrasound.h un.h utime.h \ 39header-y += baycom.h
30 utsname.h video_decoder.h video_encoder.h videotext.h vt.h \ 40header-y += bfs_fs.h
31 wavefront.h wireless.h xattr.h x25.h zorro_ids.h 41header-y += blkpg.h
42header-y += bpqether.h
43header-y += cdk.h
44header-y += chio.h
45header-y += coda_psdev.h
46header-y += coff.h
47header-y += comstats.h
48header-y += consolemap.h
49header-y += cycx_cfm.h
50header-y += dm-ioctl.h
51header-y += dn.h
52header-y += dqblk_v1.h
53header-y += dqblk_v2.h
54header-y += dqblk_xfs.h
55header-y += efs_fs_sb.h
56header-y += elf-fdpic.h
57header-y += elf.h
58header-y += elf-em.h
59header-y += fadvise.h
60header-y += fd.h
61header-y += fdreg.h
62header-y += ftape-header-segment.h
63header-y += ftape-vendors.h
64header-y += fuse.h
65header-y += futex.h
66header-y += genetlink.h
67header-y += gen_stats.h
68header-y += gigaset_dev.h
69header-y += hdsmart.h
70header-y += hpfs_fs.h
71header-y += hysdn_if.h
72header-y += i2c-dev.h
73header-y += i8k.h
74header-y += icmp.h
75header-y += if_arcnet.h
76header-y += if_arp.h
77header-y += if_bonding.h
78header-y += if_cablemodem.h
79header-y += if_fc.h
80header-y += if_fddi.h
81header-y += if.h
82header-y += if_hippi.h
83header-y += if_infiniband.h
84header-y += if_packet.h
85header-y += if_plip.h
86header-y += if_ppp.h
87header-y += if_slip.h
88header-y += if_strip.h
89header-y += if_tunnel.h
90header-y += in6.h
91header-y += in_route.h
92header-y += ioctl.h
93header-y += ip.h
94header-y += ipmi_msgdefs.h
95header-y += ip_mp_alg.h
96header-y += ipsec.h
97header-y += ipx.h
98header-y += irda.h
99header-y += isdn_divertif.h
100header-y += iso_fs.h
101header-y += ite_gpio.h
102header-y += ixjuser.h
103header-y += jffs2.h
104header-y += keyctl.h
105header-y += limits.h
106header-y += major.h
107header-y += matroxfb.h
108header-y += meye.h
109header-y += minix_fs.h
110header-y += mmtimer.h
111header-y += mqueue.h
112header-y += mtio.h
113header-y += ncp_no.h
114header-y += netfilter_arp.h
115header-y += netrom.h
116header-y += nfs2.h
117header-y += nfs4_mount.h
118header-y += nfs_mount.h
119header-y += openprom_fs.h
120header-y += param.h
121header-y += pci_ids.h
122header-y += pci_regs.h
123header-y += personality.h
124header-y += pfkeyv2.h
125header-y += pg.h
126header-y += pkt_cls.h
127header-y += pkt_sched.h
128header-y += posix_types.h
129header-y += ppdev.h
130header-y += prctl.h
131header-y += ps2esdi.h
132header-y += qic117.h
133header-y += qnxtypes.h
134header-y += quotaio_v1.h
135header-y += quotaio_v2.h
136header-y += radeonfb.h
137header-y += raw.h
138header-y += resource.h
139header-y += rose.h
140header-y += sctp.h
141header-y += smbno.h
142header-y += snmp.h
143header-y += sockios.h
144header-y += som.h
145header-y += sound.h
146header-y += stddef.h
147header-y += synclink.h
148header-y += telephony.h
149header-y += termios.h
150header-y += ticable.h
151header-y += times.h
152header-y += tiocl.h
153header-y += tipc.h
154header-y += toshiba.h
155header-y += ultrasound.h
156header-y += un.h
157header-y += utime.h
158header-y += utsname.h
159header-y += video_decoder.h
160header-y += video_encoder.h
161header-y += videotext.h
162header-y += vt.h
163header-y += wavefront.h
164header-y += wireless.h
165header-y += xattr.h
166header-y += x25.h
167header-y += zorro_ids.h
32 168
33unifdef-y += acct.h adb.h adfs_fs.h agpgart.h apm_bios.h atalk.h \ 169unifdef-y += acct.h
34 atmarp.h atmdev.h atm.h atm_tcp.h audit.h auto_fs.h binfmts.h \ 170unifdef-y += adb.h
35 capability.h capi.h cciss_ioctl.h cdrom.h cm4000_cs.h \ 171unifdef-y += adfs_fs.h
36 cn_proc.h coda.h connector.h cramfs_fs.h cuda.h cyclades.h \ 172unifdef-y += agpgart.h
37 dccp.h dirent.h divert.h elfcore.h errno.h errqueue.h \ 173unifdef-y += apm_bios.h
38 ethtool.h eventpoll.h ext2_fs.h ext3_fs.h fb.h fcntl.h \ 174unifdef-y += atalk.h
39 filter.h flat.h fs.h ftape.h gameport.h generic_serial.h \ 175unifdef-y += atmarp.h
40 genhd.h hayesesp.h hdlcdrv.h hdlc.h hdreg.h hiddev.h hpet.h \ 176unifdef-y += atmdev.h
41 i2c.h i2o-dev.h icmpv6.h if_bridge.h if_ec.h \ 177unifdef-y += atm.h
42 if_eql.h if_ether.h if_frad.h if_ltalk.h if_pppox.h \ 178unifdef-y += atm_tcp.h
43 if_shaper.h if_tr.h if_tun.h if_vlan.h if_wanpipe.h igmp.h \ 179unifdef-y += audit.h
44 inet_diag.h in.h inotify.h input.h ipc.h ipmi.h ipv6.h \ 180unifdef-y += auto_fs.h
45 ipv6_route.h isdn.h isdnif.h isdn_ppp.h isicom.h jbd.h \ 181unifdef-y += binfmts.h
46 joystick.h kdev_t.h kd.h kernelcapi.h kernel.h keyboard.h \ 182unifdef-y += capability.h
47 llc.h loop.h lp.h mempolicy.h mii.h mman.h mroute.h msdos_fs.h \ 183unifdef-y += capi.h
48 msg.h nbd.h ncp_fs.h ncp.h ncp_mount.h netdevice.h \ 184unifdef-y += cciss_ioctl.h
49 netfilter_bridge.h netfilter_decnet.h netfilter.h \ 185unifdef-y += cdrom.h
50 netfilter_ipv4.h netfilter_ipv6.h netfilter_logging.h net.h \ 186unifdef-y += cm4000_cs.h
51 netlink.h nfs3.h nfs4.h nfsacl.h nfs_fs.h nfs.h nfs_idmap.h \ 187unifdef-y += cn_proc.h
52 n_r3964.h nubus.h nvram.h parport.h patchkey.h pci.h pktcdvd.h \ 188unifdef-y += coda.h
53 pmu.h poll.h ppp_defs.h ppp-comp.h ptrace.h qnx4_fs.h quota.h \ 189unifdef-y += connector.h
54 random.h reboot.h reiserfs_fs.h reiserfs_xattr.h romfs_fs.h \ 190unifdef-y += cramfs_fs.h
55 route.h rtc.h rtnetlink.h scc.h sched.h sdla.h \ 191unifdef-y += cuda.h
56 selinux_netlink.h sem.h serial_core.h serial.h serio.h shm.h \ 192unifdef-y += cyclades.h
57 signal.h smb_fs.h smb.h smb_mount.h socket.h sonet.h sonypi.h \ 193unifdef-y += dccp.h
58 soundcard.h stat.h sysctl.h tcp.h time.h timex.h tty.h types.h \ 194unifdef-y += dirent.h
59 udf_fs_i.h udp.h uinput.h uio.h unistd.h usb_ch9.h \ 195unifdef-y += divert.h
60 usbdevice_fs.h user.h videodev2.h videodev.h wait.h \ 196unifdef-y += elfcore.h
61 wanrouter.h watchdog.h xfrm.h zftape.h 197unifdef-y += errno.h
198unifdef-y += errqueue.h
199unifdef-y += ethtool.h
200unifdef-y += eventpoll.h
201unifdef-y += ext2_fs.h
202unifdef-y += ext3_fs.h
203unifdef-y += fb.h
204unifdef-y += fcntl.h
205unifdef-y += filter.h
206unifdef-y += flat.h
207unifdef-y += fs.h
208unifdef-y += ftape.h
209unifdef-y += gameport.h
210unifdef-y += generic_serial.h
211unifdef-y += genhd.h
212unifdef-y += hayesesp.h
213unifdef-y += hdlcdrv.h
214unifdef-y += hdlc.h
215unifdef-y += hdreg.h
216unifdef-y += hiddev.h
217unifdef-y += hpet.h
218unifdef-y += i2c.h
219unifdef-y += i2o-dev.h
220unifdef-y += icmpv6.h
221unifdef-y += if_bridge.h
222unifdef-y += if_ec.h
223unifdef-y += if_eql.h
224unifdef-y += if_ether.h
225unifdef-y += if_frad.h
226unifdef-y += if_ltalk.h
227unifdef-y += if_pppox.h
228unifdef-y += if_shaper.h
229unifdef-y += if_tr.h
230unifdef-y += if_tun.h
231unifdef-y += if_vlan.h
232unifdef-y += if_wanpipe.h
233unifdef-y += igmp.h
234unifdef-y += inet_diag.h
235unifdef-y += in.h
236unifdef-y += inotify.h
237unifdef-y += input.h
238unifdef-y += ipc.h
239unifdef-y += ipmi.h
240unifdef-y += ipv6.h
241unifdef-y += ipv6_route.h
242unifdef-y += isdn.h
243unifdef-y += isdnif.h
244unifdef-y += isdn_ppp.h
245unifdef-y += isicom.h
246unifdef-y += jbd.h
247unifdef-y += joystick.h
248unifdef-y += kdev_t.h
249unifdef-y += kd.h
250unifdef-y += kernelcapi.h
251unifdef-y += kernel.h
252unifdef-y += keyboard.h
253unifdef-y += llc.h
254unifdef-y += loop.h
255unifdef-y += lp.h
256unifdef-y += mempolicy.h
257unifdef-y += mii.h
258unifdef-y += mman.h
259unifdef-y += mroute.h
260unifdef-y += msdos_fs.h
261unifdef-y += msg.h
262unifdef-y += nbd.h
263unifdef-y += ncp_fs.h
264unifdef-y += ncp.h
265unifdef-y += ncp_mount.h
266unifdef-y += netdevice.h
267unifdef-y += netfilter_bridge.h
268unifdef-y += netfilter_decnet.h
269unifdef-y += netfilter.h
270unifdef-y += netfilter_ipv4.h
271unifdef-y += netfilter_ipv6.h
272unifdef-y += netfilter_logging.h
273unifdef-y += net.h
274unifdef-y += netlink.h
275unifdef-y += nfs3.h
276unifdef-y += nfs4.h
277unifdef-y += nfsacl.h
278unifdef-y += nfs_fs.h
279unifdef-y += nfs.h
280unifdef-y += nfs_idmap.h
281unifdef-y += n_r3964.h
282unifdef-y += nubus.h
283unifdef-y += nvram.h
284unifdef-y += parport.h
285unifdef-y += patchkey.h
286unifdef-y += pci.h
287unifdef-y += pktcdvd.h
288unifdef-y += pmu.h
289unifdef-y += poll.h
290unifdef-y += ppp_defs.h
291unifdef-y += ppp-comp.h
292unifdef-y += ptrace.h
293unifdef-y += qnx4_fs.h
294unifdef-y += quota.h
295unifdef-y += random.h
296unifdef-y += reboot.h
297unifdef-y += reiserfs_fs.h
298unifdef-y += reiserfs_xattr.h
299unifdef-y += romfs_fs.h
300unifdef-y += route.h
301unifdef-y += rtc.h
302unifdef-y += rtnetlink.h
303unifdef-y += scc.h
304unifdef-y += sched.h
305unifdef-y += sdla.h
306unifdef-y += selinux_netlink.h
307unifdef-y += sem.h
308unifdef-y += serial_core.h
309unifdef-y += serial.h
310unifdef-y += serio.h
311unifdef-y += shm.h
312unifdef-y += signal.h
313unifdef-y += smb_fs.h
314unifdef-y += smb.h
315unifdef-y += smb_mount.h
316unifdef-y += socket.h
317unifdef-y += sonet.h
318unifdef-y += sonypi.h
319unifdef-y += soundcard.h
320unifdef-y += stat.h
321unifdef-y += sysctl.h
322unifdef-y += tcp.h
323unifdef-y += time.h
324unifdef-y += timex.h
325unifdef-y += tty.h
326unifdef-y += types.h
327unifdef-y += udf_fs_i.h
328unifdef-y += udp.h
329unifdef-y += uinput.h
330unifdef-y += uio.h
331unifdef-y += unistd.h
332unifdef-y += usb_ch9.h
333unifdef-y += usbdevice_fs.h
334unifdef-y += user.h
335unifdef-y += videodev2.h
336unifdef-y += videodev.h
337unifdef-y += wait.h
338unifdef-y += wanrouter.h
339unifdef-y += watchdog.h
340unifdef-y += xfrm.h
341unifdef-y += zftape.h
62 342
63objhdr-y := version.h 343objhdr-y += version.h
diff --git a/include/linux/byteorder/Kbuild b/include/linux/byteorder/Kbuild
index 84a57d4fb212..56499ab9e32e 100644
--- a/include/linux/byteorder/Kbuild
+++ b/include/linux/byteorder/Kbuild
@@ -1,2 +1,7 @@
1unifdef-y += generic.h swabb.h swab.h 1header-y += big_endian.h
2header-y += big_endian.h little_endian.h pdp_endian.h 2header-y += little_endian.h
3header-y += pdp_endian.h
4
5unifdef-y += generic.h
6unifdef-y += swabb.h
7unifdef-y += swab.h
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 7f946241b879..8f2ffa4caabf 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -17,20 +17,36 @@
17#ifndef _LINUX_CRYPTO_H 17#ifndef _LINUX_CRYPTO_H
18#define _LINUX_CRYPTO_H 18#define _LINUX_CRYPTO_H
19 19
20#include <asm/atomic.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/types.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/slab.h>
24#include <linux/string.h> 25#include <linux/string.h>
25#include <asm/page.h> 26#include <linux/uaccess.h>
26 27
27/* 28/*
28 * Algorithm masks and types. 29 * Algorithm masks and types.
29 */ 30 */
30#define CRYPTO_ALG_TYPE_MASK 0x000000ff 31#define CRYPTO_ALG_TYPE_MASK 0x0000000f
31#define CRYPTO_ALG_TYPE_CIPHER 0x00000001 32#define CRYPTO_ALG_TYPE_CIPHER 0x00000001
32#define CRYPTO_ALG_TYPE_DIGEST 0x00000002 33#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
33#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004 34#define CRYPTO_ALG_TYPE_HASH 0x00000003
35#define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004
36#define CRYPTO_ALG_TYPE_COMPRESS 0x00000005
37
38#define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e
39
40#define CRYPTO_ALG_LARVAL 0x00000010
41#define CRYPTO_ALG_DEAD 0x00000020
42#define CRYPTO_ALG_DYING 0x00000040
43#define CRYPTO_ALG_ASYNC 0x00000080
44
45/*
46 * Set this bit if and only if the algorithm requires another algorithm of
47 * the same type to handle corner cases.
48 */
49#define CRYPTO_ALG_NEED_FALLBACK 0x00000100
34 50
35/* 51/*
36 * Transform masks and values (for crt_flags). 52 * Transform masks and values (for crt_flags).
@@ -61,8 +77,37 @@
61#define CRYPTO_DIR_ENCRYPT 1 77#define CRYPTO_DIR_ENCRYPT 1
62#define CRYPTO_DIR_DECRYPT 0 78#define CRYPTO_DIR_DECRYPT 0
63 79
80/*
81 * The macro CRYPTO_MINALIGN_ATTR (along with the void * type in the actual
82 * declaration) is used to ensure that the crypto_tfm context structure is
83 * aligned correctly for the given architecture so that there are no alignment
84 * faults for C data types. In particular, this is required on platforms such
85 * as arm where pointers are 32-bit aligned but there are data types such as
86 * u64 which require 64-bit alignment.
87 */
88#if defined(ARCH_KMALLOC_MINALIGN)
89#define CRYPTO_MINALIGN ARCH_KMALLOC_MINALIGN
90#elif defined(ARCH_SLAB_MINALIGN)
91#define CRYPTO_MINALIGN ARCH_SLAB_MINALIGN
92#endif
93
94#ifdef CRYPTO_MINALIGN
95#define CRYPTO_MINALIGN_ATTR __attribute__ ((__aligned__(CRYPTO_MINALIGN)))
96#else
97#define CRYPTO_MINALIGN_ATTR
98#endif
99
64struct scatterlist; 100struct scatterlist;
101struct crypto_blkcipher;
102struct crypto_hash;
65struct crypto_tfm; 103struct crypto_tfm;
104struct crypto_type;
105
106struct blkcipher_desc {
107 struct crypto_blkcipher *tfm;
108 void *info;
109 u32 flags;
110};
66 111
67struct cipher_desc { 112struct cipher_desc {
68 struct crypto_tfm *tfm; 113 struct crypto_tfm *tfm;
@@ -72,30 +117,50 @@ struct cipher_desc {
72 void *info; 117 void *info;
73}; 118};
74 119
120struct hash_desc {
121 struct crypto_hash *tfm;
122 u32 flags;
123};
124
75/* 125/*
76 * Algorithms: modular crypto algorithm implementations, managed 126 * Algorithms: modular crypto algorithm implementations, managed
77 * via crypto_register_alg() and crypto_unregister_alg(). 127 * via crypto_register_alg() and crypto_unregister_alg().
78 */ 128 */
129struct blkcipher_alg {
130 int (*setkey)(struct crypto_tfm *tfm, const u8 *key,
131 unsigned int keylen);
132 int (*encrypt)(struct blkcipher_desc *desc,
133 struct scatterlist *dst, struct scatterlist *src,
134 unsigned int nbytes);
135 int (*decrypt)(struct blkcipher_desc *desc,
136 struct scatterlist *dst, struct scatterlist *src,
137 unsigned int nbytes);
138
139 unsigned int min_keysize;
140 unsigned int max_keysize;
141 unsigned int ivsize;
142};
143
79struct cipher_alg { 144struct cipher_alg {
80 unsigned int cia_min_keysize; 145 unsigned int cia_min_keysize;
81 unsigned int cia_max_keysize; 146 unsigned int cia_max_keysize;
82 int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key, 147 int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key,
83 unsigned int keylen, u32 *flags); 148 unsigned int keylen);
84 void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); 149 void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
85 void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); 150 void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
86 151
87 unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc, 152 unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc,
88 u8 *dst, const u8 *src, 153 u8 *dst, const u8 *src,
89 unsigned int nbytes); 154 unsigned int nbytes) __deprecated;
90 unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc, 155 unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc,
91 u8 *dst, const u8 *src, 156 u8 *dst, const u8 *src,
92 unsigned int nbytes); 157 unsigned int nbytes) __deprecated;
93 unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc, 158 unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc,
94 u8 *dst, const u8 *src, 159 u8 *dst, const u8 *src,
95 unsigned int nbytes); 160 unsigned int nbytes) __deprecated;
96 unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc, 161 unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc,
97 u8 *dst, const u8 *src, 162 u8 *dst, const u8 *src,
98 unsigned int nbytes); 163 unsigned int nbytes) __deprecated;
99}; 164};
100 165
101struct digest_alg { 166struct digest_alg {
@@ -105,7 +170,20 @@ struct digest_alg {
105 unsigned int len); 170 unsigned int len);
106 void (*dia_final)(struct crypto_tfm *tfm, u8 *out); 171 void (*dia_final)(struct crypto_tfm *tfm, u8 *out);
107 int (*dia_setkey)(struct crypto_tfm *tfm, const u8 *key, 172 int (*dia_setkey)(struct crypto_tfm *tfm, const u8 *key,
108 unsigned int keylen, u32 *flags); 173 unsigned int keylen);
174};
175
176struct hash_alg {
177 int (*init)(struct hash_desc *desc);
178 int (*update)(struct hash_desc *desc, struct scatterlist *sg,
179 unsigned int nbytes);
180 int (*final)(struct hash_desc *desc, u8 *out);
181 int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
182 unsigned int nbytes, u8 *out);
183 int (*setkey)(struct crypto_hash *tfm, const u8 *key,
184 unsigned int keylen);
185
186 unsigned int digestsize;
109}; 187};
110 188
111struct compress_alg { 189struct compress_alg {
@@ -115,30 +193,40 @@ struct compress_alg {
115 unsigned int slen, u8 *dst, unsigned int *dlen); 193 unsigned int slen, u8 *dst, unsigned int *dlen);
116}; 194};
117 195
196#define cra_blkcipher cra_u.blkcipher
118#define cra_cipher cra_u.cipher 197#define cra_cipher cra_u.cipher
119#define cra_digest cra_u.digest 198#define cra_digest cra_u.digest
199#define cra_hash cra_u.hash
120#define cra_compress cra_u.compress 200#define cra_compress cra_u.compress
121 201
122struct crypto_alg { 202struct crypto_alg {
123 struct list_head cra_list; 203 struct list_head cra_list;
204 struct list_head cra_users;
205
124 u32 cra_flags; 206 u32 cra_flags;
125 unsigned int cra_blocksize; 207 unsigned int cra_blocksize;
126 unsigned int cra_ctxsize; 208 unsigned int cra_ctxsize;
127 unsigned int cra_alignmask; 209 unsigned int cra_alignmask;
128 210
129 int cra_priority; 211 int cra_priority;
212 atomic_t cra_refcnt;
130 213
131 char cra_name[CRYPTO_MAX_ALG_NAME]; 214 char cra_name[CRYPTO_MAX_ALG_NAME];
132 char cra_driver_name[CRYPTO_MAX_ALG_NAME]; 215 char cra_driver_name[CRYPTO_MAX_ALG_NAME];
133 216
217 const struct crypto_type *cra_type;
218
134 union { 219 union {
220 struct blkcipher_alg blkcipher;
135 struct cipher_alg cipher; 221 struct cipher_alg cipher;
136 struct digest_alg digest; 222 struct digest_alg digest;
223 struct hash_alg hash;
137 struct compress_alg compress; 224 struct compress_alg compress;
138 } cra_u; 225 } cra_u;
139 226
140 int (*cra_init)(struct crypto_tfm *tfm); 227 int (*cra_init)(struct crypto_tfm *tfm);
141 void (*cra_exit)(struct crypto_tfm *tfm); 228 void (*cra_exit)(struct crypto_tfm *tfm);
229 void (*cra_destroy)(struct crypto_alg *alg);
142 230
143 struct module *cra_module; 231 struct module *cra_module;
144}; 232};
@@ -153,20 +241,39 @@ int crypto_unregister_alg(struct crypto_alg *alg);
153 * Algorithm query interface. 241 * Algorithm query interface.
154 */ 242 */
155#ifdef CONFIG_CRYPTO 243#ifdef CONFIG_CRYPTO
156int crypto_alg_available(const char *name, u32 flags); 244int crypto_alg_available(const char *name, u32 flags)
245 __deprecated_for_modules;
246int crypto_has_alg(const char *name, u32 type, u32 mask);
157#else 247#else
248static int crypto_alg_available(const char *name, u32 flags);
249 __deprecated_for_modules;
158static inline int crypto_alg_available(const char *name, u32 flags) 250static inline int crypto_alg_available(const char *name, u32 flags)
159{ 251{
160 return 0; 252 return 0;
161} 253}
254
255static inline int crypto_has_alg(const char *name, u32 type, u32 mask)
256{
257 return 0;
258}
162#endif 259#endif
163 260
164/* 261/*
165 * Transforms: user-instantiated objects which encapsulate algorithms 262 * Transforms: user-instantiated objects which encapsulate algorithms
166 * and core processing logic. Managed via crypto_alloc_tfm() and 263 * and core processing logic. Managed via crypto_alloc_*() and
167 * crypto_free_tfm(), as well as the various helpers below. 264 * crypto_free_*(), as well as the various helpers below.
168 */ 265 */
169 266
267struct blkcipher_tfm {
268 void *iv;
269 int (*setkey)(struct crypto_tfm *tfm, const u8 *key,
270 unsigned int keylen);
271 int (*encrypt)(struct blkcipher_desc *desc, struct scatterlist *dst,
272 struct scatterlist *src, unsigned int nbytes);
273 int (*decrypt)(struct blkcipher_desc *desc, struct scatterlist *dst,
274 struct scatterlist *src, unsigned int nbytes);
275};
276
170struct cipher_tfm { 277struct cipher_tfm {
171 void *cit_iv; 278 void *cit_iv;
172 unsigned int cit_ivsize; 279 unsigned int cit_ivsize;
@@ -190,20 +297,20 @@ struct cipher_tfm {
190 struct scatterlist *src, 297 struct scatterlist *src,
191 unsigned int nbytes, u8 *iv); 298 unsigned int nbytes, u8 *iv);
192 void (*cit_xor_block)(u8 *dst, const u8 *src); 299 void (*cit_xor_block)(u8 *dst, const u8 *src);
300 void (*cit_encrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
301 void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
193}; 302};
194 303
195struct digest_tfm { 304struct hash_tfm {
196 void (*dit_init)(struct crypto_tfm *tfm); 305 int (*init)(struct hash_desc *desc);
197 void (*dit_update)(struct crypto_tfm *tfm, 306 int (*update)(struct hash_desc *desc,
198 struct scatterlist *sg, unsigned int nsg); 307 struct scatterlist *sg, unsigned int nsg);
199 void (*dit_final)(struct crypto_tfm *tfm, u8 *out); 308 int (*final)(struct hash_desc *desc, u8 *out);
200 void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, 309 int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
201 unsigned int nsg, u8 *out); 310 unsigned int nsg, u8 *out);
202 int (*dit_setkey)(struct crypto_tfm *tfm, 311 int (*setkey)(struct crypto_hash *tfm, const u8 *key,
203 const u8 *key, unsigned int keylen); 312 unsigned int keylen);
204#ifdef CONFIG_CRYPTO_HMAC 313 unsigned int digestsize;
205 void *dit_hmac_block;
206#endif
207}; 314};
208 315
209struct compress_tfm { 316struct compress_tfm {
@@ -215,8 +322,9 @@ struct compress_tfm {
215 u8 *dst, unsigned int *dlen); 322 u8 *dst, unsigned int *dlen);
216}; 323};
217 324
325#define crt_blkcipher crt_u.blkcipher
218#define crt_cipher crt_u.cipher 326#define crt_cipher crt_u.cipher
219#define crt_digest crt_u.digest 327#define crt_hash crt_u.hash
220#define crt_compress crt_u.compress 328#define crt_compress crt_u.compress
221 329
222struct crypto_tfm { 330struct crypto_tfm {
@@ -224,30 +332,43 @@ struct crypto_tfm {
224 u32 crt_flags; 332 u32 crt_flags;
225 333
226 union { 334 union {
335 struct blkcipher_tfm blkcipher;
227 struct cipher_tfm cipher; 336 struct cipher_tfm cipher;
228 struct digest_tfm digest; 337 struct hash_tfm hash;
229 struct compress_tfm compress; 338 struct compress_tfm compress;
230 } crt_u; 339 } crt_u;
231 340
232 struct crypto_alg *__crt_alg; 341 struct crypto_alg *__crt_alg;
233 342
234 char __crt_ctx[] __attribute__ ((__aligned__)); 343 void *__crt_ctx[] CRYPTO_MINALIGN_ATTR;
344};
345
346#define crypto_cipher crypto_tfm
347#define crypto_comp crypto_tfm
348
349struct crypto_blkcipher {
350 struct crypto_tfm base;
351};
352
353struct crypto_hash {
354 struct crypto_tfm base;
355};
356
357enum {
358 CRYPTOA_UNSPEC,
359 CRYPTOA_ALG,
360};
361
362struct crypto_attr_alg {
363 char name[CRYPTO_MAX_ALG_NAME];
235}; 364};
236 365
237/* 366/*
238 * Transform user interface. 367 * Transform user interface.
239 */ 368 */
240 369
241/*
242 * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
243 * If that fails and the kernel supports dynamically loadable modules, it
244 * will then attempt to load a module of the same name or alias. A refcount
245 * is grabbed on the algorithm which is then associated with the new transform.
246 *
247 * crypto_free_tfm() frees up the transform and any associated resources,
248 * then drops the refcount on the associated algorithm.
249 */
250struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); 370struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
371struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask);
251void crypto_free_tfm(struct crypto_tfm *tfm); 372void crypto_free_tfm(struct crypto_tfm *tfm);
252 373
253/* 374/*
@@ -258,6 +379,16 @@ static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
258 return tfm->__crt_alg->cra_name; 379 return tfm->__crt_alg->cra_name;
259} 380}
260 381
382static inline const char *crypto_tfm_alg_driver_name(struct crypto_tfm *tfm)
383{
384 return tfm->__crt_alg->cra_driver_name;
385}
386
387static inline int crypto_tfm_alg_priority(struct crypto_tfm *tfm)
388{
389 return tfm->__crt_alg->cra_priority;
390}
391
261static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm) 392static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
262{ 393{
263 return module_name(tfm->__crt_alg->cra_module); 394 return module_name(tfm->__crt_alg->cra_module);
@@ -268,18 +399,23 @@ static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
268 return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK; 399 return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
269} 400}
270 401
402static unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
403 __deprecated;
271static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm) 404static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
272{ 405{
273 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 406 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
274 return tfm->__crt_alg->cra_cipher.cia_min_keysize; 407 return tfm->__crt_alg->cra_cipher.cia_min_keysize;
275} 408}
276 409
410static unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
411 __deprecated;
277static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm) 412static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
278{ 413{
279 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 414 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
280 return tfm->__crt_alg->cra_cipher.cia_max_keysize; 415 return tfm->__crt_alg->cra_cipher.cia_max_keysize;
281} 416}
282 417
418static unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) __deprecated;
283static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) 419static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
284{ 420{
285 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 421 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
@@ -302,6 +438,21 @@ static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm)
302 return tfm->__crt_alg->cra_alignmask; 438 return tfm->__crt_alg->cra_alignmask;
303} 439}
304 440
441static inline u32 crypto_tfm_get_flags(struct crypto_tfm *tfm)
442{
443 return tfm->crt_flags;
444}
445
446static inline void crypto_tfm_set_flags(struct crypto_tfm *tfm, u32 flags)
447{
448 tfm->crt_flags |= flags;
449}
450
451static inline void crypto_tfm_clear_flags(struct crypto_tfm *tfm, u32 flags)
452{
453 tfm->crt_flags &= ~flags;
454}
455
305static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) 456static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
306{ 457{
307 return tfm->__crt_ctx; 458 return tfm->__crt_ctx;
@@ -316,50 +467,374 @@ static inline unsigned int crypto_tfm_ctx_alignment(void)
316/* 467/*
317 * API wrappers. 468 * API wrappers.
318 */ 469 */
319static inline void crypto_digest_init(struct crypto_tfm *tfm) 470static inline struct crypto_blkcipher *__crypto_blkcipher_cast(
471 struct crypto_tfm *tfm)
320{ 472{
321 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 473 return (struct crypto_blkcipher *)tfm;
322 tfm->crt_digest.dit_init(tfm);
323} 474}
324 475
325static inline void crypto_digest_update(struct crypto_tfm *tfm, 476static inline struct crypto_blkcipher *crypto_blkcipher_cast(
326 struct scatterlist *sg, 477 struct crypto_tfm *tfm)
327 unsigned int nsg)
328{ 478{
329 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 479 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_BLKCIPHER);
330 tfm->crt_digest.dit_update(tfm, sg, nsg); 480 return __crypto_blkcipher_cast(tfm);
331} 481}
332 482
333static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) 483static inline struct crypto_blkcipher *crypto_alloc_blkcipher(
484 const char *alg_name, u32 type, u32 mask)
334{ 485{
335 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 486 type &= ~CRYPTO_ALG_TYPE_MASK;
336 tfm->crt_digest.dit_final(tfm, out); 487 type |= CRYPTO_ALG_TYPE_BLKCIPHER;
488 mask |= CRYPTO_ALG_TYPE_MASK;
489
490 return __crypto_blkcipher_cast(crypto_alloc_base(alg_name, type, mask));
337} 491}
338 492
339static inline void crypto_digest_digest(struct crypto_tfm *tfm, 493static inline struct crypto_tfm *crypto_blkcipher_tfm(
340 struct scatterlist *sg, 494 struct crypto_blkcipher *tfm)
341 unsigned int nsg, u8 *out)
342{ 495{
343 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 496 return &tfm->base;
344 tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
345} 497}
346 498
347static inline int crypto_digest_setkey(struct crypto_tfm *tfm, 499static inline void crypto_free_blkcipher(struct crypto_blkcipher *tfm)
500{
501 crypto_free_tfm(crypto_blkcipher_tfm(tfm));
502}
503
504static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask)
505{
506 type &= ~CRYPTO_ALG_TYPE_MASK;
507 type |= CRYPTO_ALG_TYPE_BLKCIPHER;
508 mask |= CRYPTO_ALG_TYPE_MASK;
509
510 return crypto_has_alg(alg_name, type, mask);
511}
512
513static inline const char *crypto_blkcipher_name(struct crypto_blkcipher *tfm)
514{
515 return crypto_tfm_alg_name(crypto_blkcipher_tfm(tfm));
516}
517
518static inline struct blkcipher_tfm *crypto_blkcipher_crt(
519 struct crypto_blkcipher *tfm)
520{
521 return &crypto_blkcipher_tfm(tfm)->crt_blkcipher;
522}
523
524static inline struct blkcipher_alg *crypto_blkcipher_alg(
525 struct crypto_blkcipher *tfm)
526{
527 return &crypto_blkcipher_tfm(tfm)->__crt_alg->cra_blkcipher;
528}
529
530static inline unsigned int crypto_blkcipher_ivsize(struct crypto_blkcipher *tfm)
531{
532 return crypto_blkcipher_alg(tfm)->ivsize;
533}
534
535static inline unsigned int crypto_blkcipher_blocksize(
536 struct crypto_blkcipher *tfm)
537{
538 return crypto_tfm_alg_blocksize(crypto_blkcipher_tfm(tfm));
539}
540
541static inline unsigned int crypto_blkcipher_alignmask(
542 struct crypto_blkcipher *tfm)
543{
544 return crypto_tfm_alg_alignmask(crypto_blkcipher_tfm(tfm));
545}
546
547static inline u32 crypto_blkcipher_get_flags(struct crypto_blkcipher *tfm)
548{
549 return crypto_tfm_get_flags(crypto_blkcipher_tfm(tfm));
550}
551
552static inline void crypto_blkcipher_set_flags(struct crypto_blkcipher *tfm,
553 u32 flags)
554{
555 crypto_tfm_set_flags(crypto_blkcipher_tfm(tfm), flags);
556}
557
558static inline void crypto_blkcipher_clear_flags(struct crypto_blkcipher *tfm,
559 u32 flags)
560{
561 crypto_tfm_clear_flags(crypto_blkcipher_tfm(tfm), flags);
562}
563
564static inline int crypto_blkcipher_setkey(struct crypto_blkcipher *tfm,
565 const u8 *key, unsigned int keylen)
566{
567 return crypto_blkcipher_crt(tfm)->setkey(crypto_blkcipher_tfm(tfm),
568 key, keylen);
569}
570
571static inline int crypto_blkcipher_encrypt(struct blkcipher_desc *desc,
572 struct scatterlist *dst,
573 struct scatterlist *src,
574 unsigned int nbytes)
575{
576 desc->info = crypto_blkcipher_crt(desc->tfm)->iv;
577 return crypto_blkcipher_crt(desc->tfm)->encrypt(desc, dst, src, nbytes);
578}
579
580static inline int crypto_blkcipher_encrypt_iv(struct blkcipher_desc *desc,
581 struct scatterlist *dst,
582 struct scatterlist *src,
583 unsigned int nbytes)
584{
585 return crypto_blkcipher_crt(desc->tfm)->encrypt(desc, dst, src, nbytes);
586}
587
588static inline int crypto_blkcipher_decrypt(struct blkcipher_desc *desc,
589 struct scatterlist *dst,
590 struct scatterlist *src,
591 unsigned int nbytes)
592{
593 desc->info = crypto_blkcipher_crt(desc->tfm)->iv;
594 return crypto_blkcipher_crt(desc->tfm)->decrypt(desc, dst, src, nbytes);
595}
596
597static inline int crypto_blkcipher_decrypt_iv(struct blkcipher_desc *desc,
598 struct scatterlist *dst,
599 struct scatterlist *src,
600 unsigned int nbytes)
601{
602 return crypto_blkcipher_crt(desc->tfm)->decrypt(desc, dst, src, nbytes);
603}
604
605static inline void crypto_blkcipher_set_iv(struct crypto_blkcipher *tfm,
606 const u8 *src, unsigned int len)
607{
608 memcpy(crypto_blkcipher_crt(tfm)->iv, src, len);
609}
610
611static inline void crypto_blkcipher_get_iv(struct crypto_blkcipher *tfm,
612 u8 *dst, unsigned int len)
613{
614 memcpy(dst, crypto_blkcipher_crt(tfm)->iv, len);
615}
616
617static inline struct crypto_cipher *__crypto_cipher_cast(struct crypto_tfm *tfm)
618{
619 return (struct crypto_cipher *)tfm;
620}
621
622static inline struct crypto_cipher *crypto_cipher_cast(struct crypto_tfm *tfm)
623{
624 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
625 return __crypto_cipher_cast(tfm);
626}
627
628static inline struct crypto_cipher *crypto_alloc_cipher(const char *alg_name,
629 u32 type, u32 mask)
630{
631 type &= ~CRYPTO_ALG_TYPE_MASK;
632 type |= CRYPTO_ALG_TYPE_CIPHER;
633 mask |= CRYPTO_ALG_TYPE_MASK;
634
635 return __crypto_cipher_cast(crypto_alloc_base(alg_name, type, mask));
636}
637
638static inline struct crypto_tfm *crypto_cipher_tfm(struct crypto_cipher *tfm)
639{
640 return tfm;
641}
642
643static inline void crypto_free_cipher(struct crypto_cipher *tfm)
644{
645 crypto_free_tfm(crypto_cipher_tfm(tfm));
646}
647
648static inline int crypto_has_cipher(const char *alg_name, u32 type, u32 mask)
649{
650 type &= ~CRYPTO_ALG_TYPE_MASK;
651 type |= CRYPTO_ALG_TYPE_CIPHER;
652 mask |= CRYPTO_ALG_TYPE_MASK;
653
654 return crypto_has_alg(alg_name, type, mask);
655}
656
657static inline struct cipher_tfm *crypto_cipher_crt(struct crypto_cipher *tfm)
658{
659 return &crypto_cipher_tfm(tfm)->crt_cipher;
660}
661
662static inline unsigned int crypto_cipher_blocksize(struct crypto_cipher *tfm)
663{
664 return crypto_tfm_alg_blocksize(crypto_cipher_tfm(tfm));
665}
666
667static inline unsigned int crypto_cipher_alignmask(struct crypto_cipher *tfm)
668{
669 return crypto_tfm_alg_alignmask(crypto_cipher_tfm(tfm));
670}
671
672static inline u32 crypto_cipher_get_flags(struct crypto_cipher *tfm)
673{
674 return crypto_tfm_get_flags(crypto_cipher_tfm(tfm));
675}
676
677static inline void crypto_cipher_set_flags(struct crypto_cipher *tfm,
678 u32 flags)
679{
680 crypto_tfm_set_flags(crypto_cipher_tfm(tfm), flags);
681}
682
683static inline void crypto_cipher_clear_flags(struct crypto_cipher *tfm,
684 u32 flags)
685{
686 crypto_tfm_clear_flags(crypto_cipher_tfm(tfm), flags);
687}
688
689static inline int crypto_cipher_setkey(struct crypto_cipher *tfm,
348 const u8 *key, unsigned int keylen) 690 const u8 *key, unsigned int keylen)
349{ 691{
350 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 692 return crypto_cipher_crt(tfm)->cit_setkey(crypto_cipher_tfm(tfm),
351 if (tfm->crt_digest.dit_setkey == NULL) 693 key, keylen);
352 return -ENOSYS; 694}
353 return tfm->crt_digest.dit_setkey(tfm, key, keylen); 695
696static inline void crypto_cipher_encrypt_one(struct crypto_cipher *tfm,
697 u8 *dst, const u8 *src)
698{
699 crypto_cipher_crt(tfm)->cit_encrypt_one(crypto_cipher_tfm(tfm),
700 dst, src);
701}
702
703static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,
704 u8 *dst, const u8 *src)
705{
706 crypto_cipher_crt(tfm)->cit_decrypt_one(crypto_cipher_tfm(tfm),
707 dst, src);
708}
709
710void crypto_digest_init(struct crypto_tfm *tfm) __deprecated_for_modules;
711void crypto_digest_update(struct crypto_tfm *tfm,
712 struct scatterlist *sg, unsigned int nsg)
713 __deprecated_for_modules;
714void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
715 __deprecated_for_modules;
716void crypto_digest_digest(struct crypto_tfm *tfm,
717 struct scatterlist *sg, unsigned int nsg, u8 *out)
718 __deprecated_for_modules;
719
720static inline struct crypto_hash *__crypto_hash_cast(struct crypto_tfm *tfm)
721{
722 return (struct crypto_hash *)tfm;
723}
724
725static inline struct crypto_hash *crypto_hash_cast(struct crypto_tfm *tfm)
726{
727 BUG_ON((crypto_tfm_alg_type(tfm) ^ CRYPTO_ALG_TYPE_HASH) &
728 CRYPTO_ALG_TYPE_HASH_MASK);
729 return __crypto_hash_cast(tfm);
354} 730}
355 731
356static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, 732static int crypto_digest_setkey(struct crypto_tfm *tfm, const u8 *key,
733 unsigned int keylen) __deprecated;
734static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
357 const u8 *key, unsigned int keylen) 735 const u8 *key, unsigned int keylen)
358{ 736{
359 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 737 return tfm->crt_hash.setkey(crypto_hash_cast(tfm), key, keylen);
360 return tfm->crt_cipher.cit_setkey(tfm, key, keylen); 738}
739
740static inline struct crypto_hash *crypto_alloc_hash(const char *alg_name,
741 u32 type, u32 mask)
742{
743 type &= ~CRYPTO_ALG_TYPE_MASK;
744 type |= CRYPTO_ALG_TYPE_HASH;
745 mask |= CRYPTO_ALG_TYPE_HASH_MASK;
746
747 return __crypto_hash_cast(crypto_alloc_base(alg_name, type, mask));
748}
749
750static inline struct crypto_tfm *crypto_hash_tfm(struct crypto_hash *tfm)
751{
752 return &tfm->base;
753}
754
755static inline void crypto_free_hash(struct crypto_hash *tfm)
756{
757 crypto_free_tfm(crypto_hash_tfm(tfm));
758}
759
760static inline int crypto_has_hash(const char *alg_name, u32 type, u32 mask)
761{
762 type &= ~CRYPTO_ALG_TYPE_MASK;
763 type |= CRYPTO_ALG_TYPE_HASH;
764 mask |= CRYPTO_ALG_TYPE_HASH_MASK;
765
766 return crypto_has_alg(alg_name, type, mask);
767}
768
769static inline struct hash_tfm *crypto_hash_crt(struct crypto_hash *tfm)
770{
771 return &crypto_hash_tfm(tfm)->crt_hash;
772}
773
774static inline unsigned int crypto_hash_blocksize(struct crypto_hash *tfm)
775{
776 return crypto_tfm_alg_blocksize(crypto_hash_tfm(tfm));
777}
778
779static inline unsigned int crypto_hash_alignmask(struct crypto_hash *tfm)
780{
781 return crypto_tfm_alg_alignmask(crypto_hash_tfm(tfm));
782}
783
784static inline unsigned int crypto_hash_digestsize(struct crypto_hash *tfm)
785{
786 return crypto_hash_crt(tfm)->digestsize;
787}
788
789static inline u32 crypto_hash_get_flags(struct crypto_hash *tfm)
790{
791 return crypto_tfm_get_flags(crypto_hash_tfm(tfm));
792}
793
794static inline void crypto_hash_set_flags(struct crypto_hash *tfm, u32 flags)
795{
796 crypto_tfm_set_flags(crypto_hash_tfm(tfm), flags);
361} 797}
362 798
799static inline void crypto_hash_clear_flags(struct crypto_hash *tfm, u32 flags)
800{
801 crypto_tfm_clear_flags(crypto_hash_tfm(tfm), flags);
802}
803
804static inline int crypto_hash_init(struct hash_desc *desc)
805{
806 return crypto_hash_crt(desc->tfm)->init(desc);
807}
808
809static inline int crypto_hash_update(struct hash_desc *desc,
810 struct scatterlist *sg,
811 unsigned int nbytes)
812{
813 return crypto_hash_crt(desc->tfm)->update(desc, sg, nbytes);
814}
815
816static inline int crypto_hash_final(struct hash_desc *desc, u8 *out)
817{
818 return crypto_hash_crt(desc->tfm)->final(desc, out);
819}
820
821static inline int crypto_hash_digest(struct hash_desc *desc,
822 struct scatterlist *sg,
823 unsigned int nbytes, u8 *out)
824{
825 return crypto_hash_crt(desc->tfm)->digest(desc, sg, nbytes, out);
826}
827
828static inline int crypto_hash_setkey(struct crypto_hash *hash,
829 const u8 *key, unsigned int keylen)
830{
831 return crypto_hash_crt(hash)->setkey(hash, key, keylen);
832}
833
834static int crypto_cipher_encrypt(struct crypto_tfm *tfm,
835 struct scatterlist *dst,
836 struct scatterlist *src,
837 unsigned int nbytes) __deprecated;
363static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, 838static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
364 struct scatterlist *dst, 839 struct scatterlist *dst,
365 struct scatterlist *src, 840 struct scatterlist *src,
@@ -369,16 +844,23 @@ static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
369 return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); 844 return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
370} 845}
371 846
847static int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
848 struct scatterlist *dst,
849 struct scatterlist *src,
850 unsigned int nbytes, u8 *iv) __deprecated;
372static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, 851static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
373 struct scatterlist *dst, 852 struct scatterlist *dst,
374 struct scatterlist *src, 853 struct scatterlist *src,
375 unsigned int nbytes, u8 *iv) 854 unsigned int nbytes, u8 *iv)
376{ 855{
377 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 856 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
378 BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
379 return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv); 857 return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
380} 858}
381 859
860static int crypto_cipher_decrypt(struct crypto_tfm *tfm,
861 struct scatterlist *dst,
862 struct scatterlist *src,
863 unsigned int nbytes) __deprecated;
382static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, 864static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
383 struct scatterlist *dst, 865 struct scatterlist *dst,
384 struct scatterlist *src, 866 struct scatterlist *src,
@@ -388,16 +870,21 @@ static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
388 return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); 870 return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
389} 871}
390 872
873static int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
874 struct scatterlist *dst,
875 struct scatterlist *src,
876 unsigned int nbytes, u8 *iv) __deprecated;
391static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, 877static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
392 struct scatterlist *dst, 878 struct scatterlist *dst,
393 struct scatterlist *src, 879 struct scatterlist *src,
394 unsigned int nbytes, u8 *iv) 880 unsigned int nbytes, u8 *iv)
395{ 881{
396 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 882 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
397 BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
398 return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv); 883 return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
399} 884}
400 885
886static void crypto_cipher_set_iv(struct crypto_tfm *tfm,
887 const u8 *src, unsigned int len) __deprecated;
401static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, 888static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
402 const u8 *src, unsigned int len) 889 const u8 *src, unsigned int len)
403{ 890{
@@ -405,6 +892,8 @@ static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
405 memcpy(tfm->crt_cipher.cit_iv, src, len); 892 memcpy(tfm->crt_cipher.cit_iv, src, len);
406} 893}
407 894
895static void crypto_cipher_get_iv(struct crypto_tfm *tfm,
896 u8 *dst, unsigned int len) __deprecated;
408static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, 897static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
409 u8 *dst, unsigned int len) 898 u8 *dst, unsigned int len)
410{ 899{
@@ -412,34 +901,70 @@ static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
412 memcpy(dst, tfm->crt_cipher.cit_iv, len); 901 memcpy(dst, tfm->crt_cipher.cit_iv, len);
413} 902}
414 903
415static inline int crypto_comp_compress(struct crypto_tfm *tfm, 904static inline struct crypto_comp *__crypto_comp_cast(struct crypto_tfm *tfm)
905{
906 return (struct crypto_comp *)tfm;
907}
908
909static inline struct crypto_comp *crypto_comp_cast(struct crypto_tfm *tfm)
910{
911 BUG_ON((crypto_tfm_alg_type(tfm) ^ CRYPTO_ALG_TYPE_COMPRESS) &
912 CRYPTO_ALG_TYPE_MASK);
913 return __crypto_comp_cast(tfm);
914}
915
916static inline struct crypto_comp *crypto_alloc_comp(const char *alg_name,
917 u32 type, u32 mask)
918{
919 type &= ~CRYPTO_ALG_TYPE_MASK;
920 type |= CRYPTO_ALG_TYPE_COMPRESS;
921 mask |= CRYPTO_ALG_TYPE_MASK;
922
923 return __crypto_comp_cast(crypto_alloc_base(alg_name, type, mask));
924}
925
926static inline struct crypto_tfm *crypto_comp_tfm(struct crypto_comp *tfm)
927{
928 return tfm;
929}
930
931static inline void crypto_free_comp(struct crypto_comp *tfm)
932{
933 crypto_free_tfm(crypto_comp_tfm(tfm));
934}
935
936static inline int crypto_has_comp(const char *alg_name, u32 type, u32 mask)
937{
938 type &= ~CRYPTO_ALG_TYPE_MASK;
939 type |= CRYPTO_ALG_TYPE_COMPRESS;
940 mask |= CRYPTO_ALG_TYPE_MASK;
941
942 return crypto_has_alg(alg_name, type, mask);
943}
944
945static inline const char *crypto_comp_name(struct crypto_comp *tfm)
946{
947 return crypto_tfm_alg_name(crypto_comp_tfm(tfm));
948}
949
950static inline struct compress_tfm *crypto_comp_crt(struct crypto_comp *tfm)
951{
952 return &crypto_comp_tfm(tfm)->crt_compress;
953}
954
955static inline int crypto_comp_compress(struct crypto_comp *tfm,
416 const u8 *src, unsigned int slen, 956 const u8 *src, unsigned int slen,
417 u8 *dst, unsigned int *dlen) 957 u8 *dst, unsigned int *dlen)
418{ 958{
419 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); 959 return crypto_comp_crt(tfm)->cot_compress(tfm, src, slen, dst, dlen);
420 return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
421} 960}
422 961
423static inline int crypto_comp_decompress(struct crypto_tfm *tfm, 962static inline int crypto_comp_decompress(struct crypto_comp *tfm,
424 const u8 *src, unsigned int slen, 963 const u8 *src, unsigned int slen,
425 u8 *dst, unsigned int *dlen) 964 u8 *dst, unsigned int *dlen)
426{ 965{
427 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); 966 return crypto_comp_crt(tfm)->cot_decompress(tfm, src, slen, dst, dlen);
428 return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
429} 967}
430 968
431/*
432 * HMAC support.
433 */
434#ifdef CONFIG_CRYPTO_HMAC
435void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
436void crypto_hmac_update(struct crypto_tfm *tfm,
437 struct scatterlist *sg, unsigned int nsg);
438void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
439 unsigned int *keylen, u8 *out);
440void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
441 struct scatterlist *sg, unsigned int nsg, u8 *out);
442#endif /* CONFIG_CRYPTO_HMAC */
443
444#endif /* _LINUX_CRYPTO_H */ 969#endif /* _LINUX_CRYPTO_H */
445 970
diff --git a/include/linux/dvb/Kbuild b/include/linux/dvb/Kbuild
index 63973af72fd5..d97b3a51e227 100644
--- a/include/linux/dvb/Kbuild
+++ b/include/linux/dvb/Kbuild
@@ -1,2 +1,9 @@
1header-y += ca.h frontend.h net.h osd.h version.h 1header-y += ca.h
2unifdef-y := audio.h dmx.h video.h 2header-y += frontend.h
3header-y += net.h
4header-y += osd.h
5header-y += version.h
6
7unifdef-y += audio.h
8unifdef-y += dmx.h
9unifdef-y += video.h
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index f6977708585c..f7ca0b09075d 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -148,6 +148,17 @@ struct ccw_device_id {
148#define CCW_DEVICE_ID_MATCH_DEVICE_TYPE 0x04 148#define CCW_DEVICE_ID_MATCH_DEVICE_TYPE 0x04
149#define CCW_DEVICE_ID_MATCH_DEVICE_MODEL 0x08 149#define CCW_DEVICE_ID_MATCH_DEVICE_MODEL 0x08
150 150
151/* s390 AP bus devices */
152struct ap_device_id {
153 __u16 match_flags; /* which fields to match against */
154 __u8 dev_type; /* device type */
155 __u8 pad1;
156 __u32 pad2;
157 kernel_ulong_t driver_info;
158};
159
160#define AP_DEVICE_ID_MATCH_DEVICE_TYPE 0x01
161
151 162
152#define PNP_ID_LEN 8 163#define PNP_ID_LEN 8
153#define PNP_MAX_DEVICES 8 164#define PNP_MAX_DEVICES 8
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index 1d3a14e2da6e..9a285cecf249 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -1,11 +1,38 @@
1header-y := nf_conntrack_sctp.h nf_conntrack_tuple_common.h \ 1header-y += nf_conntrack_sctp.h
2 nfnetlink_conntrack.h nfnetlink_log.h nfnetlink_queue.h \ 2header-y += nf_conntrack_tuple_common.h
3 xt_CLASSIFY.h xt_comment.h xt_connbytes.h xt_connmark.h \ 3header-y += nfnetlink_conntrack.h
4 xt_CONNMARK.h xt_conntrack.h xt_dccp.h xt_esp.h \ 4header-y += nfnetlink_log.h
5 xt_helper.h xt_length.h xt_limit.h xt_mac.h xt_mark.h \ 5header-y += nfnetlink_queue.h
6 xt_MARK.h xt_multiport.h xt_NFQUEUE.h xt_pkttype.h \ 6header-y += xt_CLASSIFY.h
7 xt_policy.h xt_realm.h xt_sctp.h xt_state.h xt_string.h \ 7header-y += xt_comment.h
8 xt_tcpmss.h xt_tcpudp.h xt_SECMARK.h xt_CONNSECMARK.h 8header-y += xt_connbytes.h
9header-y += xt_connmark.h
10header-y += xt_CONNMARK.h
11header-y += xt_conntrack.h
12header-y += xt_dccp.h
13header-y += xt_esp.h
14header-y += xt_helper.h
15header-y += xt_length.h
16header-y += xt_limit.h
17header-y += xt_mac.h
18header-y += xt_mark.h
19header-y += xt_MARK.h
20header-y += xt_multiport.h
21header-y += xt_NFQUEUE.h
22header-y += xt_pkttype.h
23header-y += xt_policy.h
24header-y += xt_realm.h
25header-y += xt_sctp.h
26header-y += xt_state.h
27header-y += xt_string.h
28header-y += xt_tcpmss.h
29header-y += xt_tcpudp.h
30header-y += xt_SECMARK.h
31header-y += xt_CONNSECMARK.h
9 32
10unifdef-y := nf_conntrack_common.h nf_conntrack_ftp.h \ 33unifdef-y += nf_conntrack_common.h
11 nf_conntrack_tcp.h nfnetlink.h x_tables.h xt_physdev.h 34unifdef-y += nf_conntrack_ftp.h
35unifdef-y += nf_conntrack_tcp.h
36unifdef-y += nfnetlink.h
37unifdef-y += x_tables.h
38unifdef-y += xt_physdev.h
diff --git a/include/linux/netfilter_arp/Kbuild b/include/linux/netfilter_arp/Kbuild
index 198ec5e7b17d..4f13dfcb92ea 100644
--- a/include/linux/netfilter_arp/Kbuild
+++ b/include/linux/netfilter_arp/Kbuild
@@ -1,2 +1,3 @@
1header-y := arpt_mangle.h 1header-y += arpt_mangle.h
2unifdef-y := arp_tables.h 2
3unifdef-y += arp_tables.h
diff --git a/include/linux/netfilter_bridge/Kbuild b/include/linux/netfilter_bridge/Kbuild
index 5b1aba6abbad..76ff4c47d8c4 100644
--- a/include/linux/netfilter_bridge/Kbuild
+++ b/include/linux/netfilter_bridge/Kbuild
@@ -1,4 +1,17 @@
1header-y += ebt_among.h ebt_arp.h ebt_arpreply.h ebt_ip.h ebt_limit.h \ 1header-y += ebt_among.h
2 ebt_log.h ebt_mark_m.h ebt_mark_t.h ebt_nat.h ebt_pkttype.h \ 2header-y += ebt_arp.h
3 ebt_redirect.h ebt_stp.h ebt_ulog.h ebt_vlan.h 3header-y += ebt_arpreply.h
4unifdef-y := ebtables.h ebt_802_3.h 4header-y += ebt_ip.h
5header-y += ebt_limit.h
6header-y += ebt_log.h
7header-y += ebt_mark_m.h
8header-y += ebt_mark_t.h
9header-y += ebt_nat.h
10header-y += ebt_pkttype.h
11header-y += ebt_redirect.h
12header-y += ebt_stp.h
13header-y += ebt_ulog.h
14header-y += ebt_vlan.h
15
16unifdef-y += ebtables.h
17unifdef-y += ebt_802_3.h
diff --git a/include/linux/netfilter_ipv4/Kbuild b/include/linux/netfilter_ipv4/Kbuild
index 04e4d2721689..591c1a809c00 100644
--- a/include/linux/netfilter_ipv4/Kbuild
+++ b/include/linux/netfilter_ipv4/Kbuild
@@ -1,21 +1,63 @@
1header-y += ip_conntrack_helper.h
2header-y += ip_conntrack_helper_h323_asn1.h
3header-y += ip_conntrack_helper_h323_types.h
4header-y += ip_conntrack_protocol.h
5header-y += ip_conntrack_sctp.h
6header-y += ip_conntrack_tcp.h
7header-y += ip_conntrack_tftp.h
8header-y += ip_nat_pptp.h
9header-y += ipt_addrtype.h
10header-y += ipt_ah.h
11header-y += ipt_CLASSIFY.h
12header-y += ipt_CLUSTERIP.h
13header-y += ipt_comment.h
14header-y += ipt_connbytes.h
15header-y += ipt_connmark.h
16header-y += ipt_CONNMARK.h
17header-y += ipt_conntrack.h
18header-y += ipt_dccp.h
19header-y += ipt_dscp.h
20header-y += ipt_DSCP.h
21header-y += ipt_ecn.h
22header-y += ipt_ECN.h
23header-y += ipt_esp.h
24header-y += ipt_hashlimit.h
25header-y += ipt_helper.h
26header-y += ipt_iprange.h
27header-y += ipt_length.h
28header-y += ipt_limit.h
29header-y += ipt_LOG.h
30header-y += ipt_mac.h
31header-y += ipt_mark.h
32header-y += ipt_MARK.h
33header-y += ipt_multiport.h
34header-y += ipt_NFQUEUE.h
35header-y += ipt_owner.h
36header-y += ipt_physdev.h
37header-y += ipt_pkttype.h
38header-y += ipt_policy.h
39header-y += ipt_realm.h
40header-y += ipt_recent.h
41header-y += ipt_REJECT.h
42header-y += ipt_SAME.h
43header-y += ipt_sctp.h
44header-y += ipt_state.h
45header-y += ipt_string.h
46header-y += ipt_tcpmss.h
47header-y += ipt_TCPMSS.h
48header-y += ipt_tos.h
49header-y += ipt_TOS.h
50header-y += ipt_ttl.h
51header-y += ipt_TTL.h
52header-y += ipt_ULOG.h
1 53
2header-y := ip_conntrack_helper.h ip_conntrack_helper_h323_asn1.h \ 54unifdef-y += ip_conntrack.h
3 ip_conntrack_helper_h323_types.h ip_conntrack_protocol.h \ 55unifdef-y += ip_conntrack_h323.h
4 ip_conntrack_sctp.h ip_conntrack_tcp.h ip_conntrack_tftp.h \ 56unifdef-y += ip_conntrack_irc.h
5 ip_nat_pptp.h ipt_addrtype.h ipt_ah.h \ 57unifdef-y += ip_conntrack_pptp.h
6 ipt_CLASSIFY.h ipt_CLUSTERIP.h ipt_comment.h \ 58unifdef-y += ip_conntrack_proto_gre.h
7 ipt_connbytes.h ipt_connmark.h ipt_CONNMARK.h \ 59unifdef-y += ip_conntrack_tuple.h
8 ipt_conntrack.h ipt_dccp.h ipt_dscp.h ipt_DSCP.h ipt_ecn.h \ 60unifdef-y += ip_nat.h
9 ipt_ECN.h ipt_esp.h ipt_hashlimit.h ipt_helper.h \ 61unifdef-y += ip_nat_rule.h
10 ipt_iprange.h ipt_length.h ipt_limit.h ipt_LOG.h ipt_mac.h \ 62unifdef-y += ip_queue.h
11 ipt_mark.h ipt_MARK.h ipt_multiport.h ipt_NFQUEUE.h \ 63unifdef-y += ip_tables.h
12 ipt_owner.h ipt_physdev.h ipt_pkttype.h ipt_policy.h \
13 ipt_realm.h ipt_recent.h ipt_REJECT.h ipt_SAME.h \
14 ipt_sctp.h ipt_state.h ipt_string.h ipt_tcpmss.h \
15 ipt_TCPMSS.h ipt_tos.h ipt_TOS.h ipt_ttl.h ipt_TTL.h \
16 ipt_ULOG.h
17
18unifdef-y := ip_conntrack.h ip_conntrack_h323.h ip_conntrack_irc.h \
19 ip_conntrack_pptp.h ip_conntrack_proto_gre.h \
20 ip_conntrack_tuple.h ip_nat.h ip_nat_rule.h ip_queue.h \
21 ip_tables.h
diff --git a/include/linux/netfilter_ipv6/Kbuild b/include/linux/netfilter_ipv6/Kbuild
index 913ddbf55b4b..9dd978d149ff 100644
--- a/include/linux/netfilter_ipv6/Kbuild
+++ b/include/linux/netfilter_ipv6/Kbuild
@@ -1,6 +1,21 @@
1header-y += ip6t_HL.h ip6t_LOG.h ip6t_MARK.h ip6t_REJECT.h ip6t_ah.h \ 1header-y += ip6t_HL.h
2 ip6t_esp.h ip6t_frag.h ip6t_hl.h ip6t_ipv6header.h \ 2header-y += ip6t_LOG.h
3 ip6t_length.h ip6t_limit.h ip6t_mac.h ip6t_mark.h \ 3header-y += ip6t_MARK.h
4 ip6t_multiport.h ip6t_opts.h ip6t_owner.h ip6t_policy.h \ 4header-y += ip6t_REJECT.h
5 ip6t_physdev.h ip6t_rt.h 5header-y += ip6t_ah.h
6unifdef-y := ip6_tables.h 6header-y += ip6t_esp.h
7header-y += ip6t_frag.h
8header-y += ip6t_hl.h
9header-y += ip6t_ipv6header.h
10header-y += ip6t_length.h
11header-y += ip6t_limit.h
12header-y += ip6t_mac.h
13header-y += ip6t_mark.h
14header-y += ip6t_multiport.h
15header-y += ip6t_opts.h
16header-y += ip6t_owner.h
17header-y += ip6t_policy.h
18header-y += ip6t_physdev.h
19header-y += ip6t_rt.h
20
21unifdef-y += ip6_tables.h
diff --git a/include/linux/nfsd/Kbuild b/include/linux/nfsd/Kbuild
index c8c545665885..d9c5455808e5 100644
--- a/include/linux/nfsd/Kbuild
+++ b/include/linux/nfsd/Kbuild
@@ -1,2 +1,7 @@
1unifdef-y := const.h export.h stats.h syscall.h nfsfh.h debug.h auth.h 1unifdef-y += const.h
2 2unifdef-y += export.h
3unifdef-y += stats.h
4unifdef-y += syscall.h
5unifdef-y += nfsfh.h
6unifdef-y += debug.h
7unifdef-y += auth.h
diff --git a/include/linux/raid/Kbuild b/include/linux/raid/Kbuild
index 73fa27a8d552..2415a64c5e51 100644
--- a/include/linux/raid/Kbuild
+++ b/include/linux/raid/Kbuild
@@ -1 +1,2 @@
1header-y += md_p.h md_u.h 1header-y += md_p.h
2header-y += md_u.h
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 66ff545552f7..4efbd9c445f5 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,7 +5,7 @@
5#include <linux/mm.h> 5#include <linux/mm.h>
6#include <linux/string.h> 6#include <linux/string.h>
7 7
8static inline void sg_set_buf(struct scatterlist *sg, void *buf, 8static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
9 unsigned int buflen) 9 unsigned int buflen)
10{ 10{
11 sg->page = virt_to_page(buf); 11 sg->page = virt_to_page(buf);
@@ -13,7 +13,7 @@ static inline void sg_set_buf(struct scatterlist *sg, void *buf,
13 sg->length = buflen; 13 sg->length = buflen;
14} 14}
15 15
16static inline void sg_init_one(struct scatterlist *sg, void *buf, 16static inline void sg_init_one(struct scatterlist *sg, const void *buf,
17 unsigned int buflen) 17 unsigned int buflen)
18{ 18{
19 memset(sg, 0, sizeof(*sg)); 19 memset(sg, 0, sizeof(*sg));
diff --git a/include/linux/sunrpc/Kbuild b/include/linux/sunrpc/Kbuild
index 0d1d768a27bf..fb438f158eee 100644
--- a/include/linux/sunrpc/Kbuild
+++ b/include/linux/sunrpc/Kbuild
@@ -1 +1 @@
unifdef-y := debug.h unifdef-y += debug.h
diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
index 1279280d7196..e30ba201910a 100644
--- a/include/linux/sunrpc/gss_krb5.h
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -46,8 +46,8 @@ struct krb5_ctx {
46 unsigned char seed[16]; 46 unsigned char seed[16];
47 int signalg; 47 int signalg;
48 int sealalg; 48 int sealalg;
49 struct crypto_tfm *enc; 49 struct crypto_blkcipher *enc;
50 struct crypto_tfm *seq; 50 struct crypto_blkcipher *seq;
51 s32 endtime; 51 s32 endtime;
52 u32 seq_send; 52 u32 seq_send;
53 struct xdr_netobj mech_used; 53 struct xdr_netobj mech_used;
@@ -136,26 +136,27 @@ gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset,
136 136
137 137
138u32 138u32
139krb5_encrypt(struct crypto_tfm * key, 139krb5_encrypt(struct crypto_blkcipher *key,
140 void *iv, void *in, void *out, int length); 140 void *iv, void *in, void *out, int length);
141 141
142u32 142u32
143krb5_decrypt(struct crypto_tfm * key, 143krb5_decrypt(struct crypto_blkcipher *key,
144 void *iv, void *in, void *out, int length); 144 void *iv, void *in, void *out, int length);
145 145
146int 146int
147gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *outbuf, int offset, 147gss_encrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *outbuf,
148 struct page **pages); 148 int offset, struct page **pages);
149 149
150int 150int
151gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *inbuf, int offset); 151gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *inbuf,
152 int offset);
152 153
153s32 154s32
154krb5_make_seq_num(struct crypto_tfm * key, 155krb5_make_seq_num(struct crypto_blkcipher *key,
155 int direction, 156 int direction,
156 s32 seqnum, unsigned char *cksum, unsigned char *buf); 157 s32 seqnum, unsigned char *cksum, unsigned char *buf);
157 158
158s32 159s32
159krb5_get_seq_num(struct crypto_tfm * key, 160krb5_get_seq_num(struct crypto_blkcipher *key,
160 unsigned char *cksum, 161 unsigned char *cksum,
161 unsigned char *buf, int *direction, s32 * seqnum); 162 unsigned char *buf, int *direction, s32 * seqnum);
diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h
index 336e218c2782..2cf3fbb40b4f 100644
--- a/include/linux/sunrpc/gss_spkm3.h
+++ b/include/linux/sunrpc/gss_spkm3.h
@@ -19,9 +19,9 @@ struct spkm3_ctx {
19 unsigned int req_flags ; 19 unsigned int req_flags ;
20 struct xdr_netobj share_key; 20 struct xdr_netobj share_key;
21 int conf_alg; 21 int conf_alg;
22 struct crypto_tfm* derived_conf_key; 22 struct crypto_blkcipher *derived_conf_key;
23 int intg_alg; 23 int intg_alg;
24 struct crypto_tfm* derived_integ_key; 24 struct crypto_blkcipher *derived_integ_key;
25 int keyestb_alg; /* alg used to get share_key */ 25 int keyestb_alg; /* alg used to get share_key */
26 int owf_alg; /* one way function */ 26 int owf_alg; /* one way function */
27}; 27};
diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild
index 5251a505b2f1..78dfbac36375 100644
--- a/include/linux/tc_act/Kbuild
+++ b/include/linux/tc_act/Kbuild
@@ -1 +1,4 @@
1header-y += tc_gact.h tc_ipt.h tc_mirred.h tc_pedit.h 1header-y += tc_gact.h
2header-y += tc_ipt.h
3header-y += tc_mirred.h
4header-y += tc_pedit.h
diff --git a/include/linux/tc_ematch/Kbuild b/include/linux/tc_ematch/Kbuild
index 381e93018df6..4a58a1c32a00 100644
--- a/include/linux/tc_ematch/Kbuild
+++ b/include/linux/tc_ematch/Kbuild
@@ -1 +1,4 @@
1headers-y := tc_em_cmp.h tc_em_meta.h tc_em_nbyte.h tc_em_text.h 1header-y += tc_em_cmp.h
2header-y += tc_em_meta.h
3header-y += tc_em_nbyte.h
4header-y += tc_em_text.h
diff --git a/include/mtd/Kbuild b/include/mtd/Kbuild
index e1da2a5b2a57..13e7a3c6d794 100644
--- a/include/mtd/Kbuild
+++ b/include/mtd/Kbuild
@@ -1,2 +1,6 @@
1unifdef-y := mtd-abi.h 1header-y += inftl-user.h
2header-y := inftl-user.h jffs2-user.h mtd-user.h nftl-user.h 2header-y += jffs2-user.h
3header-y += mtd-user.h
4header-y += nftl-user.h
5
6unifdef-y += mtd-abi.h
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 1da3f7fa7993..b0a67b7ffdcd 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -34,6 +34,7 @@ struct mtd_oob_buf {
34#define MTD_WRITEABLE 0x400 /* Device is writeable */ 34#define MTD_WRITEABLE 0x400 /* Device is writeable */
35#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */ 35#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */
36#define MTD_NO_ERASE 0x1000 /* No erase necessary */ 36#define MTD_NO_ERASE 0x1000 /* No erase necessary */
37#define MTD_STUPID_LOCK 0x2000 /* Always locked after reset */
37 38
38// Some common devices / combinations of capabilities 39// Some common devices / combinations of capabilities
39#define MTD_CAP_ROM 0 40#define MTD_CAP_ROM 0
diff --git a/include/net/ah.h b/include/net/ah.h
index ceff00afae09..8f257c159902 100644
--- a/include/net/ah.h
+++ b/include/net/ah.h
@@ -1,6 +1,7 @@
1#ifndef _NET_AH_H 1#ifndef _NET_AH_H
2#define _NET_AH_H 2#define _NET_AH_H
3 3
4#include <linux/crypto.h>
4#include <net/xfrm.h> 5#include <net/xfrm.h>
5 6
6/* This is the maximum truncated ICV length that we know of. */ 7/* This is the maximum truncated ICV length that we know of. */
@@ -14,22 +15,29 @@ struct ah_data
14 int icv_full_len; 15 int icv_full_len;
15 int icv_trunc_len; 16 int icv_trunc_len;
16 17
17 void (*icv)(struct ah_data*, 18 struct crypto_hash *tfm;
18 struct sk_buff *skb, u8 *icv);
19
20 struct crypto_tfm *tfm;
21}; 19};
22 20
23static inline void 21static inline int ah_mac_digest(struct ah_data *ahp, struct sk_buff *skb,
24ah_hmac_digest(struct ah_data *ahp, struct sk_buff *skb, u8 *auth_data) 22 u8 *auth_data)
25{ 23{
26 struct crypto_tfm *tfm = ahp->tfm; 24 struct hash_desc desc;
25 int err;
26
27 desc.tfm = ahp->tfm;
28 desc.flags = 0;
27 29
28 memset(auth_data, 0, ahp->icv_trunc_len); 30 memset(auth_data, 0, ahp->icv_trunc_len);
29 crypto_hmac_init(tfm, ahp->key, &ahp->key_len); 31 err = crypto_hash_init(&desc);
30 skb_icv_walk(skb, tfm, 0, skb->len, crypto_hmac_update); 32 if (unlikely(err))
31 crypto_hmac_final(tfm, ahp->key, &ahp->key_len, ahp->work_icv); 33 goto out;
32 memcpy(auth_data, ahp->work_icv, ahp->icv_trunc_len); 34 err = skb_icv_walk(skb, &desc, 0, skb->len, crypto_hash_update);
35 if (unlikely(err))
36 goto out;
37 err = crypto_hash_final(&desc, ahp->work_icv);
38
39out:
40 return err;
33} 41}
34 42
35#endif 43#endif
diff --git a/include/net/esp.h b/include/net/esp.h
index 90cd94fad7d9..064366d66eea 100644
--- a/include/net/esp.h
+++ b/include/net/esp.h
@@ -1,6 +1,7 @@
1#ifndef _NET_ESP_H 1#ifndef _NET_ESP_H
2#define _NET_ESP_H 2#define _NET_ESP_H
3 3
4#include <linux/crypto.h>
4#include <net/xfrm.h> 5#include <net/xfrm.h>
5#include <asm/scatterlist.h> 6#include <asm/scatterlist.h>
6 7
@@ -21,7 +22,7 @@ struct esp_data
21 * >= crypto_tfm_alg_ivsize(tfm). */ 22 * >= crypto_tfm_alg_ivsize(tfm). */
22 int ivlen; 23 int ivlen;
23 int padlen; /* 0..255 */ 24 int padlen; /* 0..255 */
24 struct crypto_tfm *tfm; /* crypto handle */ 25 struct crypto_blkcipher *tfm; /* crypto handle */
25 } conf; 26 } conf;
26 27
27 /* Integrity. It is active when icv_full_len != 0 */ 28 /* Integrity. It is active when icv_full_len != 0 */
@@ -34,7 +35,7 @@ struct esp_data
34 void (*icv)(struct esp_data*, 35 void (*icv)(struct esp_data*,
35 struct sk_buff *skb, 36 struct sk_buff *skb,
36 int offset, int len, u8 *icv); 37 int offset, int len, u8 *icv);
37 struct crypto_tfm *tfm; 38 struct crypto_hash *tfm;
38 } auth; 39 } auth;
39}; 40};
40 41
@@ -42,18 +43,22 @@ extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset,
42extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); 43extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer);
43extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len); 44extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
44 45
45static inline void 46static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb,
46esp_hmac_digest(struct esp_data *esp, struct sk_buff *skb, int offset, 47 int offset, int len)
47 int len, u8 *auth_data)
48{ 48{
49 struct crypto_tfm *tfm = esp->auth.tfm; 49 struct hash_desc desc;
50 char *icv = esp->auth.work_icv; 50 int err;
51 51
52 memset(auth_data, 0, esp->auth.icv_trunc_len); 52 desc.tfm = esp->auth.tfm;
53 crypto_hmac_init(tfm, esp->auth.key, &esp->auth.key_len); 53 desc.flags = 0;
54 skb_icv_walk(skb, tfm, offset, len, crypto_hmac_update); 54
55 crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, icv); 55 err = crypto_hash_init(&desc);
56 memcpy(auth_data, icv, esp->auth.icv_trunc_len); 56 if (unlikely(err))
57 return err;
58 err = skb_icv_walk(skb, &desc, offset, len, crypto_hash_update);
59 if (unlikely(err))
60 return err;
61 return crypto_hash_final(&desc, esp->auth.work_icv);
57} 62}
58 63
59#endif 64#endif
diff --git a/include/net/ipcomp.h b/include/net/ipcomp.h
index e651a57ecdd5..87c1af3e5e82 100644
--- a/include/net/ipcomp.h
+++ b/include/net/ipcomp.h
@@ -1,11 +1,14 @@
1#ifndef _NET_IPCOMP_H 1#ifndef _NET_IPCOMP_H
2#define _NET_IPCOMP_H 2#define _NET_IPCOMP_H
3 3
4#include <linux/crypto.h>
5#include <linux/types.h>
6
4#define IPCOMP_SCRATCH_SIZE 65400 7#define IPCOMP_SCRATCH_SIZE 65400
5 8
6struct ipcomp_data { 9struct ipcomp_data {
7 u16 threshold; 10 u16 threshold;
8 struct crypto_tfm **tfms; 11 struct crypto_comp **tfms;
9}; 12};
10 13
11#endif 14#endif
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index c51541ee0247..57166bfdf8eb 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -312,9 +312,9 @@ enum { SCTP_MAX_GABS = 16 };
312 */ 312 */
313 313
314#if defined (CONFIG_SCTP_HMAC_MD5) 314#if defined (CONFIG_SCTP_HMAC_MD5)
315#define SCTP_COOKIE_HMAC_ALG "md5" 315#define SCTP_COOKIE_HMAC_ALG "hmac(md5)"
316#elif defined (CONFIG_SCTP_HMAC_SHA1) 316#elif defined (CONFIG_SCTP_HMAC_SHA1)
317#define SCTP_COOKIE_HMAC_ALG "sha1" 317#define SCTP_COOKIE_HMAC_ALG "hmac(sha1)"
318#else 318#else
319#define SCTP_COOKIE_HMAC_ALG NULL 319#define SCTP_COOKIE_HMAC_ALG NULL
320#endif 320#endif
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 92eae0e0f3f1..1c1abce5f6b6 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -330,17 +330,6 @@ static inline void sctp_v6_exit(void) { return; }
330 330
331#endif /* #if defined(CONFIG_IPV6) */ 331#endif /* #if defined(CONFIG_IPV6) */
332 332
333/* Some wrappers, in case crypto not available. */
334#if defined (CONFIG_CRYPTO_HMAC)
335#define sctp_crypto_alloc_tfm crypto_alloc_tfm
336#define sctp_crypto_free_tfm crypto_free_tfm
337#define sctp_crypto_hmac crypto_hmac
338#else
339#define sctp_crypto_alloc_tfm(x...) NULL
340#define sctp_crypto_free_tfm(x...)
341#define sctp_crypto_hmac(x...)
342#endif
343
344 333
345/* Map an association to an assoc_id. */ 334/* Map an association to an assoc_id. */
346static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) 335static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index e5aa7ff1f5b5..0412e730c765 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -87,6 +87,7 @@ struct sctp_bind_addr;
87struct sctp_ulpq; 87struct sctp_ulpq;
88struct sctp_ep_common; 88struct sctp_ep_common;
89struct sctp_ssnmap; 89struct sctp_ssnmap;
90struct crypto_hash;
90 91
91 92
92#include <net/sctp/tsnmap.h> 93#include <net/sctp/tsnmap.h>
@@ -264,7 +265,7 @@ struct sctp_sock {
264 struct sctp_pf *pf; 265 struct sctp_pf *pf;
265 266
266 /* Access to HMAC transform. */ 267 /* Access to HMAC transform. */
267 struct crypto_tfm *hmac; 268 struct crypto_hash *hmac;
268 269
269 /* What is our base endpointer? */ 270 /* What is our base endpointer? */
270 struct sctp_endpoint *ep; 271 struct sctp_endpoint *ep;
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9c5ee9f20b65..3ecd9fa1ed4b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -8,7 +8,6 @@
8#include <linux/list.h> 8#include <linux/list.h>
9#include <linux/skbuff.h> 9#include <linux/skbuff.h>
10#include <linux/socket.h> 10#include <linux/socket.h>
11#include <linux/crypto.h>
12#include <linux/pfkeyv2.h> 11#include <linux/pfkeyv2.h>
13#include <linux/in6.h> 12#include <linux/in6.h>
14#include <linux/mutex.h> 13#include <linux/mutex.h>
@@ -855,6 +854,7 @@ struct xfrm_algo_comp_info {
855 854
856struct xfrm_algo_desc { 855struct xfrm_algo_desc {
857 char *name; 856 char *name;
857 char *compat;
858 u8 available:1; 858 u8 available:1;
859 union { 859 union {
860 struct xfrm_algo_auth_info auth; 860 struct xfrm_algo_auth_info auth;
@@ -984,11 +984,13 @@ extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe);
984extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe); 984extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe);
985extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe); 985extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe);
986 986
987struct crypto_tfm; 987struct hash_desc;
988typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int); 988struct scatterlist;
989typedef int (icv_update_fn_t)(struct hash_desc *, struct scatterlist *,
990 unsigned int);
989 991
990extern void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, 992extern int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *tfm,
991 int offset, int len, icv_update_fn_t icv_update); 993 int offset, int len, icv_update_fn_t icv_update);
992 994
993static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b, 995static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b,
994 int family) 996 int family)
diff --git a/include/rdma/Kbuild b/include/rdma/Kbuild
index eb710ba9b1a0..e7c043216558 100644
--- a/include/rdma/Kbuild
+++ b/include/rdma/Kbuild
@@ -1 +1 @@
header-y := ib_user_mad.h header-y += ib_user_mad.h
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index 0ff67398928d..81b62307621d 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -40,7 +40,7 @@ struct rdma_dev_addr {
40 unsigned char src_dev_addr[MAX_ADDR_LEN]; 40 unsigned char src_dev_addr[MAX_ADDR_LEN];
41 unsigned char dst_dev_addr[MAX_ADDR_LEN]; 41 unsigned char dst_dev_addr[MAX_ADDR_LEN];
42 unsigned char broadcast[MAX_ADDR_LEN]; 42 unsigned char broadcast[MAX_ADDR_LEN];
43 enum ib_node_type dev_type; 43 enum rdma_node_type dev_type;
44}; 44};
45 45
46/** 46/**
@@ -72,6 +72,9 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
72 72
73void rdma_addr_cancel(struct rdma_dev_addr *addr); 73void rdma_addr_cancel(struct rdma_dev_addr *addr);
74 74
75int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
76 const unsigned char *dst_dev_addr);
77
75static inline int ip_addr_size(struct sockaddr *addr) 78static inline int ip_addr_size(struct sockaddr *addr)
76{ 79{
77 return addr->sa_family == AF_INET6 ? 80 return addr->sa_family == AF_INET6 ?
@@ -113,4 +116,16 @@ static inline void ib_addr_set_dgid(struct rdma_dev_addr *dev_addr,
113 memcpy(dev_addr->dst_dev_addr + 4, gid, sizeof *gid); 116 memcpy(dev_addr->dst_dev_addr + 4, gid, sizeof *gid);
114} 117}
115 118
119static inline void iw_addr_get_sgid(struct rdma_dev_addr *dev_addr,
120 union ib_gid *gid)
121{
122 memcpy(gid, dev_addr->src_dev_addr, sizeof *gid);
123}
124
125static inline void iw_addr_get_dgid(struct rdma_dev_addr *dev_addr,
126 union ib_gid *gid)
127{
128 memcpy(gid, dev_addr->dst_dev_addr, sizeof *gid);
129}
130
116#endif /* IB_ADDR_H */ 131#endif /* IB_ADDR_H */
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index c99e4420fd7e..97715b0c20b6 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
4 * Copyright (c) 2006 Intel Corporation. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -36,8 +37,11 @@
36#ifndef IB_SA_H 37#ifndef IB_SA_H
37#define IB_SA_H 38#define IB_SA_H
38 39
40#include <linux/completion.h>
39#include <linux/compiler.h> 41#include <linux/compiler.h>
40 42
43#include <asm/atomic.h>
44
41#include <rdma/ib_verbs.h> 45#include <rdma/ib_verbs.h>
42#include <rdma/ib_mad.h> 46#include <rdma/ib_mad.h>
43 47
@@ -79,8 +83,8 @@ enum {
79}; 83};
80 84
81enum ib_sa_selector { 85enum ib_sa_selector {
82 IB_SA_GTE = 0, 86 IB_SA_GT = 0,
83 IB_SA_LTE = 1, 87 IB_SA_LT = 1,
84 IB_SA_EQ = 2, 88 IB_SA_EQ = 2,
85 /* 89 /*
86 * The meaning of "best" depends on the attribute: for 90 * The meaning of "best" depends on the attribute: for
@@ -250,11 +254,28 @@ struct ib_sa_service_rec {
250 u64 data64[2]; 254 u64 data64[2];
251}; 255};
252 256
257struct ib_sa_client {
258 atomic_t users;
259 struct completion comp;
260};
261
262/**
263 * ib_sa_register_client - Register an SA client.
264 */
265void ib_sa_register_client(struct ib_sa_client *client);
266
267/**
268 * ib_sa_unregister_client - Deregister an SA client.
269 * @client: Client object to deregister.
270 */
271void ib_sa_unregister_client(struct ib_sa_client *client);
272
253struct ib_sa_query; 273struct ib_sa_query;
254 274
255void ib_sa_cancel_query(int id, struct ib_sa_query *query); 275void ib_sa_cancel_query(int id, struct ib_sa_query *query);
256 276
257int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, 277int ib_sa_path_rec_get(struct ib_sa_client *client,
278 struct ib_device *device, u8 port_num,
258 struct ib_sa_path_rec *rec, 279 struct ib_sa_path_rec *rec,
259 ib_sa_comp_mask comp_mask, 280 ib_sa_comp_mask comp_mask,
260 int timeout_ms, gfp_t gfp_mask, 281 int timeout_ms, gfp_t gfp_mask,
@@ -264,7 +285,8 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
264 void *context, 285 void *context,
265 struct ib_sa_query **query); 286 struct ib_sa_query **query);
266 287
267int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, 288int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
289 struct ib_device *device, u8 port_num,
268 u8 method, 290 u8 method,
269 struct ib_sa_mcmember_rec *rec, 291 struct ib_sa_mcmember_rec *rec,
270 ib_sa_comp_mask comp_mask, 292 ib_sa_comp_mask comp_mask,
@@ -275,7 +297,8 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
275 void *context, 297 void *context,
276 struct ib_sa_query **query); 298 struct ib_sa_query **query);
277 299
278int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, 300int ib_sa_service_rec_query(struct ib_sa_client *client,
301 struct ib_device *device, u8 port_num,
279 u8 method, 302 u8 method,
280 struct ib_sa_service_rec *rec, 303 struct ib_sa_service_rec *rec,
281 ib_sa_comp_mask comp_mask, 304 ib_sa_comp_mask comp_mask,
@@ -288,6 +311,7 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num,
288 311
289/** 312/**
290 * ib_sa_mcmember_rec_set - Start an MCMember set query 313 * ib_sa_mcmember_rec_set - Start an MCMember set query
314 * @client:SA client
291 * @device:device to send query on 315 * @device:device to send query on
292 * @port_num: port number to send query on 316 * @port_num: port number to send query on
293 * @rec:MCMember Record to send in query 317 * @rec:MCMember Record to send in query
@@ -311,7 +335,8 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num,
311 * cancel the query. 335 * cancel the query.
312 */ 336 */
313static inline int 337static inline int
314ib_sa_mcmember_rec_set(struct ib_device *device, u8 port_num, 338ib_sa_mcmember_rec_set(struct ib_sa_client *client,
339 struct ib_device *device, u8 port_num,
315 struct ib_sa_mcmember_rec *rec, 340 struct ib_sa_mcmember_rec *rec,
316 ib_sa_comp_mask comp_mask, 341 ib_sa_comp_mask comp_mask,
317 int timeout_ms, gfp_t gfp_mask, 342 int timeout_ms, gfp_t gfp_mask,
@@ -321,7 +346,7 @@ ib_sa_mcmember_rec_set(struct ib_device *device, u8 port_num,
321 void *context, 346 void *context,
322 struct ib_sa_query **query) 347 struct ib_sa_query **query)
323{ 348{
324 return ib_sa_mcmember_rec_query(device, port_num, 349 return ib_sa_mcmember_rec_query(client, device, port_num,
325 IB_MGMT_METHOD_SET, 350 IB_MGMT_METHOD_SET,
326 rec, comp_mask, 351 rec, comp_mask,
327 timeout_ms, gfp_mask, callback, 352 timeout_ms, gfp_mask, callback,
@@ -330,6 +355,7 @@ ib_sa_mcmember_rec_set(struct ib_device *device, u8 port_num,
330 355
331/** 356/**
332 * ib_sa_mcmember_rec_delete - Start an MCMember delete query 357 * ib_sa_mcmember_rec_delete - Start an MCMember delete query
358 * @client:SA client
333 * @device:device to send query on 359 * @device:device to send query on
334 * @port_num: port number to send query on 360 * @port_num: port number to send query on
335 * @rec:MCMember Record to send in query 361 * @rec:MCMember Record to send in query
@@ -353,7 +379,8 @@ ib_sa_mcmember_rec_set(struct ib_device *device, u8 port_num,
353 * cancel the query. 379 * cancel the query.
354 */ 380 */
355static inline int 381static inline int
356ib_sa_mcmember_rec_delete(struct ib_device *device, u8 port_num, 382ib_sa_mcmember_rec_delete(struct ib_sa_client *client,
383 struct ib_device *device, u8 port_num,
357 struct ib_sa_mcmember_rec *rec, 384 struct ib_sa_mcmember_rec *rec,
358 ib_sa_comp_mask comp_mask, 385 ib_sa_comp_mask comp_mask,
359 int timeout_ms, gfp_t gfp_mask, 386 int timeout_ms, gfp_t gfp_mask,
@@ -363,7 +390,7 @@ ib_sa_mcmember_rec_delete(struct ib_device *device, u8 port_num,
363 void *context, 390 void *context,
364 struct ib_sa_query **query) 391 struct ib_sa_query **query)
365{ 392{
366 return ib_sa_mcmember_rec_query(device, port_num, 393 return ib_sa_mcmember_rec_query(client, device, port_num,
367 IB_SA_METHOD_DELETE, 394 IB_SA_METHOD_DELETE,
368 rec, comp_mask, 395 rec, comp_mask,
369 timeout_ms, gfp_mask, callback, 396 timeout_ms, gfp_mask, callback,
diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h
index 7b5372010f4b..db1b814b62cc 100644
--- a/include/rdma/ib_user_verbs.h
+++ b/include/rdma/ib_user_verbs.h
@@ -275,6 +275,8 @@ struct ib_uverbs_resize_cq {
275 275
276struct ib_uverbs_resize_cq_resp { 276struct ib_uverbs_resize_cq_resp {
277 __u32 cqe; 277 __u32 cqe;
278 __u32 reserved;
279 __u64 driver_data[0];
278}; 280};
279 281
280struct ib_uverbs_poll_cq { 282struct ib_uverbs_poll_cq {
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index ee1f3a355666..8eacc3510993 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -56,12 +56,22 @@ union ib_gid {
56 } global; 56 } global;
57}; 57};
58 58
59enum ib_node_type { 59enum rdma_node_type {
60 IB_NODE_CA = 1, 60 /* IB values map to NodeInfo:NodeType. */
61 IB_NODE_SWITCH, 61 RDMA_NODE_IB_CA = 1,
62 IB_NODE_ROUTER 62 RDMA_NODE_IB_SWITCH,
63 RDMA_NODE_IB_ROUTER,
64 RDMA_NODE_RNIC
63}; 65};
64 66
67enum rdma_transport_type {
68 RDMA_TRANSPORT_IB,
69 RDMA_TRANSPORT_IWARP
70};
71
72enum rdma_transport_type
73rdma_node_get_transport(enum rdma_node_type node_type) __attribute_const__;
74
65enum ib_device_cap_flags { 75enum ib_device_cap_flags {
66 IB_DEVICE_RESIZE_MAX_WR = 1, 76 IB_DEVICE_RESIZE_MAX_WR = 1,
67 IB_DEVICE_BAD_PKEY_CNTR = (1<<1), 77 IB_DEVICE_BAD_PKEY_CNTR = (1<<1),
@@ -78,6 +88,9 @@ enum ib_device_cap_flags {
78 IB_DEVICE_RC_RNR_NAK_GEN = (1<<12), 88 IB_DEVICE_RC_RNR_NAK_GEN = (1<<12),
79 IB_DEVICE_SRQ_RESIZE = (1<<13), 89 IB_DEVICE_SRQ_RESIZE = (1<<13),
80 IB_DEVICE_N_NOTIFY_CQ = (1<<14), 90 IB_DEVICE_N_NOTIFY_CQ = (1<<14),
91 IB_DEVICE_ZERO_STAG = (1<<15),
92 IB_DEVICE_SEND_W_INV = (1<<16),
93 IB_DEVICE_MEM_WINDOW = (1<<17)
81}; 94};
82 95
83enum ib_atomic_cap { 96enum ib_atomic_cap {
@@ -835,6 +848,8 @@ struct ib_cache {
835 u8 *lmc_cache; 848 u8 *lmc_cache;
836}; 849};
837 850
851struct iw_cm_verbs;
852
838struct ib_device { 853struct ib_device {
839 struct device *dma_device; 854 struct device *dma_device;
840 855
@@ -851,6 +866,8 @@ struct ib_device {
851 866
852 u32 flags; 867 u32 flags;
853 868
869 struct iw_cm_verbs *iwcm;
870
854 int (*query_device)(struct ib_device *device, 871 int (*query_device)(struct ib_device *device,
855 struct ib_device_attr *device_attr); 872 struct ib_device_attr *device_attr);
856 int (*query_port)(struct ib_device *device, 873 int (*query_port)(struct ib_device *device,
@@ -888,7 +905,8 @@ struct ib_device {
888 struct ib_udata *udata); 905 struct ib_udata *udata);
889 int (*modify_srq)(struct ib_srq *srq, 906 int (*modify_srq)(struct ib_srq *srq,
890 struct ib_srq_attr *srq_attr, 907 struct ib_srq_attr *srq_attr,
891 enum ib_srq_attr_mask srq_attr_mask); 908 enum ib_srq_attr_mask srq_attr_mask,
909 struct ib_udata *udata);
892 int (*query_srq)(struct ib_srq *srq, 910 int (*query_srq)(struct ib_srq *srq,
893 struct ib_srq_attr *srq_attr); 911 struct ib_srq_attr *srq_attr);
894 int (*destroy_srq)(struct ib_srq *srq); 912 int (*destroy_srq)(struct ib_srq *srq);
@@ -900,7 +918,8 @@ struct ib_device {
900 struct ib_udata *udata); 918 struct ib_udata *udata);
901 int (*modify_qp)(struct ib_qp *qp, 919 int (*modify_qp)(struct ib_qp *qp,
902 struct ib_qp_attr *qp_attr, 920 struct ib_qp_attr *qp_attr,
903 int qp_attr_mask); 921 int qp_attr_mask,
922 struct ib_udata *udata);
904 int (*query_qp)(struct ib_qp *qp, 923 int (*query_qp)(struct ib_qp *qp,
905 struct ib_qp_attr *qp_attr, 924 struct ib_qp_attr *qp_attr,
906 int qp_attr_mask, 925 int qp_attr_mask,
diff --git a/include/rdma/iw_cm.h b/include/rdma/iw_cm.h
new file mode 100644
index 000000000000..aeefa9b740dc
--- /dev/null
+++ b/include/rdma/iw_cm.h
@@ -0,0 +1,258 @@
1/*
2 * Copyright (c) 2005 Network Appliance, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#ifndef IW_CM_H
34#define IW_CM_H
35
36#include <linux/in.h>
37#include <rdma/ib_cm.h>
38
39struct iw_cm_id;
40
41enum iw_cm_event_type {
42 IW_CM_EVENT_CONNECT_REQUEST = 1, /* connect request received */
43 IW_CM_EVENT_CONNECT_REPLY, /* reply from active connect request */
44 IW_CM_EVENT_ESTABLISHED, /* passive side accept successful */
45 IW_CM_EVENT_DISCONNECT, /* orderly shutdown */
46 IW_CM_EVENT_CLOSE /* close complete */
47};
48
49enum iw_cm_event_status {
50 IW_CM_EVENT_STATUS_OK = 0, /* request successful */
51 IW_CM_EVENT_STATUS_ACCEPTED = 0, /* connect request accepted */
52 IW_CM_EVENT_STATUS_REJECTED, /* connect request rejected */
53 IW_CM_EVENT_STATUS_TIMEOUT, /* the operation timed out */
54 IW_CM_EVENT_STATUS_RESET, /* reset from remote peer */
55 IW_CM_EVENT_STATUS_EINVAL, /* asynchronous failure for bad parm */
56};
57
58struct iw_cm_event {
59 enum iw_cm_event_type event;
60 enum iw_cm_event_status status;
61 struct sockaddr_in local_addr;
62 struct sockaddr_in remote_addr;
63 void *private_data;
64 u8 private_data_len;
65 void* provider_data;
66};
67
68/**
69 * iw_cm_handler - Function to be called by the IW CM when delivering events
70 * to the client.
71 *
72 * @cm_id: The IW CM identifier associated with the event.
73 * @event: Pointer to the event structure.
74 */
75typedef int (*iw_cm_handler)(struct iw_cm_id *cm_id,
76 struct iw_cm_event *event);
77
78/**
79 * iw_event_handler - Function called by the provider when delivering provider
80 * events to the IW CM. Returns either 0 indicating the event was processed
81 * or -errno if the event could not be processed.
82 *
83 * @cm_id: The IW CM identifier associated with the event.
84 * @event: Pointer to the event structure.
85 */
86typedef int (*iw_event_handler)(struct iw_cm_id *cm_id,
87 struct iw_cm_event *event);
88
89struct iw_cm_id {
90 iw_cm_handler cm_handler; /* client callback function */
91 void *context; /* client cb context */
92 struct ib_device *device;
93 struct sockaddr_in local_addr;
94 struct sockaddr_in remote_addr;
95 void *provider_data; /* provider private data */
96 iw_event_handler event_handler; /* cb for provider
97 events */
98 /* Used by provider to add and remove refs on IW cm_id */
99 void (*add_ref)(struct iw_cm_id *);
100 void (*rem_ref)(struct iw_cm_id *);
101};
102
103struct iw_cm_conn_param {
104 const void *private_data;
105 u16 private_data_len;
106 u32 ord;
107 u32 ird;
108 u32 qpn;
109};
110
111struct iw_cm_verbs {
112 void (*add_ref)(struct ib_qp *qp);
113
114 void (*rem_ref)(struct ib_qp *qp);
115
116 struct ib_qp * (*get_qp)(struct ib_device *device,
117 int qpn);
118
119 int (*connect)(struct iw_cm_id *cm_id,
120 struct iw_cm_conn_param *conn_param);
121
122 int (*accept)(struct iw_cm_id *cm_id,
123 struct iw_cm_conn_param *conn_param);
124
125 int (*reject)(struct iw_cm_id *cm_id,
126 const void *pdata, u8 pdata_len);
127
128 int (*create_listen)(struct iw_cm_id *cm_id,
129 int backlog);
130
131 int (*destroy_listen)(struct iw_cm_id *cm_id);
132};
133
134/**
135 * iw_create_cm_id - Create an IW CM identifier.
136 *
137 * @device: The IB device on which to create the IW CM identier.
138 * @event_handler: User callback invoked to report events associated with the
139 * returned IW CM identifier.
140 * @context: User specified context associated with the id.
141 */
142struct iw_cm_id *iw_create_cm_id(struct ib_device *device,
143 iw_cm_handler cm_handler, void *context);
144
145/**
146 * iw_destroy_cm_id - Destroy an IW CM identifier.
147 *
148 * @cm_id: The previously created IW CM identifier to destroy.
149 *
150 * The client can assume that no events will be delivered for the CM ID after
151 * this function returns.
152 */
153void iw_destroy_cm_id(struct iw_cm_id *cm_id);
154
155/**
156 * iw_cm_bind_qp - Unbind the specified IW CM identifier and QP
157 *
158 * @cm_id: The IW CM idenfier to unbind from the QP.
159 * @qp: The QP
160 *
161 * This is called by the provider when destroying the QP to ensure
162 * that any references held by the IWCM are released. It may also
163 * be called by the IWCM when destroying a CM_ID to that any
164 * references held by the provider are released.
165 */
166void iw_cm_unbind_qp(struct iw_cm_id *cm_id, struct ib_qp *qp);
167
168/**
169 * iw_cm_get_qp - Return the ib_qp associated with a QPN
170 *
171 * @ib_device: The IB device
172 * @qpn: The queue pair number
173 */
174struct ib_qp *iw_cm_get_qp(struct ib_device *device, int qpn);
175
176/**
177 * iw_cm_listen - Listen for incoming connection requests on the
178 * specified IW CM id.
179 *
180 * @cm_id: The IW CM identifier.
181 * @backlog: The maximum number of outstanding un-accepted inbound listen
182 * requests to queue.
183 *
184 * The source address and port number are specified in the IW CM identifier
185 * structure.
186 */
187int iw_cm_listen(struct iw_cm_id *cm_id, int backlog);
188
189/**
190 * iw_cm_accept - Called to accept an incoming connect request.
191 *
192 * @cm_id: The IW CM identifier associated with the connection request.
193 * @iw_param: Pointer to a structure containing connection establishment
194 * parameters.
195 *
196 * The specified cm_id will have been provided in the event data for a
197 * CONNECT_REQUEST event. Subsequent events related to this connection will be
198 * delivered to the specified IW CM identifier prior and may occur prior to
199 * the return of this function. If this function returns a non-zero value, the
200 * client can assume that no events will be delivered to the specified IW CM
201 * identifier.
202 */
203int iw_cm_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param);
204
205/**
206 * iw_cm_reject - Reject an incoming connection request.
207 *
208 * @cm_id: Connection identifier associated with the request.
209 * @private_daa: Pointer to data to deliver to the remote peer as part of the
210 * reject message.
211 * @private_data_len: The number of bytes in the private_data parameter.
212 *
213 * The client can assume that no events will be delivered to the specified IW
214 * CM identifier following the return of this function. The private_data
215 * buffer is available for reuse when this function returns.
216 */
217int iw_cm_reject(struct iw_cm_id *cm_id, const void *private_data,
218 u8 private_data_len);
219
220/**
221 * iw_cm_connect - Called to request a connection to a remote peer.
222 *
223 * @cm_id: The IW CM identifier for the connection.
224 * @iw_param: Pointer to a structure containing connection establishment
225 * parameters.
226 *
227 * Events may be delivered to the specified IW CM identifier prior to the
228 * return of this function. If this function returns a non-zero value, the
229 * client can assume that no events will be delivered to the specified IW CM
230 * identifier.
231 */
232int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param);
233
234/**
235 * iw_cm_disconnect - Close the specified connection.
236 *
237 * @cm_id: The IW CM identifier to close.
238 * @abrupt: If 0, the connection will be closed gracefully, otherwise, the
239 * connection will be reset.
240 *
241 * The IW CM identifier is still active until the IW_CM_EVENT_CLOSE event is
242 * delivered.
243 */
244int iw_cm_disconnect(struct iw_cm_id *cm_id, int abrupt);
245
246/**
247 * iw_cm_init_qp_attr - Called to initialize the attributes of the QP
248 * associated with a IW CM identifier.
249 *
250 * @cm_id: The IW CM identifier associated with the QP
251 * @qp_attr: Pointer to the QP attributes structure.
252 * @qp_attr_mask: Pointer to a bit vector specifying which QP attributes are
253 * valid.
254 */
255int iw_cm_init_qp_attr(struct iw_cm_id *cm_id, struct ib_qp_attr *qp_attr,
256 int *qp_attr_mask);
257
258#endif /* IW_CM_H */
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index 402c63d7226b..deb5a0a4cee5 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -117,6 +117,14 @@ struct rdma_cm_id {
117struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler, 117struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
118 void *context, enum rdma_port_space ps); 118 void *context, enum rdma_port_space ps);
119 119
120/**
121 * rdma_destroy_id - Destroys an RDMA identifier.
122 *
123 * @id: RDMA identifier.
124 *
125 * Note: calling this function has the effect of canceling in-flight
126 * asynchronous operations associated with the id.
127 */
120void rdma_destroy_id(struct rdma_cm_id *id); 128void rdma_destroy_id(struct rdma_cm_id *id);
121 129
122/** 130/**
@@ -237,6 +245,10 @@ int rdma_listen(struct rdma_cm_id *id, int backlog);
237 * Typically, this routine is only called by the listener to accept a connection 245 * Typically, this routine is only called by the listener to accept a connection
238 * request. It must also be called on the active side of a connection if the 246 * request. It must also be called on the active side of a connection if the
239 * user is performing their own QP transitions. 247 * user is performing their own QP transitions.
248 *
249 * In the case of error, a reject message is sent to the remote side and the
250 * state of the qp associated with the id is modified to error, such that any
251 * previously posted receive buffers would be flushed.
240 */ 252 */
241int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param); 253int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param);
242 254
diff --git a/include/scsi/Kbuild b/include/scsi/Kbuild
index 14a033d73314..744f85011f1e 100644
--- a/include/scsi/Kbuild
+++ b/include/scsi/Kbuild
@@ -1,2 +1,4 @@
1header-y += scsi.h 1header-y += scsi.h
2unifdef-y := scsi_ioctl.h sg.h 2
3unifdef-y += scsi_ioctl.h
4unifdef-y += sg.h
diff --git a/include/sound/Kbuild b/include/sound/Kbuild
index 3a5a3df61496..fd054a344324 100644
--- a/include/sound/Kbuild
+++ b/include/sound/Kbuild
@@ -1,2 +1,10 @@
1header-y := asound_fm.h hdsp.h hdspm.h sfnt_info.h sscape_ioctl.h 1header-y += asound_fm.h
2unifdef-y := asequencer.h asound.h emu10k1.h sb16_csp.h 2header-y += hdsp.h
3header-y += hdspm.h
4header-y += sfnt_info.h
5header-y += sscape_ioctl.h
6
7unifdef-y += asequencer.h
8unifdef-y += asound.h
9unifdef-y += emu10k1.h
10unifdef-y += sb16_csp.h
diff --git a/include/video/Kbuild b/include/video/Kbuild
index 76a60737cc15..a14f9c045b8c 100644
--- a/include/video/Kbuild
+++ b/include/video/Kbuild
@@ -1 +1 @@
unifdef-y := sisfb.h unifdef-y += sisfb.h
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 098c66846339..35aa3426c3fa 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -9,6 +9,7 @@
9 * more details. 9 * more details.
10 */ 10 */
11 11
12#include <linux/err.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
@@ -48,7 +49,7 @@ struct ieee80211_ccmp_data {
48 49
49 int key_idx; 50 int key_idx;
50 51
51 struct crypto_tfm *tfm; 52 struct crypto_cipher *tfm;
52 53
53 /* scratch buffers for virt_to_page() (crypto API) */ 54 /* scratch buffers for virt_to_page() (crypto API) */
54 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], 55 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
@@ -56,20 +57,10 @@ struct ieee80211_ccmp_data {
56 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; 57 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
57}; 58};
58 59
59static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm, 60static inline void ieee80211_ccmp_aes_encrypt(struct crypto_cipher *tfm,
60 const u8 pt[16], u8 ct[16]) 61 const u8 pt[16], u8 ct[16])
61{ 62{
62 struct scatterlist src, dst; 63 crypto_cipher_encrypt_one(tfm, ct, pt);
63
64 src.page = virt_to_page(pt);
65 src.offset = offset_in_page(pt);
66 src.length = AES_BLOCK_LEN;
67
68 dst.page = virt_to_page(ct);
69 dst.offset = offset_in_page(ct);
70 dst.length = AES_BLOCK_LEN;
71
72 crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
73} 64}
74 65
75static void *ieee80211_ccmp_init(int key_idx) 66static void *ieee80211_ccmp_init(int key_idx)
@@ -81,10 +72,11 @@ static void *ieee80211_ccmp_init(int key_idx)
81 goto fail; 72 goto fail;
82 priv->key_idx = key_idx; 73 priv->key_idx = key_idx;
83 74
84 priv->tfm = crypto_alloc_tfm("aes", 0); 75 priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
85 if (priv->tfm == NULL) { 76 if (IS_ERR(priv->tfm)) {
86 printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " 77 printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
87 "crypto API aes\n"); 78 "crypto API aes\n");
79 priv->tfm = NULL;
88 goto fail; 80 goto fail;
89 } 81 }
90 82
@@ -93,7 +85,7 @@ static void *ieee80211_ccmp_init(int key_idx)
93 fail: 85 fail:
94 if (priv) { 86 if (priv) {
95 if (priv->tfm) 87 if (priv->tfm)
96 crypto_free_tfm(priv->tfm); 88 crypto_free_cipher(priv->tfm);
97 kfree(priv); 89 kfree(priv);
98 } 90 }
99 91
@@ -104,7 +96,7 @@ static void ieee80211_ccmp_deinit(void *priv)
104{ 96{
105 struct ieee80211_ccmp_data *_priv = priv; 97 struct ieee80211_ccmp_data *_priv = priv;
106 if (_priv && _priv->tfm) 98 if (_priv && _priv->tfm)
107 crypto_free_tfm(_priv->tfm); 99 crypto_free_cipher(_priv->tfm);
108 kfree(priv); 100 kfree(priv);
109} 101}
110 102
@@ -115,7 +107,7 @@ static inline void xor_block(u8 * b, u8 * a, size_t len)
115 b[i] ^= a[i]; 107 b[i] ^= a[i];
116} 108}
117 109
118static void ccmp_init_blocks(struct crypto_tfm *tfm, 110static void ccmp_init_blocks(struct crypto_cipher *tfm,
119 struct ieee80211_hdr_4addr *hdr, 111 struct ieee80211_hdr_4addr *hdr,
120 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0) 112 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
121{ 113{
@@ -398,7 +390,7 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
398{ 390{
399 struct ieee80211_ccmp_data *data = priv; 391 struct ieee80211_ccmp_data *data = priv;
400 int keyidx; 392 int keyidx;
401 struct crypto_tfm *tfm = data->tfm; 393 struct crypto_cipher *tfm = data->tfm;
402 394
403 keyidx = data->key_idx; 395 keyidx = data->key_idx;
404 memset(data, 0, sizeof(*data)); 396 memset(data, 0, sizeof(*data));
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index f2df2f5b3e4c..259572dfd4f1 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -9,6 +9,7 @@
9 * more details. 9 * more details.
10 */ 10 */
11 11
12#include <linux/err.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
@@ -52,10 +53,10 @@ struct ieee80211_tkip_data {
52 53
53 int key_idx; 54 int key_idx;
54 55
55 struct crypto_tfm *tx_tfm_arc4; 56 struct crypto_blkcipher *rx_tfm_arc4;
56 struct crypto_tfm *tx_tfm_michael; 57 struct crypto_hash *rx_tfm_michael;
57 struct crypto_tfm *rx_tfm_arc4; 58 struct crypto_blkcipher *tx_tfm_arc4;
58 struct crypto_tfm *rx_tfm_michael; 59 struct crypto_hash *tx_tfm_michael;
59 60
60 /* scratch buffers for virt_to_page() (crypto API) */ 61 /* scratch buffers for virt_to_page() (crypto API) */
61 u8 rx_hdr[16], tx_hdr[16]; 62 u8 rx_hdr[16], tx_hdr[16];
@@ -87,31 +88,37 @@ static void *ieee80211_tkip_init(int key_idx)
87 88
88 priv->key_idx = key_idx; 89 priv->key_idx = key_idx;
89 90
90 priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0); 91 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
91 if (priv->tx_tfm_arc4 == NULL) { 92 CRYPTO_ALG_ASYNC);
93 if (IS_ERR(priv->tx_tfm_arc4)) {
92 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 94 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
93 "crypto API arc4\n"); 95 "crypto API arc4\n");
96 priv->tfm_arc4 = NULL;
94 goto fail; 97 goto fail;
95 } 98 }
96 99
97 priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0); 100 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
98 if (priv->tx_tfm_michael == NULL) { 101 CRYPTO_ALG_ASYNC);
102 if (IS_ERR(priv->tx_tfm_michael)) {
99 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 103 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
100 "crypto API michael_mic\n"); 104 "crypto API michael_mic\n");
101 goto fail; 105 goto fail;
102 } 106 }
103 107
104 priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0); 108 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
105 if (priv->rx_tfm_arc4 == NULL) { 109 CRYPTO_ALG_ASYNC);
110 if (IS_ERR(priv->rx_tfm_arc4)) {
106 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 111 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
107 "crypto API arc4\n"); 112 "crypto API arc4\n");
108 goto fail; 113 goto fail;
109 } 114 }
110 115
111 priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0); 116 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
112 if (priv->rx_tfm_michael == NULL) { 117 CRYPTO_ALG_ASYNC);
118 if (IS_ERR(priv->rx_tfm_michael)) {
113 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 119 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
114 "crypto API michael_mic\n"); 120 "crypto API michael_mic\n");
121 priv->tfm_michael = NULL;
115 goto fail; 122 goto fail;
116 } 123 }
117 124
@@ -120,13 +127,13 @@ static void *ieee80211_tkip_init(int key_idx)
120 fail: 127 fail:
121 if (priv) { 128 if (priv) {
122 if (priv->tx_tfm_michael) 129 if (priv->tx_tfm_michael)
123 crypto_free_tfm(priv->tx_tfm_michael); 130 crypto_free_hash(priv->tx_tfm_michael);
124 if (priv->tx_tfm_arc4) 131 if (priv->tx_tfm_arc4)
125 crypto_free_tfm(priv->tx_tfm_arc4); 132 crypto_free_blkcipher(priv->tx_tfm_arc4);
126 if (priv->rx_tfm_michael) 133 if (priv->rx_tfm_michael)
127 crypto_free_tfm(priv->rx_tfm_michael); 134 crypto_free_hash(priv->rx_tfm_michael);
128 if (priv->rx_tfm_arc4) 135 if (priv->rx_tfm_arc4)
129 crypto_free_tfm(priv->rx_tfm_arc4); 136 crypto_free_blkcipher(priv->rx_tfm_arc4);
130 kfree(priv); 137 kfree(priv);
131 } 138 }
132 139
@@ -138,13 +145,13 @@ static void ieee80211_tkip_deinit(void *priv)
138 struct ieee80211_tkip_data *_priv = priv; 145 struct ieee80211_tkip_data *_priv = priv;
139 if (_priv) { 146 if (_priv) {
140 if (_priv->tx_tfm_michael) 147 if (_priv->tx_tfm_michael)
141 crypto_free_tfm(_priv->tx_tfm_michael); 148 crypto_free_hash(_priv->tx_tfm_michael);
142 if (_priv->tx_tfm_arc4) 149 if (_priv->tx_tfm_arc4)
143 crypto_free_tfm(_priv->tx_tfm_arc4); 150 crypto_free_blkcipher(_priv->tx_tfm_arc4);
144 if (_priv->rx_tfm_michael) 151 if (_priv->rx_tfm_michael)
145 crypto_free_tfm(_priv->rx_tfm_michael); 152 crypto_free_hash(_priv->rx_tfm_michael);
146 if (_priv->rx_tfm_arc4) 153 if (_priv->rx_tfm_arc4)
147 crypto_free_tfm(_priv->rx_tfm_arc4); 154 crypto_free_blkcipher(_priv->rx_tfm_arc4);
148 } 155 }
149 kfree(priv); 156 kfree(priv);
150} 157}
@@ -344,6 +351,7 @@ static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
344static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 351static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
345{ 352{
346 struct ieee80211_tkip_data *tkey = priv; 353 struct ieee80211_tkip_data *tkey = priv;
354 struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
347 int len; 355 int len;
348 u8 rc4key[16], *pos, *icv; 356 u8 rc4key[16], *pos, *icv;
349 u32 crc; 357 u32 crc;
@@ -377,31 +385,17 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
377 icv[2] = crc >> 16; 385 icv[2] = crc >> 16;
378 icv[3] = crc >> 24; 386 icv[3] = crc >> 24;
379 387
380 crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); 388 crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
381 sg.page = virt_to_page(pos); 389 sg.page = virt_to_page(pos);
382 sg.offset = offset_in_page(pos); 390 sg.offset = offset_in_page(pos);
383 sg.length = len + 4; 391 sg.length = len + 4;
384 crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4); 392 return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
385
386 return 0;
387}
388
389/*
390 * deal with seq counter wrapping correctly.
391 * refer to timer_after() for jiffies wrapping handling
392 */
393static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
394 u32 iv32_o, u16 iv16_o)
395{
396 if ((s32)iv32_n - (s32)iv32_o < 0 ||
397 (iv32_n == iv32_o && iv16_n <= iv16_o))
398 return 1;
399 return 0;
400} 393}
401 394
402static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 395static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
403{ 396{
404 struct ieee80211_tkip_data *tkey = priv; 397 struct ieee80211_tkip_data *tkey = priv;
398 struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
405 u8 rc4key[16]; 399 u8 rc4key[16];
406 u8 keyidx, *pos; 400 u8 keyidx, *pos;
407 u32 iv32; 401 u32 iv32;
@@ -472,11 +466,18 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
472 466
473 plen = skb->len - hdr_len - 12; 467 plen = skb->len - hdr_len - 12;
474 468
475 crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); 469 crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
476 sg.page = virt_to_page(pos); 470 sg.page = virt_to_page(pos);
477 sg.offset = offset_in_page(pos); 471 sg.offset = offset_in_page(pos);
478 sg.length = plen + 4; 472 sg.length = plen + 4;
479 crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4); 473 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
474 if (net_ratelimit()) {
475 printk(KERN_DEBUG ": TKIP: failed to decrypt "
476 "received packet from " MAC_FMT "\n",
477 MAC_ARG(hdr->addr2));
478 }
479 return -7;
480 }
480 481
481 crc = ~crc32_le(~0, pos, plen); 482 crc = ~crc32_le(~0, pos, plen);
482 icv[0] = crc; 483 icv[0] = crc;
@@ -510,9 +511,10 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
510 return keyidx; 511 return keyidx;
511} 512}
512 513
513static int michael_mic(struct crypto_tfm *tfm_michael, u8 * key, u8 * hdr, 514static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
514 u8 * data, size_t data_len, u8 * mic) 515 u8 * data, size_t data_len, u8 * mic)
515{ 516{
517 struct hash_desc desc;
516 struct scatterlist sg[2]; 518 struct scatterlist sg[2];
517 519
518 if (tfm_michael == NULL) { 520 if (tfm_michael == NULL) {
@@ -527,12 +529,12 @@ static int michael_mic(struct crypto_tfm *tfm_michael, u8 * key, u8 * hdr,
527 sg[1].offset = offset_in_page(data); 529 sg[1].offset = offset_in_page(data);
528 sg[1].length = data_len; 530 sg[1].length = data_len;
529 531
530 crypto_digest_init(tfm_michael); 532 if (crypto_hash_setkey(tfm_michael, key, 8))
531 crypto_digest_setkey(tfm_michael, key, 8); 533 return -1;
532 crypto_digest_update(tfm_michael, sg, 2);
533 crypto_digest_final(tfm_michael, mic);
534 534
535 return 0; 535 desc.tfm = tfm_michael;
536 desc.flags = 0;
537 return crypto_hash_digest(&desc, sg, data_len + 16, mic);
536} 538}
537 539
538static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) 540static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
@@ -656,10 +658,10 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
656{ 658{
657 struct ieee80211_tkip_data *tkey = priv; 659 struct ieee80211_tkip_data *tkey = priv;
658 int keyidx; 660 int keyidx;
659 struct crypto_tfm *tfm = tkey->tx_tfm_michael; 661 struct crypto_hash *tfm = tkey->tx_tfm_michael;
660 struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4; 662 struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
661 struct crypto_tfm *tfm3 = tkey->rx_tfm_michael; 663 struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
662 struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4; 664 struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
663 665
664 keyidx = tkey->key_idx; 666 keyidx = tkey->key_idx;
665 memset(tkey, 0, sizeof(*tkey)); 667 memset(tkey, 0, sizeof(*tkey));
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index b435b28857ed..9eeec13c28b0 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -9,6 +9,7 @@
9 * more details. 9 * more details.
10 */ 10 */
11 11
12#include <linux/err.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
@@ -32,8 +33,8 @@ struct prism2_wep_data {
32 u8 key[WEP_KEY_LEN + 1]; 33 u8 key[WEP_KEY_LEN + 1];
33 u8 key_len; 34 u8 key_len;
34 u8 key_idx; 35 u8 key_idx;
35 struct crypto_tfm *tx_tfm; 36 struct crypto_blkcipher *tx_tfm;
36 struct crypto_tfm *rx_tfm; 37 struct crypto_blkcipher *rx_tfm;
37}; 38};
38 39
39static void *prism2_wep_init(int keyidx) 40static void *prism2_wep_init(int keyidx)
@@ -45,15 +46,16 @@ static void *prism2_wep_init(int keyidx)
45 goto fail; 46 goto fail;
46 priv->key_idx = keyidx; 47 priv->key_idx = keyidx;
47 48
48 priv->tx_tfm = crypto_alloc_tfm("arc4", 0); 49 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
49 if (priv->tx_tfm == NULL) { 50 if (IS_ERR(priv->tx_tfm)) {
50 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " 51 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
51 "crypto API arc4\n"); 52 "crypto API arc4\n");
53 priv->tfm = NULL;
52 goto fail; 54 goto fail;
53 } 55 }
54 56
55 priv->rx_tfm = crypto_alloc_tfm("arc4", 0); 57 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
56 if (priv->rx_tfm == NULL) { 58 if (IS_ERR(priv->rx_tfm)) {
57 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " 59 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
58 "crypto API arc4\n"); 60 "crypto API arc4\n");
59 goto fail; 61 goto fail;
@@ -66,9 +68,9 @@ static void *prism2_wep_init(int keyidx)
66 fail: 68 fail:
67 if (priv) { 69 if (priv) {
68 if (priv->tx_tfm) 70 if (priv->tx_tfm)
69 crypto_free_tfm(priv->tx_tfm); 71 crypto_free_blkcipher(priv->tx_tfm);
70 if (priv->rx_tfm) 72 if (priv->rx_tfm)
71 crypto_free_tfm(priv->rx_tfm); 73 crypto_free_blkcipher(priv->rx_tfm);
72 kfree(priv); 74 kfree(priv);
73 } 75 }
74 return NULL; 76 return NULL;
@@ -79,9 +81,9 @@ static void prism2_wep_deinit(void *priv)
79 struct prism2_wep_data *_priv = priv; 81 struct prism2_wep_data *_priv = priv;
80 if (_priv) { 82 if (_priv) {
81 if (_priv->tx_tfm) 83 if (_priv->tx_tfm)
82 crypto_free_tfm(_priv->tx_tfm); 84 crypto_free_blkcipher(_priv->tx_tfm);
83 if (_priv->rx_tfm) 85 if (_priv->rx_tfm)
84 crypto_free_tfm(_priv->rx_tfm); 86 crypto_free_blkcipher(_priv->rx_tfm);
85 } 87 }
86 kfree(priv); 88 kfree(priv);
87} 89}
@@ -133,6 +135,7 @@ static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len,
133static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 135static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
134{ 136{
135 struct prism2_wep_data *wep = priv; 137 struct prism2_wep_data *wep = priv;
138 struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
136 u32 crc, klen, len; 139 u32 crc, klen, len;
137 u8 *pos, *icv; 140 u8 *pos, *icv;
138 struct scatterlist sg; 141 struct scatterlist sg;
@@ -164,13 +167,11 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
164 icv[2] = crc >> 16; 167 icv[2] = crc >> 16;
165 icv[3] = crc >> 24; 168 icv[3] = crc >> 24;
166 169
167 crypto_cipher_setkey(wep->tx_tfm, key, klen); 170 crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
168 sg.page = virt_to_page(pos); 171 sg.page = virt_to_page(pos);
169 sg.offset = offset_in_page(pos); 172 sg.offset = offset_in_page(pos);
170 sg.length = len + 4; 173 sg.length = len + 4;
171 crypto_cipher_encrypt(wep->tx_tfm, &sg, &sg, len + 4); 174 return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
172
173 return 0;
174} 175}
175 176
176/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of 177/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
@@ -183,6 +184,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
183static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 184static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
184{ 185{
185 struct prism2_wep_data *wep = priv; 186 struct prism2_wep_data *wep = priv;
187 struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
186 u32 crc, klen, plen; 188 u32 crc, klen, plen;
187 u8 key[WEP_KEY_LEN + 3]; 189 u8 key[WEP_KEY_LEN + 3];
188 u8 keyidx, *pos, icv[4]; 190 u8 keyidx, *pos, icv[4];
@@ -207,11 +209,12 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
207 /* Apply RC4 to data and compute CRC32 over decrypted data */ 209 /* Apply RC4 to data and compute CRC32 over decrypted data */
208 plen = skb->len - hdr_len - 8; 210 plen = skb->len - hdr_len - 8;
209 211
210 crypto_cipher_setkey(wep->rx_tfm, key, klen); 212 crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
211 sg.page = virt_to_page(pos); 213 sg.page = virt_to_page(pos);
212 sg.offset = offset_in_page(pos); 214 sg.offset = offset_in_page(pos);
213 sg.length = plen + 4; 215 sg.length = plen + 4;
214 crypto_cipher_decrypt(wep->rx_tfm, &sg, &sg, plen + 4); 216 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
217 return -7;
215 218
216 crc = ~crc32_le(~0, pos, plen); 219 crc = ~crc32_le(~0, pos, plen);
217 icv[0] = crc; 220 icv[0] = crc;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 8514106761b0..3b5d504a74be 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -386,6 +386,7 @@ config INET_ESP
386 select CRYPTO 386 select CRYPTO
387 select CRYPTO_HMAC 387 select CRYPTO_HMAC
388 select CRYPTO_MD5 388 select CRYPTO_MD5
389 select CRYPTO_CBC
389 select CRYPTO_SHA1 390 select CRYPTO_SHA1
390 select CRYPTO_DES 391 select CRYPTO_DES
391 ---help--- 392 ---help---
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 1366bc6ce6a5..2b98943e6b02 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -1,3 +1,4 @@
1#include <linux/err.h>
1#include <linux/module.h> 2#include <linux/module.h>
2#include <net/ip.h> 3#include <net/ip.h>
3#include <net/xfrm.h> 4#include <net/xfrm.h>
@@ -97,7 +98,10 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
97 ah->spi = x->id.spi; 98 ah->spi = x->id.spi;
98 ah->seq_no = htonl(++x->replay.oseq); 99 ah->seq_no = htonl(++x->replay.oseq);
99 xfrm_aevent_doreplay(x); 100 xfrm_aevent_doreplay(x);
100 ahp->icv(ahp, skb, ah->auth_data); 101 err = ah_mac_digest(ahp, skb, ah->auth_data);
102 if (err)
103 goto error;
104 memcpy(ah->auth_data, ahp->work_icv, ahp->icv_trunc_len);
101 105
102 top_iph->tos = iph->tos; 106 top_iph->tos = iph->tos;
103 top_iph->ttl = iph->ttl; 107 top_iph->ttl = iph->ttl;
@@ -119,6 +123,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
119{ 123{
120 int ah_hlen; 124 int ah_hlen;
121 int ihl; 125 int ihl;
126 int err = -EINVAL;
122 struct iphdr *iph; 127 struct iphdr *iph;
123 struct ip_auth_hdr *ah; 128 struct ip_auth_hdr *ah;
124 struct ah_data *ahp; 129 struct ah_data *ahp;
@@ -166,8 +171,11 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
166 171
167 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); 172 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
168 skb_push(skb, ihl); 173 skb_push(skb, ihl);
169 ahp->icv(ahp, skb, ah->auth_data); 174 err = ah_mac_digest(ahp, skb, ah->auth_data);
170 if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { 175 if (err)
176 goto out;
177 err = -EINVAL;
178 if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
171 x->stats.integrity_failed++; 179 x->stats.integrity_failed++;
172 goto out; 180 goto out;
173 } 181 }
@@ -179,7 +187,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
179 return 0; 187 return 0;
180 188
181out: 189out:
182 return -EINVAL; 190 return err;
183} 191}
184 192
185static void ah4_err(struct sk_buff *skb, u32 info) 193static void ah4_err(struct sk_buff *skb, u32 info)
@@ -204,6 +212,7 @@ static int ah_init_state(struct xfrm_state *x)
204{ 212{
205 struct ah_data *ahp = NULL; 213 struct ah_data *ahp = NULL;
206 struct xfrm_algo_desc *aalg_desc; 214 struct xfrm_algo_desc *aalg_desc;
215 struct crypto_hash *tfm;
207 216
208 if (!x->aalg) 217 if (!x->aalg)
209 goto error; 218 goto error;
@@ -221,24 +230,27 @@ static int ah_init_state(struct xfrm_state *x)
221 230
222 ahp->key = x->aalg->alg_key; 231 ahp->key = x->aalg->alg_key;
223 ahp->key_len = (x->aalg->alg_key_len+7)/8; 232 ahp->key_len = (x->aalg->alg_key_len+7)/8;
224 ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); 233 tfm = crypto_alloc_hash(x->aalg->alg_name, 0, CRYPTO_ALG_ASYNC);
225 if (!ahp->tfm) 234 if (IS_ERR(tfm))
235 goto error;
236
237 ahp->tfm = tfm;
238 if (crypto_hash_setkey(tfm, ahp->key, ahp->key_len))
226 goto error; 239 goto error;
227 ahp->icv = ah_hmac_digest;
228 240
229 /* 241 /*
230 * Lookup the algorithm description maintained by xfrm_algo, 242 * Lookup the algorithm description maintained by xfrm_algo,
231 * verify crypto transform properties, and store information 243 * verify crypto transform properties, and store information
232 * we need for AH processing. This lookup cannot fail here 244 * we need for AH processing. This lookup cannot fail here
233 * after a successful crypto_alloc_tfm(). 245 * after a successful crypto_alloc_hash().
234 */ 246 */
235 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 247 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
236 BUG_ON(!aalg_desc); 248 BUG_ON(!aalg_desc);
237 249
238 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 250 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
239 crypto_tfm_alg_digestsize(ahp->tfm)) { 251 crypto_hash_digestsize(tfm)) {
240 printk(KERN_INFO "AH: %s digestsize %u != %hu\n", 252 printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
241 x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm), 253 x->aalg->alg_name, crypto_hash_digestsize(tfm),
242 aalg_desc->uinfo.auth.icv_fullbits/8); 254 aalg_desc->uinfo.auth.icv_fullbits/8);
243 goto error; 255 goto error;
244 } 256 }
@@ -262,7 +274,7 @@ static int ah_init_state(struct xfrm_state *x)
262error: 274error:
263 if (ahp) { 275 if (ahp) {
264 kfree(ahp->work_icv); 276 kfree(ahp->work_icv);
265 crypto_free_tfm(ahp->tfm); 277 crypto_free_hash(ahp->tfm);
266 kfree(ahp); 278 kfree(ahp);
267 } 279 }
268 return -EINVAL; 280 return -EINVAL;
@@ -277,7 +289,7 @@ static void ah_destroy(struct xfrm_state *x)
277 289
278 kfree(ahp->work_icv); 290 kfree(ahp->work_icv);
279 ahp->work_icv = NULL; 291 ahp->work_icv = NULL;
280 crypto_free_tfm(ahp->tfm); 292 crypto_free_hash(ahp->tfm);
281 ahp->tfm = NULL; 293 ahp->tfm = NULL;
282 kfree(ahp); 294 kfree(ahp);
283} 295}
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index fc2f8ce441de..b428489f6ccd 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -1,3 +1,4 @@
1#include <linux/err.h>
1#include <linux/module.h> 2#include <linux/module.h>
2#include <net/ip.h> 3#include <net/ip.h>
3#include <net/xfrm.h> 4#include <net/xfrm.h>
@@ -16,7 +17,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
16 int err; 17 int err;
17 struct iphdr *top_iph; 18 struct iphdr *top_iph;
18 struct ip_esp_hdr *esph; 19 struct ip_esp_hdr *esph;
19 struct crypto_tfm *tfm; 20 struct crypto_blkcipher *tfm;
21 struct blkcipher_desc desc;
20 struct esp_data *esp; 22 struct esp_data *esp;
21 struct sk_buff *trailer; 23 struct sk_buff *trailer;
22 int blksize; 24 int blksize;
@@ -36,7 +38,9 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
36 esp = x->data; 38 esp = x->data;
37 alen = esp->auth.icv_trunc_len; 39 alen = esp->auth.icv_trunc_len;
38 tfm = esp->conf.tfm; 40 tfm = esp->conf.tfm;
39 blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4); 41 desc.tfm = tfm;
42 desc.flags = 0;
43 blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
40 clen = ALIGN(clen + 2, blksize); 44 clen = ALIGN(clen + 2, blksize);
41 if (esp->conf.padlen) 45 if (esp->conf.padlen)
42 clen = ALIGN(clen, esp->conf.padlen); 46 clen = ALIGN(clen, esp->conf.padlen);
@@ -92,7 +96,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
92 xfrm_aevent_doreplay(x); 96 xfrm_aevent_doreplay(x);
93 97
94 if (esp->conf.ivlen) 98 if (esp->conf.ivlen)
95 crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 99 crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
96 100
97 do { 101 do {
98 struct scatterlist *sg = &esp->sgbuf[0]; 102 struct scatterlist *sg = &esp->sgbuf[0];
@@ -103,26 +107,27 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
103 goto error; 107 goto error;
104 } 108 }
105 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); 109 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
106 crypto_cipher_encrypt(tfm, sg, sg, clen); 110 err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
107 if (unlikely(sg != &esp->sgbuf[0])) 111 if (unlikely(sg != &esp->sgbuf[0]))
108 kfree(sg); 112 kfree(sg);
109 } while (0); 113 } while (0);
110 114
115 if (unlikely(err))
116 goto error;
117
111 if (esp->conf.ivlen) { 118 if (esp->conf.ivlen) {
112 memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 119 memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
113 crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 120 crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
114 } 121 }
115 122
116 if (esp->auth.icv_full_len) { 123 if (esp->auth.icv_full_len) {
117 esp->auth.icv(esp, skb, (u8*)esph-skb->data, 124 err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,
118 sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); 125 sizeof(*esph) + esp->conf.ivlen + clen);
119 pskb_put(skb, trailer, alen); 126 memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);
120 } 127 }
121 128
122 ip_send_check(top_iph); 129 ip_send_check(top_iph);
123 130
124 err = 0;
125
126error: 131error:
127 return err; 132 return err;
128} 133}
@@ -137,8 +142,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
137 struct iphdr *iph; 142 struct iphdr *iph;
138 struct ip_esp_hdr *esph; 143 struct ip_esp_hdr *esph;
139 struct esp_data *esp = x->data; 144 struct esp_data *esp = x->data;
145 struct crypto_blkcipher *tfm = esp->conf.tfm;
146 struct blkcipher_desc desc = { .tfm = tfm };
140 struct sk_buff *trailer; 147 struct sk_buff *trailer;
141 int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 148 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
142 int alen = esp->auth.icv_trunc_len; 149 int alen = esp->auth.icv_trunc_len;
143 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; 150 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;
144 int nfrags; 151 int nfrags;
@@ -146,6 +153,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
146 u8 nexthdr[2]; 153 u8 nexthdr[2];
147 struct scatterlist *sg; 154 struct scatterlist *sg;
148 int padlen; 155 int padlen;
156 int err;
149 157
150 if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) 158 if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr)))
151 goto out; 159 goto out;
@@ -155,15 +163,16 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
155 163
156 /* If integrity check is required, do this. */ 164 /* If integrity check is required, do this. */
157 if (esp->auth.icv_full_len) { 165 if (esp->auth.icv_full_len) {
158 u8 sum[esp->auth.icv_full_len]; 166 u8 sum[alen];
159 u8 sum1[alen];
160
161 esp->auth.icv(esp, skb, 0, skb->len-alen, sum);
162 167
163 if (skb_copy_bits(skb, skb->len-alen, sum1, alen)) 168 err = esp_mac_digest(esp, skb, 0, skb->len - alen);
169 if (err)
170 goto out;
171
172 if (skb_copy_bits(skb, skb->len - alen, sum, alen))
164 BUG(); 173 BUG();
165 174
166 if (unlikely(memcmp(sum, sum1, alen))) { 175 if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
167 x->stats.integrity_failed++; 176 x->stats.integrity_failed++;
168 goto out; 177 goto out;
169 } 178 }
@@ -178,7 +187,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
178 187
179 /* Get ivec. This can be wrong, check against another impls. */ 188 /* Get ivec. This can be wrong, check against another impls. */
180 if (esp->conf.ivlen) 189 if (esp->conf.ivlen)
181 crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm)); 190 crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
182 191
183 sg = &esp->sgbuf[0]; 192 sg = &esp->sgbuf[0];
184 193
@@ -188,9 +197,11 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
188 goto out; 197 goto out;
189 } 198 }
190 skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen); 199 skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
191 crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); 200 err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
192 if (unlikely(sg != &esp->sgbuf[0])) 201 if (unlikely(sg != &esp->sgbuf[0]))
193 kfree(sg); 202 kfree(sg);
203 if (unlikely(err))
204 return err;
194 205
195 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) 206 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
196 BUG(); 207 BUG();
@@ -254,7 +265,7 @@ out:
254static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) 265static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
255{ 266{
256 struct esp_data *esp = x->data; 267 struct esp_data *esp = x->data;
257 u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 268 u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
258 269
259 if (x->props.mode) { 270 if (x->props.mode) {
260 mtu = ALIGN(mtu + 2, blksize); 271 mtu = ALIGN(mtu + 2, blksize);
@@ -293,11 +304,11 @@ static void esp_destroy(struct xfrm_state *x)
293 if (!esp) 304 if (!esp)
294 return; 305 return;
295 306
296 crypto_free_tfm(esp->conf.tfm); 307 crypto_free_blkcipher(esp->conf.tfm);
297 esp->conf.tfm = NULL; 308 esp->conf.tfm = NULL;
298 kfree(esp->conf.ivec); 309 kfree(esp->conf.ivec);
299 esp->conf.ivec = NULL; 310 esp->conf.ivec = NULL;
300 crypto_free_tfm(esp->auth.tfm); 311 crypto_free_hash(esp->auth.tfm);
301 esp->auth.tfm = NULL; 312 esp->auth.tfm = NULL;
302 kfree(esp->auth.work_icv); 313 kfree(esp->auth.work_icv);
303 esp->auth.work_icv = NULL; 314 esp->auth.work_icv = NULL;
@@ -307,6 +318,7 @@ static void esp_destroy(struct xfrm_state *x)
307static int esp_init_state(struct xfrm_state *x) 318static int esp_init_state(struct xfrm_state *x)
308{ 319{
309 struct esp_data *esp = NULL; 320 struct esp_data *esp = NULL;
321 struct crypto_blkcipher *tfm;
310 322
311 /* null auth and encryption can have zero length keys */ 323 /* null auth and encryption can have zero length keys */
312 if (x->aalg) { 324 if (x->aalg) {
@@ -322,22 +334,27 @@ static int esp_init_state(struct xfrm_state *x)
322 334
323 if (x->aalg) { 335 if (x->aalg) {
324 struct xfrm_algo_desc *aalg_desc; 336 struct xfrm_algo_desc *aalg_desc;
337 struct crypto_hash *hash;
325 338
326 esp->auth.key = x->aalg->alg_key; 339 esp->auth.key = x->aalg->alg_key;
327 esp->auth.key_len = (x->aalg->alg_key_len+7)/8; 340 esp->auth.key_len = (x->aalg->alg_key_len+7)/8;
328 esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); 341 hash = crypto_alloc_hash(x->aalg->alg_name, 0,
329 if (esp->auth.tfm == NULL) 342 CRYPTO_ALG_ASYNC);
343 if (IS_ERR(hash))
344 goto error;
345
346 esp->auth.tfm = hash;
347 if (crypto_hash_setkey(hash, esp->auth.key, esp->auth.key_len))
330 goto error; 348 goto error;
331 esp->auth.icv = esp_hmac_digest;
332 349
333 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 350 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
334 BUG_ON(!aalg_desc); 351 BUG_ON(!aalg_desc);
335 352
336 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 353 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
337 crypto_tfm_alg_digestsize(esp->auth.tfm)) { 354 crypto_hash_digestsize(hash)) {
338 NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n", 355 NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n",
339 x->aalg->alg_name, 356 x->aalg->alg_name,
340 crypto_tfm_alg_digestsize(esp->auth.tfm), 357 crypto_hash_digestsize(hash),
341 aalg_desc->uinfo.auth.icv_fullbits/8); 358 aalg_desc->uinfo.auth.icv_fullbits/8);
342 goto error; 359 goto error;
343 } 360 }
@@ -351,13 +368,11 @@ static int esp_init_state(struct xfrm_state *x)
351 } 368 }
352 esp->conf.key = x->ealg->alg_key; 369 esp->conf.key = x->ealg->alg_key;
353 esp->conf.key_len = (x->ealg->alg_key_len+7)/8; 370 esp->conf.key_len = (x->ealg->alg_key_len+7)/8;
354 if (x->props.ealgo == SADB_EALG_NULL) 371 tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
355 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_ECB); 372 if (IS_ERR(tfm))
356 else
357 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC);
358 if (esp->conf.tfm == NULL)
359 goto error; 373 goto error;
360 esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm); 374 esp->conf.tfm = tfm;
375 esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
361 esp->conf.padlen = 0; 376 esp->conf.padlen = 0;
362 if (esp->conf.ivlen) { 377 if (esp->conf.ivlen) {
363 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); 378 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
@@ -365,7 +380,7 @@ static int esp_init_state(struct xfrm_state *x)
365 goto error; 380 goto error;
366 get_random_bytes(esp->conf.ivec, esp->conf.ivlen); 381 get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
367 } 382 }
368 if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) 383 if (crypto_blkcipher_setkey(tfm, esp->conf.key, esp->conf.key_len))
369 goto error; 384 goto error;
370 x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; 385 x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
371 if (x->props.mode) 386 if (x->props.mode)
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index a0c28b2b756e..5bb9c9f03fb6 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -32,7 +32,7 @@
32 32
33struct ipcomp_tfms { 33struct ipcomp_tfms {
34 struct list_head list; 34 struct list_head list;
35 struct crypto_tfm **tfms; 35 struct crypto_comp **tfms;
36 int users; 36 int users;
37}; 37};
38 38
@@ -46,7 +46,7 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)
46 int err, plen, dlen; 46 int err, plen, dlen;
47 struct ipcomp_data *ipcd = x->data; 47 struct ipcomp_data *ipcd = x->data;
48 u8 *start, *scratch; 48 u8 *start, *scratch;
49 struct crypto_tfm *tfm; 49 struct crypto_comp *tfm;
50 int cpu; 50 int cpu;
51 51
52 plen = skb->len; 52 plen = skb->len;
@@ -107,7 +107,7 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
107 struct iphdr *iph = skb->nh.iph; 107 struct iphdr *iph = skb->nh.iph;
108 struct ipcomp_data *ipcd = x->data; 108 struct ipcomp_data *ipcd = x->data;
109 u8 *start, *scratch; 109 u8 *start, *scratch;
110 struct crypto_tfm *tfm; 110 struct crypto_comp *tfm;
111 int cpu; 111 int cpu;
112 112
113 ihlen = iph->ihl * 4; 113 ihlen = iph->ihl * 4;
@@ -302,7 +302,7 @@ static void **ipcomp_alloc_scratches(void)
302 return scratches; 302 return scratches;
303} 303}
304 304
305static void ipcomp_free_tfms(struct crypto_tfm **tfms) 305static void ipcomp_free_tfms(struct crypto_comp **tfms)
306{ 306{
307 struct ipcomp_tfms *pos; 307 struct ipcomp_tfms *pos;
308 int cpu; 308 int cpu;
@@ -324,28 +324,28 @@ static void ipcomp_free_tfms(struct crypto_tfm **tfms)
324 return; 324 return;
325 325
326 for_each_possible_cpu(cpu) { 326 for_each_possible_cpu(cpu) {
327 struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); 327 struct crypto_comp *tfm = *per_cpu_ptr(tfms, cpu);
328 crypto_free_tfm(tfm); 328 crypto_free_comp(tfm);
329 } 329 }
330 free_percpu(tfms); 330 free_percpu(tfms);
331} 331}
332 332
333static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name) 333static struct crypto_comp **ipcomp_alloc_tfms(const char *alg_name)
334{ 334{
335 struct ipcomp_tfms *pos; 335 struct ipcomp_tfms *pos;
336 struct crypto_tfm **tfms; 336 struct crypto_comp **tfms;
337 int cpu; 337 int cpu;
338 338
339 /* This can be any valid CPU ID so we don't need locking. */ 339 /* This can be any valid CPU ID so we don't need locking. */
340 cpu = raw_smp_processor_id(); 340 cpu = raw_smp_processor_id();
341 341
342 list_for_each_entry(pos, &ipcomp_tfms_list, list) { 342 list_for_each_entry(pos, &ipcomp_tfms_list, list) {
343 struct crypto_tfm *tfm; 343 struct crypto_comp *tfm;
344 344
345 tfms = pos->tfms; 345 tfms = pos->tfms;
346 tfm = *per_cpu_ptr(tfms, cpu); 346 tfm = *per_cpu_ptr(tfms, cpu);
347 347
348 if (!strcmp(crypto_tfm_alg_name(tfm), alg_name)) { 348 if (!strcmp(crypto_comp_name(tfm), alg_name)) {
349 pos->users++; 349 pos->users++;
350 return tfms; 350 return tfms;
351 } 351 }
@@ -359,12 +359,13 @@ static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name)
359 INIT_LIST_HEAD(&pos->list); 359 INIT_LIST_HEAD(&pos->list);
360 list_add(&pos->list, &ipcomp_tfms_list); 360 list_add(&pos->list, &ipcomp_tfms_list);
361 361
362 pos->tfms = tfms = alloc_percpu(struct crypto_tfm *); 362 pos->tfms = tfms = alloc_percpu(struct crypto_comp *);
363 if (!tfms) 363 if (!tfms)
364 goto error; 364 goto error;
365 365
366 for_each_possible_cpu(cpu) { 366 for_each_possible_cpu(cpu) {
367 struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); 367 struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
368 CRYPTO_ALG_ASYNC);
368 if (!tfm) 369 if (!tfm)
369 goto error; 370 goto error;
370 *per_cpu_ptr(tfms, cpu) = tfm; 371 *per_cpu_ptr(tfms, cpu) = tfm;
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index e923d4dea418..0ba06c0c5d39 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -77,6 +77,7 @@ config INET6_ESP
77 select CRYPTO 77 select CRYPTO
78 select CRYPTO_HMAC 78 select CRYPTO_HMAC
79 select CRYPTO_MD5 79 select CRYPTO_MD5
80 select CRYPTO_CBC
80 select CRYPTO_SHA1 81 select CRYPTO_SHA1
81 select CRYPTO_DES 82 select CRYPTO_DES
82 ---help--- 83 ---help---
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 9d4831bd4335..00ffa7bc6c9f 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -213,7 +213,10 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
213 ah->spi = x->id.spi; 213 ah->spi = x->id.spi;
214 ah->seq_no = htonl(++x->replay.oseq); 214 ah->seq_no = htonl(++x->replay.oseq);
215 xfrm_aevent_doreplay(x); 215 xfrm_aevent_doreplay(x);
216 ahp->icv(ahp, skb, ah->auth_data); 216 err = ah_mac_digest(ahp, skb, ah->auth_data);
217 if (err)
218 goto error_free_iph;
219 memcpy(ah->auth_data, ahp->work_icv, ahp->icv_trunc_len);
217 220
218 err = 0; 221 err = 0;
219 222
@@ -251,6 +254,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
251 u16 hdr_len; 254 u16 hdr_len;
252 u16 ah_hlen; 255 u16 ah_hlen;
253 int nexthdr; 256 int nexthdr;
257 int err = -EINVAL;
254 258
255 if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) 259 if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
256 goto out; 260 goto out;
@@ -292,8 +296,11 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
292 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); 296 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
293 memset(ah->auth_data, 0, ahp->icv_trunc_len); 297 memset(ah->auth_data, 0, ahp->icv_trunc_len);
294 skb_push(skb, hdr_len); 298 skb_push(skb, hdr_len);
295 ahp->icv(ahp, skb, ah->auth_data); 299 err = ah_mac_digest(ahp, skb, ah->auth_data);
296 if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { 300 if (err)
301 goto free_out;
302 err = -EINVAL;
303 if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
297 LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n"); 304 LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n");
298 x->stats.integrity_failed++; 305 x->stats.integrity_failed++;
299 goto free_out; 306 goto free_out;
@@ -310,7 +317,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
310free_out: 317free_out:
311 kfree(tmp_hdr); 318 kfree(tmp_hdr);
312out: 319out:
313 return -EINVAL; 320 return err;
314} 321}
315 322
316static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 323static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
@@ -338,6 +345,7 @@ static int ah6_init_state(struct xfrm_state *x)
338{ 345{
339 struct ah_data *ahp = NULL; 346 struct ah_data *ahp = NULL;
340 struct xfrm_algo_desc *aalg_desc; 347 struct xfrm_algo_desc *aalg_desc;
348 struct crypto_hash *tfm;
341 349
342 if (!x->aalg) 350 if (!x->aalg)
343 goto error; 351 goto error;
@@ -355,24 +363,27 @@ static int ah6_init_state(struct xfrm_state *x)
355 363
356 ahp->key = x->aalg->alg_key; 364 ahp->key = x->aalg->alg_key;
357 ahp->key_len = (x->aalg->alg_key_len+7)/8; 365 ahp->key_len = (x->aalg->alg_key_len+7)/8;
358 ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); 366 tfm = crypto_alloc_hash(x->aalg->alg_name, 0, CRYPTO_ALG_ASYNC);
359 if (!ahp->tfm) 367 if (IS_ERR(tfm))
368 goto error;
369
370 ahp->tfm = tfm;
371 if (crypto_hash_setkey(tfm, ahp->key, ahp->key_len))
360 goto error; 372 goto error;
361 ahp->icv = ah_hmac_digest;
362 373
363 /* 374 /*
364 * Lookup the algorithm description maintained by xfrm_algo, 375 * Lookup the algorithm description maintained by xfrm_algo,
365 * verify crypto transform properties, and store information 376 * verify crypto transform properties, and store information
366 * we need for AH processing. This lookup cannot fail here 377 * we need for AH processing. This lookup cannot fail here
367 * after a successful crypto_alloc_tfm(). 378 * after a successful crypto_alloc_hash().
368 */ 379 */
369 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 380 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
370 BUG_ON(!aalg_desc); 381 BUG_ON(!aalg_desc);
371 382
372 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 383 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
373 crypto_tfm_alg_digestsize(ahp->tfm)) { 384 crypto_hash_digestsize(tfm)) {
374 printk(KERN_INFO "AH: %s digestsize %u != %hu\n", 385 printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
375 x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm), 386 x->aalg->alg_name, crypto_hash_digestsize(tfm),
376 aalg_desc->uinfo.auth.icv_fullbits/8); 387 aalg_desc->uinfo.auth.icv_fullbits/8);
377 goto error; 388 goto error;
378 } 389 }
@@ -396,7 +407,7 @@ static int ah6_init_state(struct xfrm_state *x)
396error: 407error:
397 if (ahp) { 408 if (ahp) {
398 kfree(ahp->work_icv); 409 kfree(ahp->work_icv);
399 crypto_free_tfm(ahp->tfm); 410 crypto_free_hash(ahp->tfm);
400 kfree(ahp); 411 kfree(ahp);
401 } 412 }
402 return -EINVAL; 413 return -EINVAL;
@@ -411,7 +422,7 @@ static void ah6_destroy(struct xfrm_state *x)
411 422
412 kfree(ahp->work_icv); 423 kfree(ahp->work_icv);
413 ahp->work_icv = NULL; 424 ahp->work_icv = NULL;
414 crypto_free_tfm(ahp->tfm); 425 crypto_free_hash(ahp->tfm);
415 ahp->tfm = NULL; 426 ahp->tfm = NULL;
416 kfree(ahp); 427 kfree(ahp);
417} 428}
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index a278d5e862fe..2ebfd281e721 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -24,6 +24,7 @@
24 * This file is derived from net/ipv4/esp.c 24 * This file is derived from net/ipv4/esp.c
25 */ 25 */
26 26
27#include <linux/err.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <net/ip.h> 29#include <net/ip.h>
29#include <net/xfrm.h> 30#include <net/xfrm.h>
@@ -44,7 +45,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
44 int hdr_len; 45 int hdr_len;
45 struct ipv6hdr *top_iph; 46 struct ipv6hdr *top_iph;
46 struct ipv6_esp_hdr *esph; 47 struct ipv6_esp_hdr *esph;
47 struct crypto_tfm *tfm; 48 struct crypto_blkcipher *tfm;
49 struct blkcipher_desc desc;
48 struct esp_data *esp; 50 struct esp_data *esp;
49 struct sk_buff *trailer; 51 struct sk_buff *trailer;
50 int blksize; 52 int blksize;
@@ -67,7 +69,9 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
67 69
68 alen = esp->auth.icv_trunc_len; 70 alen = esp->auth.icv_trunc_len;
69 tfm = esp->conf.tfm; 71 tfm = esp->conf.tfm;
70 blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4); 72 desc.tfm = tfm;
73 desc.flags = 0;
74 blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
71 clen = ALIGN(clen + 2, blksize); 75 clen = ALIGN(clen + 2, blksize);
72 if (esp->conf.padlen) 76 if (esp->conf.padlen)
73 clen = ALIGN(clen, esp->conf.padlen); 77 clen = ALIGN(clen, esp->conf.padlen);
@@ -96,7 +100,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
96 xfrm_aevent_doreplay(x); 100 xfrm_aevent_doreplay(x);
97 101
98 if (esp->conf.ivlen) 102 if (esp->conf.ivlen)
99 crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 103 crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
100 104
101 do { 105 do {
102 struct scatterlist *sg = &esp->sgbuf[0]; 106 struct scatterlist *sg = &esp->sgbuf[0];
@@ -107,24 +111,25 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
107 goto error; 111 goto error;
108 } 112 }
109 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); 113 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
110 crypto_cipher_encrypt(tfm, sg, sg, clen); 114 err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
111 if (unlikely(sg != &esp->sgbuf[0])) 115 if (unlikely(sg != &esp->sgbuf[0]))
112 kfree(sg); 116 kfree(sg);
113 } while (0); 117 } while (0);
114 118
119 if (unlikely(err))
120 goto error;
121
115 if (esp->conf.ivlen) { 122 if (esp->conf.ivlen) {
116 memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 123 memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
117 crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 124 crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
118 } 125 }
119 126
120 if (esp->auth.icv_full_len) { 127 if (esp->auth.icv_full_len) {
121 esp->auth.icv(esp, skb, (u8*)esph-skb->data, 128 err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,
122 sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); 129 sizeof(*esph) + esp->conf.ivlen + clen);
123 pskb_put(skb, trailer, alen); 130 memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);
124 } 131 }
125 132
126 err = 0;
127
128error: 133error:
129 return err; 134 return err;
130} 135}
@@ -134,8 +139,10 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
134 struct ipv6hdr *iph; 139 struct ipv6hdr *iph;
135 struct ipv6_esp_hdr *esph; 140 struct ipv6_esp_hdr *esph;
136 struct esp_data *esp = x->data; 141 struct esp_data *esp = x->data;
142 struct crypto_blkcipher *tfm = esp->conf.tfm;
143 struct blkcipher_desc desc = { .tfm = tfm };
137 struct sk_buff *trailer; 144 struct sk_buff *trailer;
138 int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 145 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
139 int alen = esp->auth.icv_trunc_len; 146 int alen = esp->auth.icv_trunc_len;
140 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; 147 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen;
141 148
@@ -155,15 +162,16 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
155 162
156 /* If integrity check is required, do this. */ 163 /* If integrity check is required, do this. */
157 if (esp->auth.icv_full_len) { 164 if (esp->auth.icv_full_len) {
158 u8 sum[esp->auth.icv_full_len]; 165 u8 sum[alen];
159 u8 sum1[alen];
160 166
161 esp->auth.icv(esp, skb, 0, skb->len-alen, sum); 167 ret = esp_mac_digest(esp, skb, 0, skb->len - alen);
168 if (ret)
169 goto out;
162 170
163 if (skb_copy_bits(skb, skb->len-alen, sum1, alen)) 171 if (skb_copy_bits(skb, skb->len - alen, sum, alen))
164 BUG(); 172 BUG();
165 173
166 if (unlikely(memcmp(sum, sum1, alen))) { 174 if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
167 x->stats.integrity_failed++; 175 x->stats.integrity_failed++;
168 ret = -EINVAL; 176 ret = -EINVAL;
169 goto out; 177 goto out;
@@ -182,7 +190,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
182 190
183 /* Get ivec. This can be wrong, check against another impls. */ 191 /* Get ivec. This can be wrong, check against another impls. */
184 if (esp->conf.ivlen) 192 if (esp->conf.ivlen)
185 crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm)); 193 crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
186 194
187 { 195 {
188 u8 nexthdr[2]; 196 u8 nexthdr[2];
@@ -197,9 +205,11 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
197 } 205 }
198 } 206 }
199 skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen); 207 skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen);
200 crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); 208 ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
201 if (unlikely(sg != &esp->sgbuf[0])) 209 if (unlikely(sg != &esp->sgbuf[0]))
202 kfree(sg); 210 kfree(sg);
211 if (unlikely(ret))
212 goto out;
203 213
204 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) 214 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
205 BUG(); 215 BUG();
@@ -225,7 +235,7 @@ out:
225static u32 esp6_get_max_size(struct xfrm_state *x, int mtu) 235static u32 esp6_get_max_size(struct xfrm_state *x, int mtu)
226{ 236{
227 struct esp_data *esp = x->data; 237 struct esp_data *esp = x->data;
228 u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 238 u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
229 239
230 if (x->props.mode) { 240 if (x->props.mode) {
231 mtu = ALIGN(mtu + 2, blksize); 241 mtu = ALIGN(mtu + 2, blksize);
@@ -266,11 +276,11 @@ static void esp6_destroy(struct xfrm_state *x)
266 if (!esp) 276 if (!esp)
267 return; 277 return;
268 278
269 crypto_free_tfm(esp->conf.tfm); 279 crypto_free_blkcipher(esp->conf.tfm);
270 esp->conf.tfm = NULL; 280 esp->conf.tfm = NULL;
271 kfree(esp->conf.ivec); 281 kfree(esp->conf.ivec);
272 esp->conf.ivec = NULL; 282 esp->conf.ivec = NULL;
273 crypto_free_tfm(esp->auth.tfm); 283 crypto_free_hash(esp->auth.tfm);
274 esp->auth.tfm = NULL; 284 esp->auth.tfm = NULL;
275 kfree(esp->auth.work_icv); 285 kfree(esp->auth.work_icv);
276 esp->auth.work_icv = NULL; 286 esp->auth.work_icv = NULL;
@@ -280,6 +290,7 @@ static void esp6_destroy(struct xfrm_state *x)
280static int esp6_init_state(struct xfrm_state *x) 290static int esp6_init_state(struct xfrm_state *x)
281{ 291{
282 struct esp_data *esp = NULL; 292 struct esp_data *esp = NULL;
293 struct crypto_blkcipher *tfm;
283 294
284 /* null auth and encryption can have zero length keys */ 295 /* null auth and encryption can have zero length keys */
285 if (x->aalg) { 296 if (x->aalg) {
@@ -298,24 +309,29 @@ static int esp6_init_state(struct xfrm_state *x)
298 309
299 if (x->aalg) { 310 if (x->aalg) {
300 struct xfrm_algo_desc *aalg_desc; 311 struct xfrm_algo_desc *aalg_desc;
312 struct crypto_hash *hash;
301 313
302 esp->auth.key = x->aalg->alg_key; 314 esp->auth.key = x->aalg->alg_key;
303 esp->auth.key_len = (x->aalg->alg_key_len+7)/8; 315 esp->auth.key_len = (x->aalg->alg_key_len+7)/8;
304 esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); 316 hash = crypto_alloc_hash(x->aalg->alg_name, 0,
305 if (esp->auth.tfm == NULL) 317 CRYPTO_ALG_ASYNC);
318 if (IS_ERR(hash))
319 goto error;
320
321 esp->auth.tfm = hash;
322 if (crypto_hash_setkey(hash, esp->auth.key, esp->auth.key_len))
306 goto error; 323 goto error;
307 esp->auth.icv = esp_hmac_digest;
308 324
309 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 325 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
310 BUG_ON(!aalg_desc); 326 BUG_ON(!aalg_desc);
311 327
312 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 328 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
313 crypto_tfm_alg_digestsize(esp->auth.tfm)) { 329 crypto_hash_digestsize(hash)) {
314 printk(KERN_INFO "ESP: %s digestsize %u != %hu\n", 330 NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n",
315 x->aalg->alg_name, 331 x->aalg->alg_name,
316 crypto_tfm_alg_digestsize(esp->auth.tfm), 332 crypto_hash_digestsize(hash),
317 aalg_desc->uinfo.auth.icv_fullbits/8); 333 aalg_desc->uinfo.auth.icv_fullbits/8);
318 goto error; 334 goto error;
319 } 335 }
320 336
321 esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; 337 esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
@@ -327,13 +343,11 @@ static int esp6_init_state(struct xfrm_state *x)
327 } 343 }
328 esp->conf.key = x->ealg->alg_key; 344 esp->conf.key = x->ealg->alg_key;
329 esp->conf.key_len = (x->ealg->alg_key_len+7)/8; 345 esp->conf.key_len = (x->ealg->alg_key_len+7)/8;
330 if (x->props.ealgo == SADB_EALG_NULL) 346 tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
331 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_ECB); 347 if (IS_ERR(tfm))
332 else
333 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC);
334 if (esp->conf.tfm == NULL)
335 goto error; 348 goto error;
336 esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm); 349 esp->conf.tfm = tfm;
350 esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
337 esp->conf.padlen = 0; 351 esp->conf.padlen = 0;
338 if (esp->conf.ivlen) { 352 if (esp->conf.ivlen) {
339 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); 353 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
@@ -341,7 +355,7 @@ static int esp6_init_state(struct xfrm_state *x)
341 goto error; 355 goto error;
342 get_random_bytes(esp->conf.ivec, esp->conf.ivlen); 356 get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
343 } 357 }
344 if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) 358 if (crypto_blkcipher_setkey(tfm, esp->conf.key, esp->conf.key_len))
345 goto error; 359 goto error;
346 x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; 360 x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
347 if (x->props.mode) 361 if (x->props.mode)
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 7e4d1c17bfbc..a81e9e9d93bd 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -53,7 +53,7 @@
53 53
54struct ipcomp6_tfms { 54struct ipcomp6_tfms {
55 struct list_head list; 55 struct list_head list;
56 struct crypto_tfm **tfms; 56 struct crypto_comp **tfms;
57 int users; 57 int users;
58}; 58};
59 59
@@ -70,7 +70,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
70 int plen, dlen; 70 int plen, dlen;
71 struct ipcomp_data *ipcd = x->data; 71 struct ipcomp_data *ipcd = x->data;
72 u8 *start, *scratch; 72 u8 *start, *scratch;
73 struct crypto_tfm *tfm; 73 struct crypto_comp *tfm;
74 int cpu; 74 int cpu;
75 75
76 if (skb_linearize_cow(skb)) 76 if (skb_linearize_cow(skb))
@@ -129,7 +129,7 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
129 struct ipcomp_data *ipcd = x->data; 129 struct ipcomp_data *ipcd = x->data;
130 int plen, dlen; 130 int plen, dlen;
131 u8 *start, *scratch; 131 u8 *start, *scratch;
132 struct crypto_tfm *tfm; 132 struct crypto_comp *tfm;
133 int cpu; 133 int cpu;
134 134
135 hdr_len = skb->h.raw - skb->data; 135 hdr_len = skb->h.raw - skb->data;
@@ -301,7 +301,7 @@ static void **ipcomp6_alloc_scratches(void)
301 return scratches; 301 return scratches;
302} 302}
303 303
304static void ipcomp6_free_tfms(struct crypto_tfm **tfms) 304static void ipcomp6_free_tfms(struct crypto_comp **tfms)
305{ 305{
306 struct ipcomp6_tfms *pos; 306 struct ipcomp6_tfms *pos;
307 int cpu; 307 int cpu;
@@ -323,28 +323,28 @@ static void ipcomp6_free_tfms(struct crypto_tfm **tfms)
323 return; 323 return;
324 324
325 for_each_possible_cpu(cpu) { 325 for_each_possible_cpu(cpu) {
326 struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); 326 struct crypto_comp *tfm = *per_cpu_ptr(tfms, cpu);
327 crypto_free_tfm(tfm); 327 crypto_free_comp(tfm);
328 } 328 }
329 free_percpu(tfms); 329 free_percpu(tfms);
330} 330}
331 331
332static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name) 332static struct crypto_comp **ipcomp6_alloc_tfms(const char *alg_name)
333{ 333{
334 struct ipcomp6_tfms *pos; 334 struct ipcomp6_tfms *pos;
335 struct crypto_tfm **tfms; 335 struct crypto_comp **tfms;
336 int cpu; 336 int cpu;
337 337
338 /* This can be any valid CPU ID so we don't need locking. */ 338 /* This can be any valid CPU ID so we don't need locking. */
339 cpu = raw_smp_processor_id(); 339 cpu = raw_smp_processor_id();
340 340
341 list_for_each_entry(pos, &ipcomp6_tfms_list, list) { 341 list_for_each_entry(pos, &ipcomp6_tfms_list, list) {
342 struct crypto_tfm *tfm; 342 struct crypto_comp *tfm;
343 343
344 tfms = pos->tfms; 344 tfms = pos->tfms;
345 tfm = *per_cpu_ptr(tfms, cpu); 345 tfm = *per_cpu_ptr(tfms, cpu);
346 346
347 if (!strcmp(crypto_tfm_alg_name(tfm), alg_name)) { 347 if (!strcmp(crypto_comp_name(tfm), alg_name)) {
348 pos->users++; 348 pos->users++;
349 return tfms; 349 return tfms;
350 } 350 }
@@ -358,12 +358,13 @@ static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name)
358 INIT_LIST_HEAD(&pos->list); 358 INIT_LIST_HEAD(&pos->list);
359 list_add(&pos->list, &ipcomp6_tfms_list); 359 list_add(&pos->list, &ipcomp6_tfms_list);
360 360
361 pos->tfms = tfms = alloc_percpu(struct crypto_tfm *); 361 pos->tfms = tfms = alloc_percpu(struct crypto_comp *);
362 if (!tfms) 362 if (!tfms)
363 goto error; 363 goto error;
364 364
365 for_each_possible_cpu(cpu) { 365 for_each_possible_cpu(cpu) {
366 struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); 366 struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
367 CRYPTO_ALG_ASYNC);
367 if (!tfm) 368 if (!tfm)
368 goto error; 369 goto error;
369 *per_cpu_ptr(tfms, cpu) = tfm; 370 *per_cpu_ptr(tfms, cpu) = tfm;
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index ffda1d680529..35c49ff2d062 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -173,7 +173,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
173 SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); 173 SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
174 174
175 /* Free up the HMAC transform. */ 175 /* Free up the HMAC transform. */
176 sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac); 176 crypto_free_hash(sctp_sk(ep->base.sk)->hmac);
177 177
178 /* Cleanup. */ 178 /* Cleanup. */
179 sctp_inq_free(&ep->base.inqueue); 179 sctp_inq_free(&ep->base.inqueue);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 17b509282cf2..7745bdea7817 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1282,10 +1282,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
1282 1282
1283 retval = kmalloc(*cookie_len, GFP_ATOMIC); 1283 retval = kmalloc(*cookie_len, GFP_ATOMIC);
1284 1284
1285 if (!retval) { 1285 if (!retval)
1286 *cookie_len = 0;
1287 goto nodata; 1286 goto nodata;
1288 }
1289 1287
1290 /* Clear this memory since we are sending this data structure 1288 /* Clear this memory since we are sending this data structure
1291 * out on the network. 1289 * out on the network.
@@ -1321,19 +1319,29 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
1321 ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len); 1319 ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len);
1322 1320
1323 if (sctp_sk(ep->base.sk)->hmac) { 1321 if (sctp_sk(ep->base.sk)->hmac) {
1322 struct hash_desc desc;
1323
1324 /* Sign the message. */ 1324 /* Sign the message. */
1325 sg.page = virt_to_page(&cookie->c); 1325 sg.page = virt_to_page(&cookie->c);
1326 sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE; 1326 sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
1327 sg.length = bodysize; 1327 sg.length = bodysize;
1328 keylen = SCTP_SECRET_SIZE; 1328 keylen = SCTP_SECRET_SIZE;
1329 key = (char *)ep->secret_key[ep->current_key]; 1329 key = (char *)ep->secret_key[ep->current_key];
1330 desc.tfm = sctp_sk(ep->base.sk)->hmac;
1331 desc.flags = 0;
1330 1332
1331 sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, 1333 if (crypto_hash_setkey(desc.tfm, key, keylen) ||
1332 &sg, 1, cookie->signature); 1334 crypto_hash_digest(&desc, &sg, bodysize, cookie->signature))
1335 goto free_cookie;
1333 } 1336 }
1334 1337
1335nodata:
1336 return retval; 1338 return retval;
1339
1340free_cookie:
1341 kfree(retval);
1342nodata:
1343 *cookie_len = 0;
1344 return NULL;
1337} 1345}
1338 1346
1339/* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */ 1347/* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */
@@ -1354,6 +1362,7 @@ struct sctp_association *sctp_unpack_cookie(
1354 sctp_scope_t scope; 1362 sctp_scope_t scope;
1355 struct sk_buff *skb = chunk->skb; 1363 struct sk_buff *skb = chunk->skb;
1356 struct timeval tv; 1364 struct timeval tv;
1365 struct hash_desc desc;
1357 1366
1358 /* Header size is static data prior to the actual cookie, including 1367 /* Header size is static data prior to the actual cookie, including
1359 * any padding. 1368 * any padding.
@@ -1389,17 +1398,25 @@ struct sctp_association *sctp_unpack_cookie(
1389 sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE; 1398 sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
1390 sg.length = bodysize; 1399 sg.length = bodysize;
1391 key = (char *)ep->secret_key[ep->current_key]; 1400 key = (char *)ep->secret_key[ep->current_key];
1401 desc.tfm = sctp_sk(ep->base.sk)->hmac;
1402 desc.flags = 0;
1392 1403
1393 memset(digest, 0x00, SCTP_SIGNATURE_SIZE); 1404 memset(digest, 0x00, SCTP_SIGNATURE_SIZE);
1394 sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, &sg, 1405 if (crypto_hash_setkey(desc.tfm, key, keylen) ||
1395 1, digest); 1406 crypto_hash_digest(&desc, &sg, bodysize, digest)) {
1407 *error = -SCTP_IERROR_NOMEM;
1408 goto fail;
1409 }
1396 1410
1397 if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { 1411 if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
1398 /* Try the previous key. */ 1412 /* Try the previous key. */
1399 key = (char *)ep->secret_key[ep->last_key]; 1413 key = (char *)ep->secret_key[ep->last_key];
1400 memset(digest, 0x00, SCTP_SIGNATURE_SIZE); 1414 memset(digest, 0x00, SCTP_SIGNATURE_SIZE);
1401 sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, 1415 if (crypto_hash_setkey(desc.tfm, key, keylen) ||
1402 &sg, 1, digest); 1416 crypto_hash_digest(&desc, &sg, bodysize, digest)) {
1417 *error = -SCTP_IERROR_NOMEM;
1418 goto fail;
1419 }
1403 1420
1404 if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { 1421 if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
1405 /* Yikes! Still bad signature! */ 1422 /* Yikes! Still bad signature! */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index dab15949958e..85caf7963886 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4898,7 +4898,7 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
4898int sctp_inet_listen(struct socket *sock, int backlog) 4898int sctp_inet_listen(struct socket *sock, int backlog)
4899{ 4899{
4900 struct sock *sk = sock->sk; 4900 struct sock *sk = sock->sk;
4901 struct crypto_tfm *tfm=NULL; 4901 struct crypto_hash *tfm = NULL;
4902 int err = -EINVAL; 4902 int err = -EINVAL;
4903 4903
4904 if (unlikely(backlog < 0)) 4904 if (unlikely(backlog < 0))
@@ -4911,7 +4911,7 @@ int sctp_inet_listen(struct socket *sock, int backlog)
4911 4911
4912 /* Allocate HMAC for generating cookie. */ 4912 /* Allocate HMAC for generating cookie. */
4913 if (sctp_hmac_alg) { 4913 if (sctp_hmac_alg) {
4914 tfm = sctp_crypto_alloc_tfm(sctp_hmac_alg, 0); 4914 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
4915 if (!tfm) { 4915 if (!tfm) {
4916 err = -ENOSYS; 4916 err = -ENOSYS;
4917 goto out; 4917 goto out;
@@ -4937,7 +4937,7 @@ out:
4937 sctp_release_sock(sk); 4937 sctp_release_sock(sk);
4938 return err; 4938 return err;
4939cleanup: 4939cleanup:
4940 sctp_crypto_free_tfm(tfm); 4940 crypto_free_hash(tfm);
4941 goto out; 4941 goto out;
4942} 4942}
4943 4943
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 76b969e6904f..e11a40b25cce 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -34,6 +34,7 @@
34 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 34 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
35 */ 35 */
36 36
37#include <linux/err.h>
37#include <linux/types.h> 38#include <linux/types.h>
38#include <linux/mm.h> 39#include <linux/mm.h>
39#include <linux/slab.h> 40#include <linux/slab.h>
@@ -49,7 +50,7 @@
49 50
50u32 51u32
51krb5_encrypt( 52krb5_encrypt(
52 struct crypto_tfm *tfm, 53 struct crypto_blkcipher *tfm,
53 void * iv, 54 void * iv,
54 void * in, 55 void * in,
55 void * out, 56 void * out,
@@ -58,26 +59,27 @@ krb5_encrypt(
58 u32 ret = -EINVAL; 59 u32 ret = -EINVAL;
59 struct scatterlist sg[1]; 60 struct scatterlist sg[1];
60 u8 local_iv[16] = {0}; 61 u8 local_iv[16] = {0};
62 struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv };
61 63
62 dprintk("RPC: krb5_encrypt: input data:\n"); 64 dprintk("RPC: krb5_encrypt: input data:\n");
63 print_hexl((u32 *)in, length, 0); 65 print_hexl((u32 *)in, length, 0);
64 66
65 if (length % crypto_tfm_alg_blocksize(tfm) != 0) 67 if (length % crypto_blkcipher_blocksize(tfm) != 0)
66 goto out; 68 goto out;
67 69
68 if (crypto_tfm_alg_ivsize(tfm) > 16) { 70 if (crypto_blkcipher_ivsize(tfm) > 16) {
69 dprintk("RPC: gss_k5encrypt: tfm iv size to large %d\n", 71 dprintk("RPC: gss_k5encrypt: tfm iv size to large %d\n",
70 crypto_tfm_alg_ivsize(tfm)); 72 crypto_blkcipher_ivsize(tfm));
71 goto out; 73 goto out;
72 } 74 }
73 75
74 if (iv) 76 if (iv)
75 memcpy(local_iv, iv, crypto_tfm_alg_ivsize(tfm)); 77 memcpy(local_iv, iv, crypto_blkcipher_ivsize(tfm));
76 78
77 memcpy(out, in, length); 79 memcpy(out, in, length);
78 sg_set_buf(sg, out, length); 80 sg_set_buf(sg, out, length);
79 81
80 ret = crypto_cipher_encrypt_iv(tfm, sg, sg, length, local_iv); 82 ret = crypto_blkcipher_encrypt_iv(&desc, sg, sg, length);
81 83
82 dprintk("RPC: krb5_encrypt: output data:\n"); 84 dprintk("RPC: krb5_encrypt: output data:\n");
83 print_hexl((u32 *)out, length, 0); 85 print_hexl((u32 *)out, length, 0);
@@ -90,7 +92,7 @@ EXPORT_SYMBOL(krb5_encrypt);
90 92
91u32 93u32
92krb5_decrypt( 94krb5_decrypt(
93 struct crypto_tfm *tfm, 95 struct crypto_blkcipher *tfm,
94 void * iv, 96 void * iv,
95 void * in, 97 void * in,
96 void * out, 98 void * out,
@@ -99,25 +101,26 @@ krb5_decrypt(
99 u32 ret = -EINVAL; 101 u32 ret = -EINVAL;
100 struct scatterlist sg[1]; 102 struct scatterlist sg[1];
101 u8 local_iv[16] = {0}; 103 u8 local_iv[16] = {0};
104 struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv };
102 105
103 dprintk("RPC: krb5_decrypt: input data:\n"); 106 dprintk("RPC: krb5_decrypt: input data:\n");
104 print_hexl((u32 *)in, length, 0); 107 print_hexl((u32 *)in, length, 0);
105 108
106 if (length % crypto_tfm_alg_blocksize(tfm) != 0) 109 if (length % crypto_blkcipher_blocksize(tfm) != 0)
107 goto out; 110 goto out;
108 111
109 if (crypto_tfm_alg_ivsize(tfm) > 16) { 112 if (crypto_blkcipher_ivsize(tfm) > 16) {
110 dprintk("RPC: gss_k5decrypt: tfm iv size to large %d\n", 113 dprintk("RPC: gss_k5decrypt: tfm iv size to large %d\n",
111 crypto_tfm_alg_ivsize(tfm)); 114 crypto_blkcipher_ivsize(tfm));
112 goto out; 115 goto out;
113 } 116 }
114 if (iv) 117 if (iv)
115 memcpy(local_iv,iv, crypto_tfm_alg_ivsize(tfm)); 118 memcpy(local_iv,iv, crypto_blkcipher_ivsize(tfm));
116 119
117 memcpy(out, in, length); 120 memcpy(out, in, length);
118 sg_set_buf(sg, out, length); 121 sg_set_buf(sg, out, length);
119 122
120 ret = crypto_cipher_decrypt_iv(tfm, sg, sg, length, local_iv); 123 ret = crypto_blkcipher_decrypt_iv(&desc, sg, sg, length);
121 124
122 dprintk("RPC: krb5_decrypt: output_data:\n"); 125 dprintk("RPC: krb5_decrypt: output_data:\n");
123 print_hexl((u32 *)out, length, 0); 126 print_hexl((u32 *)out, length, 0);
@@ -197,11 +200,9 @@ out:
197static int 200static int
198checksummer(struct scatterlist *sg, void *data) 201checksummer(struct scatterlist *sg, void *data)
199{ 202{
200 struct crypto_tfm *tfm = (struct crypto_tfm *)data; 203 struct hash_desc *desc = data;
201 204
202 crypto_digest_update(tfm, sg, 1); 205 return crypto_hash_update(desc, sg, sg->length);
203
204 return 0;
205} 206}
206 207
207/* checksum the plaintext data and hdrlen bytes of the token header */ 208/* checksum the plaintext data and hdrlen bytes of the token header */
@@ -210,8 +211,9 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
210 int body_offset, struct xdr_netobj *cksum) 211 int body_offset, struct xdr_netobj *cksum)
211{ 212{
212 char *cksumname; 213 char *cksumname;
213 struct crypto_tfm *tfm = NULL; /* XXX add to ctx? */ 214 struct hash_desc desc; /* XXX add to ctx? */
214 struct scatterlist sg[1]; 215 struct scatterlist sg[1];
216 int err;
215 217
216 switch (cksumtype) { 218 switch (cksumtype) {
217 case CKSUMTYPE_RSA_MD5: 219 case CKSUMTYPE_RSA_MD5:
@@ -222,25 +224,35 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
222 " unsupported checksum %d", cksumtype); 224 " unsupported checksum %d", cksumtype);
223 return GSS_S_FAILURE; 225 return GSS_S_FAILURE;
224 } 226 }
225 if (!(tfm = crypto_alloc_tfm(cksumname, CRYPTO_TFM_REQ_MAY_SLEEP))) 227 desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC);
228 if (IS_ERR(desc.tfm))
226 return GSS_S_FAILURE; 229 return GSS_S_FAILURE;
227 cksum->len = crypto_tfm_alg_digestsize(tfm); 230 cksum->len = crypto_hash_digestsize(desc.tfm);
231 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
228 232
229 crypto_digest_init(tfm); 233 err = crypto_hash_init(&desc);
234 if (err)
235 goto out;
230 sg_set_buf(sg, header, hdrlen); 236 sg_set_buf(sg, header, hdrlen);
231 crypto_digest_update(tfm, sg, 1); 237 err = crypto_hash_update(&desc, sg, hdrlen);
232 process_xdr_buf(body, body_offset, body->len - body_offset, 238 if (err)
233 checksummer, tfm); 239 goto out;
234 crypto_digest_final(tfm, cksum->data); 240 err = process_xdr_buf(body, body_offset, body->len - body_offset,
235 crypto_free_tfm(tfm); 241 checksummer, &desc);
236 return 0; 242 if (err)
243 goto out;
244 err = crypto_hash_final(&desc, cksum->data);
245
246out:
247 crypto_free_hash(desc.tfm);
248 return err ? GSS_S_FAILURE : 0;
237} 249}
238 250
239EXPORT_SYMBOL(make_checksum); 251EXPORT_SYMBOL(make_checksum);
240 252
241struct encryptor_desc { 253struct encryptor_desc {
242 u8 iv[8]; /* XXX hard-coded blocksize */ 254 u8 iv[8]; /* XXX hard-coded blocksize */
243 struct crypto_tfm *tfm; 255 struct blkcipher_desc desc;
244 int pos; 256 int pos;
245 struct xdr_buf *outbuf; 257 struct xdr_buf *outbuf;
246 struct page **pages; 258 struct page **pages;
@@ -285,8 +297,8 @@ encryptor(struct scatterlist *sg, void *data)
285 if (thislen == 0) 297 if (thislen == 0)
286 return 0; 298 return 0;
287 299
288 ret = crypto_cipher_encrypt_iv(desc->tfm, desc->outfrags, desc->infrags, 300 ret = crypto_blkcipher_encrypt_iv(&desc->desc, desc->outfrags,
289 thislen, desc->iv); 301 desc->infrags, thislen);
290 if (ret) 302 if (ret)
291 return ret; 303 return ret;
292 if (fraglen) { 304 if (fraglen) {
@@ -305,16 +317,18 @@ encryptor(struct scatterlist *sg, void *data)
305} 317}
306 318
307int 319int
308gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset, 320gss_encrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
309 struct page **pages) 321 int offset, struct page **pages)
310{ 322{
311 int ret; 323 int ret;
312 struct encryptor_desc desc; 324 struct encryptor_desc desc;
313 325
314 BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0); 326 BUG_ON((buf->len - offset) % crypto_blkcipher_blocksize(tfm) != 0);
315 327
316 memset(desc.iv, 0, sizeof(desc.iv)); 328 memset(desc.iv, 0, sizeof(desc.iv));
317 desc.tfm = tfm; 329 desc.desc.tfm = tfm;
330 desc.desc.info = desc.iv;
331 desc.desc.flags = 0;
318 desc.pos = offset; 332 desc.pos = offset;
319 desc.outbuf = buf; 333 desc.outbuf = buf;
320 desc.pages = pages; 334 desc.pages = pages;
@@ -329,7 +343,7 @@ EXPORT_SYMBOL(gss_encrypt_xdr_buf);
329 343
330struct decryptor_desc { 344struct decryptor_desc {
331 u8 iv[8]; /* XXX hard-coded blocksize */ 345 u8 iv[8]; /* XXX hard-coded blocksize */
332 struct crypto_tfm *tfm; 346 struct blkcipher_desc desc;
333 struct scatterlist frags[4]; 347 struct scatterlist frags[4];
334 int fragno; 348 int fragno;
335 int fraglen; 349 int fraglen;
@@ -355,8 +369,8 @@ decryptor(struct scatterlist *sg, void *data)
355 if (thislen == 0) 369 if (thislen == 0)
356 return 0; 370 return 0;
357 371
358 ret = crypto_cipher_decrypt_iv(desc->tfm, desc->frags, desc->frags, 372 ret = crypto_blkcipher_decrypt_iv(&desc->desc, desc->frags,
359 thislen, desc->iv); 373 desc->frags, thislen);
360 if (ret) 374 if (ret)
361 return ret; 375 return ret;
362 if (fraglen) { 376 if (fraglen) {
@@ -373,15 +387,18 @@ decryptor(struct scatterlist *sg, void *data)
373} 387}
374 388
375int 389int
376gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset) 390gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
391 int offset)
377{ 392{
378 struct decryptor_desc desc; 393 struct decryptor_desc desc;
379 394
380 /* XXXJBF: */ 395 /* XXXJBF: */
381 BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0); 396 BUG_ON((buf->len - offset) % crypto_blkcipher_blocksize(tfm) != 0);
382 397
383 memset(desc.iv, 0, sizeof(desc.iv)); 398 memset(desc.iv, 0, sizeof(desc.iv));
384 desc.tfm = tfm; 399 desc.desc.tfm = tfm;
400 desc.desc.info = desc.iv;
401 desc.desc.flags = 0;
385 desc.fragno = 0; 402 desc.fragno = 0;
386 desc.fraglen = 0; 403 desc.fraglen = 0;
387 return process_xdr_buf(buf, offset, buf->len - offset, decryptor, &desc); 404 return process_xdr_buf(buf, offset, buf->len - offset, decryptor, &desc);
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 70e1e53a632b..325e72e4fd31 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -34,6 +34,7 @@
34 * 34 *
35 */ 35 */
36 36
37#include <linux/err.h>
37#include <linux/module.h> 38#include <linux/module.h>
38#include <linux/init.h> 39#include <linux/init.h>
39#include <linux/types.h> 40#include <linux/types.h>
@@ -78,10 +79,10 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
78} 79}
79 80
80static inline const void * 81static inline const void *
81get_key(const void *p, const void *end, struct crypto_tfm **res) 82get_key(const void *p, const void *end, struct crypto_blkcipher **res)
82{ 83{
83 struct xdr_netobj key; 84 struct xdr_netobj key;
84 int alg, alg_mode; 85 int alg;
85 char *alg_name; 86 char *alg_name;
86 87
87 p = simple_get_bytes(p, end, &alg, sizeof(alg)); 88 p = simple_get_bytes(p, end, &alg, sizeof(alg));
@@ -93,18 +94,19 @@ get_key(const void *p, const void *end, struct crypto_tfm **res)
93 94
94 switch (alg) { 95 switch (alg) {
95 case ENCTYPE_DES_CBC_RAW: 96 case ENCTYPE_DES_CBC_RAW:
96 alg_name = "des"; 97 alg_name = "cbc(des)";
97 alg_mode = CRYPTO_TFM_MODE_CBC;
98 break; 98 break;
99 default: 99 default:
100 printk("gss_kerberos_mech: unsupported algorithm %d\n", alg); 100 printk("gss_kerberos_mech: unsupported algorithm %d\n", alg);
101 goto out_err_free_key; 101 goto out_err_free_key;
102 } 102 }
103 if (!(*res = crypto_alloc_tfm(alg_name, alg_mode))) { 103 *res = crypto_alloc_blkcipher(alg_name, 0, CRYPTO_ALG_ASYNC);
104 if (IS_ERR(*res)) {
104 printk("gss_kerberos_mech: unable to initialize crypto algorithm %s\n", alg_name); 105 printk("gss_kerberos_mech: unable to initialize crypto algorithm %s\n", alg_name);
106 *res = NULL;
105 goto out_err_free_key; 107 goto out_err_free_key;
106 } 108 }
107 if (crypto_cipher_setkey(*res, key.data, key.len)) { 109 if (crypto_blkcipher_setkey(*res, key.data, key.len)) {
108 printk("gss_kerberos_mech: error setting key for crypto algorithm %s\n", alg_name); 110 printk("gss_kerberos_mech: error setting key for crypto algorithm %s\n", alg_name);
109 goto out_err_free_tfm; 111 goto out_err_free_tfm;
110 } 112 }
@@ -113,7 +115,7 @@ get_key(const void *p, const void *end, struct crypto_tfm **res)
113 return p; 115 return p;
114 116
115out_err_free_tfm: 117out_err_free_tfm:
116 crypto_free_tfm(*res); 118 crypto_free_blkcipher(*res);
117out_err_free_key: 119out_err_free_key:
118 kfree(key.data); 120 kfree(key.data);
119 p = ERR_PTR(-EINVAL); 121 p = ERR_PTR(-EINVAL);
@@ -172,9 +174,9 @@ gss_import_sec_context_kerberos(const void *p,
172 return 0; 174 return 0;
173 175
174out_err_free_key2: 176out_err_free_key2:
175 crypto_free_tfm(ctx->seq); 177 crypto_free_blkcipher(ctx->seq);
176out_err_free_key1: 178out_err_free_key1:
177 crypto_free_tfm(ctx->enc); 179 crypto_free_blkcipher(ctx->enc);
178out_err_free_mech: 180out_err_free_mech:
179 kfree(ctx->mech_used.data); 181 kfree(ctx->mech_used.data);
180out_err_free_ctx: 182out_err_free_ctx:
@@ -187,8 +189,8 @@ static void
187gss_delete_sec_context_kerberos(void *internal_ctx) { 189gss_delete_sec_context_kerberos(void *internal_ctx) {
188 struct krb5_ctx *kctx = internal_ctx; 190 struct krb5_ctx *kctx = internal_ctx;
189 191
190 crypto_free_tfm(kctx->seq); 192 crypto_free_blkcipher(kctx->seq);
191 crypto_free_tfm(kctx->enc); 193 crypto_free_blkcipher(kctx->enc);
192 kfree(kctx->mech_used.data); 194 kfree(kctx->mech_used.data);
193 kfree(kctx); 195 kfree(kctx);
194} 196}
diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
index c53ead39118d..c604baf3a5f6 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
@@ -41,7 +41,7 @@
41#endif 41#endif
42 42
43s32 43s32
44krb5_make_seq_num(struct crypto_tfm *key, 44krb5_make_seq_num(struct crypto_blkcipher *key,
45 int direction, 45 int direction,
46 s32 seqnum, 46 s32 seqnum,
47 unsigned char *cksum, unsigned char *buf) 47 unsigned char *cksum, unsigned char *buf)
@@ -62,7 +62,7 @@ krb5_make_seq_num(struct crypto_tfm *key,
62} 62}
63 63
64s32 64s32
65krb5_get_seq_num(struct crypto_tfm *key, 65krb5_get_seq_num(struct crypto_blkcipher *key,
66 unsigned char *cksum, 66 unsigned char *cksum,
67 unsigned char *buf, 67 unsigned char *buf,
68 int *direction, s32 * seqnum) 68 int *direction, s32 * seqnum)
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 89d1f3e14128..f179415d0c38 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -149,7 +149,7 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
149 goto out_err; 149 goto out_err;
150 } 150 }
151 151
152 blocksize = crypto_tfm_alg_blocksize(kctx->enc); 152 blocksize = crypto_blkcipher_blocksize(kctx->enc);
153 gss_krb5_add_padding(buf, offset, blocksize); 153 gss_krb5_add_padding(buf, offset, blocksize);
154 BUG_ON((buf->len - offset) % blocksize); 154 BUG_ON((buf->len - offset) % blocksize);
155 plainlen = blocksize + buf->len - offset; 155 plainlen = blocksize + buf->len - offset;
@@ -346,7 +346,7 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
346 /* Copy the data back to the right position. XXX: Would probably be 346 /* Copy the data back to the right position. XXX: Would probably be
347 * better to copy and encrypt at the same time. */ 347 * better to copy and encrypt at the same time. */
348 348
349 blocksize = crypto_tfm_alg_blocksize(kctx->enc); 349 blocksize = crypto_blkcipher_blocksize(kctx->enc);
350 data_start = ptr + 22 + blocksize; 350 data_start = ptr + 22 + blocksize;
351 orig_start = buf->head[0].iov_base + offset; 351 orig_start = buf->head[0].iov_base + offset;
352 data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start; 352 data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start;
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index 88dcb52d171b..bdedf456bc17 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -34,6 +34,7 @@
34 * 34 *
35 */ 35 */
36 36
37#include <linux/err.h>
37#include <linux/module.h> 38#include <linux/module.h>
38#include <linux/init.h> 39#include <linux/init.h>
39#include <linux/types.h> 40#include <linux/types.h>
@@ -83,10 +84,11 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
83} 84}
84 85
85static inline const void * 86static inline const void *
86get_key(const void *p, const void *end, struct crypto_tfm **res, int *resalg) 87get_key(const void *p, const void *end, struct crypto_blkcipher **res,
88 int *resalg)
87{ 89{
88 struct xdr_netobj key = { 0 }; 90 struct xdr_netobj key = { 0 };
89 int alg_mode,setkey = 0; 91 int setkey = 0;
90 char *alg_name; 92 char *alg_name;
91 93
92 p = simple_get_bytes(p, end, resalg, sizeof(*resalg)); 94 p = simple_get_bytes(p, end, resalg, sizeof(*resalg));
@@ -98,14 +100,12 @@ get_key(const void *p, const void *end, struct crypto_tfm **res, int *resalg)
98 100
99 switch (*resalg) { 101 switch (*resalg) {
100 case NID_des_cbc: 102 case NID_des_cbc:
101 alg_name = "des"; 103 alg_name = "cbc(des)";
102 alg_mode = CRYPTO_TFM_MODE_CBC;
103 setkey = 1; 104 setkey = 1;
104 break; 105 break;
105 case NID_cast5_cbc: 106 case NID_cast5_cbc:
106 /* XXXX here in name only, not used */ 107 /* XXXX here in name only, not used */
107 alg_name = "cast5"; 108 alg_name = "cbc(cast5)";
108 alg_mode = CRYPTO_TFM_MODE_CBC;
109 setkey = 0; /* XXX will need to set to 1 */ 109 setkey = 0; /* XXX will need to set to 1 */
110 break; 110 break;
111 case NID_md5: 111 case NID_md5:
@@ -113,19 +113,20 @@ get_key(const void *p, const void *end, struct crypto_tfm **res, int *resalg)
113 dprintk("RPC: SPKM3 get_key: NID_md5 zero Key length\n"); 113 dprintk("RPC: SPKM3 get_key: NID_md5 zero Key length\n");
114 } 114 }
115 alg_name = "md5"; 115 alg_name = "md5";
116 alg_mode = 0;
117 setkey = 0; 116 setkey = 0;
118 break; 117 break;
119 default: 118 default:
120 dprintk("gss_spkm3_mech: unsupported algorithm %d\n", *resalg); 119 dprintk("gss_spkm3_mech: unsupported algorithm %d\n", *resalg);
121 goto out_err_free_key; 120 goto out_err_free_key;
122 } 121 }
123 if (!(*res = crypto_alloc_tfm(alg_name, alg_mode))) { 122 *res = crypto_alloc_blkcipher(alg_name, 0, CRYPTO_ALG_ASYNC);
123 if (IS_ERR(*res)) {
124 printk("gss_spkm3_mech: unable to initialize crypto algorthm %s\n", alg_name); 124 printk("gss_spkm3_mech: unable to initialize crypto algorthm %s\n", alg_name);
125 *res = NULL;
125 goto out_err_free_key; 126 goto out_err_free_key;
126 } 127 }
127 if (setkey) { 128 if (setkey) {
128 if (crypto_cipher_setkey(*res, key.data, key.len)) { 129 if (crypto_blkcipher_setkey(*res, key.data, key.len)) {
129 printk("gss_spkm3_mech: error setting key for crypto algorthm %s\n", alg_name); 130 printk("gss_spkm3_mech: error setting key for crypto algorthm %s\n", alg_name);
130 goto out_err_free_tfm; 131 goto out_err_free_tfm;
131 } 132 }
@@ -136,7 +137,7 @@ get_key(const void *p, const void *end, struct crypto_tfm **res, int *resalg)
136 return p; 137 return p;
137 138
138out_err_free_tfm: 139out_err_free_tfm:
139 crypto_free_tfm(*res); 140 crypto_free_blkcipher(*res);
140out_err_free_key: 141out_err_free_key:
141 if(key.len > 0) 142 if(key.len > 0)
142 kfree(key.data); 143 kfree(key.data);
@@ -204,9 +205,9 @@ gss_import_sec_context_spkm3(const void *p, size_t len,
204 return 0; 205 return 0;
205 206
206out_err_free_key2: 207out_err_free_key2:
207 crypto_free_tfm(ctx->derived_integ_key); 208 crypto_free_blkcipher(ctx->derived_integ_key);
208out_err_free_key1: 209out_err_free_key1:
209 crypto_free_tfm(ctx->derived_conf_key); 210 crypto_free_blkcipher(ctx->derived_conf_key);
210out_err_free_s_key: 211out_err_free_s_key:
211 kfree(ctx->share_key.data); 212 kfree(ctx->share_key.data);
212out_err_free_mech: 213out_err_free_mech:
@@ -223,8 +224,8 @@ static void
223gss_delete_sec_context_spkm3(void *internal_ctx) { 224gss_delete_sec_context_spkm3(void *internal_ctx) {
224 struct spkm3_ctx *sctx = internal_ctx; 225 struct spkm3_ctx *sctx = internal_ctx;
225 226
226 crypto_free_tfm(sctx->derived_integ_key); 227 crypto_free_blkcipher(sctx->derived_integ_key);
227 crypto_free_tfm(sctx->derived_conf_key); 228 crypto_free_blkcipher(sctx->derived_conf_key);
228 kfree(sctx->share_key.data); 229 kfree(sctx->share_key.data);
229 kfree(sctx->mech_used.data); 230 kfree(sctx->mech_used.data);
230 kfree(sctx); 231 kfree(sctx);
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 04e1aea58bc9..5a0dbeb6bbe8 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -30,7 +30,8 @@
30 */ 30 */
31static struct xfrm_algo_desc aalg_list[] = { 31static struct xfrm_algo_desc aalg_list[] = {
32{ 32{
33 .name = "digest_null", 33 .name = "hmac(digest_null)",
34 .compat = "digest_null",
34 35
35 .uinfo = { 36 .uinfo = {
36 .auth = { 37 .auth = {
@@ -47,7 +48,8 @@ static struct xfrm_algo_desc aalg_list[] = {
47 } 48 }
48}, 49},
49{ 50{
50 .name = "md5", 51 .name = "hmac(md5)",
52 .compat = "md5",
51 53
52 .uinfo = { 54 .uinfo = {
53 .auth = { 55 .auth = {
@@ -64,7 +66,8 @@ static struct xfrm_algo_desc aalg_list[] = {
64 } 66 }
65}, 67},
66{ 68{
67 .name = "sha1", 69 .name = "hmac(sha1)",
70 .compat = "sha1",
68 71
69 .uinfo = { 72 .uinfo = {
70 .auth = { 73 .auth = {
@@ -81,7 +84,8 @@ static struct xfrm_algo_desc aalg_list[] = {
81 } 84 }
82}, 85},
83{ 86{
84 .name = "sha256", 87 .name = "hmac(sha256)",
88 .compat = "sha256",
85 89
86 .uinfo = { 90 .uinfo = {
87 .auth = { 91 .auth = {
@@ -98,7 +102,8 @@ static struct xfrm_algo_desc aalg_list[] = {
98 } 102 }
99}, 103},
100{ 104{
101 .name = "ripemd160", 105 .name = "hmac(ripemd160)",
106 .compat = "ripemd160",
102 107
103 .uinfo = { 108 .uinfo = {
104 .auth = { 109 .auth = {
@@ -118,7 +123,8 @@ static struct xfrm_algo_desc aalg_list[] = {
118 123
119static struct xfrm_algo_desc ealg_list[] = { 124static struct xfrm_algo_desc ealg_list[] = {
120{ 125{
121 .name = "cipher_null", 126 .name = "ecb(cipher_null)",
127 .compat = "cipher_null",
122 128
123 .uinfo = { 129 .uinfo = {
124 .encr = { 130 .encr = {
@@ -135,7 +141,8 @@ static struct xfrm_algo_desc ealg_list[] = {
135 } 141 }
136}, 142},
137{ 143{
138 .name = "des", 144 .name = "cbc(des)",
145 .compat = "des",
139 146
140 .uinfo = { 147 .uinfo = {
141 .encr = { 148 .encr = {
@@ -152,7 +159,8 @@ static struct xfrm_algo_desc ealg_list[] = {
152 } 159 }
153}, 160},
154{ 161{
155 .name = "des3_ede", 162 .name = "cbc(des3_ede)",
163 .compat = "des3_ede",
156 164
157 .uinfo = { 165 .uinfo = {
158 .encr = { 166 .encr = {
@@ -169,7 +177,8 @@ static struct xfrm_algo_desc ealg_list[] = {
169 } 177 }
170}, 178},
171{ 179{
172 .name = "cast128", 180 .name = "cbc(cast128)",
181 .compat = "cast128",
173 182
174 .uinfo = { 183 .uinfo = {
175 .encr = { 184 .encr = {
@@ -186,7 +195,8 @@ static struct xfrm_algo_desc ealg_list[] = {
186 } 195 }
187}, 196},
188{ 197{
189 .name = "blowfish", 198 .name = "cbc(blowfish)",
199 .compat = "blowfish",
190 200
191 .uinfo = { 201 .uinfo = {
192 .encr = { 202 .encr = {
@@ -203,7 +213,8 @@ static struct xfrm_algo_desc ealg_list[] = {
203 } 213 }
204}, 214},
205{ 215{
206 .name = "aes", 216 .name = "cbc(aes)",
217 .compat = "aes",
207 218
208 .uinfo = { 219 .uinfo = {
209 .encr = { 220 .encr = {
@@ -220,7 +231,8 @@ static struct xfrm_algo_desc ealg_list[] = {
220 } 231 }
221}, 232},
222{ 233{
223 .name = "serpent", 234 .name = "cbc(serpent)",
235 .compat = "serpent",
224 236
225 .uinfo = { 237 .uinfo = {
226 .encr = { 238 .encr = {
@@ -237,7 +249,8 @@ static struct xfrm_algo_desc ealg_list[] = {
237 } 249 }
238}, 250},
239{ 251{
240 .name = "twofish", 252 .name = "cbc(twofish)",
253 .compat = "twofish",
241 254
242 .uinfo = { 255 .uinfo = {
243 .encr = { 256 .encr = {
@@ -350,8 +363,8 @@ struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
350EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); 363EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
351 364
352static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, 365static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
353 int entries, char *name, 366 int entries, u32 type, u32 mask,
354 int probe) 367 char *name, int probe)
355{ 368{
356 int i, status; 369 int i, status;
357 370
@@ -359,7 +372,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
359 return NULL; 372 return NULL;
360 373
361 for (i = 0; i < entries; i++) { 374 for (i = 0; i < entries; i++) {
362 if (strcmp(name, list[i].name)) 375 if (strcmp(name, list[i].name) &&
376 (!list[i].compat || strcmp(name, list[i].compat)))
363 continue; 377 continue;
364 378
365 if (list[i].available) 379 if (list[i].available)
@@ -368,7 +382,7 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
368 if (!probe) 382 if (!probe)
369 break; 383 break;
370 384
371 status = crypto_alg_available(name, 0); 385 status = crypto_has_alg(name, type, mask | CRYPTO_ALG_ASYNC);
372 if (!status) 386 if (!status)
373 break; 387 break;
374 388
@@ -380,19 +394,25 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
380 394
381struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) 395struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
382{ 396{
383 return xfrm_get_byname(aalg_list, aalg_entries(), name, probe); 397 return xfrm_get_byname(aalg_list, aalg_entries(),
398 CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK,
399 name, probe);
384} 400}
385EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); 401EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
386 402
387struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) 403struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
388{ 404{
389 return xfrm_get_byname(ealg_list, ealg_entries(), name, probe); 405 return xfrm_get_byname(ealg_list, ealg_entries(),
406 CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK,
407 name, probe);
390} 408}
391EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); 409EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
392 410
393struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) 411struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
394{ 412{
395 return xfrm_get_byname(calg_list, calg_entries(), name, probe); 413 return xfrm_get_byname(calg_list, calg_entries(),
414 CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK,
415 name, probe);
396} 416}
397EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); 417EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
398 418
@@ -427,19 +447,22 @@ void xfrm_probe_algs(void)
427 BUG_ON(in_softirq()); 447 BUG_ON(in_softirq());
428 448
429 for (i = 0; i < aalg_entries(); i++) { 449 for (i = 0; i < aalg_entries(); i++) {
430 status = crypto_alg_available(aalg_list[i].name, 0); 450 status = crypto_has_hash(aalg_list[i].name, 0,
451 CRYPTO_ALG_ASYNC);
431 if (aalg_list[i].available != status) 452 if (aalg_list[i].available != status)
432 aalg_list[i].available = status; 453 aalg_list[i].available = status;
433 } 454 }
434 455
435 for (i = 0; i < ealg_entries(); i++) { 456 for (i = 0; i < ealg_entries(); i++) {
436 status = crypto_alg_available(ealg_list[i].name, 0); 457 status = crypto_has_blkcipher(ealg_list[i].name, 0,
458 CRYPTO_ALG_ASYNC);
437 if (ealg_list[i].available != status) 459 if (ealg_list[i].available != status)
438 ealg_list[i].available = status; 460 ealg_list[i].available = status;
439 } 461 }
440 462
441 for (i = 0; i < calg_entries(); i++) { 463 for (i = 0; i < calg_entries(); i++) {
442 status = crypto_alg_available(calg_list[i].name, 0); 464 status = crypto_has_comp(calg_list[i].name, 0,
465 CRYPTO_ALG_ASYNC);
443 if (calg_list[i].available != status) 466 if (calg_list[i].available != status)
444 calg_list[i].available = status; 467 calg_list[i].available = status;
445 } 468 }
@@ -471,11 +494,12 @@ EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
471 494
472/* Move to common area: it is shared with AH. */ 495/* Move to common area: it is shared with AH. */
473 496
474void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, 497int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
475 int offset, int len, icv_update_fn_t icv_update) 498 int offset, int len, icv_update_fn_t icv_update)
476{ 499{
477 int start = skb_headlen(skb); 500 int start = skb_headlen(skb);
478 int i, copy = start - offset; 501 int i, copy = start - offset;
502 int err;
479 struct scatterlist sg; 503 struct scatterlist sg;
480 504
481 /* Checksum header. */ 505 /* Checksum header. */
@@ -487,10 +511,12 @@ void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
487 sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; 511 sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
488 sg.length = copy; 512 sg.length = copy;
489 513
490 icv_update(tfm, &sg, 1); 514 err = icv_update(desc, &sg, copy);
515 if (unlikely(err))
516 return err;
491 517
492 if ((len -= copy) == 0) 518 if ((len -= copy) == 0)
493 return; 519 return 0;
494 offset += copy; 520 offset += copy;
495 } 521 }
496 522
@@ -510,10 +536,12 @@ void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
510 sg.offset = frag->page_offset + offset-start; 536 sg.offset = frag->page_offset + offset-start;
511 sg.length = copy; 537 sg.length = copy;
512 538
513 icv_update(tfm, &sg, 1); 539 err = icv_update(desc, &sg, copy);
540 if (unlikely(err))
541 return err;
514 542
515 if (!(len -= copy)) 543 if (!(len -= copy))
516 return; 544 return 0;
517 offset += copy; 545 offset += copy;
518 } 546 }
519 start = end; 547 start = end;
@@ -531,15 +559,19 @@ void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
531 if ((copy = end - offset) > 0) { 559 if ((copy = end - offset) > 0) {
532 if (copy > len) 560 if (copy > len)
533 copy = len; 561 copy = len;
534 skb_icv_walk(list, tfm, offset-start, copy, icv_update); 562 err = skb_icv_walk(list, desc, offset-start,
563 copy, icv_update);
564 if (unlikely(err))
565 return err;
535 if ((len -= copy) == 0) 566 if ((len -= copy) == 0)
536 return; 567 return 0;
537 offset += copy; 568 offset += copy;
538 } 569 }
539 start = end; 570 start = end;
540 } 571 }
541 } 572 }
542 BUG_ON(len); 573 BUG_ON(len);
574 return 0;
543} 575}
544EXPORT_SYMBOL_GPL(skb_icv_walk); 576EXPORT_SYMBOL_GPL(skb_icv_walk);
545 577
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 3e6a722d072e..fa79ddc4239e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -10,6 +10,7 @@
10 * 10 *
11 */ 11 */
12 12
13#include <linux/crypto.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/types.h> 16#include <linux/types.h>
@@ -212,6 +213,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
212 return -ENOMEM; 213 return -ENOMEM;
213 214
214 memcpy(p, ualg, len); 215 memcpy(p, ualg, len);
216 strcpy(p->alg_name, algo->name);
215 *algpp = p; 217 *algpp = p;
216 return 0; 218 return 0;
217} 219}
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index b34924663ac1..f7844f6aa487 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -62,6 +62,8 @@ my (@stack, $re, $x, $xs);
62 } elsif ($arch eq 'ppc64') { 62 } elsif ($arch eq 'ppc64') {
63 #XXX 63 #XXX
64 $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o; 64 $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
65 } elsif ($arch eq 'powerpc') {
66 $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o;
65 } elsif ($arch =~ /^s390x?$/) { 67 } elsif ($arch =~ /^s390x?$/) {
66 # 11160: a7 fb ff 60 aghi %r15,-160 68 # 11160: a7 fb ff 60 aghi %r15,-160
67 $re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o; 69 $re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o;
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index e2de650d3dbf..de76da80443f 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -265,6 +265,14 @@ static int do_ccw_entry(const char *filename,
265 return 1; 265 return 1;
266} 266}
267 267
268/* looks like: "ap:tN" */
269static int do_ap_entry(const char *filename,
270 struct ap_device_id *id, char *alias)
271{
272 sprintf(alias, "ap:t%02X", id->dev_type);
273 return 1;
274}
275
268/* Looks like: "serio:tyNprNidNexN" */ 276/* Looks like: "serio:tyNprNidNexN" */
269static int do_serio_entry(const char *filename, 277static int do_serio_entry(const char *filename,
270 struct serio_device_id *id, char *alias) 278 struct serio_device_id *id, char *alias)
@@ -503,6 +511,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
503 do_table(symval, sym->st_size, 511 do_table(symval, sym->st_size,
504 sizeof(struct ccw_device_id), "ccw", 512 sizeof(struct ccw_device_id), "ccw",
505 do_ccw_entry, mod); 513 do_ccw_entry, mod);
514 else if (sym_is(symname, "__mod_ap_device_table"))
515 do_table(symval, sym->st_size,
516 sizeof(struct ap_device_id), "ap",
517 do_ap_entry, mod);
506 else if (sym_is(symname, "__mod_serio_device_table")) 518 else if (sym_is(symname, "__mod_serio_device_table"))
507 do_table(symval, sym->st_size, 519 do_table(symval, sym->st_size,
508 sizeof(struct serio_device_id), "serio", 520 sizeof(struct serio_device_id), "serio",
diff --git a/security/seclvl.c b/security/seclvl.c
index c26dd7de0471..8f6291991fbc 100644
--- a/security/seclvl.c
+++ b/security/seclvl.c
@@ -16,6 +16,7 @@
16 * (at your option) any later version. 16 * (at your option) any later version.
17 */ 17 */
18 18
19#include <linux/err.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/moduleparam.h> 21#include <linux/moduleparam.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
@@ -197,26 +198,27 @@ static unsigned char hashedPassword[SHA1_DIGEST_SIZE];
197static int 198static int
198plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len) 199plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len)
199{ 200{
200 struct crypto_tfm *tfm; 201 struct hash_desc desc;
201 struct scatterlist sg; 202 struct scatterlist sg;
203 int err;
204
202 if (len > PAGE_SIZE) { 205 if (len > PAGE_SIZE) {
203 seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d " 206 seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d "
204 "characters). Largest possible is %lu " 207 "characters). Largest possible is %lu "
205 "bytes.\n", len, PAGE_SIZE); 208 "bytes.\n", len, PAGE_SIZE);
206 return -EINVAL; 209 return -EINVAL;
207 } 210 }
208 tfm = crypto_alloc_tfm("sha1", CRYPTO_TFM_REQ_MAY_SLEEP); 211 desc.tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
209 if (tfm == NULL) { 212 if (IS_ERR(desc.tfm)) {
210 seclvl_printk(0, KERN_ERR, 213 seclvl_printk(0, KERN_ERR,
211 "Failed to load transform for SHA1\n"); 214 "Failed to load transform for SHA1\n");
212 return -EINVAL; 215 return -EINVAL;
213 } 216 }
214 sg_init_one(&sg, (u8 *)plaintext, len); 217 sg_init_one(&sg, (u8 *)plaintext, len);
215 crypto_digest_init(tfm); 218 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
216 crypto_digest_update(tfm, &sg, 1); 219 err = crypto_hash_digest(&desc, &sg, len, hash);
217 crypto_digest_final(tfm, hash); 220 crypto_free_hash(desc.tfm);
218 crypto_free_tfm(tfm); 221 return err;
219 return 0;
220} 222}
221 223
222/** 224/**
diff --git a/sound/aoa/core/snd-aoa-gpio-feature.c b/sound/aoa/core/snd-aoa-gpio-feature.c
index f69d33357a28..7c26089527f6 100644
--- a/sound/aoa/core/snd-aoa-gpio-feature.c
+++ b/sound/aoa/core/snd-aoa-gpio-feature.c
@@ -56,7 +56,7 @@ static struct device_node *get_gpio(char *name,
56{ 56{
57 struct device_node *np, *gpio; 57 struct device_node *np, *gpio;
58 u32 *reg; 58 u32 *reg;
59 char *audio_gpio; 59 const char *audio_gpio;
60 60
61 *gpioptr = -1; 61 *gpioptr = -1;
62 62
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
index 4359903f4376..9ae659f82430 100644
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -347,8 +347,8 @@ int
347setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol) 347setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol)
348{ 348{
349 struct device_node *np; 349 struct device_node *np;
350 u32* pp; 350 const u32* pp;
351 351
352 np = find_devices("gpio"); 352 np = find_devices("gpio");
353 if (!np) 353 if (!np)
354 return -ENODEV; 354 return -ENODEV;
@@ -356,7 +356,8 @@ setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int*
356 np = np->child; 356 np = np->child;
357 while(np != 0) { 357 while(np != 0) {
358 if (name) { 358 if (name) {
359 char *property = get_property(np,"audio-gpio",NULL); 359 const char *property =
360 get_property(np,"audio-gpio",NULL);
360 if (property != 0 && strcmp(property,name) == 0) 361 if (property != 0 && strcmp(property,name) == 0)
361 break; 362 break;
362 } else if (compatible && device_is_compatible(np, compatible)) 363 } else if (compatible && device_is_compatible(np, compatible))
@@ -365,11 +366,11 @@ setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int*
365 } 366 }
366 if (!np) 367 if (!np)
367 return -ENODEV; 368 return -ENODEV;
368 pp = (u32 *)get_property(np, "AAPL,address", NULL); 369 pp = get_property(np, "AAPL,address", NULL);
369 if (!pp) 370 if (!pp)
370 return -ENODEV; 371 return -ENODEV;
371 *gpio_addr = (*pp) & 0x0000ffff; 372 *gpio_addr = (*pp) & 0x0000ffff;
372 pp = (u32 *)get_property(np, "audio-gpio-active-state", NULL); 373 pp = get_property(np, "audio-gpio-active-state", NULL);
373 if (pp) 374 if (pp)
374 *gpio_pol = *pp; 375 *gpio_pol = *pp;
375 else 376 else
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 84f6b19c07ca..6ae2d5b9aa4a 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -1035,7 +1035,7 @@ static struct device_node *find_audio_device(const char *name)
1035 return NULL; 1035 return NULL;
1036 1036
1037 for (np = np->child; np; np = np->sibling) { 1037 for (np = np->child; np; np = np->sibling) {
1038 char *property = get_property(np, "audio-gpio", NULL); 1038 const char *property = get_property(np, "audio-gpio", NULL);
1039 if (property && strcmp(property, name) == 0) 1039 if (property && strcmp(property, name) == 0)
1040 return np; 1040 return np;
1041 } 1041 }
@@ -1062,7 +1062,8 @@ static long tumbler_find_device(const char *device, const char *platform,
1062 struct pmac_gpio *gp, int is_compatible) 1062 struct pmac_gpio *gp, int is_compatible)
1063{ 1063{
1064 struct device_node *node; 1064 struct device_node *node;
1065 u32 *base, addr; 1065 const u32 *base;
1066 u32 addr;
1066 1067
1067 if (is_compatible) 1068 if (is_compatible)
1068 node = find_compatible_audio_device(device); 1069 node = find_compatible_audio_device(device);
@@ -1074,9 +1075,9 @@ static long tumbler_find_device(const char *device, const char *platform,
1074 return -ENODEV; 1075 return -ENODEV;
1075 } 1076 }
1076 1077
1077 base = (u32 *)get_property(node, "AAPL,address", NULL); 1078 base = get_property(node, "AAPL,address", NULL);
1078 if (! base) { 1079 if (! base) {
1079 base = (u32 *)get_property(node, "reg", NULL); 1080 base = get_property(node, "reg", NULL);
1080 if (!base) { 1081 if (!base) {
1081 DBG("(E) cannot find address for device %s !\n", device); 1082 DBG("(E) cannot find address for device %s !\n", device);
1082 snd_printd("cannot find address for device %s\n", device); 1083 snd_printd("cannot find address for device %s\n", device);
@@ -1090,13 +1091,13 @@ static long tumbler_find_device(const char *device, const char *platform,
1090 1091
1091 gp->addr = addr & 0x0000ffff; 1092 gp->addr = addr & 0x0000ffff;
1092 /* Try to find the active state, default to 0 ! */ 1093 /* Try to find the active state, default to 0 ! */
1093 base = (u32 *)get_property(node, "audio-gpio-active-state", NULL); 1094 base = get_property(node, "audio-gpio-active-state", NULL);
1094 if (base) { 1095 if (base) {
1095 gp->active_state = *base; 1096 gp->active_state = *base;
1096 gp->active_val = (*base) ? 0x5 : 0x4; 1097 gp->active_val = (*base) ? 0x5 : 0x4;
1097 gp->inactive_val = (*base) ? 0x4 : 0x5; 1098 gp->inactive_val = (*base) ? 0x4 : 0x5;
1098 } else { 1099 } else {
1099 u32 *prop = NULL; 1100 const u32 *prop = NULL;
1100 gp->active_state = 0; 1101 gp->active_state = 0;
1101 gp->active_val = 0x4; 1102 gp->active_val = 0x4;
1102 gp->inactive_val = 0x5; 1103 gp->inactive_val = 0x5;
@@ -1105,7 +1106,7 @@ static long tumbler_find_device(const char *device, const char *platform,
1105 * as we don't yet have an interpreter for these things 1106 * as we don't yet have an interpreter for these things
1106 */ 1107 */
1107 if (platform) 1108 if (platform)
1108 prop = (u32 *)get_property(node, platform, NULL); 1109 prop = get_property(node, platform, NULL);
1109 if (prop) { 1110 if (prop) {
1110 if (prop[3] == 0x9 && prop[4] == 0x9) { 1111 if (prop[3] == 0x9 && prop[4] == 0x9) {
1111 gp->active_val = 0xd; 1112 gp->active_val = 0xd;