From e3297b4a2787a63e33d10cb914a30e5c9682b684 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 9 Feb 2007 17:08:57 +0000 Subject: [PATCH] --- yaml --- r: 47301 b: refs/heads/master c: 7726942fb15edd46e4fe8ab37f9a99795191e585 h: refs/heads/master i: 47299: d404953a6ea03d0882d89be6e8f17fef63bd1e12 v: v3 --- [refs] | 2 +- trunk/Documentation/crypto/api-intro.txt | 4 - .../feature-removal-schedule.txt | 12 + .../sound/alsa/ALSA-Configuration.txt | 60 +- .../sound/alsa/DocBook/alsa-driver-api.tmpl | 4 +- .../alsa/DocBook/writing-an-alsa-driver.tmpl | 33 +- trunk/Documentation/sound/alsa/hda_codec.txt | 10 +- trunk/Documentation/sound/alsa/soc/DAI.txt | 56 - .../Documentation/sound/alsa/soc/clocking.txt | 51 - trunk/Documentation/sound/alsa/soc/codec.txt | 197 -- trunk/Documentation/sound/alsa/soc/dapm.txt | 297 -- .../Documentation/sound/alsa/soc/machine.txt | 113 - .../Documentation/sound/alsa/soc/overview.txt | 83 - .../Documentation/sound/alsa/soc/platform.txt | 58 - .../sound/alsa/soc/pops_clicks.txt | 52 - trunk/MAINTAINERS | 15 +- trunk/arch/avr32/boards/atstk1000/Makefile | 2 +- trunk/arch/avr32/boards/atstk1000/atstk1002.c | 53 +- trunk/arch/avr32/boards/atstk1000/spi.c | 27 + trunk/arch/avr32/kernel/cpu.c | 1 - trunk/arch/avr32/kernel/irq.c | 1 - trunk/arch/avr32/kernel/setup.c | 4 +- trunk/arch/avr32/lib/libgcc.h | 33 + trunk/arch/avr32/lib/longlong.h | 98 + trunk/arch/avr32/mach-at32ap/Makefile | 2 +- trunk/arch/avr32/mach-at32ap/at32ap7000.c | 60 +- trunk/arch/avr32/mach-at32ap/extint.c | 36 +- trunk/arch/avr32/mach-at32ap/pio.c | 255 +- trunk/arch/avr32/mm/cache.c | 32 +- trunk/arch/i386/kernel/hpet.c | 5 +- trunk/arch/i386/kernel/io_apic.c | 2 +- trunk/arch/i386/kernel/sysenter.c | 53 +- trunk/arch/i386/mm/pageattr.c | 2 +- trunk/arch/ia64/kernel/crash.c | 2 +- trunk/arch/ia64/kernel/smp.c | 4 +- trunk/arch/mips/dec/Makefile | 1 - trunk/arch/mips/dec/prom/identify.c | 3 - trunk/arch/mips/dec/setup.c | 2 - trunk/arch/mips/dec/tc.c | 95 - trunk/arch/powerpc/kernel/vdso.c | 104 +- trunk/arch/powerpc/platforms/cell/iommu.c | 5 +- trunk/arch/powerpc/platforms/celleb/pci.c | 12 +- .../arch/powerpc/platforms/celleb/scc_epci.c | 56 +- trunk/arch/powerpc/platforms/chrp/setup.c | 4 +- trunk/arch/powerpc/platforms/ps3/interrupt.c | 2 - trunk/arch/powerpc/platforms/ps3/system-bus.c | 2 - trunk/arch/powerpc/xmon/spu-dis.c | 2 +- trunk/arch/s390/defconfig | 3 +- trunk/arch/sh/kernel/vsyscall/vsyscall.c | 58 +- trunk/arch/x86_64/ia32/syscall32.c | 59 +- trunk/block/ll_rw_blk.c | 2 +- trunk/crypto/Kconfig | 31 - trunk/crypto/Makefile | 3 - trunk/crypto/algapi.c | 15 +- trunk/crypto/api.c | 80 +- trunk/crypto/blkcipher.c | 9 +- trunk/crypto/camellia.c | 1801 ----------- trunk/crypto/cbc.c | 9 +- trunk/crypto/cipher.c | 447 ++- trunk/crypto/compress.c | 5 + trunk/crypto/digest.c | 24 +- trunk/crypto/ecb.c | 9 +- trunk/crypto/fcrypt.c | 423 --- trunk/crypto/hash.c | 5 +- trunk/crypto/hmac.c | 9 +- trunk/crypto/internal.h | 27 +- trunk/crypto/lrw.c | 11 +- trunk/crypto/pcbc.c | 349 --- trunk/crypto/tcrypt.c | 73 +- trunk/crypto/tcrypt.h | 538 +--- trunk/crypto/xcbc.c | 60 +- trunk/drivers/Makefile | 2 +- trunk/drivers/acpi/bay.c | 2 +- trunk/drivers/ata/ahci.c | 2 +- trunk/drivers/ata/sata_svw.c | 6 +- trunk/drivers/char/Makefile | 2 + trunk/drivers/char/apm-emulation.c | 672 ++++ trunk/drivers/char/watchdog/machzwd.c | 2 +- trunk/drivers/crypto/geode-aes.c | 2 +- trunk/drivers/hwmon/ams/ams-input.c | 2 +- .../infiniband/ulp/iser/iser_initiator.c | 4 +- trunk/drivers/input/touchscreen/ucb1400_ts.c | 2 +- trunk/drivers/kvm/kvm_main.c | 63 +- trunk/drivers/kvm/mmu.c | 2 +- trunk/drivers/kvm/svm.c | 8 +- trunk/drivers/kvm/vmx.c | 2 +- trunk/drivers/macintosh/Kconfig | 2 +- trunk/drivers/macintosh/rack-meter.c | 6 +- trunk/drivers/md/bitmap.c | 22 +- trunk/drivers/md/raid5.c | 42 +- trunk/drivers/media/common/ir-keymaps.c | 1 + .../media/video/usbvision/usbvision-video.c | 2 +- trunk/drivers/misc/Kconfig | 2 +- trunk/drivers/misc/lkdtm.c | 4 +- trunk/drivers/mmc/Kconfig | 2 +- trunk/drivers/net/3c503.c | 3 +- trunk/drivers/net/Kconfig | 43 +- trunk/drivers/net/Makefile | 1 - trunk/drivers/net/ac3200.c | 3 +- trunk/drivers/net/atl1/Makefile | 2 - trunk/drivers/net/atl1/atl1.h | 283 -- trunk/drivers/net/atl1/atl1_ethtool.c | 508 --- trunk/drivers/net/atl1/atl1_hw.c | 718 ----- trunk/drivers/net/atl1/atl1_hw.h | 951 ------ trunk/drivers/net/atl1/atl1_main.c | 2468 --------------- trunk/drivers/net/atl1/atl1_param.c | 206 -- trunk/drivers/net/bonding/bond_alb.c | 4 +- trunk/drivers/net/bonding/bond_main.c | 4 +- trunk/drivers/net/cxgb3/cxgb3_main.c | 86 +- trunk/drivers/net/cxgb3/cxgb3_offload.c | 4 +- trunk/drivers/net/defxx.c | 928 ++---- trunk/drivers/net/defxx.h | 58 +- trunk/drivers/net/e2100.c | 3 +- trunk/drivers/net/es3210.c | 2 +- trunk/drivers/net/macsonic.c | 1 - trunk/drivers/net/mv643xx_eth.c | 1 + trunk/drivers/net/r8169.c | 4 +- trunk/drivers/net/s2io.c | 2 +- trunk/drivers/net/s2io.h | 6 +- trunk/drivers/net/slip.c | 5 +- trunk/drivers/net/smc-mca.c | 3 +- trunk/drivers/net/smc-ultra.c | 3 +- trunk/drivers/net/smc-ultra32.c | 3 +- trunk/drivers/net/spider_net.c | 2 +- trunk/drivers/net/tg3.c | 2 +- trunk/drivers/net/ucc_geth.c | 79 +- trunk/drivers/net/ucc_geth_phy.c | 2 - trunk/drivers/net/wan/pc300too.c | 16 +- trunk/drivers/net/wd.c | 2 +- trunk/drivers/pcmcia/m32r_pcc.c | 2 +- trunk/drivers/rtc/rtc-dev.c | 2 +- trunk/drivers/rtc/rtc-pcf8563.c | 40 +- trunk/drivers/s390/char/monreader.c | 218 +- trunk/drivers/s390/char/vmlogrdr.c | 279 +- trunk/drivers/s390/net/Kconfig | 7 + trunk/drivers/s390/net/Makefile | 1 + trunk/drivers/s390/net/iucv.c | 2540 +++++++++++++++ trunk/drivers/s390/net/iucv.h | 849 +++++ trunk/drivers/s390/net/netiucv.c | 1314 ++++---- trunk/drivers/s390/net/smsgiucv.c | 147 +- trunk/drivers/scsi/NCR53C9x.c | 8 +- trunk/drivers/scsi/NCR53C9x.h | 2 +- trunk/drivers/scsi/blz1230.c | 3 +- trunk/drivers/scsi/blz2060.c | 2 +- trunk/drivers/scsi/cyberstorm.c | 2 +- trunk/drivers/scsi/cyberstormII.c | 2 +- trunk/drivers/scsi/dec_esp.c | 355 +-- trunk/drivers/scsi/fastlane.c | 2 +- trunk/drivers/scsi/iscsi_tcp.c | 2 +- trunk/drivers/scsi/jazz_esp.c | 2 +- trunk/drivers/scsi/libiscsi.c | 40 +- trunk/drivers/scsi/mac_esp.c | 2 +- trunk/drivers/scsi/mca_53c9x.c | 2 +- trunk/drivers/scsi/oktagon_esp.c | 2 +- trunk/drivers/scsi/osst.c | 8 +- trunk/drivers/scsi/osst.h | 68 +- trunk/drivers/scsi/sun3x_esp.c | 2 +- trunk/drivers/serial/uartlite.c | 6 +- trunk/drivers/tc/Makefile | 2 +- trunk/drivers/tc/tc-driver.c | 110 - trunk/drivers/tc/tc.c | 339 +- trunk/drivers/usb/host/ehci-ps3.c | 2 +- trunk/drivers/usb/host/ehci.h | 12 +- trunk/drivers/usb/host/ohci-ps3.c | 2 +- trunk/drivers/usb/host/ohci.h | 12 +- trunk/drivers/usb/net/gl620a.c | 26 +- trunk/drivers/usb/serial/cp2101.c | 8 +- trunk/drivers/video/Kconfig | 8 +- trunk/drivers/video/pmag-ba-fb.c | 95 +- trunk/drivers/video/pmagb-b-fb.c | 98 +- trunk/fs/9p/vfs_inode.c | 7 +- trunk/fs/dlm/lowcomms-tcp.c | 23 +- trunk/fs/ecryptfs/crypto.c | 4 +- trunk/fs/ecryptfs/ecryptfs_kernel.h | 1 + trunk/fs/hugetlbfs/inode.c | 5 +- trunk/fs/ufs/dir.c | 21 +- trunk/fs/ufs/super.c | 5 +- trunk/include/asm-alpha/io.h | 9 + trunk/include/asm-arm/arch-ixp4xx/io.h | 3 + trunk/include/asm-arm/io.h | 5 + .../asm-avr32/arch-at32ap/at32ap7000.h | 2 - trunk/include/asm-avr32/arch-at32ap/gpio.h | 27 - trunk/include/asm-avr32/arch-at32ap/irq.h | 14 - trunk/include/asm-avr32/arch-at32ap/portmux.h | 8 +- trunk/include/asm-avr32/checksum.h | 2 +- trunk/include/asm-avr32/dma-mapping.h | 8 - trunk/include/asm-avr32/gpio.h | 6 - trunk/include/asm-avr32/irq.h | 8 +- trunk/include/asm-avr32/posix_types.h | 2 +- trunk/include/asm-avr32/uaccess.h | 6 + trunk/include/asm-cris/io.h | 5 + trunk/include/asm-i386/io.h | 6 + trunk/include/asm-mips/dec/system.h | 3 +- trunk/include/asm-mips/dec/tc.h | 41 + trunk/include/asm-mips/dec/tcinfo.h | 47 + trunk/include/asm-mips/dec/tcmodule.h | 39 + trunk/include/asm-mips/io.h | 6 + trunk/include/asm-parisc/io.h | 9 + trunk/include/asm-ppc/io.h | 2 + trunk/include/asm-x86_64/io.h | 6 + trunk/include/asm-x86_64/proto.h | 1 + trunk/include/crypto/algapi.h | 24 +- trunk/include/linux/apm-emulation.h | 62 + trunk/include/linux/atmarp.h | 2 + trunk/include/linux/crypto.h | 148 +- trunk/include/linux/eisa.h | 10 - trunk/include/linux/gfp.h | 2 +- trunk/include/linux/i2c-id.h | 2 - trunk/include/linux/if_packet.h | 10 - trunk/include/linux/mm.h | 3 - trunk/include/linux/net.h | 2 +- trunk/include/linux/netdevice.h | 2 +- trunk/include/linux/netfilter/Kbuild | 1 - .../linux/netfilter/nf_conntrack_sane.h | 21 - .../linux/netfilter/nf_conntrack_tcp.h | 4 +- trunk/include/linux/netfilter/xt_TCPMSS.h | 10 - trunk/include/linux/netfilter_ipv4/ip_nat.h | 1 - .../include/linux/netfilter_ipv4/ip_tables.h | 22 +- .../include/linux/netfilter_ipv4/ipt_TCPMSS.h | 7 +- .../include/linux/netfilter_ipv6/ip6_tables.h | 35 +- trunk/include/linux/netfilter_ipv6/ip6t_mh.h | 15 - trunk/include/linux/pagemap.h | 2 + trunk/include/linux/pci_ids.h | 2 - trunk/include/linux/pfkeyv2.h | 4 +- trunk/include/linux/raid/bitmap.h | 1 - trunk/include/linux/socket.h | 4 +- trunk/include/linux/sunrpc/svcsock.h | 2 +- trunk/include/linux/sysctl.h | 3 +- trunk/include/linux/tc.h | 141 - trunk/include/linux/tcp.h | 2 +- trunk/include/linux/ufs_fs.h | 1 - trunk/include/linux/wanrouter.h | 8 + trunk/include/linux/xfrm.h | 19 - trunk/include/net/inet_hashtables.h | 10 +- trunk/include/net/iucv/af_iucv.h | 106 - trunk/include/net/iucv/iucv.h | 415 --- trunk/include/net/netfilter/nf_conntrack.h | 2 - trunk/include/net/netfilter/nf_nat.h | 1 - trunk/include/net/route.h | 5 +- trunk/include/net/tcp.h | 5 +- trunk/include/net/x25.h | 18 - trunk/include/net/xfrm.h | 47 - trunk/include/scsi/iscsi_proto.h | 46 +- trunk/include/sound/ac97_codec.h | 4 +- trunk/include/sound/ad1848.h | 2 +- trunk/include/sound/ak4114.h | 3 +- trunk/include/sound/ak4117.h | 2 +- trunk/include/sound/ak4xxx-adda.h | 6 +- trunk/include/sound/control.h | 5 +- trunk/include/sound/core.h | 62 +- trunk/include/sound/emu10k1.h | 418 +-- trunk/include/sound/pcm.h | 4 - trunk/include/sound/pt2258.h | 37 - trunk/include/sound/sb16_csp.h | 14 - trunk/include/sound/snd_wavefront.h | 2 - trunk/include/sound/soc-dapm.h | 286 -- trunk/include/sound/soc.h | 461 --- trunk/include/sound/typedefs.h | 173 ++ trunk/include/sound/version.h | 4 +- trunk/include/sound/vx_core.h | 2 +- trunk/include/sound/ymfpci.h | 6 +- trunk/kernel/power/Kconfig | 26 + trunk/mm/filemap.c | 20 + trunk/mm/hugetlb.c | 2 - trunk/mm/mmap.c | 72 - trunk/mm/page_alloc.c | 7 +- trunk/net/Kconfig | 1 - trunk/net/Makefile | 1 - trunk/net/atm/common.c | 3 +- trunk/net/bluetooth/hidp/hidp.h | 2 +- trunk/net/bluetooth/hidp/sock.c | 2 +- trunk/net/bridge/br_netfilter.c | 29 +- trunk/net/bridge/br_netlink.c | 14 +- trunk/net/bridge/netfilter/ebt_ip.c | 1 - trunk/net/bridge/netfilter/ebt_log.c | 1 - trunk/net/core/dev.c | 13 +- trunk/net/core/dst.c | 9 +- trunk/net/core/fib_rules.c | 14 +- trunk/net/core/neighbour.c | 29 +- trunk/net/core/rtnetlink.c | 23 +- trunk/net/dccp/ccids/ccid3.c | 5 +- trunk/net/dccp/ipv4.c | 2 +- trunk/net/dccp/ipv6.c | 2 +- trunk/net/dccp/proto.c | 4 +- trunk/net/decnet/dn_dev.c | 14 +- trunk/net/decnet/dn_table.c | 11 +- trunk/net/ipv4/af_inet.c | 2 +- trunk/net/ipv4/datagram.c | 2 +- trunk/net/ipv4/devinet.c | 14 +- trunk/net/ipv4/fib_semantics.c | 14 +- trunk/net/ipv4/igmp.c | 2 - trunk/net/ipv4/inet_diag.c | 19 +- trunk/net/ipv4/inet_hashtables.c | 2 +- trunk/net/ipv4/inet_timewait_sock.c | 4 +- trunk/net/ipv4/ip_gre.c | 3 +- trunk/net/ipv4/ipip.c | 3 +- trunk/net/ipv4/netfilter/Kconfig | 26 + trunk/net/ipv4/netfilter/Makefile | 1 + .../ipv4/netfilter/ip_conntrack_proto_tcp.c | 40 +- trunk/net/ipv4/netfilter/ip_nat_core.c | 12 +- trunk/net/ipv4/netfilter/ip_nat_helper.c | 2 +- trunk/net/ipv4/netfilter/ip_nat_proto_tcp.c | 5 - trunk/net/ipv4/netfilter/ip_nat_proto_udp.c | 5 - trunk/net/ipv4/netfilter/ip_nat_rule.c | 32 +- trunk/net/ipv4/netfilter/ip_tables.c | 40 +- trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c | 15 +- trunk/net/ipv4/netfilter/ipt_ECN.c | 13 +- trunk/net/ipv4/netfilter/ipt_LOG.c | 16 +- trunk/net/ipv4/netfilter/ipt_MASQUERADE.c | 9 +- trunk/net/ipv4/netfilter/ipt_NETMAP.c | 8 +- trunk/net/ipv4/netfilter/ipt_REDIRECT.c | 8 +- trunk/net/ipv4/netfilter/ipt_REJECT.c | 12 +- trunk/net/ipv4/netfilter/ipt_SAME.c | 8 +- trunk/net/ipv4/netfilter/ipt_TCPMSS.c | 207 ++ trunk/net/ipv4/netfilter/ipt_TOS.c | 11 +- trunk/net/ipv4/netfilter/ipt_TTL.c | 11 +- trunk/net/ipv4/netfilter/ipt_ULOG.c | 18 +- trunk/net/ipv4/netfilter/ipt_addrtype.c | 9 +- trunk/net/ipv4/netfilter/ipt_ah.c | 10 +- trunk/net/ipv4/netfilter/ipt_ecn.c | 10 +- trunk/net/ipv4/netfilter/ipt_iprange.c | 10 +- trunk/net/ipv4/netfilter/ipt_owner.c | 9 +- trunk/net/ipv4/netfilter/ipt_recent.c | 12 +- trunk/net/ipv4/netfilter/ipt_tos.c | 10 +- trunk/net/ipv4/netfilter/ipt_ttl.c | 11 +- trunk/net/ipv4/netfilter/iptable_filter.c | 2 +- trunk/net/ipv4/netfilter/iptable_mangle.c | 2 +- trunk/net/ipv4/netfilter/iptable_raw.c | 2 +- trunk/net/ipv4/netfilter/nf_nat_core.c | 12 +- trunk/net/ipv4/netfilter/nf_nat_helper.c | 2 +- trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c | 4 - trunk/net/ipv4/netfilter/nf_nat_proto_udp.c | 4 - trunk/net/ipv4/netfilter/nf_nat_rule.c | 8 +- trunk/net/ipv4/netfilter/nf_nat_standalone.c | 6 + trunk/net/ipv4/raw.c | 2 +- trunk/net/ipv4/route.c | 5 +- trunk/net/ipv4/tcp.c | 7 +- trunk/net/ipv4/tcp_input.c | 105 +- trunk/net/ipv4/tcp_ipv4.c | 18 +- trunk/net/ipv4/tcp_output.c | 3 +- trunk/net/ipv4/udp.c | 2 +- trunk/net/ipv4/xfrm4_mode_tunnel.c | 57 +- trunk/net/ipv4/xfrm4_policy.c | 51 +- trunk/net/ipv4/xfrm4_state.c | 1 - trunk/net/ipv6/addrconf.c | 70 +- trunk/net/ipv6/datagram.c | 2 +- trunk/net/ipv6/inet6_hashtables.c | 4 +- trunk/net/ipv6/ip6_tunnel.c | 3 +- trunk/net/ipv6/mcast.c | 2 - trunk/net/ipv6/mip6.c | 26 + trunk/net/ipv6/netfilter/Kconfig | 8 - trunk/net/ipv6/netfilter/Makefile | 1 - trunk/net/ipv6/netfilter/ip6_tables.c | 12 +- trunk/net/ipv6/netfilter/ip6t_HL.c | 17 +- trunk/net/ipv6/netfilter/ip6t_LOG.c | 15 +- trunk/net/ipv6/netfilter/ip6t_REJECT.c | 10 +- trunk/net/ipv6/netfilter/ip6t_ah.c | 8 +- trunk/net/ipv6/netfilter/ip6t_eui64.c | 8 +- trunk/net/ipv6/netfilter/ip6t_frag.c | 8 +- trunk/net/ipv6/netfilter/ip6t_hbh.c | 1 - trunk/net/ipv6/netfilter/ip6t_hl.c | 11 +- trunk/net/ipv6/netfilter/ip6t_ipv6header.c | 8 +- trunk/net/ipv6/netfilter/ip6t_mh.c | 108 - trunk/net/ipv6/netfilter/ip6t_owner.c | 8 +- trunk/net/ipv6/netfilter/ip6t_rt.c | 8 +- trunk/net/ipv6/netfilter/ip6table_filter.c | 21 +- trunk/net/ipv6/netfilter/ip6table_mangle.c | 21 +- trunk/net/ipv6/netfilter/ip6table_raw.c | 19 + trunk/net/ipv6/raw.c | 15 +- trunk/net/ipv6/route.c | 33 +- trunk/net/ipv6/sit.c | 3 +- trunk/net/ipv6/tcp_ipv6.c | 2 +- trunk/net/ipv6/udp.c | 2 +- trunk/net/ipv6/xfrm6_mode_tunnel.c | 42 +- trunk/net/ipv6/xfrm6_policy.c | 46 +- trunk/net/ipv6/xfrm6_state.c | 1 - trunk/net/ipx/af_ipx.c | 24 +- trunk/net/irda/irias_object.c | 40 - trunk/net/irda/irlan/irlan_common.c | 23 +- trunk/net/iucv/Kconfig | 15 - trunk/net/iucv/Makefile | 6 - trunk/net/iucv/af_iucv.c | 1077 ------- trunk/net/iucv/iucv.c | 1619 ---------- trunk/net/key/af_key.c | 422 --- trunk/net/netfilter/Kconfig | 39 - trunk/net/netfilter/Makefile | 2 - trunk/net/netfilter/nf_conntrack_proto_tcp.c | 40 +- trunk/net/netfilter/nf_conntrack_sane.c | 242 -- trunk/net/netfilter/xt_CLASSIFY.c | 4 +- trunk/net/netfilter/xt_CONNMARK.c | 5 +- trunk/net/netfilter/xt_CONNSECMARK.c | 6 +- trunk/net/netfilter/xt_MARK.c | 8 +- trunk/net/netfilter/xt_SECMARK.c | 4 +- trunk/net/netfilter/xt_TCPMSS.c | 296 -- trunk/net/netfilter/xt_hashlimit.c | 1 - trunk/net/packet/af_packet.c | 79 +- trunk/net/sched/act_ipt.c | 2 +- trunk/net/sched/sch_generic.c | 2 +- trunk/net/sched/sch_prio.c | 15 - trunk/net/sched/sch_sfq.c | 2 - trunk/net/socket.c | 29 +- trunk/net/sunrpc/svc.c | 4 +- trunk/net/sunrpc/svcsock.c | 52 +- trunk/net/wanrouter/wanmain.c | 17 +- trunk/net/x25/Makefile | 2 +- trunk/net/x25/af_x25.c | 32 +- trunk/net/x25/sysctl_net_x25.c | 8 - trunk/net/x25/x25_dev.c | 13 +- trunk/net/x25/x25_forward.c | 163 - trunk/net/x25/x25_proc.c | 98 - trunk/net/x25/x25_route.c | 3 - trunk/net/xfrm/Kconfig | 26 - trunk/net/xfrm/xfrm_algo.c | 17 - trunk/net/xfrm/xfrm_policy.c | 231 -- trunk/net/xfrm/xfrm_state.c | 184 +- trunk/net/xfrm/xfrm_user.c | 173 -- trunk/sound/Kconfig | 2 - trunk/sound/Makefile | 2 +- trunk/sound/ac97_bus.c | 4 - trunk/sound/aoa/aoa.h | 2 +- trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c | 11 +- trunk/sound/aoa/core/snd-aoa-alsa.c | 5 +- trunk/sound/aoa/core/snd-aoa-alsa.h | 2 +- trunk/sound/aoa/core/snd-aoa-core.c | 4 +- .../sound/aoa/fabrics/snd-aoa-fabric-layout.c | 13 +- trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c | 22 +- trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c | 407 ++- trunk/sound/aoa/soundbus/i2sbus/i2sbus.h | 6 - trunk/sound/arm/aaci.h | 2 +- trunk/sound/core/control.c | 42 +- trunk/sound/core/control_compat.c | 5 +- trunk/sound/core/device.c | 24 +- trunk/sound/core/hwdep.c | 19 +- trunk/sound/core/init.c | 22 +- trunk/sound/core/memalloc.c | 10 +- trunk/sound/core/misc.c | 28 - trunk/sound/core/pcm.c | 50 +- trunk/sound/core/pcm_lib.c | 5 - trunk/sound/core/pcm_memory.c | 23 - trunk/sound/core/rawmidi.c | 29 +- trunk/sound/core/seq/seq_clientmgr.c | 14 +- trunk/sound/core/seq/seq_device.c | 25 +- trunk/sound/core/seq/seq_ports.c | 51 +- trunk/sound/core/seq/seq_virmidi.c | 4 +- trunk/sound/core/sound.c | 15 +- trunk/sound/core/timer.c | 80 +- trunk/sound/drivers/Kconfig | 11 - trunk/sound/drivers/Makefile | 2 - trunk/sound/drivers/dummy.c | 2 +- trunk/sound/drivers/portman2x4.c | 876 ------ trunk/sound/drivers/serial-u16550.c | 221 +- trunk/sound/drivers/vx/vx_mixer.c | 2 +- trunk/sound/i2c/Makefile | 1 - trunk/sound/i2c/other/Makefile | 4 +- trunk/sound/i2c/other/ak4114.c | 29 +- trunk/sound/i2c/other/ak4117.c | 2 +- trunk/sound/i2c/other/ak4xxx-adda.c | 110 +- trunk/sound/i2c/other/pt2258.c | 233 -- trunk/sound/isa/Kconfig | 2 - trunk/sound/isa/ad1816a/ad1816a_lib.c | 10 +- trunk/sound/isa/ad1848/ad1848_lib.c | 6 +- trunk/sound/isa/gus/gus_main.c | 6 +- trunk/sound/isa/opl3sa2.c | 4 +- trunk/sound/isa/sb/sb16_csp.c | 61 +- trunk/sound/isa/wavefront/wavefront.c | 1 - trunk/sound/isa/wavefront/wavefront_fx.c | 812 ++++- trunk/sound/isa/wavefront/yss225.c | 2739 ----------------- trunk/sound/pci/Kconfig | 30 +- trunk/sound/pci/ac97/ac97_codec.c | 64 +- trunk/sound/pci/ac97/ac97_patch.c | 549 +--- trunk/sound/pci/ac97/ac97_patch.h | 1 - trunk/sound/pci/ac97/ak4531_codec.c | 6 +- trunk/sound/pci/als300.c | 6 +- trunk/sound/pci/atiixp.c | 31 +- trunk/sound/pci/atiixp_modem.c | 2 +- trunk/sound/pci/ca0106/ca0106_main.c | 21 +- trunk/sound/pci/ca0106/ca0106_mixer.c | 50 +- trunk/sound/pci/cs4281.c | 2 +- trunk/sound/pci/echoaudio/darla20.c | 1 - trunk/sound/pci/echoaudio/darla24.c | 1 - trunk/sound/pci/echoaudio/echo3g.c | 1 - trunk/sound/pci/echoaudio/echo3g_dsp.c | 2 +- trunk/sound/pci/echoaudio/echoaudio.c | 18 +- trunk/sound/pci/echoaudio/gina20.c | 1 - trunk/sound/pci/echoaudio/gina24.c | 1 - trunk/sound/pci/echoaudio/indigo.c | 1 - trunk/sound/pci/echoaudio/indigodj.c | 1 - trunk/sound/pci/echoaudio/indigoio.c | 1 - trunk/sound/pci/echoaudio/layla20.c | 1 - trunk/sound/pci/echoaudio/layla24.c | 1 - trunk/sound/pci/echoaudio/mia.c | 1 - trunk/sound/pci/echoaudio/mona.c | 1 - trunk/sound/pci/emu10k1/emu10k1_main.c | 616 +--- trunk/sound/pci/emu10k1/emu10k1x.c | 6 +- trunk/sound/pci/emu10k1/emufx.c | 204 +- trunk/sound/pci/emu10k1/emumixer.c | 745 +---- trunk/sound/pci/emu10k1/emupcm.c | 147 +- trunk/sound/pci/emu10k1/emuproc.c | 34 +- trunk/sound/pci/emu10k1/io.c | 104 - trunk/sound/pci/emu10k1/p16v.c | 14 +- trunk/sound/pci/emu10k1/p17v.h | 47 - trunk/sound/pci/emu10k1/voice.c | 2 +- trunk/sound/pci/ens1370.c | 154 +- trunk/sound/pci/es1938.c | 2 +- trunk/sound/pci/fm801.c | 2 +- trunk/sound/pci/hda/Makefile | 11 +- trunk/sound/pci/hda/hda_codec.c | 68 +- trunk/sound/pci/hda/hda_intel.c | 33 +- trunk/sound/pci/hda/hda_local.h | 12 +- trunk/sound/pci/hda/hda_patch.h | 6 - trunk/sound/pci/hda/patch_analog.c | 165 +- trunk/sound/pci/hda/patch_cmedia.c | 24 +- trunk/sound/pci/hda/patch_conexant.c | 1311 -------- trunk/sound/pci/hda/patch_realtek.c | 2377 ++------------ trunk/sound/pci/hda/patch_sigmatel.c | 692 ++--- trunk/sound/pci/hda/patch_via.c | 1396 --------- trunk/sound/pci/ice1712/Makefile | 2 +- trunk/sound/pci/ice1712/amp.c | 4 +- trunk/sound/pci/ice1712/amp.h | 2 +- trunk/sound/pci/ice1712/aureon.c | 186 +- trunk/sound/pci/ice1712/aureon.h | 6 +- trunk/sound/pci/ice1712/delta.c | 34 +- trunk/sound/pci/ice1712/delta.h | 2 +- trunk/sound/pci/ice1712/ews.c | 24 +- trunk/sound/pci/ice1712/ews.h | 2 +- trunk/sound/pci/ice1712/hoontech.c | 7 +- trunk/sound/pci/ice1712/hoontech.h | 2 +- trunk/sound/pci/ice1712/ice1712.c | 74 +- trunk/sound/pci/ice1712/ice1712.h | 18 +- trunk/sound/pci/ice1712/ice1724.c | 78 +- trunk/sound/pci/ice1712/juli.c | 36 +- trunk/sound/pci/ice1712/juli.h | 2 +- trunk/sound/pci/ice1712/phase.c | 76 +- trunk/sound/pci/ice1712/phase.h | 2 +- trunk/sound/pci/ice1712/pontis.c | 42 +- trunk/sound/pci/ice1712/pontis.h | 2 +- trunk/sound/pci/ice1712/prodigy192.c | 40 +- trunk/sound/pci/ice1712/prodigy192.h | 2 +- trunk/sound/pci/ice1712/revo.c | 372 +-- trunk/sound/pci/ice1712/revo.h | 13 +- trunk/sound/pci/ice1712/vt1720_mobo.c | 59 +- trunk/sound/pci/ice1712/vt1720_mobo.h | 2 +- trunk/sound/pci/ice1712/wtm.c | 542 ---- trunk/sound/pci/ice1712/wtm.h | 20 - trunk/sound/pci/intel8x0.c | 208 +- trunk/sound/pci/intel8x0m.c | 120 +- trunk/sound/pci/korg1212/korg1212.c | 45 +- trunk/sound/pci/maestro3.c | 373 ++- trunk/sound/pci/mixart/mixart_mixer.c | 4 +- trunk/sound/pci/nm256/nm256.c | 56 +- trunk/sound/pci/pcxhr/pcxhr_mixer.c | 6 +- trunk/sound/pci/rme9652/hdsp.c | 38 - trunk/sound/pci/rme9652/hdspm.c | 1324 ++------ trunk/sound/pci/trident/trident_main.c | 4 +- trunk/sound/pci/via82xx.c | 134 +- trunk/sound/pci/via82xx_modem.c | 2 +- trunk/sound/pci/vx222/vx222.c | 4 +- trunk/sound/pci/vx222/vx222_ops.c | 2 +- trunk/sound/pci/ymfpci/ymfpci_image.h | 6 +- trunk/sound/pci/ymfpci/ymfpci_main.c | 171 +- trunk/sound/pcmcia/vx/vxp_mixer.c | 2 +- trunk/sound/pcmcia/vx/vxpocket.c | 2 +- trunk/sound/soc/Kconfig | 32 - trunk/sound/soc/Makefile | 4 - trunk/sound/soc/at91/Kconfig | 32 - trunk/sound/soc/at91/Makefile | 11 - trunk/sound/soc/at91/at91-i2s.c | 720 ----- trunk/sound/soc/at91/at91-i2s.h | 27 - trunk/sound/soc/at91/at91-pcm.c | 432 --- trunk/sound/soc/at91/at91-pcm.h | 72 - trunk/sound/soc/at91/eti_b1_wm8731.c | 375 --- trunk/sound/soc/codecs/Kconfig | 15 - trunk/sound/soc/codecs/Makefile | 9 - trunk/sound/soc/codecs/ac97.c | 156 - trunk/sound/soc/codecs/ac97.h | 18 - trunk/sound/soc/codecs/wm8731.c | 758 ----- trunk/sound/soc/codecs/wm8731.h | 44 - trunk/sound/soc/codecs/wm8750.c | 1049 ------- trunk/sound/soc/codecs/wm8750.h | 67 - trunk/sound/soc/codecs/wm9712.c | 771 ----- trunk/sound/soc/codecs/wm9712.h | 14 - trunk/sound/soc/pxa/Kconfig | 60 - trunk/sound/soc/pxa/Makefile | 20 - trunk/sound/soc/pxa/corgi.c | 383 --- trunk/sound/soc/pxa/poodle.c | 352 --- trunk/sound/soc/pxa/pxa2xx-ac97.c | 431 --- trunk/sound/soc/pxa/pxa2xx-ac97.h | 22 - trunk/sound/soc/pxa/pxa2xx-i2s.c | 318 -- trunk/sound/soc/pxa/pxa2xx-i2s.h | 20 - trunk/sound/soc/pxa/pxa2xx-pcm.c | 372 --- trunk/sound/soc/pxa/pxa2xx-pcm.h | 34 - trunk/sound/soc/pxa/spitz.c | 394 --- trunk/sound/soc/pxa/tosa.c | 289 -- trunk/sound/soc/soc-core.c | 1587 ---------- trunk/sound/soc/soc-dapm.c | 1323 -------- trunk/sound/sparc/dbri.c | 2 +- trunk/sound/usb/usbaudio.c | 189 +- trunk/sound/usb/usbaudio.h | 1 - trunk/sound/usb/usbquirks.h | 32 +- 599 files changed, 12581 insertions(+), 46838 deletions(-) delete mode 100644 trunk/Documentation/sound/alsa/soc/DAI.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/clocking.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/codec.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/dapm.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/machine.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/overview.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/platform.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/pops_clicks.txt create mode 100644 trunk/arch/avr32/boards/atstk1000/spi.c create mode 100644 trunk/arch/avr32/lib/libgcc.h create mode 100644 trunk/arch/avr32/lib/longlong.h delete mode 100644 trunk/arch/mips/dec/tc.c delete mode 100644 trunk/crypto/camellia.c delete mode 100644 trunk/crypto/fcrypt.c delete mode 100644 trunk/crypto/pcbc.c create mode 100644 trunk/drivers/char/apm-emulation.c delete mode 100644 trunk/drivers/net/atl1/Makefile delete mode 100644 trunk/drivers/net/atl1/atl1.h delete mode 100644 trunk/drivers/net/atl1/atl1_ethtool.c delete mode 100644 trunk/drivers/net/atl1/atl1_hw.c delete mode 100644 trunk/drivers/net/atl1/atl1_hw.h delete mode 100644 trunk/drivers/net/atl1/atl1_main.c delete mode 100644 trunk/drivers/net/atl1/atl1_param.c create mode 100644 trunk/drivers/s390/net/iucv.c create mode 100644 trunk/drivers/s390/net/iucv.h delete mode 100644 trunk/drivers/tc/tc-driver.c delete mode 100644 trunk/include/asm-avr32/arch-at32ap/gpio.h delete mode 100644 trunk/include/asm-avr32/arch-at32ap/irq.h delete mode 100644 trunk/include/asm-avr32/gpio.h create mode 100644 trunk/include/asm-mips/dec/tc.h create mode 100644 trunk/include/asm-mips/dec/tcinfo.h create mode 100644 trunk/include/asm-mips/dec/tcmodule.h create mode 100644 trunk/include/linux/apm-emulation.h delete mode 100644 trunk/include/linux/netfilter/nf_conntrack_sane.h delete mode 100644 trunk/include/linux/netfilter/xt_TCPMSS.h delete mode 100644 trunk/include/linux/netfilter_ipv6/ip6t_mh.h delete mode 100644 trunk/include/linux/tc.h delete mode 100644 trunk/include/net/iucv/af_iucv.h delete mode 100644 trunk/include/net/iucv/iucv.h delete mode 100644 trunk/include/sound/pt2258.h delete mode 100644 trunk/include/sound/soc-dapm.h delete mode 100644 trunk/include/sound/soc.h create mode 100644 trunk/include/sound/typedefs.h create mode 100644 trunk/net/ipv4/netfilter/ipt_TCPMSS.c delete mode 100644 trunk/net/ipv6/netfilter/ip6t_mh.c delete mode 100644 trunk/net/iucv/Kconfig delete mode 100644 trunk/net/iucv/Makefile delete mode 100644 trunk/net/iucv/af_iucv.c delete mode 100644 trunk/net/iucv/iucv.c delete mode 100644 trunk/net/netfilter/nf_conntrack_sane.c delete mode 100644 trunk/net/netfilter/xt_TCPMSS.c delete mode 100644 trunk/net/x25/x25_forward.c delete mode 100644 trunk/sound/drivers/portman2x4.c delete mode 100644 trunk/sound/i2c/other/pt2258.c delete mode 100644 trunk/sound/isa/wavefront/yss225.c delete mode 100644 trunk/sound/pci/hda/patch_conexant.c delete mode 100644 trunk/sound/pci/hda/patch_via.c delete mode 100644 trunk/sound/pci/ice1712/wtm.c delete mode 100644 trunk/sound/pci/ice1712/wtm.h delete mode 100644 trunk/sound/soc/Kconfig delete mode 100644 trunk/sound/soc/Makefile delete mode 100644 trunk/sound/soc/at91/Kconfig delete mode 100644 trunk/sound/soc/at91/Makefile delete mode 100644 trunk/sound/soc/at91/at91-i2s.c delete mode 100644 trunk/sound/soc/at91/at91-i2s.h delete mode 100644 trunk/sound/soc/at91/at91-pcm.c delete mode 100644 trunk/sound/soc/at91/at91-pcm.h delete mode 100644 trunk/sound/soc/at91/eti_b1_wm8731.c delete mode 100644 trunk/sound/soc/codecs/Kconfig delete mode 100644 trunk/sound/soc/codecs/Makefile delete mode 100644 trunk/sound/soc/codecs/ac97.c delete mode 100644 trunk/sound/soc/codecs/ac97.h delete mode 100644 trunk/sound/soc/codecs/wm8731.c delete mode 100644 trunk/sound/soc/codecs/wm8731.h delete mode 100644 trunk/sound/soc/codecs/wm8750.c delete mode 100644 trunk/sound/soc/codecs/wm8750.h delete mode 100644 trunk/sound/soc/codecs/wm9712.c delete mode 100644 trunk/sound/soc/codecs/wm9712.h delete mode 100644 trunk/sound/soc/pxa/Kconfig delete mode 100644 trunk/sound/soc/pxa/Makefile delete mode 100644 trunk/sound/soc/pxa/corgi.c delete mode 100644 trunk/sound/soc/pxa/poodle.c delete mode 100644 trunk/sound/soc/pxa/pxa2xx-ac97.c delete mode 100644 trunk/sound/soc/pxa/pxa2xx-ac97.h delete mode 100644 trunk/sound/soc/pxa/pxa2xx-i2s.c delete mode 100644 trunk/sound/soc/pxa/pxa2xx-i2s.h delete mode 100644 trunk/sound/soc/pxa/pxa2xx-pcm.c delete mode 100644 trunk/sound/soc/pxa/pxa2xx-pcm.h delete mode 100644 trunk/sound/soc/pxa/spitz.c delete mode 100644 trunk/sound/soc/pxa/tosa.c delete mode 100644 trunk/sound/soc/soc-core.c delete mode 100644 trunk/sound/soc/soc-dapm.c diff --git a/[refs] b/[refs] index 97f77fcbd7ce..f1fb9a7f6d6a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2affc857efdf7dacace234b63d289d67260c95a6 +refs/heads/master: 7726942fb15edd46e4fe8ab37f9a99795191e585 diff --git a/trunk/Documentation/crypto/api-intro.txt b/trunk/Documentation/crypto/api-intro.txt index e41a79aa71ce..5a03a2801d67 100644 --- a/trunk/Documentation/crypto/api-intro.txt +++ b/trunk/Documentation/crypto/api-intro.txt @@ -193,7 +193,6 @@ Original developers of the crypto algorithms: Kartikey Mahendra Bhatt (CAST6) Jon Oberheide (ARC4) Jouni Malinen (Michael MIC) - NTT(Nippon Telegraph and Telephone Corporation) (Camellia) SHA1 algorithm contributors: Jean-Francois Dive @@ -247,9 +246,6 @@ Tiger algorithm contributors: VIA PadLock contributors: Michal Ludvig -Camellia algorithm contributors: - NTT(Nippon Telegraph and Telephone Corporation) (Camellia) - Generic scatterwalk code by Adam J. Richter Please send any credits updates or corrections to: diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 4a1d8979ed92..2dc5e5da8f88 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -186,6 +186,18 @@ Who: Greg Kroah-Hartman --------------------------- +What: find_trylock_page +When: January 2007 +Why: The interface no longer has any callers left in the kernel. It + is an odd interface (compared with other find_*_page functions), in + that it does not take a refcount to the page, only the page lock. + It should be replaced with find_get_page or find_lock_page if possible. + This feature removal can be reevaluated if users of the interface + cannot cleanly use something else. +Who: Nick Piggin + +--------------------------- + What: Interrupt only SA_* flags When: Januar 2007 Why: The interrupt related SA_* flags are replaced by IRQF_* to move them diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index c30ff1bb2d10..9fef210ab50a 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -242,12 +242,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ac97_clock - AC'97 clock (default = 48000) ac97_quirk - AC'97 workaround for strange hardware See "AC97 Quirk Option" section below. - ac97_codec - Workaround to specify which AC'97 codec - instead of probing. If this works for you - file a bug with your `lspci -vn` output. - -2 -- Force probing. - -1 -- Default behavior. - 0-2 -- Use the specified codec. spdif_aclink - S/PDIF transfer over AC-link (default = 1) This module supports one card and autoprobe. @@ -785,7 +779,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. asus-dig ASUS with SPDIF out asus-dig2 ASUS with SPDIF out (using GPIO2) uniwill 3-jack - fujitsu Fujitsu Laptops (Pi1536) F1734 2-jack lg LG laptop (m1 express dual) lg-lw LG LW20/LW25 laptop @@ -807,18 +800,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ALC262 fujitsu Fujitsu Laptop hp-bpc HP xw4400/6400/8400/9400 laptops - hp-bpc-d7000 HP BPC D7000 benq Benq ED8 - hippo Hippo (ATI) with jack detection, Sony UX-90s - hippo_1 Hippo (Benq) with jack detection basic fixed pin assignment w/o SPDIF auto auto-config reading BIOS (default) ALC882/885 3stack-dig 3-jack with SPDIF I/O - 6stack-dig 6-jack digital with SPDIF I/O + 6stck-dig 6-jack digital with SPDIF I/O arima Arima W820Di1 - macpro MacPro support auto auto-config reading BIOS (default) ALC883/888 @@ -828,10 +817,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O 6stack-dig-demo 6-jack digital for Intel demo board acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) - medion Medion Laptops - targa-dig Targa/MSI - targa-2ch-dig Targs/MSI with 2-channel - laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) auto auto-config reading BIOS (default) ALC861/660 @@ -840,16 +825,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 6stack-dig 6-jack with SPDIF I/O 3stack-660 3-jack (for ALC660) uniwill-m31 Uniwill M31 laptop - toshiba Toshiba laptop support - asus Asus laptop support - asus-laptop ASUS F2/F3 laptops - auto auto-config reading BIOS (default) - - ALC861VD/660VD - 3stack 3-jack - 3stack-dig 3-jack with SPDIF OUT - 6stack-dig 6-jack with SPDIF OUT - 3stack-660 3-jack (for ALC660VD) auto auto-config reading BIOS (default) CMI9880 @@ -870,7 +845,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack 3-stack, shared surrounds laptop 2-channel only (FSC V2060, Samsung M50) laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J) - ultra 2-channel with EAPD (Samsung Ultra tablet PC) AD1988 6stack 6-jack @@ -880,31 +854,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. laptop 3-jack with hp-jack automute laptop-dig ditto with SPDIF auto auto-config reading BIOS (default) - - Conexant 5045 - laptop Laptop config - test for testing/debugging purpose, almost all controls - can be adjusted. Appearing only when compiled with - $CONFIG_SND_DEBUG=y - - Conexant 5047 - laptop Basic Laptop config - laptop-hp Laptop config for some HP models (subdevice 30A5) - laptop-eapd Laptop config with EAPD support - test for testing/debugging purpose, almost all controls - can be adjusted. Appearing only when compiled with - $CONFIG_SND_DEBUG=y STAC9200/9205/9220/9221/9254 ref Reference board 3stack D945 3stack 5stack D945 5stack + SPDIF - STAC9202/9250/9251 - ref Reference board, base config - m2-2 Some Gateway MX series laptops - m6 Some Gateway NX series laptops - STAC9227/9228/9229/927x ref Reference board 3stack D965 3stack @@ -1019,7 +974,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards. * MidiMan M Audio Revolution 5.1 * MidiMan M Audio Revolution 7.1 - * MidiMan M Audio Audiophile 192 * AMP Ltd AUDIO2000 * TerraTec Aureon 5.1 Sky * TerraTec Aureon 7.1 Space @@ -1039,7 +993,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. model - Use the given board model, one of the following: revo51, revo71, amp2000, prodigy71, prodigy71lt, - prodigy192, aureon51, aureon71, universe, ap192, + prodigy192, aureon51, aureon71, universe, k8x800, phase22, phase28, ms300, av710 This module supports multiple cards and autoprobe. @@ -1095,9 +1049,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. buggy_semaphore - Enable workaround for hardwares with buggy semaphores (e.g. on some ASUS laptops) (default off) - spdif_aclink - Use S/PDIF over AC-link instead of direct connection - from the controller chip - (0 = off, 1 = on, -1 = default) This module supports one chip and autoprobe. @@ -1420,13 +1371,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple cards. - Module snd-portman2x4 - --------------------- - - Module for Midiman Portman 2x4 parallel port MIDI interface - - This module supports multiple cards. - Module snd-powermac (on ppc only) --------------------------------- diff --git a/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl index c4d2e3507af9..1f3ae3e32d69 100644 --- a/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl +++ b/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl @@ -36,7 +36,7 @@ Management of Cards and Devices - Card Management + Card Managment !Esound/core/init.c Device Components @@ -59,7 +59,7 @@ PCM Format Helpers !Esound/core/pcm_misc.c - PCM Memory Management + PCM Memory Managment !Esound/core/pcm_memory.c diff --git a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index 74d3a35b59bc..ccd0a953953d 100644 --- a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -1360,7 +1360,8 @@ substream->runtime. This runtime pointer holds the various information; it holds the copy of hw_params and sw_params configurations, the buffer - pointers, mmap records, spinlocks, etc. Almost everything you + pointers, mmap records, spinlocks, etc. Almost everyhing you need for controlling the PCM can be found there. @@ -2339,7 +2340,7 @@ struct _snd_pcm_runtime { When the PCM substreams can be synchronized (typically, - synchronized start/stop of a playback and a capture streams), + synchorinized start/stop of a playback and a capture streams), you can give SNDRV_PCM_INFO_SYNC_START, too. In this case, you'll need to check the linked-list of PCM substreams in the trigger callback. This will be @@ -3061,7 +3062,8 @@ struct _snd_pcm_runtime { Interrupt Handler Case #1 lock); @@ -3104,7 +3106,8 @@ struct _snd_pcm_runtime { Interrupt Handler Case #2 lock); @@ -3244,7 +3247,7 @@ struct _snd_pcm_runtime { You can even define your own constraint rules. For example, let's suppose my_chip can manage a substream of 1 channel if and only if the format is S16_LE, otherwise it supports any format - specified in the snd_pcm_hardware structure (or in any + specified in the snd_pcm_hardware stucture (or in any other constraint_list). You can build a rule like this: @@ -3687,6 +3690,16 @@ struct _snd_pcm_runtime { + + Here, the chip instance is retrieved via + snd_kcontrol_chip() macro. This macro + just accesses to kcontrol->private_data. The + kcontrol->private_data field is + given as the argument of snd_ctl_new() + (see the later subsection + Constructor). + + The value field is depending on the type of control as well as on info callback. For example, @@ -3767,7 +3780,7 @@ struct _snd_pcm_runtime { Like get callback, when the control has more than one elements, - all elements must be evaluated in this callback, too. + all elemehts must be evaluated in this callback, too. @@ -5528,12 +5541,12 @@ struct _snd_pcm_runtime { #ifdef CONFIG_PM static int snd_my_suspend(struct pci_dev *pci, pm_message_t state) { - .... /* do things for suspend */ + .... /* do things for suspsend */ return 0; } static int snd_my_resume(struct pci_dev *pci) { - .... /* do things for suspend */ + .... /* do things for suspsend */ return 0; } #endif @@ -6098,7 +6111,7 @@ struct _snd_pcm_runtime { - + Acknowledgments I would like to thank Phil Kerr for his help for improvement and diff --git a/trunk/Documentation/sound/alsa/hda_codec.txt b/trunk/Documentation/sound/alsa/hda_codec.txt index 4eaae2a45534..0be57ed81302 100644 --- a/trunk/Documentation/sound/alsa/hda_codec.txt +++ b/trunk/Documentation/sound/alsa/hda_codec.txt @@ -277,11 +277,11 @@ Helper Functions snd_hda_get_codec_name() stores the codec name on the given string. snd_hda_check_board_config() can be used to obtain the configuration -information matching with the device. Define the model string table -and the table with struct snd_pci_quirk entries (zero-terminated), -and pass it to the function. The function checks the modelname given -as a module parameter, and PCI subsystem IDs. If the matching entry -is found, it returns the config field value. +information matching with the device. Define the table with struct +hda_board_config entries (zero-terminated), and pass it to the +function. The function checks the modelname given as a module +parameter, and PCI subsystem IDs. If the matching entry is found, it +returns the config field value. snd_hda_add_new_ctls() can be used to create and add control entries. Pass the zero-terminated array of struct snd_kcontrol_new. The same array diff --git a/trunk/Documentation/sound/alsa/soc/DAI.txt b/trunk/Documentation/sound/alsa/soc/DAI.txt deleted file mode 100644 index 58cbfd01ea8f..000000000000 --- a/trunk/Documentation/sound/alsa/soc/DAI.txt +++ /dev/null @@ -1,56 +0,0 @@ -ASoC currently supports the three main Digital Audio Interfaces (DAI) found on -SoC controllers and portable audio CODECS today, namely AC97, I2S and PCM. - - -AC97 -==== - - AC97 is a five wire interface commonly found on many PC sound cards. It is -now also popular in many portable devices. This DAI has a reset line and time -multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines. -The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the -frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97 -frame is 21uS long and is divided into 13 time slots. - -The AC97 specification can be found at :- -http://www.intel.com/design/chipsets/audio/ac97_r23.pdf - - -I2S -=== - - I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and -Rx lines are used for audio transmision, whilst the bit clock (BCLK) and -left/right clock (LRC) synchronise the link. I2S is flexible in that either the -controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock -usually varies depending on the sample rate and the master system clock -(SYSCLK). LRCLK is the same as the sample rate. A few devices support separate -ADC and DAC LRCLK's, this allows for similtanious capture and playback at -different sample rates. - -I2S has several different operating modes:- - - o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC - transition. - - o Left Justified - MSB is transmitted on transition of LRC. - - o Right Justified - MSB is transmitted sample size BCLK's before LRC - transition. - -PCM -=== - -PCM is another 4 wire interface, very similar to I2S, that can support a more -flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used -to synchronise the link whilst the Tx and Rx lines are used to transmit and -receive the audio data. Bit clock usually varies depending on sample rate -whilst sync runs at the sample rate. PCM also supports Time Division -Multiplexing (TDM) in that several devices can use the bus similtaniuosly (This -is sometimes referred to as network mode). - -Common PCM operating modes:- - - o Mode A - MSB is transmitted on falling edge of first BCLK after FRAME/SYNC. - - o Mode B - MSB is transmitted on rising edge of FRAME/SYNC. diff --git a/trunk/Documentation/sound/alsa/soc/clocking.txt b/trunk/Documentation/sound/alsa/soc/clocking.txt deleted file mode 100644 index e93960d53a1e..000000000000 --- a/trunk/Documentation/sound/alsa/soc/clocking.txt +++ /dev/null @@ -1,51 +0,0 @@ -Audio Clocking -============== - -This text describes the audio clocking terms in ASoC and digital audio in -general. Note: Audio clocking can be complex ! - - -Master Clock ------------- - -Every audio subsystem is driven by a master clock (sometimes refered to as MCLK -or SYSCLK). This audio master clock can be derived from a number of sources -(e.g. crystal, PLL, CPU clock) and is responsible for producing the correct -audio playback and capture sample rates. - -Some master clocks (e.g. PLL's and CPU based clocks) are configuarble in that -their speed can be altered by software (depending on the system use and to save -power). Other master clocks are fixed at at set frequency (i.e. crystals). - - -DAI Clocks ----------- -The Digital Audio Interface is usually driven by a Bit Clock (often referred to -as BCLK). This clock is used to drive the digital audio data across the link -between the codec and CPU. - -The DAI also has a frame clock to signal the start of each audio frame. This -clock is sometimes referred to as LRC (left right clock) or FRAME. This clock -runs at exactly the sample rate (LRC = Rate). - -Bit Clock can be generated as follows:- - -BCLK = MCLK / x - - or - -BCLK = LRC * x - - or - -BCLK = LRC * Channels * Word Size - -This relationship depends on the codec or SoC CPU in particular. In general -it's best to configure BCLK to the lowest possible speed (depending on your -rate, number of channels and wordsize) to save on power. - -It's also desireable to use the codec (if possible) to drive (or master) the -audio clocks as it's usually gives more accurate sample rates than the CPU. - - - diff --git a/trunk/Documentation/sound/alsa/soc/codec.txt b/trunk/Documentation/sound/alsa/soc/codec.txt deleted file mode 100644 index 48983c75aad9..000000000000 --- a/trunk/Documentation/sound/alsa/soc/codec.txt +++ /dev/null @@ -1,197 +0,0 @@ -ASoC Codec Driver -================= - -The codec driver is generic and hardware independent code that configures the -codec to provide audio capture and playback. It should contain no code that is -specific to the target platform or machine. All platform and machine specific -code should be added to the platform and machine drivers respectively. - -Each codec driver *must* provide the following features:- - - 1) Codec DAI and PCM configuration - 2) Codec control IO - using I2C, 3 Wire(SPI) or both API's - 3) Mixers and audio controls - 4) Codec audio operations - -Optionally, codec drivers can also provide:- - - 5) DAPM description. - 6) DAPM event handler. - 7) DAC Digital mute control. - -It's probably best to use this guide in conjuction with the existing codec -driver code in sound/soc/codecs/ - -ASoC Codec driver breakdown -=========================== - -1 - Codec DAI and PCM configuration ------------------------------------ -Each codec driver must have a struct snd_soc_codec_dai to define it's DAI and -PCM's capablities and operations. This struct is exported so that it can be -registered with the core by your machine driver. - -e.g. - -struct snd_soc_codec_dai wm8731_dai = { - .name = "WM8731", - /* playback capabilities */ - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8731_RATES, - .formats = WM8731_FORMATS,}, - /* capture capabilities */ - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8731_RATES, - .formats = WM8731_FORMATS,}, - /* pcm operations - see section 4 below */ - .ops = { - .prepare = wm8731_pcm_prepare, - .hw_params = wm8731_hw_params, - .shutdown = wm8731_shutdown, - }, - /* DAI operations - see DAI.txt */ - .dai_ops = { - .digital_mute = wm8731_mute, - .set_sysclk = wm8731_set_dai_sysclk, - .set_fmt = wm8731_set_dai_fmt, - } -}; -EXPORT_SYMBOL_GPL(wm8731_dai); - - -2 - Codec control IO --------------------- -The codec can ususally be controlled via an I2C or SPI style interface (AC97 -combines control with data in the DAI). The codec drivers will have to provide -functions to read and write the codec registers along with supplying a register -cache:- - - /* IO control data and register cache */ - void *control_data; /* codec control (i2c/3wire) data */ - void *reg_cache; - -Codec read/write should do any data formatting and call the hardware read write -below to perform the IO. These functions are called by the core and alsa when -performing DAPM or changing the mixer:- - - unsigned int (*read)(struct snd_soc_codec *, unsigned int); - int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); - -Codec hardware IO functions - usually points to either the I2C, SPI or AC97 -read/write:- - - hw_write_t hw_write; - hw_read_t hw_read; - - -3 - Mixers and audio controls ------------------------------ -All the codec mixers and audio controls can be defined using the convenience -macros defined in soc.h. - - #define SOC_SINGLE(xname, reg, shift, mask, invert) - -Defines a single control as follows:- - - xname = Control name e.g. "Playback Volume" - reg = codec register - shift = control bit(s) offset in register - mask = control bit size(s) e.g. mask of 7 = 3 bits - invert = the control is inverted - -Other macros include:- - - #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) - -A stereo control - - #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert) - -A stereo control spanning 2 registers - - #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) - -Defines an single enumerated control as follows:- - - xreg = register - xshift = control bit(s) offset in register - xmask = control bit(s) size - xtexts = pointer to array of strings that describe each setting - - #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) - -Defines a stereo enumerated control - - -4 - Codec Audio Operations --------------------------- -The codec driver also supports the following alsa operations:- - -/* SoC audio ops */ -struct snd_soc_ops { - int (*startup)(struct snd_pcm_substream *); - void (*shutdown)(struct snd_pcm_substream *); - int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); - int (*hw_free)(struct snd_pcm_substream *); - int (*prepare)(struct snd_pcm_substream *); -}; - -Please refer to the alsa driver PCM documentation for details. -http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c436.htm - - -5 - DAPM description. ---------------------- -The Dynamic Audio Power Management description describes the codec's power -components, their relationships and registers to the ASoC core. Please read -dapm.txt for details of building the description. - -Please also see the examples in other codec drivers. - - -6 - DAPM event handler ----------------------- -This function is a callback that handles codec domain PM calls and system -domain PM calls (e.g. suspend and resume). It's used to put the codec to sleep -when not in use. - -Power states:- - - SNDRV_CTL_POWER_D0: /* full On */ - /* vref/mid, clk and osc on, active */ - - SNDRV_CTL_POWER_D1: /* partial On */ - SNDRV_CTL_POWER_D2: /* partial On */ - - SNDRV_CTL_POWER_D3hot: /* Off, with power */ - /* everything off except vref/vmid, inactive */ - - SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */ - - -7 - Codec DAC digital mute control. ------------------------------------- -Most codecs have a digital mute before the DAC's that can be used to minimise -any system noise. The mute stops any digital data from entering the DAC. - -A callback can be created that is called by the core for each codec DAI when the -mute is applied or freed. - -i.e. - -static int wm8974_mute(struct snd_soc_codec *codec, - struct snd_soc_codec_dai *dai, int mute) -{ - u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf; - if(mute) - wm8974_write(codec, WM8974_DAC, mute_reg | 0x40); - else - wm8974_write(codec, WM8974_DAC, mute_reg); - return 0; -} diff --git a/trunk/Documentation/sound/alsa/soc/dapm.txt b/trunk/Documentation/sound/alsa/soc/dapm.txt deleted file mode 100644 index c11877f5b4a1..000000000000 --- a/trunk/Documentation/sound/alsa/soc/dapm.txt +++ /dev/null @@ -1,297 +0,0 @@ -Dynamic Audio Power Management for Portable Devices -=================================================== - -1. Description -============== - -Dynamic Audio Power Management (DAPM) is designed to allow portable Linux devices -to use the minimum amount of power within the audio subsystem at all times. It -is independent of other kernel PM and as such, can easily co-exist with the -other PM systems. - -DAPM is also completely transparent to all user space applications as all power -switching is done within the ASoC core. No code changes or recompiling are -required for user space applications. DAPM makes power switching descisions based -upon any audio stream (capture/playback) activity and audio mixer settings -within the device. - -DAPM spans the whole machine. It covers power control within the entire audio -subsystem, this includes internal codec power blocks and machine level power -systems. - -There are 4 power domains within DAPM - - 1. Codec domain - VREF, VMID (core codec and audio power) - Usually controlled at codec probe/remove and suspend/resume, although - can be set at stream time if power is not needed for sidetone, etc. - - 2. Platform/Machine domain - physically connected inputs and outputs - Is platform/machine and user action specific, is configured by the - machine driver and responds to asynchronous events e.g when HP - are inserted - - 3. Path domain - audio susbsystem signal paths - Automatically set when mixer and mux settings are changed by the user. - e.g. alsamixer, amixer. - - 4. Stream domain - DAC's and ADC's. - Enabled and disabled when stream playback/capture is started and - stopped respectively. e.g. aplay, arecord. - -All DAPM power switching descisons are made automatically by consulting an audio -routing map of the whole machine. This map is specific to each machine and -consists of the interconnections between every audio component (including -internal codec components). All audio components that effect power are called -widgets hereafter. - - -2. DAPM Widgets -=============== - -Audio DAPM widgets fall into a number of types:- - - o Mixer - Mixes several analog signals into a single analog signal. - o Mux - An analog switch that outputs only 1 of it's inputs. - o PGA - A programmable gain amplifier or attenuation widget. - o ADC - Analog to Digital Converter - o DAC - Digital to Analog Converter - o Switch - An analog switch - o Input - A codec input pin - o Output - A codec output pin - o Headphone - Headphone (and optional Jack) - o Mic - Mic (and optional Jack) - o Line - Line Input/Output (and optional Jack) - o Speaker - Speaker - o Pre - Special PRE widget (exec before all others) - o Post - Special POST widget (exec after all others) - -(Widgets are defined in include/sound/soc-dapm.h) - -Widgets are usually added in the codec driver and the machine driver. There are -convience macros defined in soc-dapm.h that can be used to quickly build a -list of widgets of the codecs and machines DAPM widgets. - -Most widgets have a name, register, shift and invert. Some widgets have extra -parameters for stream name and kcontrols. - - -2.1 Stream Domain Widgets -------------------------- - -Stream Widgets relate to the stream power domain and only consist of ADC's -(analog to digital converters) and DAC's (digital to analog converters). - -Stream widgets have the following format:- - -SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), - -NOTE: the stream name must match the corresponding stream name in your codecs -snd_soc_codec_dai. - -e.g. stream widgets for HiFi playback and capture - -SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1), -SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1), - - -2.2 Path Domain Widgets ------------------------ - -Path domain widgets have a ability to control or effect the audio signal or -audio paths within the audio subsystem. They have the following form:- - -SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls) - -Any widget kcontrols can be set using the controls and num_controls members. - -e.g. Mixer widget (the kcontrols are declared first) - -/* Output Mixer */ -static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = { -SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), -SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), -SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), -}; - -SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls, - ARRAY_SIZE(wm8731_output_mixer_controls)), - - -2.3 Platform/Machine domain Widgets ------------------------------------ - -Machine widgets are different from codec widgets in that they don't have a -codec register bit associated with them. A machine widget is assigned to each -machine audio component (non codec) that can be independently powered. e.g. - - o Speaker Amp - o Microphone Bias - o Jack connectors - -A machine widget can have an optional call back. - -e.g. Jack connector widget for an external Mic that enables Mic Bias -when the Mic is inserted:- - -static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event) -{ - if(SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS); - else - reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS); - - return 0; -} - -SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), - - -2.4 Codec Domain ----------------- - -The Codec power domain has no widgets and is handled by the codecs DAPM event -handler. This handler is called when the codec powerstate is changed wrt to any -stream event or by kernel PM events. - - -2.5 Virtual Widgets -------------------- - -Sometimes widgets exist in the codec or machine audio map that don't have any -corresponding register bit for power control. In this case it's necessary to -create a virtual widget - a widget with no control bits e.g. - -SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), - -This can be used to merge to signal paths together in software. - -After all the widgets have been defined, they can then be added to the DAPM -subsystem individually with a call to snd_soc_dapm_new_control(). - - -3. Codec Widget Interconnections -================================ - -Widgets are connected to each other within the codec and machine by audio -paths (called interconnections). Each interconnection must be defined in order -to create a map of all audio paths between widgets. -This is easiest with a diagram of the codec (and schematic of the machine audio -system), as it requires joining widgets together via their audio signal paths. - -i.e. from the WM8731 codec's output mixer (wm8731.c) - -The WM8731 output mixer has 3 inputs (sources) - - 1. Line Bypass Input - 2. DAC (HiFi playback) - 3. Mic Sidetone Input - -Each input in this example has a kcontrol associated with it (defined in example -above) and is connected to the output mixer via it's kcontrol name. We can now -connect the destination widget (wrt audio signal) with it's source widgets. - - /* output mixer */ - {"Output Mixer", "Line Bypass Switch", "Line Input"}, - {"Output Mixer", "HiFi Playback Switch", "DAC"}, - {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, - -So we have :- - - Destination Widget <=== Path Name <=== Source Widget - -Or:- - - Sink, Path, Source - -Or :- - - "Output Mixer" is connected to the "DAC" via the "HiFi Playback Switch". - -When there is no path name connecting widgets (e.g. a direct connection) we -pass NULL for the path name. - -Interconnections are created with a call to:- - -snd_soc_dapm_connect_input(codec, sink, path, source); - -Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and -interconnections have been registered with the core. This causes the core to -scan the codec and machine so that the internal DAPM state matches the -physical state of the machine. - - -3.1 Machine Widget Interconnections ------------------------------------ -Machine widget interconnections are created in the same way as codec ones and -directly connect the codec pins to machine level widgets. - -e.g. connects the speaker out codec pins to the internal speaker. - - /* ext speaker connected to codec pins LOUT2, ROUT2 */ - {"Ext Spk", NULL , "ROUT2"}, - {"Ext Spk", NULL , "LOUT2"}, - -This allows the DAPM to power on and off pins that are connected (and in use) -and pins that are NC respectively. - - -4 Endpoint Widgets -=================== -An endpoint is a start or end point (widget) of an audio signal within the -machine and includes the codec. e.g. - - o Headphone Jack - o Internal Speaker - o Internal Mic - o Mic Jack - o Codec Pins - -When a codec pin is NC it can be marked as not used with a call to - -snd_soc_dapm_set_endpoint(codec, "Widget Name", 0); - -The last argument is 0 for inactive and 1 for active. This way the pin and its -input widget will never be powered up and consume power. - -This also applies to machine widgets. e.g. if a headphone is connected to a -jack then the jack can be marked active. If the headphone is removed, then -the headphone jack can be marked inactive. - - -5 DAPM Widget Events -==================== - -Some widgets can register their interest with the DAPM core in PM events. -e.g. A Speaker with an amplifier registers a widget so the amplifier can be -powered only when the spk is in use. - -/* turn speaker amplifier on/off depending on use */ -static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); - - return 0; -} - -/* corgi machine dapm widgets */ -static const struct snd_soc_dapm_widget wm8731_dapm_widgets = - SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event); - -Please see soc-dapm.h for all other widgets that support events. - - -5.1 Event types ---------------- - -The following event types are supported by event widgets. - -/* dapm event types */ -#define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */ -#define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */ -#define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */ -#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ -#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ -#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ diff --git a/trunk/Documentation/sound/alsa/soc/machine.txt b/trunk/Documentation/sound/alsa/soc/machine.txt deleted file mode 100644 index 72bd222f2a21..000000000000 --- a/trunk/Documentation/sound/alsa/soc/machine.txt +++ /dev/null @@ -1,113 +0,0 @@ -ASoC Machine Driver -=================== - -The ASoC machine (or board) driver is the code that glues together the platform -and codec drivers. - -The machine driver can contain codec and platform specific code. It registers -the audio subsystem with the kernel as a platform device and is represented by -the following struct:- - -/* SoC machine */ -struct snd_soc_machine { - char *name; - - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - - /* the pre and post PM functions are used to do any PM work before and - * after the codec and DAI's do any PM work. */ - int (*suspend_pre)(struct platform_device *pdev, pm_message_t state); - int (*suspend_post)(struct platform_device *pdev, pm_message_t state); - int (*resume_pre)(struct platform_device *pdev); - int (*resume_post)(struct platform_device *pdev); - - /* machine stream operations */ - struct snd_soc_ops *ops; - - /* CPU <--> Codec DAI links */ - struct snd_soc_dai_link *dai_link; - int num_links; -}; - -probe()/remove() ----------------- -probe/remove are optional. Do any machine specific probe here. - - -suspend()/resume() ------------------- -The machine driver has pre and post versions of suspend and resume to take care -of any machine audio tasks that have to be done before or after the codec, DAI's -and DMA is suspended and resumed. Optional. - - -Machine operations ------------------- -The machine specific audio operations can be set here. Again this is optional. - - -Machine DAI Configuration -------------------------- -The machine DAI configuration glues all the codec and CPU DAI's together. It can -also be used to set up the DAI system clock and for any machine related DAI -initialisation e.g. the machine audio map can be connected to the codec audio -map, unconnnected codec pins can be set as such. Please see corgi.c, spitz.c -for examples. - -struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. - -/* corgi digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link corgi_dai = { - .name = "WM8731", - .stream_name = "WM8731", - .cpu_dai = &pxa_i2s_dai, - .codec_dai = &wm8731_dai, - .init = corgi_wm8731_init, - .ops = &corgi_ops, -}; - -struct snd_soc_machine then sets up the machine with it's DAI's. e.g. - -/* corgi audio machine driver */ -static struct snd_soc_machine snd_soc_machine_corgi = { - .name = "Corgi", - .dai_link = &corgi_dai, - .num_links = 1, -}; - - -Machine Audio Subsystem ------------------------ - -The machine soc device glues the platform, machine and codec driver together. -Private data can also be set here. e.g. - -/* corgi audio private data */ -static struct wm8731_setup_data corgi_wm8731_setup = { - .i2c_address = 0x1b, -}; - -/* corgi audio subsystem */ -static struct snd_soc_device corgi_snd_devdata = { - .machine = &snd_soc_machine_corgi, - .platform = &pxa2xx_soc_platform, - .codec_dev = &soc_codec_dev_wm8731, - .codec_data = &corgi_wm8731_setup, -}; - - -Machine Power Map ------------------ - -The machine driver can optionally extend the codec power map and to become an -audio power map of the audio subsystem. This allows for automatic power up/down -of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack -sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for -details. - - -Machine Controls ----------------- - -Machine specific audio mixer controls can be added in the dai init function. \ No newline at end of file diff --git a/trunk/Documentation/sound/alsa/soc/overview.txt b/trunk/Documentation/sound/alsa/soc/overview.txt deleted file mode 100644 index 753c5cc5984a..000000000000 --- a/trunk/Documentation/sound/alsa/soc/overview.txt +++ /dev/null @@ -1,83 +0,0 @@ -ALSA SoC Layer -============== - -The overall project goal of the ALSA System on Chip (ASoC) layer is to provide -better ALSA support for embedded system on chip procesors (e.g. pxa2xx, au1x00, -iMX, etc) and portable audio codecs. Currently there is some support in the -kernel for SoC audio, however it has some limitations:- - - * Currently, codec drivers are often tightly coupled to the underlying SoC - cpu. This is not ideal and leads to code duplication i.e. Linux now has 4 - different wm8731 drivers for 4 different SoC platforms. - - * There is no standard method to signal user initiated audio events. - e.g. Headphone/Mic insertion, Headphone/Mic detection after an insertion - event. These are quite common events on portable devices and ofter require - machine specific code to re route audio, enable amps etc after such an event. - - * Current drivers tend to power up the entire codec when playing - (or recording) audio. This is fine for a PC, but tends to waste a lot of - power on portable devices. There is also no support for saving power via - changing codec oversampling rates, bias currents, etc. - - -ASoC Design -=========== - -The ASoC layer is designed to address these issues and provide the following -features :- - - * Codec independence. Allows reuse of codec drivers on other platforms - and machines. - - * Easy I2S/PCM audio interface setup between codec and SoC. Each SoC interface - and codec registers it's audio interface capabilities with the core and are - subsequently matched and configured when the application hw params are known. - - * Dynamic Audio Power Management (DAPM). DAPM automatically sets the codec to - it's minimum power state at all times. This includes powering up/down - internal power blocks depending on the internal codec audio routing and any - active streams. - - * Pop and click reduction. Pops and clicks can be reduced by powering the - codec up/down in the correct sequence (including using digital mute). ASoC - signals the codec when to change power states. - - * Machine specific controls: Allow machines to add controls to the sound card - e.g. volume control for speaker amp. - -To achieve all this, ASoC basically splits an embedded audio system into 3 -components :- - - * Codec driver: The codec driver is platform independent and contains audio - controls, audio interface capabilities, codec dapm definition and codec IO - functions. - - * Platform driver: The platform driver contains the audio dma engine and audio - interface drivers (e.g. I2S, AC97, PCM) for that platform. - - * Machine driver: The machine driver handles any machine specific controls and - audio events. i.e. turing on an amp at start of playback. - - -Documentation -============= - -The documentation is spilt into the following sections:- - -overview.txt: This file. - -codec.txt: Codec driver internals. - -DAI.txt: Description of Digital Audio Interface standards and how to configure -a DAI within your codec and CPU DAI drivers. - -dapm.txt: Dynamic Audio Power Management - -platform.txt: Platform audio DMA and DAI. - -machine.txt: Machine driver internals. - -pop_clicks.txt: How to minimise audio artifacts. - -clocking.txt: ASoC clocking for best power performance. \ No newline at end of file diff --git a/trunk/Documentation/sound/alsa/soc/platform.txt b/trunk/Documentation/sound/alsa/soc/platform.txt deleted file mode 100644 index e95b16d5a53b..000000000000 --- a/trunk/Documentation/sound/alsa/soc/platform.txt +++ /dev/null @@ -1,58 +0,0 @@ -ASoC Platform Driver -==================== - -An ASoC platform driver can be divided into audio DMA and SoC DAI configuration -and control. The platform drivers only target the SoC CPU and must have no board -specific code. - -Audio DMA -========= - -The platform DMA driver optionally supports the following alsa operations:- - -/* SoC audio ops */ -struct snd_soc_ops { - int (*startup)(struct snd_pcm_substream *); - void (*shutdown)(struct snd_pcm_substream *); - int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); - int (*hw_free)(struct snd_pcm_substream *); - int (*prepare)(struct snd_pcm_substream *); - int (*trigger)(struct snd_pcm_substream *, int); -}; - -The platform driver exports it's DMA functionailty via struct snd_soc_platform:- - -struct snd_soc_platform { - char *name; - - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - int (*suspend)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai); - int (*resume)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai); - - /* pcm creation and destruction */ - int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *); - void (*pcm_free)(struct snd_pcm *); - - /* platform stream ops */ - struct snd_pcm_ops *pcm_ops; -}; - -Please refer to the alsa driver documentation for details of audio DMA. -http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c436.htm - -An example DMA driver is soc/pxa/pxa2xx-pcm.c - - -SoC DAI Drivers -=============== - -Each SoC DAI driver must provide the following features:- - - 1) Digital audio interface (DAI) description - 2) Digital audio interface configuration - 3) PCM's description - 4) Sysclk configuration - 5) Suspend and resume (optional) - -Please see codec.txt for a description of items 1 - 4. diff --git a/trunk/Documentation/sound/alsa/soc/pops_clicks.txt b/trunk/Documentation/sound/alsa/soc/pops_clicks.txt deleted file mode 100644 index 2cf7ee5b3d74..000000000000 --- a/trunk/Documentation/sound/alsa/soc/pops_clicks.txt +++ /dev/null @@ -1,52 +0,0 @@ -Audio Pops and Clicks -===================== - -Pops and clicks are unwanted audio artifacts caused by the powering up and down -of components within the audio subsystem. This is noticable on PC's when an -audio module is either loaded or unloaded (at module load time the sound card is -powered up and causes a popping noise on the speakers). - -Pops and clicks can be more frequent on portable systems with DAPM. This is -because the components within the subsystem are being dynamically powered -depending on the audio usage and this can subsequently cause a small pop or -click every time a component power state is changed. - - -Minimising Playback Pops and Clicks -=================================== - -Playback pops in portable audio subsystems cannot be completely eliminated atm, -however future audio codec hardware will have better pop and click supression. -Pops can be reduced within playback by powering the audio components in a -specific order. This order is different for startup and shutdown and follows -some basic rules:- - - Startup Order :- DAC --> Mixers --> Output PGA --> Digital Unmute - - Shutdown Order :- Digital Mute --> Output PGA --> Mixers --> DAC - -This assumes that the codec PCM output path from the DAC is via a mixer and then -a PGA (programmable gain amplifier) before being output to the speakers. - - -Minimising Capture Pops and Clicks -================================== - -Capture artifacts are somewhat easier to get rid as we can delay activating the -ADC until all the pops have occured. This follows similar power rules to -playback in that components are powered in a sequence depending upon stream -startup or shutdown. - - Startup Order - Input PGA --> Mixers --> ADC - - Shutdown Order - ADC --> Mixers --> Input PGA - - -Zipper Noise -============ -An unwanted zipper noise can occur within the audio playback or capture stream -when a volume control is changed near its maximum gain value. The zipper noise -is heard when the gain increase or decrease changes the mean audio signal -amplitude too quickly. It can be minimised by enabling the zero cross setting -for each volume control. The ZC forces the gain change to occur when the signal -crosses the zero amplitude line. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index a6c1ebd18d0f..fe35f3ac4cd3 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1114,7 +1114,7 @@ S: Supported DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER P: Tobias Ringstrom M: tori@unhappy.mine.nu -L: netdev@vger.kernel.org +L: linux-kernel@vger.kernel.org S: Maintained DOCBOOK FOR DOCUMENTATION @@ -2361,7 +2361,7 @@ S: Maintained NETWORKING [WIRELESS] P: John W. Linville M: linville@tuxdriver.com -L: linux-wireless@vger.kernel.org +L: netdev@vger.kernel.org T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git S: Maintained @@ -3037,12 +3037,6 @@ M: perex@suse.cz L: alsa-devel@alsa-project.org S: Maintained -SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT -P: Liam Girdwood -M: liam.girdwood@wolfsonmicro.com -L: alsa-devel@alsa-project.org -S: Supported - SPI SUBSYSTEM P: David Brownell M: dbrownell@users.sourceforge.net @@ -3293,11 +3287,6 @@ L: vtun@office.satix.net W: http://vtun.sourceforge.net/tun S: Maintained -TURBOCHANNEL SUBSYSTEM -P: Maciej W. Rozycki -M: macro@linux-mips.org -S: Maintained - U14-34F SCSI DRIVER P: Dario Ballabio M: ballabio_dario@emc.com diff --git a/trunk/arch/avr32/boards/atstk1000/Makefile b/trunk/arch/avr32/boards/atstk1000/Makefile index 8e0992201bb9..df9499480530 100644 --- a/trunk/arch/avr32/boards/atstk1000/Makefile +++ b/trunk/arch/avr32/boards/atstk1000/Makefile @@ -1,2 +1,2 @@ -obj-y += setup.o flash.o +obj-y += setup.o spi.o flash.o obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o diff --git a/trunk/arch/avr32/boards/atstk1000/atstk1002.c b/trunk/arch/avr32/boards/atstk1000/atstk1002.c index d47e39f0e971..32b361f31c2c 100644 --- a/trunk/arch/avr32/boards/atstk1000/atstk1002.c +++ b/trunk/arch/avr32/boards/atstk1000/atstk1002.c @@ -8,24 +8,17 @@ * published by the Free Software Foundation. */ #include -#include #include #include #include #include #include #include -#include #include #include -#include #include #include -#include - - -#define SW2_DEFAULT /* MMCI and UART_A available */ struct eth_addr { u8 addr[6]; @@ -36,16 +29,6 @@ static struct eth_addr __initdata hw_addr[2]; static struct eth_platform_data __initdata eth_data[2]; extern struct lcdc_platform_data atstk1000_fb0_data; -static struct spi_board_info spi_board_info[] __initdata = { - { - .modalias = "ltv350qv", - .controller_data = (void *)GPIO_PIN_PA(4), - .max_speed_hz = 16000000, - .bus_num = 0, - .chip_select = 1, - }, -}; - /* * The next two functions should go away as the boot loader is * supposed to initialize the macb address registers with a valid @@ -103,53 +86,23 @@ static void __init set_hw_addr(struct platform_device *pdev) void __init setup_board(void) { -#ifdef SW2_DEFAULT - at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */ -#else - at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */ -#endif - /* USART 2/unused: expansion connector */ - at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */ + at32_map_usart(1, 0); /* /dev/ttyS0 */ + at32_map_usart(2, 1); /* /dev/ttyS1 */ + at32_map_usart(3, 2); /* /dev/ttyS2 */ at32_setup_serial_console(0); } static int __init atstk1002_init(void) { - /* - * ATSTK1000 uses 32-bit SDRAM interface. Reserve the - * SDRAM-specific pins so that nobody messes with them. - */ - at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */ - at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */ - at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */ - at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */ - at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */ - at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */ - at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */ - at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */ - at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */ - at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */ - at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */ - at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */ - at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */ - at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */ - at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */ - at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */ - at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */ - at32_add_system_devices(); -#ifdef SW2_DEFAULT at32_add_device_usart(0); -#else at32_add_device_usart(1); -#endif at32_add_device_usart(2); set_hw_addr(at32_add_device_eth(0, ð_data[0])); - spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); at32_add_device_spi(0); at32_add_device_lcdc(0, &atstk1000_fb0_data); diff --git a/trunk/arch/avr32/boards/atstk1000/spi.c b/trunk/arch/avr32/boards/atstk1000/spi.c new file mode 100644 index 000000000000..567726c82c6e --- /dev/null +++ b/trunk/arch/avr32/boards/atstk1000/spi.c @@ -0,0 +1,27 @@ +/* + * ATSTK1000 SPI devices + * + * Copyright (C) 2005 Atmel Norway + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include + +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "ltv350qv", + .max_speed_hz = 16000000, + .bus_num = 0, + .chip_select = 1, + }, +}; + +static int board_init_spi(void) +{ + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); + return 0; +} +arch_initcall(board_init_spi); diff --git a/trunk/arch/avr32/kernel/cpu.c b/trunk/arch/avr32/kernel/cpu.c index 2e72fd2699df..342452ba2049 100644 --- a/trunk/arch/avr32/kernel/cpu.c +++ b/trunk/arch/avr32/kernel/cpu.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/avr32/kernel/irq.c b/trunk/arch/avr32/kernel/irq.c index fd311248c143..856f3548e664 100644 --- a/trunk/arch/avr32/kernel/irq.c +++ b/trunk/arch/avr32/kernel/irq.c @@ -57,7 +57,6 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%3d: ", i); for_each_online_cpu(cpu) seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); - seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-"); seq_printf(p, " %s", action->name); for (action = action->next; action; action = action->next) seq_printf(p, ", %s", action->name); diff --git a/trunk/arch/avr32/kernel/setup.c b/trunk/arch/avr32/kernel/setup.c index c6734aefb559..a34211601008 100644 --- a/trunk/arch/avr32/kernel/setup.c +++ b/trunk/arch/avr32/kernel/setup.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -175,7 +174,8 @@ static int __init parse_tag_mem_range(struct tag *tag, * Copy the data so the bootmem init code doesn't need to care * about it. */ - if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache)) + if (mem_range_next_free >= + (sizeof(mem_range_cache) / sizeof(mem_range_cache[0]))) panic("Physical memory map too complex!\n"); new = &mem_range_cache[mem_range_next_free++]; diff --git a/trunk/arch/avr32/lib/libgcc.h b/trunk/arch/avr32/lib/libgcc.h new file mode 100644 index 000000000000..5a091b5e3618 --- /dev/null +++ b/trunk/arch/avr32/lib/libgcc.h @@ -0,0 +1,33 @@ +/* Definitions for various functions 'borrowed' from gcc-3.4.3 */ + +#define BITS_PER_UNIT 8 + +typedef int QItype __attribute__ ((mode (QI))); +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +typedef float SFtype __attribute__ ((mode (SF))); +typedef float DFtype __attribute__ ((mode (DF))); +typedef int word_type __attribute__ ((mode (__word__))); + +#define W_TYPE_SIZE (4 * BITS_PER_UNIT) +#define Wtype SItype +#define UWtype USItype +#define HWtype SItype +#define UHWtype USItype +#define DWtype DItype +#define UDWtype UDItype +#define __NW(a,b) __ ## a ## si ## b +#define __NDW(a,b) __ ## a ## di ## b + +struct DWstruct {Wtype high, low;}; + +typedef union +{ + struct DWstruct s; + DWtype ll; +} DWunion; diff --git a/trunk/arch/avr32/lib/longlong.h b/trunk/arch/avr32/lib/longlong.h new file mode 100644 index 000000000000..cd5e369ac437 --- /dev/null +++ b/trunk/arch/avr32/lib/longlong.h @@ -0,0 +1,98 @@ +/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. + + This definition file is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2, or (at your option) any later version. + + This definition file is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Borrowed from gcc-3.4.3 */ + +#define __BITS4 (W_TYPE_SIZE / 4) +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) + +#define count_leading_zeros(count, x) ((count) = __builtin_clz(x)) + +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + UWtype __d1, __d0, __q1, __q0; \ + UWtype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (UWtype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (UWtype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (UWtype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +#define udiv_qrnnd __udiv_qrnnd_c + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - (__x > (al)); \ + (sl) = __x; \ + } while (0) + +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __x0, __x1, __x2, __x3; \ + UHWtype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (UWtype) __ul * __vl; \ + __x1 = (UWtype) __ul * __vh; \ + __x2 = (UWtype) __uh * __vl; \ + __x3 = (UWtype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) diff --git a/trunk/arch/avr32/mach-at32ap/Makefile b/trunk/arch/avr32/mach-at32ap/Makefile index b21bea9af8b1..f62eb6915510 100644 --- a/trunk/arch/avr32/mach-at32ap/Makefile +++ b/trunk/arch/avr32/mach-at32ap/Makefile @@ -1,2 +1,2 @@ -obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o +obj-y += at32ap.o clock.o pio.o intc.o extint.o hsmc.o obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o diff --git a/trunk/arch/avr32/mach-at32ap/at32ap7000.c b/trunk/arch/avr32/mach-at32ap/at32ap7000.c index c1e477ec7576..48f4ef38c70e 100644 --- a/trunk/arch/avr32/mach-at32ap/at32ap7000.c +++ b/trunk/arch/avr32/mach-at32ap/at32ap7000.c @@ -496,16 +496,9 @@ static struct resource pio3_resource[] = { DEFINE_DEV(pio, 3); DEV_CLK(mck, pio3, pba, 13); -static struct resource pio4_resource[] = { - PBMEM(0xffe03800), - IRQ(17), -}; -DEFINE_DEV(pio, 4); -DEV_CLK(mck, pio4, pba, 14); - void __init at32_add_system_devices(void) { - system_manager.eim_first_irq = EIM_IRQ_BASE; + system_manager.eim_first_irq = NR_INTERNAL_IRQS; platform_device_register(&at32_sm_device); platform_device_register(&at32_intc0_device); @@ -516,7 +509,6 @@ void __init at32_add_system_devices(void) platform_device_register(&pio1_device); platform_device_register(&pio2_device); platform_device_register(&pio3_device); - platform_device_register(&pio4_device); } /* -------------------------------------------------------------------- @@ -529,7 +521,7 @@ static struct atmel_uart_data atmel_usart0_data = { }; static struct resource atmel_usart0_resource[] = { PBMEM(0xffe00c00), - IRQ(6), + IRQ(7), }; DEFINE_DEV_DATA(atmel_usart, 0); DEV_CLK(usart, atmel_usart0, pba, 4); @@ -591,7 +583,7 @@ static inline void configure_usart3_pins(void) select_peripheral(PB(17), PERIPH_B, 0); /* TXD */ } -static struct platform_device *__initdata at32_usarts[4]; +static struct platform_device *at32_usarts[4]; void __init at32_map_usart(unsigned int hw_id, unsigned int line) { @@ -736,19 +728,12 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) /* -------------------------------------------------------------------- * SPI * -------------------------------------------------------------------- */ -static struct resource atmel_spi0_resource[] = { +static struct resource spi0_resource[] = { PBMEM(0xffe00000), IRQ(3), }; -DEFINE_DEV(atmel_spi, 0); -DEV_CLK(spi_clk, atmel_spi0, pba, 0); - -static struct resource atmel_spi1_resource[] = { - PBMEM(0xffe00400), - IRQ(4), -}; -DEFINE_DEV(atmel_spi, 1); -DEV_CLK(spi_clk, atmel_spi1, pba, 1); +DEFINE_DEV(spi, 0); +DEV_CLK(mck, spi0, pba, 0); struct platform_device *__init at32_add_device_spi(unsigned int id) { @@ -756,33 +741,13 @@ struct platform_device *__init at32_add_device_spi(unsigned int id) switch (id) { case 0: - pdev = &atmel_spi0_device; + pdev = &spi0_device; select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ - - /* NPCS[2:0] */ - at32_select_gpio(GPIO_PIN_PA(3), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(GPIO_PIN_PA(4), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(GPIO_PIN_PA(5), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - break; - - case 1: - pdev = &atmel_spi1_device; - select_peripheral(PB(0), PERIPH_B, 0); /* MISO */ - select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ - select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ - - /* NPCS[2:0] */ - at32_select_gpio(GPIO_PIN_PB(2), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(GPIO_PIN_PB(3), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(GPIO_PIN_PB(4), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); + select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */ + select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */ + select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */ break; default: @@ -895,7 +860,6 @@ struct clk *at32_clock_list[] = { &pio1_mck, &pio2_mck, &pio3_mck, - &pio4_mck, &atmel_usart0_usart, &atmel_usart1_usart, &atmel_usart2_usart, @@ -904,8 +868,7 @@ struct clk *at32_clock_list[] = { &macb0_pclk, &macb1_hclk, &macb1_pclk, - &atmel_spi0_spi_clk, - &atmel_spi1_spi_clk, + &spi0_mck, &lcdc0_hclk, &lcdc0_pixclk, }; @@ -917,7 +880,6 @@ void __init at32_portmux_init(void) at32_init_pio(&pio1_device); at32_init_pio(&pio2_device); at32_init_pio(&pio3_device); - at32_init_pio(&pio4_device); } void __init at32_clock_init(void) diff --git a/trunk/arch/avr32/mach-at32ap/extint.c b/trunk/arch/avr32/mach-at32ap/extint.c index 4a60eccfebd2..b59272e81b9a 100644 --- a/trunk/arch/avr32/mach-at32ap/extint.c +++ b/trunk/arch/avr32/mach-at32ap/extint.c @@ -55,11 +55,20 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) unsigned long flags; int ret = 0; - flow_type &= IRQ_TYPE_SENSE_MASK; if (flow_type == IRQ_TYPE_NONE) flow_type = IRQ_TYPE_LEVEL_LOW; desc = &irq_desc[irq]; + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + + if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { + desc->status |= IRQ_LEVEL; + set_irq_handler(irq, handle_level_irq); + } else { + set_irq_handler(irq, handle_edge_irq); + } + spin_lock_irqsave(&sm->lock, flags); mode = sm_readl(sm, EIM_MODE); @@ -88,16 +97,9 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) break; } - if (ret == 0) { - sm_writel(sm, EIM_MODE, mode); - sm_writel(sm, EIM_EDGE, edge); - sm_writel(sm, EIM_LEVEL, level); - - if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) - flow_type |= IRQ_LEVEL; - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); - desc->status |= flow_type; - } + sm_writel(sm, EIM_MODE, mode); + sm_writel(sm, EIM_EDGE, edge); + sm_writel(sm, EIM_LEVEL, level); spin_unlock_irqrestore(&sm->lock, flags); @@ -120,6 +122,8 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) unsigned long status, pending; unsigned int i, ext_irq; + spin_lock(&sm->lock); + status = sm_readl(sm, EIM_ISR); pending = status & sm_readl(sm, EIM_IMR); @@ -129,11 +133,10 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) ext_irq = i + sm->eim_first_irq; ext_desc = irq_desc + ext_irq; - if (ext_desc->status & IRQ_LEVEL) - handle_level_irq(ext_irq, ext_desc); - else - handle_edge_irq(ext_irq, ext_desc); + ext_desc->handle_irq(ext_irq, ext_desc); } + + spin_unlock(&sm->lock); } static int __init eim_init(void) @@ -165,9 +168,8 @@ static int __init eim_init(void) sm->eim_chip = &eim_chip; for (i = 0; i < nr_irqs; i++) { - /* NOTE the handler we set here is ignored by the demux */ set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip, - handle_level_irq); + handle_edge_irq); set_irq_chip_data(sm->eim_first_irq + i, sm); } diff --git a/trunk/arch/avr32/mach-at32ap/pio.c b/trunk/arch/avr32/mach-at32ap/pio.c index 9ba5654cde11..f1280ed8ed6d 100644 --- a/trunk/arch/avr32/mach-at32ap/pio.c +++ b/trunk/arch/avr32/mach-at32ap/pio.c @@ -12,9 +12,7 @@ #include #include #include -#include -#include #include #include @@ -28,8 +26,7 @@ struct pio_device { const struct platform_device *pdev; struct clk *clk; u32 pinmux_mask; - u32 gpio_mask; - char name[8]; + char name[32]; }; static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; @@ -79,9 +76,6 @@ void __init at32_select_periph(unsigned int pin, unsigned int periph, if (!(flags & AT32_GPIOF_PULLUP)) pio_writel(pio, PUDR, mask); - /* gpio_request NOT allowed */ - set_bit(pin_index, &pio->gpio_mask); - return; fail: @@ -105,52 +99,19 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags) goto fail; } - if (flags & AT32_GPIOF_OUTPUT) { - if (flags & AT32_GPIOF_HIGH) - pio_writel(pio, SODR, mask); - else - pio_writel(pio, CODR, mask); - pio_writel(pio, PUDR, mask); + pio_writel(pio, PUER, mask); + if (flags & AT32_GPIOF_HIGH) + pio_writel(pio, SODR, mask); + else + pio_writel(pio, CODR, mask); + if (flags & AT32_GPIOF_OUTPUT) pio_writel(pio, OER, mask); - } else { - if (flags & AT32_GPIOF_PULLUP) - pio_writel(pio, PUER, mask); - else - pio_writel(pio, PUDR, mask); - if (flags & AT32_GPIOF_DEGLITCH) - pio_writel(pio, IFER, mask); - else - pio_writel(pio, IFDR, mask); + else pio_writel(pio, ODR, mask); - } pio_writel(pio, PER, mask); - - /* gpio_request now allowed */ - clear_bit(pin_index, &pio->gpio_mask); - - return; - -fail: - dump_stack(); -} - -/* Reserve a pin, preventing anyone else from changing its configuration. */ -void __init at32_reserve_pin(unsigned int pin) -{ - struct pio_device *pio; - unsigned int pin_index = pin & 0x1f; - - pio = gpio_to_pio(pin); - if (unlikely(!pio)) { - printk("pio: invalid pin %u\n", pin); - goto fail; - } - - if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { - printk("%s: pin %u is busy\n", pio->name, pin_index); - goto fail; - } + if (!(flags & AT32_GPIOF_PULLUP)) + pio_writel(pio, PUDR, mask); return; @@ -158,197 +119,20 @@ void __init at32_reserve_pin(unsigned int pin) dump_stack(); } -/*--------------------------------------------------------------------------*/ - -/* GPIO API */ - -int gpio_request(unsigned int gpio, const char *label) -{ - struct pio_device *pio; - unsigned int pin; - - pio = gpio_to_pio(gpio); - if (!pio) - return -ENODEV; - - pin = gpio & 0x1f; - if (test_and_set_bit(pin, &pio->gpio_mask)) - return -EBUSY; - - return 0; -} -EXPORT_SYMBOL(gpio_request); - -void gpio_free(unsigned int gpio) -{ - struct pio_device *pio; - unsigned int pin; - - pio = gpio_to_pio(gpio); - if (!pio) { - printk(KERN_ERR - "gpio: attempted to free invalid pin %u\n", gpio); - return; - } - - pin = gpio & 0x1f; - if (!test_and_clear_bit(pin, &pio->gpio_mask)) - printk(KERN_ERR "gpio: freeing free or non-gpio pin %s-%u\n", - pio->name, pin); -} -EXPORT_SYMBOL(gpio_free); - -int gpio_direction_input(unsigned int gpio) -{ - struct pio_device *pio; - unsigned int pin; - - pio = gpio_to_pio(gpio); - if (!pio) - return -ENODEV; - - pin = gpio & 0x1f; - pio_writel(pio, ODR, 1 << pin); - - return 0; -} -EXPORT_SYMBOL(gpio_direction_input); - -int gpio_direction_output(unsigned int gpio) -{ - struct pio_device *pio; - unsigned int pin; - - pio = gpio_to_pio(gpio); - if (!pio) - return -ENODEV; - - pin = gpio & 0x1f; - pio_writel(pio, OER, 1 << pin); - - return 0; -} -EXPORT_SYMBOL(gpio_direction_output); - -int gpio_get_value(unsigned int gpio) -{ - struct pio_device *pio = &pio_dev[gpio >> 5]; - - return (pio_readl(pio, PDSR) >> (gpio & 0x1f)) & 1; -} -EXPORT_SYMBOL(gpio_get_value); - -void gpio_set_value(unsigned int gpio, int value) -{ - struct pio_device *pio = &pio_dev[gpio >> 5]; - u32 mask; - - mask = 1 << (gpio & 0x1f); - if (value) - pio_writel(pio, SODR, mask); - else - pio_writel(pio, CODR, mask); -} -EXPORT_SYMBOL(gpio_set_value); - -/*--------------------------------------------------------------------------*/ - -/* GPIO IRQ support */ - -static void gpio_irq_mask(unsigned irq) -{ - unsigned gpio = irq_to_gpio(irq); - struct pio_device *pio = &pio_dev[gpio >> 5]; - - pio_writel(pio, IDR, 1 << (gpio & 0x1f)); -} - -static void gpio_irq_unmask(unsigned irq) -{ - unsigned gpio = irq_to_gpio(irq); - struct pio_device *pio = &pio_dev[gpio >> 5]; - - pio_writel(pio, IER, 1 << (gpio & 0x1f)); -} - -static int gpio_irq_type(unsigned irq, unsigned type) -{ - if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE) - return -EINVAL; - - return 0; -} - -static struct irq_chip gpio_irqchip = { - .name = "gpio", - .mask = gpio_irq_mask, - .unmask = gpio_irq_unmask, - .set_type = gpio_irq_type, -}; - -static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) -{ - struct pio_device *pio = get_irq_chip_data(irq); - unsigned gpio_irq; - - gpio_irq = (unsigned) get_irq_data(irq); - for (;;) { - u32 isr; - struct irq_desc *d; - - /* ack pending GPIO interrupts */ - isr = pio_readl(pio, ISR) & pio_readl(pio, IMR); - if (!isr) - break; - do { - int i; - - i = ffs(isr) - 1; - isr &= ~(1 << i); - - i += gpio_irq; - d = &irq_desc[i]; - - d->handle_irq(i, d); - } while (isr); - } -} - -static void __init -gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq) -{ - unsigned i; - - set_irq_chip_data(irq, pio); - set_irq_data(irq, (void *) gpio_irq); - - for (i = 0; i < 32; i++, gpio_irq++) { - set_irq_chip_data(gpio_irq, pio); - set_irq_chip_and_handler(gpio_irq, &gpio_irqchip, - handle_simple_irq); - } - - set_irq_chained_handler(irq, gpio_irq_handler); -} - -/*--------------------------------------------------------------------------*/ - static int __init pio_probe(struct platform_device *pdev) { struct pio_device *pio = NULL; - int irq = platform_get_irq(pdev, 0); - int gpio_irq_base = GPIO_IRQ_BASE + pdev->id * 32; BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES); pio = &pio_dev[pdev->id]; BUG_ON(!pio->regs); - gpio_irq_setup(pio, irq, gpio_irq_base); + /* TODO: Interrupts */ platform_set_drvdata(pdev, pio); - printk(KERN_DEBUG "%s: base 0x%p, irq %d chains %d..%d\n", - pio->name, pio->regs, irq, gpio_irq_base, gpio_irq_base + 31); + printk(KERN_INFO "%s: Atmel Port Multiplexer at 0x%p (irq %d)\n", + pio->name, pio->regs, platform_get_irq(pdev, 0)); return 0; } @@ -364,7 +148,7 @@ static int __init pio_init(void) { return platform_driver_register(&pio_driver); } -postcore_initcall(pio_init); +subsys_initcall(pio_init); void __init at32_init_pio(struct platform_device *pdev) { @@ -400,13 +184,6 @@ void __init at32_init_pio(struct platform_device *pdev) pio->pdev = pdev; pio->regs = ioremap(regs->start, regs->end - regs->start + 1); - /* - * request_gpio() is only valid for pins that have been - * explicitly configured as GPIO and not previously requested - */ - pio->gpio_mask = ~0UL; - - /* start with irqs disabled and acked */ - pio_writel(pio, IDR, ~0UL); - (void) pio_readl(pio, ISR); + pio_writel(pio, ODR, ~0UL); + pio_writel(pio, PER, ~0UL); } diff --git a/trunk/arch/avr32/mm/cache.c b/trunk/arch/avr32/mm/cache.c index fb13f72e9a02..450515b245a0 100644 --- a/trunk/arch/avr32/mm/cache.c +++ b/trunk/arch/avr32/mm/cache.c @@ -22,34 +22,18 @@ void invalidate_dcache_region(void *start, size_t size) { - unsigned long v, begin, end, linesz, mask; - int flush = 0; + unsigned long v, begin, end, linesz; linesz = boot_cpu_data.dcache.linesz; - mask = linesz - 1; - - /* when first and/or last cachelines are shared, flush them - * instead of invalidating ... never discard valid data! - */ - begin = (unsigned long)start; - end = begin + size - 1; - - if (begin & mask) { - flush_dcache_line(start); - begin += linesz; - flush = 1; - } - if ((end & mask) != mask) { - flush_dcache_line((void *)end); - end -= linesz; - flush = 1; - } - /* remaining cachelines only need invalidation */ - for (v = begin; v <= end; v += linesz) + //printk("invalidate dcache: %p + %u\n", start, size); + + /* You asked for it, you got it */ + begin = (unsigned long)start & ~(linesz - 1); + end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); + + for (v = begin; v < end; v += linesz) invalidate_dcache_line((void *)v); - if (flush) - flush_write_buffer(); } void clean_dcache_region(void *start, size_t size) diff --git a/trunk/arch/i386/kernel/hpet.c b/trunk/arch/i386/kernel/hpet.c index 0b29d41322a2..45a8685bb60b 100644 --- a/trunk/arch/i386/kernel/hpet.c +++ b/trunk/arch/i386/kernel/hpet.c @@ -12,7 +12,7 @@ /* FSEC = 10^-15 NSEC = 10^-9 */ #define FSEC_PER_NSEC 1000000 -static void __iomem *hpet_ptr; +static void *hpet_ptr; static cycle_t read_hpet(void) { @@ -40,7 +40,8 @@ static int __init init_hpet_clocksource(void) return -ENODEV; /* calculate the hpet address: */ - hpet_base = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); + hpet_base = + (void __iomem*)ioremap_nocache(hpet_address, HPET_MMAP_SIZE); hpet_ptr = hpet_base + HPET_COUNTER; /* calculate the frequency: */ diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index ba8d302a0b72..5592fa6e1fa1 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -126,7 +126,7 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i */ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) { - volatile struct io_apic __iomem *io_apic = io_apic_base(apic); + volatile struct io_apic *io_apic = io_apic_base(apic); if (sis_apic_bug) writel(reg, &io_apic->index); writel(value, &io_apic->data); diff --git a/trunk/arch/i386/kernel/sysenter.c b/trunk/arch/i386/kernel/sysenter.c index bc882a2b1db6..5da744204d10 100644 --- a/trunk/arch/i386/kernel/sysenter.c +++ b/trunk/arch/i386/kernel/sysenter.c @@ -70,12 +70,11 @@ void enable_sep_cpu(void) */ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; -static struct page *syscall_pages[1]; +static void *syscall_page; int __init sysenter_setup(void) { - void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); - syscall_pages[0] = virt_to_page(syscall_page); + syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); #ifdef CONFIG_COMPAT_VDSO __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); @@ -97,12 +96,31 @@ int __init sysenter_setup(void) } #ifndef CONFIG_COMPAT_VDSO +static struct page *syscall_nopage(struct vm_area_struct *vma, + unsigned long adr, int *type) +{ + struct page *p = virt_to_page(adr - vma->vm_start + syscall_page); + get_page(p); + return p; +} + +/* Prevent VMA merging */ +static void syscall_vma_close(struct vm_area_struct *vma) +{ +} + +static struct vm_operations_struct syscall_vm_ops = { + .close = syscall_vma_close, + .nopage = syscall_nopage, +}; + /* Defined in vsyscall-sysenter.S */ extern void SYSENTER_RETURN; /* Setup a VMA at program startup for the vsyscall page */ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) { + struct vm_area_struct *vma; struct mm_struct *mm = current->mm; unsigned long addr; int ret; @@ -114,25 +132,38 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) goto up_fail; } + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); + if (!vma) { + ret = -ENOMEM; + goto up_fail; + } + + vma->vm_start = addr; + vma->vm_end = addr + PAGE_SIZE; + /* MAYWRITE to allow gdb to COW and set breakpoints */ + vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; /* - * MAYWRITE to allow gdb to COW and set breakpoints - * * Make sure the vDSO gets into every core dump. * Dumping its contents makes post-mortem fully interpretable later * without matching up the same kernel and hardware config to see * what PC values meant. */ - ret = install_special_mapping(mm, addr, PAGE_SIZE, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| - VM_ALWAYSDUMP, - syscall_pages); - if (ret) + vma->vm_flags |= VM_ALWAYSDUMP; + vma->vm_flags |= mm->def_flags; + vma->vm_page_prot = protection_map[vma->vm_flags & 7]; + vma->vm_ops = &syscall_vm_ops; + vma->vm_mm = mm; + + ret = insert_vm_struct(mm, vma); + if (unlikely(ret)) { + kmem_cache_free(vm_area_cachep, vma); goto up_fail; + } current->mm->context.vdso = (void *)addr; current_thread_info()->sysenter_return = (void *)VDSO_SYM(&SYSENTER_RETURN); + mm->total_vm++; up_fail: up_write(&mm->mmap_sem); return ret; diff --git a/trunk/arch/i386/mm/pageattr.c b/trunk/arch/i386/mm/pageattr.c index e223b1d4981c..ad91528bdc14 100644 --- a/trunk/arch/i386/mm/pageattr.c +++ b/trunk/arch/i386/mm/pageattr.c @@ -224,7 +224,7 @@ void global_flush_tlb(void) list_replace_init(&df_list, &l); spin_unlock_irq(&cpa_lock); if (!cpu_has_clflush) - flush_map(NULL); + flush_map(0); list_for_each_entry_safe(pg, next, &l, lru) { if (cpu_has_clflush) flush_map(page_address(pg)); diff --git a/trunk/arch/ia64/kernel/crash.c b/trunk/arch/ia64/kernel/crash.c index 37bb16f07fc3..9d92097ce96d 100644 --- a/trunk/arch/ia64/kernel/crash.c +++ b/trunk/arch/ia64/kernel/crash.c @@ -52,7 +52,7 @@ extern void ia64_dump_cpu_regs(void *); static DEFINE_PER_CPU(struct elf_prstatus, elf_prstatus); void -crash_save_this_cpu(void) +crash_save_this_cpu() { void *buf; unsigned long cfm, sof, sol; diff --git a/trunk/arch/ia64/kernel/smp.c b/trunk/arch/ia64/kernel/smp.c index 55ddd809b02d..f4c7f7769cf7 100644 --- a/trunk/arch/ia64/kernel/smp.c +++ b/trunk/arch/ia64/kernel/smp.c @@ -221,13 +221,13 @@ send_IPI_self (int op) #ifdef CONFIG_KEXEC void -kdump_smp_send_stop(void) +kdump_smp_send_stop() { send_IPI_allbutself(IPI_KDUMP_CPU_STOP); } void -kdump_smp_send_init(void) +kdump_smp_send_init() { unsigned int cpu, self_cpu; self_cpu = smp_processor_id(); diff --git a/trunk/arch/mips/dec/Makefile b/trunk/arch/mips/dec/Makefile index 8b790c2900d5..ed181fdc3ac9 100644 --- a/trunk/arch/mips/dec/Makefile +++ b/trunk/arch/mips/dec/Makefile @@ -6,7 +6,6 @@ obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \ kn02-irq.o kn02xa-berr.o reset.o setup.o time.o obj-$(CONFIG_PROM_CONSOLE) += promcon.o -obj-$(CONFIG_TC) += tc.o obj-$(CONFIG_CPU_HAS_WB) += wbflush.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/trunk/arch/mips/dec/prom/identify.c b/trunk/arch/mips/dec/prom/identify.c index c4e3c1ea0d48..81d5e878ddce 100644 --- a/trunk/arch/mips/dec/prom/identify.c +++ b/trunk/arch/mips/dec/prom/identify.c @@ -88,7 +88,6 @@ static inline void prom_init_kn02(void) { dec_kn_slot_base = KN02_SLOT_BASE; dec_kn_slot_size = KN02_SLOT_SIZE; - dec_tc_bus = 1; dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN02_RTC); } @@ -97,7 +96,6 @@ static inline void prom_init_kn02xa(void) { dec_kn_slot_base = KN02XA_SLOT_BASE; dec_kn_slot_size = IOASIC_SLOT_SIZE; - dec_tc_bus = 1; ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL); dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY); @@ -107,7 +105,6 @@ static inline void prom_init_kn03(void) { dec_kn_slot_base = KN03_SLOT_BASE; dec_kn_slot_size = IOASIC_SLOT_SIZE; - dec_tc_bus = 1; ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL); dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY); diff --git a/trunk/arch/mips/dec/setup.c b/trunk/arch/mips/dec/setup.c index b8a5e75ba0ab..1058e2f409bb 100644 --- a/trunk/arch/mips/dec/setup.c +++ b/trunk/arch/mips/dec/setup.c @@ -53,8 +53,6 @@ unsigned long dec_kn_slot_base, dec_kn_slot_size; EXPORT_SYMBOL(dec_kn_slot_base); EXPORT_SYMBOL(dec_kn_slot_size); -int dec_tc_bus; - spinlock_t ioasic_ssr_lock; volatile u32 *ioasic_base; diff --git a/trunk/arch/mips/dec/tc.c b/trunk/arch/mips/dec/tc.c deleted file mode 100644 index 732027c79834..000000000000 --- a/trunk/arch/mips/dec/tc.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * TURBOchannel architecture calls. - * - * Copyright (c) Harald Koerfgen, 1998 - * Copyright (c) 2001, 2003, 2005, 2006 Maciej W. Rozycki - * Copyright (c) 2005 James Simmons - * - * This file is subject to the terms and conditions of the GNU - * General Public License. See the file "COPYING" in the main - * directory of this archive for more details. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -/* - * Protected read byte from TURBOchannel slot space. - */ -int tc_preadb(u8 *valp, void __iomem *addr) -{ - return get_dbe(*valp, (u8 *)addr); -} - -/* - * Get TURBOchannel bus information as specified by the spec, plus - * the slot space base address and the number of slots. - */ -int __init tc_bus_get_info(struct tc_bus *tbus) -{ - if (!dec_tc_bus) - return -ENXIO; - - memcpy(&tbus->info, rex_gettcinfo(), sizeof(tbus->info)); - tbus->slot_base = CPHYSADDR((long)rex_slot_address(0)); - - switch (mips_machtype) { - case MACH_DS5000_200: - tbus->num_tcslots = 7; - break; - case MACH_DS5000_2X0: - case MACH_DS5900: - tbus->ext_slot_base = 0x20000000; - tbus->ext_slot_size = 0x20000000; - /* fall through */ - case MACH_DS5000_1XX: - tbus->num_tcslots = 3; - break; - case MACH_DS5000_XX: - tbus->num_tcslots = 2; - default: - break; - } - return 0; -} - -/* - * Get the IRQ for the specified slot. - */ -void __init tc_device_get_irq(struct tc_dev *tdev) -{ - switch (tdev->slot) { - case 0: - tdev->interrupt = dec_interrupt[DEC_IRQ_TC0]; - break; - case 1: - tdev->interrupt = dec_interrupt[DEC_IRQ_TC1]; - break; - case 2: - tdev->interrupt = dec_interrupt[DEC_IRQ_TC2]; - break; - /* - * Yuck! DS5000/200 onboard devices - */ - case 5: - tdev->interrupt = dec_interrupt[DEC_IRQ_TC5]; - break; - case 6: - tdev->interrupt = dec_interrupt[DEC_IRQ_TC6]; - break; - default: - tdev->interrupt = -1; - break; - } -} diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index 50149ec6efa4..ae0ede19879d 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -49,13 +49,9 @@ /* Max supported size for symbol names */ #define MAX_SYMNAME 64 -#define VDSO32_MAXPAGES (((0x3000 + PAGE_MASK) >> PAGE_SHIFT) + 2) -#define VDSO64_MAXPAGES (((0x3000 + PAGE_MASK) >> PAGE_SHIFT) + 2) - extern char vdso32_start, vdso32_end; static void *vdso32_kbase = &vdso32_start; unsigned int vdso32_pages; -static struct page *vdso32_pagelist[VDSO32_MAXPAGES]; unsigned long vdso32_sigtramp; unsigned long vdso32_rt_sigtramp; @@ -63,7 +59,6 @@ unsigned long vdso32_rt_sigtramp; extern char vdso64_start, vdso64_end; static void *vdso64_kbase = &vdso64_start; unsigned int vdso64_pages; -static struct page *vdso64_pagelist[VDSO64_MAXPAGES]; unsigned long vdso64_rt_sigtramp; #endif /* CONFIG_PPC64 */ @@ -169,6 +164,55 @@ static void dump_vdso_pages(struct vm_area_struct * vma) } #endif /* DEBUG */ +/* + * Keep a dummy vma_close for now, it will prevent VMA merging. + */ +static void vdso_vma_close(struct vm_area_struct * vma) +{ +} + +/* + * Our nopage() function, maps in the actual vDSO kernel pages, they will + * be mapped read-only by do_no_page(), and eventually COW'ed, either + * right away for an initial write access, or by do_wp_page(). + */ +static struct page * vdso_vma_nopage(struct vm_area_struct * vma, + unsigned long address, int *type) +{ + unsigned long offset = address - vma->vm_start; + struct page *pg; +#ifdef CONFIG_PPC64 + void *vbase = (vma->vm_mm->task_size > TASK_SIZE_USER32) ? + vdso64_kbase : vdso32_kbase; +#else + void *vbase = vdso32_kbase; +#endif + + DBG("vdso_vma_nopage(current: %s, address: %016lx, off: %lx)\n", + current->comm, address, offset); + + if (address < vma->vm_start || address > vma->vm_end) + return NOPAGE_SIGBUS; + + /* + * Last page is systemcfg. + */ + if ((vma->vm_end - address) <= PAGE_SIZE) + pg = virt_to_page(vdso_data); + else + pg = virt_to_page(vbase + offset); + + get_page(pg); + DBG(" ->page count: %d\n", page_count(pg)); + + return pg; +} + +static struct vm_operations_struct vdso_vmops = { + .close = vdso_vma_close, + .nopage = vdso_vma_nopage, +}; + /* * This is called from binfmt_elf, we create the special vma for the * vDSO and insert it into the mm struct tree @@ -177,23 +221,20 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack) { struct mm_struct *mm = current->mm; - struct page **vdso_pagelist; + struct vm_area_struct *vma; unsigned long vdso_pages; unsigned long vdso_base; int rc; #ifdef CONFIG_PPC64 if (test_thread_flag(TIF_32BIT)) { - vdso_pagelist = vdso32_pagelist; vdso_pages = vdso32_pages; vdso_base = VDSO32_MBASE; } else { - vdso_pagelist = vdso64_pagelist; vdso_pages = vdso64_pages; vdso_base = VDSO64_MBASE; } #else - vdso_pagelist = vdso32_pagelist; vdso_pages = vdso32_pages; vdso_base = VDSO32_MBASE; #endif @@ -221,6 +262,17 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, goto fail_mmapsem; } + + /* Allocate a VMA structure and fill it up */ + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); + if (vma == NULL) { + rc = -ENOMEM; + goto fail_mmapsem; + } + vma->vm_mm = mm; + vma->vm_start = vdso_base; + vma->vm_end = vma->vm_start + (vdso_pages << PAGE_SHIFT); + /* * our vma flags don't have VM_WRITE so by default, the process isn't * allowed to write those pages. @@ -230,26 +282,32 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, * and your nice userland gettimeofday will be totally dead. * It's fine to use that for setting breakpoints in the vDSO code * pages though - * + */ + vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC; + /* * Make sure the vDSO gets into every core dump. * Dumping its contents makes post-mortem fully interpretable later * without matching up the same kernel and hardware config to see * what PC values meant. */ - rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| - VM_ALWAYSDUMP, - vdso_pagelist); + vma->vm_flags |= VM_ALWAYSDUMP; + vma->vm_flags |= mm->def_flags; + vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; + vma->vm_ops = &vdso_vmops; + + /* Insert new VMA */ + rc = insert_vm_struct(mm, vma); if (rc) - goto fail_mmapsem; + goto fail_vma; - /* Put vDSO base into mm struct */ + /* Put vDSO base into mm struct and account for memory usage */ current->mm->context.vdso_base = vdso_base; - + mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; up_write(&mm->mmap_sem); return 0; + fail_vma: + kmem_cache_free(vm_area_cachep, vma); fail_mmapsem: up_write(&mm->mmap_sem); return rc; @@ -720,26 +778,18 @@ void __init vdso_init(void) } /* Make sure pages are in the correct state */ - BUG_ON(vdso32_pages + 2 > VDSO32_MAXPAGES); for (i = 0; i < vdso32_pages; i++) { struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE); ClearPageReserved(pg); get_page(pg); - vdso32_pagelist[i] = pg; - } - vdso32_pagelist[i++] = virt_to_page(vdso_data); - vdso32_pagelist[i] = NULL; + } #ifdef CONFIG_PPC64 - BUG_ON(vdso64_pages + 2 > VDSO64_MAXPAGES); for (i = 0; i < vdso64_pages; i++) { struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE); ClearPageReserved(pg); get_page(pg); - vdso64_pagelist[i] = pg; } - vdso64_pagelist[i++] = virt_to_page(vdso_data); - vdso64_pagelist[i] = NULL; #endif /* CONFIG_PPC64 */ get_page(virt_to_page(vdso_data)); diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index 67d617b60a23..b43466ba8096 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -149,8 +149,7 @@ static int cbe_nr_iommus; static void invalidate_tce_cache(struct cbe_iommu *iommu, unsigned long *pte, long n_ptes) { - unsigned long __iomem *reg; - unsigned long val; + unsigned long *reg, val; long n; reg = iommu->xlate_regs + IOC_IOPT_CacheInvd; @@ -593,7 +592,7 @@ static void __init cell_iommu_init_one(struct device_node *np, unsigned long off /* Init base fields */ i = cbe_nr_iommus++; iommu = &iommus[i]; - iommu->stab = NULL; + iommu->stab = 0; iommu->nid = nid; snprintf(iommu->name, sizeof(iommu->name), "iommu%d", i); INIT_LIST_HEAD(&iommu->windows); diff --git a/trunk/arch/powerpc/platforms/celleb/pci.c b/trunk/arch/powerpc/platforms/celleb/pci.c index 98de836dfed3..867f83a7d0c9 100644 --- a/trunk/arch/powerpc/platforms/celleb/pci.c +++ b/trunk/arch/powerpc/platforms/celleb/pci.c @@ -65,13 +65,13 @@ static inline u8 celleb_fake_config_readb(void *addr) static inline u16 celleb_fake_config_readw(void *addr) { - __le16 *p = addr; + u16 *p = addr; return le16_to_cpu(*p); } static inline u32 celleb_fake_config_readl(void *addr) { - __le32 *p = addr; + u32 *p = addr; return le32_to_cpu(*p); } @@ -83,16 +83,16 @@ static inline void celleb_fake_config_writeb(u32 val, void *addr) static inline void celleb_fake_config_writew(u32 val, void *addr) { - __le16 val16; - __le16 *p = addr; + u16 val16; + u16 *p = addr; val16 = cpu_to_le16(val); *p = val16; } static inline void celleb_fake_config_writel(u32 val, void *addr) { - __le32 val32; - __le32 *p = addr; + u32 val32; + u32 *p = addr; val32 = cpu_to_le32(val); *p = val32; } diff --git a/trunk/arch/powerpc/platforms/celleb/scc_epci.c b/trunk/arch/powerpc/platforms/celleb/scc_epci.c index c11b39c3776a..0edbc0c4f338 100644 --- a/trunk/arch/powerpc/platforms/celleb/scc_epci.c +++ b/trunk/arch/powerpc/platforms/celleb/scc_epci.c @@ -47,7 +47,7 @@ #if 0 /* test code for epci dummy read */ static void celleb_epci_dummy_read(struct pci_dev *dev) { - void __iomem *epci_base; + void *epci_base; struct device_node *node; struct pci_controller *hose; u32 val; @@ -58,7 +58,7 @@ static void celleb_epci_dummy_read(struct pci_dev *dev) if (!hose) return; - epci_base = hose->cfg_addr; + epci_base = (void *)hose->cfg_addr; val = in_be32(epci_base + SCC_EPCI_WATRP); iosync(); @@ -71,18 +71,18 @@ static inline void clear_and_disable_master_abort_interrupt( struct pci_controller *hose) { void __iomem *addr; - addr = hose->cfg_addr + PCI_COMMAND; + addr = (void *)hose->cfg_addr + PCI_COMMAND; out_be32(addr, in_be32(addr) | (PCI_STATUS_REC_MASTER_ABORT << 16)); } static int celleb_epci_check_abort(struct pci_controller *hose, - void __iomem *addr) + unsigned long addr) { void __iomem *reg, *epci_base; u32 val; iob(); - epci_base = hose->cfg_addr; + epci_base = (void *)hose->cfg_addr; reg = epci_base + PCI_COMMAND; val = in_be32(reg); @@ -108,23 +108,23 @@ static int celleb_epci_check_abort(struct pci_controller *hose, return PCIBIOS_SUCCESSFUL; } -static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose, +static unsigned long celleb_epci_make_config_addr(struct pci_controller *hose, unsigned int devfn, int where) { - void __iomem *addr; + unsigned long addr; struct pci_bus *bus = hose->bus; if (bus->self) - addr = hose->cfg_data + + addr = (unsigned long)hose->cfg_data + (((bus->number & 0xff) << 16) | ((devfn & 0xff) << 8) | (where & 0xff) | 0x01000000); else - addr = hose->cfg_data + + addr = (unsigned long)hose->cfg_data + (((devfn & 0xff) << 8) | (where & 0xff)); - pr_debug("EPCI: config_addr = 0x%p\n", addr); + pr_debug("EPCI: config_addr = 0x%016lx\n", addr); return addr; } @@ -132,7 +132,7 @@ static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose, static int celleb_epci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { - void __iomem *addr; + unsigned long addr; struct device_node *node; struct pci_controller *hose; @@ -148,17 +148,17 @@ static int celleb_epci_read_config(struct pci_bus *bus, if (bus->number == hose->first_busno && devfn == 0) { /* EPCI controller self */ - addr = hose->cfg_addr + where; + addr = (unsigned long)hose->cfg_addr + where; switch (size) { case 1: - *val = in_8(addr); + *val = in_8((u8 *)addr); break; case 2: - *val = in_be16(addr); + *val = in_be16((u16 *)addr); break; case 4: - *val = in_be32(addr); + *val = in_be32((u32 *)addr); break; default: return PCIBIOS_DEVICE_NOT_FOUND; @@ -171,13 +171,13 @@ static int celleb_epci_read_config(struct pci_bus *bus, switch (size) { case 1: - *val = in_8(addr); + *val = in_8((u8 *)addr); break; case 2: - *val = in_le16(addr); + *val = in_le16((u16 *)addr); break; case 4: - *val = in_le32(addr); + *val = in_le32((u32 *)addr); break; default: return PCIBIOS_DEVICE_NOT_FOUND; @@ -188,13 +188,13 @@ static int celleb_epci_read_config(struct pci_bus *bus, "addr=0x%lx, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n", addr, devfn, where, size, *val); - return celleb_epci_check_abort(hose, NULL); + return celleb_epci_check_abort(hose, 0); } static int celleb_epci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - void __iomem *addr; + unsigned long addr; struct device_node *node; struct pci_controller *hose; @@ -210,17 +210,17 @@ static int celleb_epci_write_config(struct pci_bus *bus, if (bus->number == hose->first_busno && devfn == 0) { /* EPCI controller self */ - addr = hose->cfg_addr + where; + addr = (unsigned long)hose->cfg_addr + where; switch (size) { case 1: - out_8(addr, val); + out_8((u8 *)addr, val); break; case 2: - out_be16(addr, val); + out_be16((u16 *)addr, val); break; case 4: - out_be32(addr, val); + out_be32((u32 *)addr, val); break; default: return PCIBIOS_DEVICE_NOT_FOUND; @@ -233,13 +233,13 @@ static int celleb_epci_write_config(struct pci_bus *bus, switch (size) { case 1: - out_8(addr, val); + out_8((u8 *)addr, val); break; case 2: - out_le16(addr, val); + out_le16((u16 *)addr, val); break; case 4: - out_le32(addr, val); + out_le32((u32 *)addr, val); break; default: return PCIBIOS_DEVICE_NOT_FOUND; @@ -261,7 +261,7 @@ static int __devinit celleb_epci_init(struct pci_controller *hose) void __iomem *reg, *epci_base; int hwres = 0; - epci_base = hose->cfg_addr; + epci_base = (void *)hose->cfg_addr; /* PCI core reset(Internal bus and PCI clock) */ reg = epci_base + SCC_EPCI_CKCTRL; diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 117c9a0055bd..e1f51d455984 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -75,7 +75,7 @@ extern irqreturn_t xmon_irq(int, void *); extern unsigned long loops_per_jiffy; /* To be replaced by RTAS when available */ -static unsigned int __iomem *briq_SPOR; +static unsigned int *briq_SPOR; #ifdef CONFIG_SMP extern struct smp_ops_t chrp_smp_ops; @@ -267,7 +267,7 @@ void __init chrp_setup_arch(void) } else if (machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0) { _chrp_type = _CHRP_briq; /* Map the SPOR register on briq and change the restart hook */ - briq_SPOR = ioremap(0xff0000e8, 4); + briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4); ppc_md.restart = briq_restart; } else { /* Let's assume it is an IBM chrp if all else fails */ diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index 631c30095617..bb17283275aa 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -194,7 +194,6 @@ int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, return result; } -EXPORT_SYMBOL_GPL(ps3_alloc_io_irq); int ps3_free_io_irq(unsigned int virq) { @@ -210,7 +209,6 @@ int ps3_free_io_irq(unsigned int virq) return result; } -EXPORT_SYMBOL_GPL(ps3_free_io_irq); /** * ps3_alloc_event_irq - Allocate a virq for use with a system event. diff --git a/trunk/arch/powerpc/platforms/ps3/system-bus.c b/trunk/arch/powerpc/platforms/ps3/system-bus.c index a9f7e4a39a2a..bce6136cbce7 100644 --- a/trunk/arch/powerpc/platforms/ps3/system-bus.c +++ b/trunk/arch/powerpc/platforms/ps3/system-bus.c @@ -57,7 +57,6 @@ int ps3_mmio_region_create(struct ps3_mmio_region *r) dump_mmio_region(r); return result; } -EXPORT_SYMBOL_GPL(ps3_mmio_region_create); int ps3_free_mmio_region(struct ps3_mmio_region *r) { @@ -73,7 +72,6 @@ int ps3_free_mmio_region(struct ps3_mmio_region *r) r->lpar_addr = 0; return result; } -EXPORT_SYMBOL_GPL(ps3_free_mmio_region); static int ps3_system_bus_match(struct device *_dev, struct device_driver *_drv) diff --git a/trunk/arch/powerpc/xmon/spu-dis.c b/trunk/arch/powerpc/xmon/spu-dis.c index e5f89837c82e..ee929c641bf3 100644 --- a/trunk/arch/powerpc/xmon/spu-dis.c +++ b/trunk/arch/powerpc/xmon/spu-dis.c @@ -85,7 +85,7 @@ get_index_for_opcode (unsigned int insn) if ((index = spu_disassemble_table[opcode & 0x7ff]) != 0) return index; - return NULL; + return 0; } /* Print a Spu instruction. */ diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 1406400bf3ea..7c621b8ef683 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -179,8 +179,6 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set CONFIG_NET_KEY=y -CONFIG_IUCV=m -CONFIG_AFIUCV=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set @@ -510,6 +508,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_LCS=m CONFIG_CTC=m +CONFIG_IUCV=m # CONFIG_NETIUCV is not set # CONFIG_SMSGIUCV is not set # CONFIG_CLAW is not set diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall.c b/trunk/arch/sh/kernel/vsyscall/vsyscall.c index 7b0f66f03319..deb46941f315 100644 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall.c +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall.c @@ -37,12 +37,11 @@ __setup("vdso=", vdso_setup); * of the ELF DSO images included therein. */ extern const char vsyscall_trapa_start, vsyscall_trapa_end; -static struct page *syscall_pages[1]; +static void *syscall_page; int __init vsyscall_init(void) { - void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); - syscall_pages[0] = virt_to_page(syscall_page); + syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); /* * XXX: Map this page to a fixmap entry if we get around @@ -56,10 +55,37 @@ int __init vsyscall_init(void) return 0; } +static struct page *syscall_vma_nopage(struct vm_area_struct *vma, + unsigned long address, int *type) +{ + unsigned long offset = address - vma->vm_start; + struct page *page; + + if (address < vma->vm_start || address > vma->vm_end) + return NOPAGE_SIGBUS; + + page = virt_to_page(syscall_page + offset); + + get_page(page); + + return page; +} + +/* Prevent VMA merging */ +static void syscall_vma_close(struct vm_area_struct *vma) +{ +} + +static struct vm_operations_struct syscall_vm_ops = { + .nopage = syscall_vma_nopage, + .close = syscall_vma_close, +}; + /* Setup a VMA at program startup for the vsyscall page */ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack) { + struct vm_area_struct *vma; struct mm_struct *mm = current->mm; unsigned long addr; int ret; @@ -71,16 +97,30 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, goto up_fail; } - ret = install_special_mapping(mm, addr, PAGE_SIZE, - VM_READ | VM_EXEC | - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | - VM_ALWAYSDUMP, - syscall_pages); - if (unlikely(ret)) + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); + if (!vma) { + ret = -ENOMEM; goto up_fail; + } + + vma->vm_start = addr; + vma->vm_end = addr + PAGE_SIZE; + /* MAYWRITE to allow gdb to COW and set breakpoints */ + vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; + vma->vm_flags |= mm->def_flags; + vma->vm_page_prot = protection_map[vma->vm_flags & 7]; + vma->vm_ops = &syscall_vm_ops; + vma->vm_mm = mm; + + ret = insert_vm_struct(mm, vma); + if (unlikely(ret)) { + kmem_cache_free(vm_area_cachep, vma); + goto up_fail; + } current->mm->context.vdso = (void *)addr; + mm->total_vm++; up_fail: up_write(&mm->mmap_sem); return ret; diff --git a/trunk/arch/x86_64/ia32/syscall32.c b/trunk/arch/x86_64/ia32/syscall32.c index 568ff0df89e7..59f1fa155915 100644 --- a/trunk/arch/x86_64/ia32/syscall32.c +++ b/trunk/arch/x86_64/ia32/syscall32.c @@ -18,34 +18,68 @@ extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; extern int sysctl_vsyscall32; -static struct page *syscall32_pages[1]; +char *syscall32_page; static int use_sysenter = -1; +static struct page * +syscall32_nopage(struct vm_area_struct *vma, unsigned long adr, int *type) +{ + struct page *p = virt_to_page(adr - vma->vm_start + syscall32_page); + get_page(p); + return p; +} + +/* Prevent VMA merging */ +static void syscall32_vma_close(struct vm_area_struct *vma) +{ +} + +static struct vm_operations_struct syscall32_vm_ops = { + .close = syscall32_vma_close, + .nopage = syscall32_nopage, +}; + struct linux_binprm; /* Setup a VMA at program startup for the vsyscall page */ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) { + int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT; + struct vm_area_struct *vma; struct mm_struct *mm = current->mm; int ret; - down_write(&mm->mmap_sem); + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + if (!vma) + return -ENOMEM; + + memset(vma, 0, sizeof(struct vm_area_struct)); + /* Could randomize here */ + vma->vm_start = VSYSCALL32_BASE; + vma->vm_end = VSYSCALL32_END; + /* MAYWRITE to allow gdb to COW and set breakpoints */ + vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; /* - * MAYWRITE to allow gdb to COW and set breakpoints - * * Make sure the vDSO gets into every core dump. * Dumping its contents makes post-mortem fully interpretable later * without matching up the same kernel and hardware config to see * what PC values meant. */ - /* Could randomize here */ - ret = install_special_mapping(mm, VSYSCALL32_BASE, PAGE_SIZE, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| - VM_ALWAYSDUMP, - syscall32_pages); + vma->vm_flags |= VM_ALWAYSDUMP; + vma->vm_flags |= mm->def_flags; + vma->vm_page_prot = protection_map[vma->vm_flags & 7]; + vma->vm_ops = &syscall32_vm_ops; + vma->vm_mm = mm; + + down_write(&mm->mmap_sem); + if ((ret = insert_vm_struct(mm, vma))) { + up_write(&mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return ret; + } + mm->total_vm += npages; up_write(&mm->mmap_sem); - return ret; + return 0; } const char *arch_vma_name(struct vm_area_struct *vma) @@ -58,10 +92,9 @@ const char *arch_vma_name(struct vm_area_struct *vma) static int __init init_syscall32(void) { - char *syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); + syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); if (!syscall32_page) panic("Cannot allocate syscall32 page"); - syscall32_pages[0] = virt_to_page(syscall32_page); if (use_sysenter > 0) { memcpy(syscall32_page, syscall32_sysenter, syscall32_sysenter_end - syscall32_sysenter); diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 38c293b987b7..fb6789725e1b 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -1264,7 +1264,7 @@ void blk_recount_segments(request_queue_t *q, struct bio *bio) bio->bi_hw_segments = nr_hw_segs; bio->bi_flags |= (1 << BIO_SEG_VALID); } -EXPORT_SYMBOL(blk_recount_segments); + static int blk_phys_contig_segment(request_queue_t *q, struct bio *bio, struct bio *nxt) diff --git a/trunk/crypto/Kconfig b/trunk/crypto/Kconfig index 086fcec44720..918b4d845f93 100644 --- a/trunk/crypto/Kconfig +++ b/trunk/crypto/Kconfig @@ -149,15 +149,6 @@ config CRYPTO_CBC CBC: Cipher Block Chaining mode This block cipher algorithm is required for IPSec. -config CRYPTO_PCBC - tristate "PCBC support" - select CRYPTO_BLKCIPHER - select CRYPTO_MANAGER - default m - help - PCBC: Propagating Cipher Block Chaining mode - This block cipher algorithm is required for RxRPC. - config CRYPTO_LRW tristate "LRW support (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -177,13 +168,6 @@ config CRYPTO_DES help DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). -config CRYPTO_FCRYPT - tristate "FCrypt cipher algorithm" - select CRYPTO_ALGAPI - select CRYPTO_BLKCIPHER - help - FCrypt algorithm used by RxRPC. - config CRYPTO_BLOWFISH tristate "Blowfish cipher algorithm" select CRYPTO_ALGAPI @@ -425,21 +409,6 @@ config CRYPTO_CRC32C See Castagnoli93. This implementation uses lib/libcrc32c. Module will be crc32c. -config CRYPTO_CAMELLIA - tristate "Camellia cipher algorithms" - depends on CRYPTO - select CRYPTO_ALGAPI - help - Camellia cipher algorithms module. - - Camellia is a symmetric key block cipher developed jointly - at NTT and Mitsubishi Electric Corporation. - - The Camellia specifies three key sizes: 128, 192 and 256 bits. - - See also: - - config CRYPTO_TEST tristate "Testing module" depends on m diff --git a/trunk/crypto/Makefile b/trunk/crypto/Makefile index 12f93f578171..60e3d24f61f5 100644 --- a/trunk/crypto/Makefile +++ b/trunk/crypto/Makefile @@ -27,16 +27,13 @@ obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o obj-$(CONFIG_CRYPTO_ECB) += ecb.o obj-$(CONFIG_CRYPTO_CBC) += cbc.o -obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o obj-$(CONFIG_CRYPTO_LRW) += lrw.o obj-$(CONFIG_CRYPTO_DES) += des.o -obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o obj-$(CONFIG_CRYPTO_AES) += aes.o -obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia.o obj-$(CONFIG_CRYPTO_CAST5) += cast5.o obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_ARC4) += arc4.o diff --git a/trunk/crypto/algapi.c b/trunk/crypto/algapi.c index f7d2185b2c8f..c91530021e9c 100644 --- a/trunk/crypto/algapi.c +++ b/trunk/crypto/algapi.c @@ -377,8 +377,7 @@ void crypto_drop_spawn(struct crypto_spawn *spawn) } EXPORT_SYMBOL_GPL(crypto_drop_spawn); -struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, - u32 mask) +struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn) { struct crypto_alg *alg; struct crypto_alg *alg2; @@ -397,18 +396,10 @@ struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, return ERR_PTR(-EAGAIN); } - tfm = ERR_PTR(-EINVAL); - if (unlikely((alg->cra_flags ^ type) & mask)) - goto out_put_alg; - - tfm = __crypto_alloc_tfm(alg, type, mask); + tfm = __crypto_alloc_tfm(alg, 0); if (IS_ERR(tfm)) - goto out_put_alg; - - return tfm; + crypto_mod_put(alg); -out_put_alg: - crypto_mod_put(alg); return tfm; } EXPORT_SYMBOL_GPL(crypto_spawn_tfm); diff --git a/trunk/crypto/api.c b/trunk/crypto/api.c index 55af8bb0f050..8c446871cd5b 100644 --- a/trunk/crypto/api.c +++ b/trunk/crypto/api.c @@ -212,12 +212,31 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) } EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup); -static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) { - const struct crypto_type *type_obj = tfm->__crt_alg->cra_type; + tfm->crt_flags = flags & CRYPTO_TFM_REQ_MASK; + flags &= ~CRYPTO_TFM_REQ_MASK; + + switch (crypto_tfm_alg_type(tfm)) { + case CRYPTO_ALG_TYPE_CIPHER: + return crypto_init_cipher_flags(tfm, flags); + + case CRYPTO_ALG_TYPE_DIGEST: + return crypto_init_digest_flags(tfm, flags); + + case CRYPTO_ALG_TYPE_COMPRESS: + return crypto_init_compress_flags(tfm, flags); + } + + return 0; +} - if (type_obj) - return type_obj->init(tfm, type, mask); +static int crypto_init_ops(struct crypto_tfm *tfm) +{ + const struct crypto_type *type = tfm->__crt_alg->cra_type; + + if (type) + return type->init(tfm); switch (crypto_tfm_alg_type(tfm)) { case CRYPTO_ALG_TYPE_CIPHER: @@ -266,29 +285,29 @@ static void crypto_exit_ops(struct crypto_tfm *tfm) } } -static unsigned int crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask) +static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags) { - const struct crypto_type *type_obj = alg->cra_type; + const struct crypto_type *type = alg->cra_type; unsigned int len; len = alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1); - if (type_obj) - return len + type_obj->ctxsize(alg, type, mask); + if (type) + return len + type->ctxsize(alg); switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { default: BUG(); case CRYPTO_ALG_TYPE_CIPHER: - len += crypto_cipher_ctxsize(alg); + len += crypto_cipher_ctxsize(alg, flags); break; case CRYPTO_ALG_TYPE_DIGEST: - len += crypto_digest_ctxsize(alg); + len += crypto_digest_ctxsize(alg, flags); break; case CRYPTO_ALG_TYPE_COMPRESS: - len += crypto_compress_ctxsize(alg); + len += crypto_compress_ctxsize(alg, flags); break; } @@ -303,21 +322,24 @@ void crypto_shoot_alg(struct crypto_alg *alg) } EXPORT_SYMBOL_GPL(crypto_shoot_alg); -struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, - u32 mask) +struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags) { struct crypto_tfm *tfm = NULL; unsigned int tfm_size; int err = -ENOMEM; - tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, type, mask); + tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags); tfm = kzalloc(tfm_size, GFP_KERNEL); if (tfm == NULL) goto out_err; tfm->__crt_alg = alg; - err = crypto_init_ops(tfm, type, mask); + err = crypto_init_flags(tfm, flags); + if (err) + goto out_free_tfm; + + err = crypto_init_ops(tfm); if (err) goto out_free_tfm; @@ -340,6 +362,31 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, } EXPORT_SYMBOL_GPL(__crypto_alloc_tfm); +struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) +{ + struct crypto_tfm *tfm = NULL; + int err; + + do { + struct crypto_alg *alg; + + alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC); + err = PTR_ERR(alg); + if (IS_ERR(alg)) + continue; + + tfm = __crypto_alloc_tfm(alg, flags); + err = 0; + if (IS_ERR(tfm)) { + crypto_mod_put(alg); + err = PTR_ERR(tfm); + tfm = NULL; + } + } while (err == -EAGAIN && !signal_pending(current)); + + return tfm; +} + /* * crypto_alloc_base - Locate algorithm and allocate transform * @alg_name: Name of algorithm @@ -373,7 +420,7 @@ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask) goto err; } - tfm = __crypto_alloc_tfm(alg, type, mask); + tfm = __crypto_alloc_tfm(alg, 0); if (!IS_ERR(tfm)) return tfm; @@ -419,6 +466,7 @@ void crypto_free_tfm(struct crypto_tfm *tfm) kfree(tfm); } +EXPORT_SYMBOL_GPL(crypto_alloc_tfm); EXPORT_SYMBOL_GPL(crypto_free_tfm); int crypto_has_alg(const char *name, u32 type, u32 mask) diff --git a/trunk/crypto/blkcipher.c b/trunk/crypto/blkcipher.c index b5befe8c3a96..6e93004f2181 100644 --- a/trunk/crypto/blkcipher.c +++ b/trunk/crypto/blkcipher.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -314,9 +313,6 @@ static int blkcipher_walk_first(struct blkcipher_desc *desc, struct crypto_blkcipher *tfm = desc->tfm; unsigned int alignmask = crypto_blkcipher_alignmask(tfm); - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - walk->nbytes = walk->total; if (unlikely(!walk->total)) return 0; @@ -349,8 +345,7 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, return cipher->setkey(tfm, key, keylen); } -static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, - u32 mask) +static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg) { struct blkcipher_alg *cipher = &alg->cra_blkcipher; unsigned int len = alg->cra_ctxsize; @@ -363,7 +358,7 @@ static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, return len; } -static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm) { struct blkcipher_tfm *crt = &tfm->crt_blkcipher; struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; diff --git a/trunk/crypto/camellia.c b/trunk/crypto/camellia.c deleted file mode 100644 index 6877ecfd90bb..000000000000 --- a/trunk/crypto/camellia.c +++ /dev/null @@ -1,1801 +0,0 @@ -/* - * Copyright (C) 2006 - * NTT (Nippon Telegraph and Telephone Corporation). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - * Algorithm Specification - * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html - */ - -/* - * - * NOTE --- NOTE --- NOTE --- NOTE - * This implementation assumes that all memory addresses passed - * as parameters are four-byte aligned. - * - */ - -#include -#include -#include -#include -#include - - -#define CAMELLIA_MIN_KEY_SIZE 16 -#define CAMELLIA_MAX_KEY_SIZE 32 -#define CAMELLIA_BLOCK_SIZE 16 -#define CAMELLIA_TABLE_BYTE_LEN 272 -#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) - -typedef u32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; - - -/* key constants */ - -#define CAMELLIA_SIGMA1L (0xA09E667FL) -#define CAMELLIA_SIGMA1R (0x3BCC908BL) -#define CAMELLIA_SIGMA2L (0xB67AE858L) -#define CAMELLIA_SIGMA2R (0x4CAA73B2L) -#define CAMELLIA_SIGMA3L (0xC6EF372FL) -#define CAMELLIA_SIGMA3R (0xE94F82BEL) -#define CAMELLIA_SIGMA4L (0x54FF53A5L) -#define CAMELLIA_SIGMA4R (0xF1D36F1CL) -#define CAMELLIA_SIGMA5L (0x10E527FAL) -#define CAMELLIA_SIGMA5R (0xDE682D1DL) -#define CAMELLIA_SIGMA6L (0xB05688C2L) -#define CAMELLIA_SIGMA6R (0xB3E6C1FDL) - -struct camellia_ctx { - int key_length; - KEY_TABLE_TYPE key_table; -}; - - -/* - * macros - */ - - -# define GETU32(pt) (((u32)(pt)[0] << 24) \ - ^ ((u32)(pt)[1] << 16) \ - ^ ((u32)(pt)[2] << 8) \ - ^ ((u32)(pt)[3])) - -#define COPY4WORD(dst, src) \ - do { \ - (dst)[0]=(src)[0]; \ - (dst)[1]=(src)[1]; \ - (dst)[2]=(src)[2]; \ - (dst)[3]=(src)[3]; \ - }while(0) - -#define SWAP4WORD(word) \ - do { \ - CAMELLIA_SWAP4((word)[0]); \ - CAMELLIA_SWAP4((word)[1]); \ - CAMELLIA_SWAP4((word)[2]); \ - CAMELLIA_SWAP4((word)[3]); \ - }while(0) - -#define XOR4WORD(a, b)/* a = a ^ b */ \ - do { \ - (a)[0]^=(b)[0]; \ - (a)[1]^=(b)[1]; \ - (a)[2]^=(b)[2]; \ - (a)[3]^=(b)[3]; \ - }while(0) - -#define XOR4WORD2(a, b, c)/* a = b ^ c */ \ - do { \ - (a)[0]=(b)[0]^(c)[0]; \ - (a)[1]=(b)[1]^(c)[1]; \ - (a)[2]=(b)[2]^(c)[2]; \ - (a)[3]=(b)[3]^(c)[3]; \ - }while(0) - -#define CAMELLIA_SUBKEY_L(INDEX) (subkey[(INDEX)*2]) -#define CAMELLIA_SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1]) - -/* rotation right shift 1byte */ -#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) -/* rotation left shift 1bit */ -#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) -/* rotation left shift 1byte */ -#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) - -#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ - do { \ - w0 = ll; \ - ll = (ll << bits) + (lr >> (32 - bits)); \ - lr = (lr << bits) + (rl >> (32 - bits)); \ - rl = (rl << bits) + (rr >> (32 - bits)); \ - rr = (rr << bits) + (w0 >> (32 - bits)); \ - } while(0) - -#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \ - do { \ - w0 = ll; \ - w1 = lr; \ - ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \ - lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \ - rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \ - rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \ - } while(0) - -#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)]) -#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)]) -#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)]) -#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)]) - -#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ - do { \ - il = xl ^ kl; \ - ir = xr ^ kr; \ - t0 = il >> 16; \ - t1 = ir >> 16; \ - yl = CAMELLIA_SP1110(ir & 0xff) \ - ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ - ^ CAMELLIA_SP3033(t1 & 0xff) \ - ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ - yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ - ^ CAMELLIA_SP0222(t0 & 0xff) \ - ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ - ^ CAMELLIA_SP4404(il & 0xff); \ - yl ^= yr; \ - yr = CAMELLIA_RR8(yr); \ - yr ^= yl; \ - } while(0) - - -/* - * for speed up - * - */ -#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ - do { \ - t0 = kll; \ - t2 = krr; \ - t0 &= ll; \ - t2 |= rr; \ - rl ^= t2; \ - lr ^= CAMELLIA_RL1(t0); \ - t3 = krl; \ - t1 = klr; \ - t3 &= rl; \ - t1 |= lr; \ - ll ^= t1; \ - rr ^= CAMELLIA_RL1(t3); \ - } while(0) - -#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ - do { \ - ir = CAMELLIA_SP1110(xr & 0xff); \ - il = CAMELLIA_SP1110((xl>>24) & 0xff); \ - ir ^= CAMELLIA_SP0222((xr>>24) & 0xff); \ - il ^= CAMELLIA_SP0222((xl>>16) & 0xff); \ - ir ^= CAMELLIA_SP3033((xr>>16) & 0xff); \ - il ^= CAMELLIA_SP3033((xl>>8) & 0xff); \ - ir ^= CAMELLIA_SP4404((xr>>8) & 0xff); \ - il ^= CAMELLIA_SP4404(xl & 0xff); \ - il ^= kl; \ - ir ^= il ^ kr; \ - yl ^= ir; \ - yr ^= CAMELLIA_RR8(il) ^ ir; \ - } while(0) - -/** - * Stuff related to the Camellia key schedule - */ -#define SUBL(x) subL[(x)] -#define SUBR(x) subR[(x)] - - -static const u32 camellia_sp1110[256] = { - 0x70707000,0x82828200,0x2c2c2c00,0xececec00, - 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500, - 0xe4e4e400,0x85858500,0x57575700,0x35353500, - 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100, - 0x23232300,0xefefef00,0x6b6b6b00,0x93939300, - 0x45454500,0x19191900,0xa5a5a500,0x21212100, - 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00, - 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00, - 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00, - 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00, - 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00, - 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00, - 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00, - 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00, - 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600, - 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00, - 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600, - 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00, - 0x74747400,0x12121200,0x2b2b2b00,0x20202000, - 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900, - 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200, - 0x34343400,0x7e7e7e00,0x76767600,0x05050500, - 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100, - 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700, - 0x14141400,0x58585800,0x3a3a3a00,0x61616100, - 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00, - 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600, - 0x53535300,0x18181800,0xf2f2f200,0x22222200, - 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200, - 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100, - 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800, - 0x60606000,0xfcfcfc00,0x69696900,0x50505000, - 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00, - 0xa1a1a100,0x89898900,0x62626200,0x97979700, - 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500, - 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200, - 0x10101000,0xc4c4c400,0x00000000,0x48484800, - 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00, - 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00, - 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400, - 0x87878700,0x5c5c5c00,0x83838300,0x02020200, - 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300, - 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300, - 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200, - 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600, - 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00, - 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00, - 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00, - 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00, - 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00, - 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600, - 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900, - 0x78787800,0x98989800,0x06060600,0x6a6a6a00, - 0xe7e7e700,0x46464600,0x71717100,0xbababa00, - 0xd4d4d400,0x25252500,0xababab00,0x42424200, - 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00, - 0x72727200,0x07070700,0xb9b9b900,0x55555500, - 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00, - 0x36363600,0x49494900,0x2a2a2a00,0x68686800, - 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400, - 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00, - 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100, - 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400, - 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00, -}; - -static const u32 camellia_sp0222[256] = { - 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, - 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, - 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, - 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, - 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, - 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, - 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, - 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, - 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, - 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, - 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, - 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, - 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, - 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, - 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, - 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, - 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, - 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, - 0x00e8e8e8,0x00242424,0x00565656,0x00404040, - 0x00e1e1e1,0x00636363,0x00090909,0x00333333, - 0x00bfbfbf,0x00989898,0x00979797,0x00858585, - 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, - 0x00dadada,0x006f6f6f,0x00535353,0x00626262, - 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, - 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, - 0x00bdbdbd,0x00363636,0x00222222,0x00383838, - 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, - 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, - 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, - 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, - 0x00484848,0x00101010,0x00d1d1d1,0x00515151, - 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, - 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, - 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, - 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, - 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, - 0x00202020,0x00898989,0x00000000,0x00909090, - 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, - 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, - 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, - 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, - 0x009b9b9b,0x00949494,0x00212121,0x00666666, - 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, - 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, - 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, - 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, - 0x00030303,0x002d2d2d,0x00dedede,0x00969696, - 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, - 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, - 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, - 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, - 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, - 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, - 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, - 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, - 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, - 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, - 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, - 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, - 0x00787878,0x00707070,0x00e3e3e3,0x00494949, - 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, - 0x00777777,0x00939393,0x00868686,0x00838383, - 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, - 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, -}; - -static const u32 camellia_sp3033[256] = { - 0x38003838,0x41004141,0x16001616,0x76007676, - 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, - 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, - 0x75007575,0x06000606,0x57005757,0xa000a0a0, - 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, - 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, - 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, - 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, - 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, - 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, - 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, - 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, - 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, - 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, - 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, - 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, - 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, - 0xfd00fdfd,0x66006666,0x58005858,0x96009696, - 0x3a003a3a,0x09000909,0x95009595,0x10001010, - 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, - 0xef00efef,0x26002626,0xe500e5e5,0x61006161, - 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, - 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, - 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, - 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, - 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, - 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, - 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, - 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, - 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, - 0x12001212,0x04000404,0x74007474,0x54005454, - 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, - 0x55005555,0x68006868,0x50005050,0xbe00bebe, - 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, - 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, - 0x70007070,0xff00ffff,0x32003232,0x69006969, - 0x08000808,0x62006262,0x00000000,0x24002424, - 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, - 0x45004545,0x81008181,0x73007373,0x6d006d6d, - 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, - 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, - 0xe600e6e6,0x25002525,0x48004848,0x99009999, - 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, - 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, - 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, - 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, - 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, - 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, - 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, - 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, - 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, - 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, - 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535, - 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d, - 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121, - 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d, - 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa, - 0x7c007c7c,0x77007777,0x56005656,0x05000505, - 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434, - 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252, - 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd, - 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0, - 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a, - 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f, -}; - -static const u32 camellia_sp4404[256] = { - 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0, - 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae, - 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5, - 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092, - 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f, - 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b, - 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d, - 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c, - 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0, - 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084, - 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076, - 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004, - 0x14140014,0x3a3a003a,0xdede00de,0x11110011, - 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2, - 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a, - 0x24240024,0xe8e800e8,0x60600060,0x69690069, - 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062, - 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064, - 0x10100010,0x00000000,0xa3a300a3,0x75750075, - 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd, - 0x87870087,0x83830083,0xcdcd00cd,0x90900090, - 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf, - 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6, - 0x81810081,0x6f6f006f,0x13130013,0x63630063, - 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc, - 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4, - 0x78780078,0x06060006,0xe7e700e7,0x71710071, - 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d, - 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac, - 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1, - 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043, - 0x15150015,0xadad00ad,0x77770077,0x80800080, - 0x82820082,0xecec00ec,0x27270027,0xe5e500e5, - 0x85850085,0x35350035,0x0c0c000c,0x41410041, - 0xefef00ef,0x93930093,0x19190019,0x21210021, - 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd, - 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce, - 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a, - 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d, - 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d, - 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d, - 0x12120012,0x20200020,0xb1b100b1,0x99990099, - 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005, - 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7, - 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c, - 0x0f0f000f,0x16160016,0x18180018,0x22220022, - 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091, - 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050, - 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097, - 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2, - 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db, - 0x03030003,0xdada00da,0x3f3f003f,0x94940094, - 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033, - 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2, - 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b, - 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e, - 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e, - 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059, - 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba, - 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa, - 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a, - 0x49490049,0x68680068,0x38380038,0xa4a400a4, - 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1, - 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e, -}; - - - -static void camellia_setup128(const unsigned char *key, u32 *subkey) -{ - u32 kll, klr, krl, krr; - u32 il, ir, t0, t1, w0, w1; - u32 kw4l, kw4r, dw, tl, tr; - u32 subL[26]; - u32 subR[26]; - - /** - * k == kll || klr || krl || krr (|| is concatination) - */ - kll = GETU32(key ); - klr = GETU32(key + 4); - krl = GETU32(key + 8); - krr = GETU32(key + 12); - /** - * generate KL dependent subkeys - */ - /* kw1 */ - SUBL(0) = kll; SUBR(0) = klr; - /* kw2 */ - SUBL(1) = krl; SUBR(1) = krr; - /* rotation left shift 15bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k3 */ - SUBL(4) = kll; SUBR(4) = klr; - /* k4 */ - SUBL(5) = krl; SUBR(5) = krr; - /* rotation left shift 15+30bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); - /* k7 */ - SUBL(10) = kll; SUBR(10) = klr; - /* k8 */ - SUBL(11) = krl; SUBR(11) = krr; - /* rotation left shift 15+30+15bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k10 */ - SUBL(13) = krl; SUBR(13) = krr; - /* rotation left shift 15+30+15+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* kl3 */ - SUBL(16) = kll; SUBR(16) = klr; - /* kl4 */ - SUBL(17) = krl; SUBR(17) = krr; - /* rotation left shift 15+30+15+17+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k13 */ - SUBL(18) = kll; SUBR(18) = klr; - /* k14 */ - SUBL(19) = krl; SUBR(19) = krr; - /* rotation left shift 15+30+15+17+17+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k17 */ - SUBL(22) = kll; SUBR(22) = klr; - /* k18 */ - SUBL(23) = krl; SUBR(23) = krr; - - /* generate KA */ - kll = SUBL(0); klr = SUBR(0); - krl = SUBL(1); krr = SUBR(1); - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, - w0, w1, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, - kll, klr, il, ir, t0, t1); - /* current status == (kll, klr, w0, w1) */ - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, - krl, krr, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, - w0, w1, il, ir, t0, t1); - kll ^= w0; klr ^= w1; - - /* generate KA dependent subkeys */ - /* k1, k2 */ - SUBL(2) = kll; SUBR(2) = klr; - SUBL(3) = krl; SUBR(3) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k5,k6 */ - SUBL(6) = kll; SUBR(6) = klr; - SUBL(7) = krl; SUBR(7) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* kl1, kl2 */ - SUBL(8) = kll; SUBR(8) = klr; - SUBL(9) = krl; SUBR(9) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k9 */ - SUBL(12) = kll; SUBR(12) = klr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k11, k12 */ - SUBL(14) = kll; SUBR(14) = klr; - SUBL(15) = krl; SUBR(15) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); - /* k15, k16 */ - SUBL(20) = kll; SUBR(20) = klr; - SUBL(21) = krl; SUBR(21) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* kw3, kw4 */ - SUBL(24) = kll; SUBR(24) = klr; - SUBL(25) = krl; SUBR(25) = krr; - - - /* absorb kw2 to other subkeys */ - /* round 2 */ - SUBL(3) ^= SUBL(1); SUBR(3) ^= SUBR(1); - /* round 4 */ - SUBL(5) ^= SUBL(1); SUBR(5) ^= SUBR(1); - /* round 6 */ - SUBL(7) ^= SUBL(1); SUBR(7) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(9); - dw = SUBL(1) & SUBL(9), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ - /* round 8 */ - SUBL(11) ^= SUBL(1); SUBR(11) ^= SUBR(1); - /* round 10 */ - SUBL(13) ^= SUBL(1); SUBR(13) ^= SUBR(1); - /* round 12 */ - SUBL(15) ^= SUBL(1); SUBR(15) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(17); - dw = SUBL(1) & SUBL(17), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ - /* round 14 */ - SUBL(19) ^= SUBL(1); SUBR(19) ^= SUBR(1); - /* round 16 */ - SUBL(21) ^= SUBL(1); SUBR(21) ^= SUBR(1); - /* round 18 */ - SUBL(23) ^= SUBL(1); SUBR(23) ^= SUBR(1); - /* kw3 */ - SUBL(24) ^= SUBL(1); SUBR(24) ^= SUBR(1); - - /* absorb kw4 to other subkeys */ - kw4l = SUBL(25); kw4r = SUBR(25); - /* round 17 */ - SUBL(22) ^= kw4l; SUBR(22) ^= kw4r; - /* round 15 */ - SUBL(20) ^= kw4l; SUBR(20) ^= kw4r; - /* round 13 */ - SUBL(18) ^= kw4l; SUBR(18) ^= kw4r; - kw4l ^= kw4r & ~SUBR(16); - dw = kw4l & SUBL(16), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ - /* round 11 */ - SUBL(14) ^= kw4l; SUBR(14) ^= kw4r; - /* round 9 */ - SUBL(12) ^= kw4l; SUBR(12) ^= kw4r; - /* round 7 */ - SUBL(10) ^= kw4l; SUBR(10) ^= kw4r; - kw4l ^= kw4r & ~SUBR(8); - dw = kw4l & SUBL(8), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ - /* round 5 */ - SUBL(6) ^= kw4l; SUBR(6) ^= kw4r; - /* round 3 */ - SUBL(4) ^= kw4l; SUBR(4) ^= kw4r; - /* round 1 */ - SUBL(2) ^= kw4l; SUBR(2) ^= kw4r; - /* kw1 */ - SUBL(0) ^= kw4l; SUBR(0) ^= kw4r; - - - /* key XOR is end of F-function */ - CAMELLIA_SUBKEY_L(0) = SUBL(0) ^ SUBL(2);/* kw1 */ - CAMELLIA_SUBKEY_R(0) = SUBR(0) ^ SUBR(2); - CAMELLIA_SUBKEY_L(2) = SUBL(3); /* round 1 */ - CAMELLIA_SUBKEY_R(2) = SUBR(3); - CAMELLIA_SUBKEY_L(3) = SUBL(2) ^ SUBL(4); /* round 2 */ - CAMELLIA_SUBKEY_R(3) = SUBR(2) ^ SUBR(4); - CAMELLIA_SUBKEY_L(4) = SUBL(3) ^ SUBL(5); /* round 3 */ - CAMELLIA_SUBKEY_R(4) = SUBR(3) ^ SUBR(5); - CAMELLIA_SUBKEY_L(5) = SUBL(4) ^ SUBL(6); /* round 4 */ - CAMELLIA_SUBKEY_R(5) = SUBR(4) ^ SUBR(6); - CAMELLIA_SUBKEY_L(6) = SUBL(5) ^ SUBL(7); /* round 5 */ - CAMELLIA_SUBKEY_R(6) = SUBR(5) ^ SUBR(7); - tl = SUBL(10) ^ (SUBR(10) & ~SUBR(8)); - dw = tl & SUBL(8), /* FL(kl1) */ - tr = SUBR(10) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(7) = SUBL(6) ^ tl; /* round 6 */ - CAMELLIA_SUBKEY_R(7) = SUBR(6) ^ tr; - CAMELLIA_SUBKEY_L(8) = SUBL(8); /* FL(kl1) */ - CAMELLIA_SUBKEY_R(8) = SUBR(8); - CAMELLIA_SUBKEY_L(9) = SUBL(9); /* FLinv(kl2) */ - CAMELLIA_SUBKEY_R(9) = SUBR(9); - tl = SUBL(7) ^ (SUBR(7) & ~SUBR(9)); - dw = tl & SUBL(9), /* FLinv(kl2) */ - tr = SUBR(7) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(10) = tl ^ SUBL(11); /* round 7 */ - CAMELLIA_SUBKEY_R(10) = tr ^ SUBR(11); - CAMELLIA_SUBKEY_L(11) = SUBL(10) ^ SUBL(12); /* round 8 */ - CAMELLIA_SUBKEY_R(11) = SUBR(10) ^ SUBR(12); - CAMELLIA_SUBKEY_L(12) = SUBL(11) ^ SUBL(13); /* round 9 */ - CAMELLIA_SUBKEY_R(12) = SUBR(11) ^ SUBR(13); - CAMELLIA_SUBKEY_L(13) = SUBL(12) ^ SUBL(14); /* round 10 */ - CAMELLIA_SUBKEY_R(13) = SUBR(12) ^ SUBR(14); - CAMELLIA_SUBKEY_L(14) = SUBL(13) ^ SUBL(15); /* round 11 */ - CAMELLIA_SUBKEY_R(14) = SUBR(13) ^ SUBR(15); - tl = SUBL(18) ^ (SUBR(18) & ~SUBR(16)); - dw = tl & SUBL(16), /* FL(kl3) */ - tr = SUBR(18) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(15) = SUBL(14) ^ tl; /* round 12 */ - CAMELLIA_SUBKEY_R(15) = SUBR(14) ^ tr; - CAMELLIA_SUBKEY_L(16) = SUBL(16); /* FL(kl3) */ - CAMELLIA_SUBKEY_R(16) = SUBR(16); - CAMELLIA_SUBKEY_L(17) = SUBL(17); /* FLinv(kl4) */ - CAMELLIA_SUBKEY_R(17) = SUBR(17); - tl = SUBL(15) ^ (SUBR(15) & ~SUBR(17)); - dw = tl & SUBL(17), /* FLinv(kl4) */ - tr = SUBR(15) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(18) = tl ^ SUBL(19); /* round 13 */ - CAMELLIA_SUBKEY_R(18) = tr ^ SUBR(19); - CAMELLIA_SUBKEY_L(19) = SUBL(18) ^ SUBL(20); /* round 14 */ - CAMELLIA_SUBKEY_R(19) = SUBR(18) ^ SUBR(20); - CAMELLIA_SUBKEY_L(20) = SUBL(19) ^ SUBL(21); /* round 15 */ - CAMELLIA_SUBKEY_R(20) = SUBR(19) ^ SUBR(21); - CAMELLIA_SUBKEY_L(21) = SUBL(20) ^ SUBL(22); /* round 16 */ - CAMELLIA_SUBKEY_R(21) = SUBR(20) ^ SUBR(22); - CAMELLIA_SUBKEY_L(22) = SUBL(21) ^ SUBL(23); /* round 17 */ - CAMELLIA_SUBKEY_R(22) = SUBR(21) ^ SUBR(23); - CAMELLIA_SUBKEY_L(23) = SUBL(22); /* round 18 */ - CAMELLIA_SUBKEY_R(23) = SUBR(22); - CAMELLIA_SUBKEY_L(24) = SUBL(24) ^ SUBL(23); /* kw3 */ - CAMELLIA_SUBKEY_R(24) = SUBR(24) ^ SUBR(23); - - /* apply the inverse of the last half of P-function */ - dw = CAMELLIA_SUBKEY_L(2) ^ CAMELLIA_SUBKEY_R(2), - dw = CAMELLIA_RL8(dw);/* round 1 */ - CAMELLIA_SUBKEY_R(2) = CAMELLIA_SUBKEY_L(2) ^ dw, - CAMELLIA_SUBKEY_L(2) = dw; - dw = CAMELLIA_SUBKEY_L(3) ^ CAMELLIA_SUBKEY_R(3), - dw = CAMELLIA_RL8(dw);/* round 2 */ - CAMELLIA_SUBKEY_R(3) = CAMELLIA_SUBKEY_L(3) ^ dw, - CAMELLIA_SUBKEY_L(3) = dw; - dw = CAMELLIA_SUBKEY_L(4) ^ CAMELLIA_SUBKEY_R(4), - dw = CAMELLIA_RL8(dw);/* round 3 */ - CAMELLIA_SUBKEY_R(4) = CAMELLIA_SUBKEY_L(4) ^ dw, - CAMELLIA_SUBKEY_L(4) = dw; - dw = CAMELLIA_SUBKEY_L(5) ^ CAMELLIA_SUBKEY_R(5), - dw = CAMELLIA_RL8(dw);/* round 4 */ - CAMELLIA_SUBKEY_R(5) = CAMELLIA_SUBKEY_L(5) ^ dw, - CAMELLIA_SUBKEY_L(5) = dw; - dw = CAMELLIA_SUBKEY_L(6) ^ CAMELLIA_SUBKEY_R(6), - dw = CAMELLIA_RL8(dw);/* round 5 */ - CAMELLIA_SUBKEY_R(6) = CAMELLIA_SUBKEY_L(6) ^ dw, - CAMELLIA_SUBKEY_L(6) = dw; - dw = CAMELLIA_SUBKEY_L(7) ^ CAMELLIA_SUBKEY_R(7), - dw = CAMELLIA_RL8(dw);/* round 6 */ - CAMELLIA_SUBKEY_R(7) = CAMELLIA_SUBKEY_L(7) ^ dw, - CAMELLIA_SUBKEY_L(7) = dw; - dw = CAMELLIA_SUBKEY_L(10) ^ CAMELLIA_SUBKEY_R(10), - dw = CAMELLIA_RL8(dw);/* round 7 */ - CAMELLIA_SUBKEY_R(10) = CAMELLIA_SUBKEY_L(10) ^ dw, - CAMELLIA_SUBKEY_L(10) = dw; - dw = CAMELLIA_SUBKEY_L(11) ^ CAMELLIA_SUBKEY_R(11), - dw = CAMELLIA_RL8(dw);/* round 8 */ - CAMELLIA_SUBKEY_R(11) = CAMELLIA_SUBKEY_L(11) ^ dw, - CAMELLIA_SUBKEY_L(11) = dw; - dw = CAMELLIA_SUBKEY_L(12) ^ CAMELLIA_SUBKEY_R(12), - dw = CAMELLIA_RL8(dw);/* round 9 */ - CAMELLIA_SUBKEY_R(12) = CAMELLIA_SUBKEY_L(12) ^ dw, - CAMELLIA_SUBKEY_L(12) = dw; - dw = CAMELLIA_SUBKEY_L(13) ^ CAMELLIA_SUBKEY_R(13), - dw = CAMELLIA_RL8(dw);/* round 10 */ - CAMELLIA_SUBKEY_R(13) = CAMELLIA_SUBKEY_L(13) ^ dw, - CAMELLIA_SUBKEY_L(13) = dw; - dw = CAMELLIA_SUBKEY_L(14) ^ CAMELLIA_SUBKEY_R(14), - dw = CAMELLIA_RL8(dw);/* round 11 */ - CAMELLIA_SUBKEY_R(14) = CAMELLIA_SUBKEY_L(14) ^ dw, - CAMELLIA_SUBKEY_L(14) = dw; - dw = CAMELLIA_SUBKEY_L(15) ^ CAMELLIA_SUBKEY_R(15), - dw = CAMELLIA_RL8(dw);/* round 12 */ - CAMELLIA_SUBKEY_R(15) = CAMELLIA_SUBKEY_L(15) ^ dw, - CAMELLIA_SUBKEY_L(15) = dw; - dw = CAMELLIA_SUBKEY_L(18) ^ CAMELLIA_SUBKEY_R(18), - dw = CAMELLIA_RL8(dw);/* round 13 */ - CAMELLIA_SUBKEY_R(18) = CAMELLIA_SUBKEY_L(18) ^ dw, - CAMELLIA_SUBKEY_L(18) = dw; - dw = CAMELLIA_SUBKEY_L(19) ^ CAMELLIA_SUBKEY_R(19), - dw = CAMELLIA_RL8(dw);/* round 14 */ - CAMELLIA_SUBKEY_R(19) = CAMELLIA_SUBKEY_L(19) ^ dw, - CAMELLIA_SUBKEY_L(19) = dw; - dw = CAMELLIA_SUBKEY_L(20) ^ CAMELLIA_SUBKEY_R(20), - dw = CAMELLIA_RL8(dw);/* round 15 */ - CAMELLIA_SUBKEY_R(20) = CAMELLIA_SUBKEY_L(20) ^ dw, - CAMELLIA_SUBKEY_L(20) = dw; - dw = CAMELLIA_SUBKEY_L(21) ^ CAMELLIA_SUBKEY_R(21), - dw = CAMELLIA_RL8(dw);/* round 16 */ - CAMELLIA_SUBKEY_R(21) = CAMELLIA_SUBKEY_L(21) ^ dw, - CAMELLIA_SUBKEY_L(21) = dw; - dw = CAMELLIA_SUBKEY_L(22) ^ CAMELLIA_SUBKEY_R(22), - dw = CAMELLIA_RL8(dw);/* round 17 */ - CAMELLIA_SUBKEY_R(22) = CAMELLIA_SUBKEY_L(22) ^ dw, - CAMELLIA_SUBKEY_L(22) = dw; - dw = CAMELLIA_SUBKEY_L(23) ^ CAMELLIA_SUBKEY_R(23), - dw = CAMELLIA_RL8(dw);/* round 18 */ - CAMELLIA_SUBKEY_R(23) = CAMELLIA_SUBKEY_L(23) ^ dw, - CAMELLIA_SUBKEY_L(23) = dw; - - return; -} - - -static void camellia_setup256(const unsigned char *key, u32 *subkey) -{ - u32 kll,klr,krl,krr; /* left half of key */ - u32 krll,krlr,krrl,krrr; /* right half of key */ - u32 il, ir, t0, t1, w0, w1; /* temporary variables */ - u32 kw4l, kw4r, dw, tl, tr; - u32 subL[34]; - u32 subR[34]; - - /** - * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) - * (|| is concatination) - */ - - kll = GETU32(key ); - klr = GETU32(key + 4); - krl = GETU32(key + 8); - krr = GETU32(key + 12); - krll = GETU32(key + 16); - krlr = GETU32(key + 20); - krrl = GETU32(key + 24); - krrr = GETU32(key + 28); - - /* generate KL dependent subkeys */ - /* kw1 */ - SUBL(0) = kll; SUBR(0) = klr; - /* kw2 */ - SUBL(1) = krl; SUBR(1) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); - /* k9 */ - SUBL(12) = kll; SUBR(12) = klr; - /* k10 */ - SUBL(13) = krl; SUBR(13) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* kl3 */ - SUBL(16) = kll; SUBR(16) = klr; - /* kl4 */ - SUBL(17) = krl; SUBR(17) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k17 */ - SUBL(22) = kll; SUBR(22) = klr; - /* k18 */ - SUBL(23) = krl; SUBR(23) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); - /* k23 */ - SUBL(30) = kll; SUBR(30) = klr; - /* k24 */ - SUBL(31) = krl; SUBR(31) = krr; - - /* generate KR dependent subkeys */ - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); - /* k3 */ - SUBL(4) = krll; SUBR(4) = krlr; - /* k4 */ - SUBL(5) = krrl; SUBR(5) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); - /* kl1 */ - SUBL(8) = krll; SUBR(8) = krlr; - /* kl2 */ - SUBL(9) = krrl; SUBR(9) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k13 */ - SUBL(18) = krll; SUBR(18) = krlr; - /* k14 */ - SUBL(19) = krrl; SUBR(19) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); - /* k19 */ - SUBL(26) = krll; SUBR(26) = krlr; - /* k20 */ - SUBL(27) = krrl; SUBR(27) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); - - /* generate KA */ - kll = SUBL(0) ^ krll; klr = SUBR(0) ^ krlr; - krl = SUBL(1) ^ krrl; krr = SUBR(1) ^ krrr; - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, - w0, w1, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, - kll, klr, il, ir, t0, t1); - kll ^= krll; klr ^= krlr; - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, - krl, krr, il, ir, t0, t1); - krl ^= w0 ^ krrl; krr ^= w1 ^ krrr; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, - w0, w1, il, ir, t0, t1); - kll ^= w0; klr ^= w1; - - /* generate KB */ - krll ^= kll; krlr ^= klr; - krrl ^= krl; krrr ^= krr; - CAMELLIA_F(krll, krlr, - CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, - w0, w1, il, ir, t0, t1); - krrl ^= w0; krrr ^= w1; - CAMELLIA_F(krrl, krrr, - CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, - w0, w1, il, ir, t0, t1); - krll ^= w0; krlr ^= w1; - - /* generate KA dependent subkeys */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k5 */ - SUBL(6) = kll; SUBR(6) = klr; - /* k6 */ - SUBL(7) = krl; SUBR(7) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); - /* k11 */ - SUBL(14) = kll; SUBR(14) = klr; - /* k12 */ - SUBL(15) = krl; SUBR(15) = krr; - /* rotation left shift 32bit */ - /* kl5 */ - SUBL(24) = klr; SUBR(24) = krl; - /* kl6 */ - SUBL(25) = krr; SUBR(25) = kll; - /* rotation left shift 49 from k11,k12 -> k21,k22 */ - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49); - /* k21 */ - SUBL(28) = kll; SUBR(28) = klr; - /* k22 */ - SUBL(29) = krl; SUBR(29) = krr; - - /* generate KB dependent subkeys */ - /* k1 */ - SUBL(2) = krll; SUBR(2) = krlr; - /* k2 */ - SUBL(3) = krrl; SUBR(3) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k7 */ - SUBL(10) = krll; SUBR(10) = krlr; - /* k8 */ - SUBL(11) = krrl; SUBR(11) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k15 */ - SUBL(20) = krll; SUBR(20) = krlr; - /* k16 */ - SUBL(21) = krrl; SUBR(21) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51); - /* kw3 */ - SUBL(32) = krll; SUBR(32) = krlr; - /* kw4 */ - SUBL(33) = krrl; SUBR(33) = krrr; - - /* absorb kw2 to other subkeys */ - /* round 2 */ - SUBL(3) ^= SUBL(1); SUBR(3) ^= SUBR(1); - /* round 4 */ - SUBL(5) ^= SUBL(1); SUBR(5) ^= SUBR(1); - /* round 6 */ - SUBL(7) ^= SUBL(1); SUBR(7) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(9); - dw = SUBL(1) & SUBL(9), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ - /* round 8 */ - SUBL(11) ^= SUBL(1); SUBR(11) ^= SUBR(1); - /* round 10 */ - SUBL(13) ^= SUBL(1); SUBR(13) ^= SUBR(1); - /* round 12 */ - SUBL(15) ^= SUBL(1); SUBR(15) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(17); - dw = SUBL(1) & SUBL(17), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ - /* round 14 */ - SUBL(19) ^= SUBL(1); SUBR(19) ^= SUBR(1); - /* round 16 */ - SUBL(21) ^= SUBL(1); SUBR(21) ^= SUBR(1); - /* round 18 */ - SUBL(23) ^= SUBL(1); SUBR(23) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(25); - dw = SUBL(1) & SUBL(25), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl6) */ - /* round 20 */ - SUBL(27) ^= SUBL(1); SUBR(27) ^= SUBR(1); - /* round 22 */ - SUBL(29) ^= SUBL(1); SUBR(29) ^= SUBR(1); - /* round 24 */ - SUBL(31) ^= SUBL(1); SUBR(31) ^= SUBR(1); - /* kw3 */ - SUBL(32) ^= SUBL(1); SUBR(32) ^= SUBR(1); - - - /* absorb kw4 to other subkeys */ - kw4l = SUBL(33); kw4r = SUBR(33); - /* round 23 */ - SUBL(30) ^= kw4l; SUBR(30) ^= kw4r; - /* round 21 */ - SUBL(28) ^= kw4l; SUBR(28) ^= kw4r; - /* round 19 */ - SUBL(26) ^= kw4l; SUBR(26) ^= kw4r; - kw4l ^= kw4r & ~SUBR(24); - dw = kw4l & SUBL(24), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */ - /* round 17 */ - SUBL(22) ^= kw4l; SUBR(22) ^= kw4r; - /* round 15 */ - SUBL(20) ^= kw4l; SUBR(20) ^= kw4r; - /* round 13 */ - SUBL(18) ^= kw4l; SUBR(18) ^= kw4r; - kw4l ^= kw4r & ~SUBR(16); - dw = kw4l & SUBL(16), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ - /* round 11 */ - SUBL(14) ^= kw4l; SUBR(14) ^= kw4r; - /* round 9 */ - SUBL(12) ^= kw4l; SUBR(12) ^= kw4r; - /* round 7 */ - SUBL(10) ^= kw4l; SUBR(10) ^= kw4r; - kw4l ^= kw4r & ~SUBR(8); - dw = kw4l & SUBL(8), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ - /* round 5 */ - SUBL(6) ^= kw4l; SUBR(6) ^= kw4r; - /* round 3 */ - SUBL(4) ^= kw4l; SUBR(4) ^= kw4r; - /* round 1 */ - SUBL(2) ^= kw4l; SUBR(2) ^= kw4r; - /* kw1 */ - SUBL(0) ^= kw4l; SUBR(0) ^= kw4r; - - /* key XOR is end of F-function */ - CAMELLIA_SUBKEY_L(0) = SUBL(0) ^ SUBL(2);/* kw1 */ - CAMELLIA_SUBKEY_R(0) = SUBR(0) ^ SUBR(2); - CAMELLIA_SUBKEY_L(2) = SUBL(3); /* round 1 */ - CAMELLIA_SUBKEY_R(2) = SUBR(3); - CAMELLIA_SUBKEY_L(3) = SUBL(2) ^ SUBL(4); /* round 2 */ - CAMELLIA_SUBKEY_R(3) = SUBR(2) ^ SUBR(4); - CAMELLIA_SUBKEY_L(4) = SUBL(3) ^ SUBL(5); /* round 3 */ - CAMELLIA_SUBKEY_R(4) = SUBR(3) ^ SUBR(5); - CAMELLIA_SUBKEY_L(5) = SUBL(4) ^ SUBL(6); /* round 4 */ - CAMELLIA_SUBKEY_R(5) = SUBR(4) ^ SUBR(6); - CAMELLIA_SUBKEY_L(6) = SUBL(5) ^ SUBL(7); /* round 5 */ - CAMELLIA_SUBKEY_R(6) = SUBR(5) ^ SUBR(7); - tl = SUBL(10) ^ (SUBR(10) & ~SUBR(8)); - dw = tl & SUBL(8), /* FL(kl1) */ - tr = SUBR(10) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(7) = SUBL(6) ^ tl; /* round 6 */ - CAMELLIA_SUBKEY_R(7) = SUBR(6) ^ tr; - CAMELLIA_SUBKEY_L(8) = SUBL(8); /* FL(kl1) */ - CAMELLIA_SUBKEY_R(8) = SUBR(8); - CAMELLIA_SUBKEY_L(9) = SUBL(9); /* FLinv(kl2) */ - CAMELLIA_SUBKEY_R(9) = SUBR(9); - tl = SUBL(7) ^ (SUBR(7) & ~SUBR(9)); - dw = tl & SUBL(9), /* FLinv(kl2) */ - tr = SUBR(7) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(10) = tl ^ SUBL(11); /* round 7 */ - CAMELLIA_SUBKEY_R(10) = tr ^ SUBR(11); - CAMELLIA_SUBKEY_L(11) = SUBL(10) ^ SUBL(12); /* round 8 */ - CAMELLIA_SUBKEY_R(11) = SUBR(10) ^ SUBR(12); - CAMELLIA_SUBKEY_L(12) = SUBL(11) ^ SUBL(13); /* round 9 */ - CAMELLIA_SUBKEY_R(12) = SUBR(11) ^ SUBR(13); - CAMELLIA_SUBKEY_L(13) = SUBL(12) ^ SUBL(14); /* round 10 */ - CAMELLIA_SUBKEY_R(13) = SUBR(12) ^ SUBR(14); - CAMELLIA_SUBKEY_L(14) = SUBL(13) ^ SUBL(15); /* round 11 */ - CAMELLIA_SUBKEY_R(14) = SUBR(13) ^ SUBR(15); - tl = SUBL(18) ^ (SUBR(18) & ~SUBR(16)); - dw = tl & SUBL(16), /* FL(kl3) */ - tr = SUBR(18) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(15) = SUBL(14) ^ tl; /* round 12 */ - CAMELLIA_SUBKEY_R(15) = SUBR(14) ^ tr; - CAMELLIA_SUBKEY_L(16) = SUBL(16); /* FL(kl3) */ - CAMELLIA_SUBKEY_R(16) = SUBR(16); - CAMELLIA_SUBKEY_L(17) = SUBL(17); /* FLinv(kl4) */ - CAMELLIA_SUBKEY_R(17) = SUBR(17); - tl = SUBL(15) ^ (SUBR(15) & ~SUBR(17)); - dw = tl & SUBL(17), /* FLinv(kl4) */ - tr = SUBR(15) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(18) = tl ^ SUBL(19); /* round 13 */ - CAMELLIA_SUBKEY_R(18) = tr ^ SUBR(19); - CAMELLIA_SUBKEY_L(19) = SUBL(18) ^ SUBL(20); /* round 14 */ - CAMELLIA_SUBKEY_R(19) = SUBR(18) ^ SUBR(20); - CAMELLIA_SUBKEY_L(20) = SUBL(19) ^ SUBL(21); /* round 15 */ - CAMELLIA_SUBKEY_R(20) = SUBR(19) ^ SUBR(21); - CAMELLIA_SUBKEY_L(21) = SUBL(20) ^ SUBL(22); /* round 16 */ - CAMELLIA_SUBKEY_R(21) = SUBR(20) ^ SUBR(22); - CAMELLIA_SUBKEY_L(22) = SUBL(21) ^ SUBL(23); /* round 17 */ - CAMELLIA_SUBKEY_R(22) = SUBR(21) ^ SUBR(23); - tl = SUBL(26) ^ (SUBR(26) - & ~SUBR(24)); - dw = tl & SUBL(24), /* FL(kl5) */ - tr = SUBR(26) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(23) = SUBL(22) ^ tl; /* round 18 */ - CAMELLIA_SUBKEY_R(23) = SUBR(22) ^ tr; - CAMELLIA_SUBKEY_L(24) = SUBL(24); /* FL(kl5) */ - CAMELLIA_SUBKEY_R(24) = SUBR(24); - CAMELLIA_SUBKEY_L(25) = SUBL(25); /* FLinv(kl6) */ - CAMELLIA_SUBKEY_R(25) = SUBR(25); - tl = SUBL(23) ^ (SUBR(23) & - ~SUBR(25)); - dw = tl & SUBL(25), /* FLinv(kl6) */ - tr = SUBR(23) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(26) = tl ^ SUBL(27); /* round 19 */ - CAMELLIA_SUBKEY_R(26) = tr ^ SUBR(27); - CAMELLIA_SUBKEY_L(27) = SUBL(26) ^ SUBL(28); /* round 20 */ - CAMELLIA_SUBKEY_R(27) = SUBR(26) ^ SUBR(28); - CAMELLIA_SUBKEY_L(28) = SUBL(27) ^ SUBL(29); /* round 21 */ - CAMELLIA_SUBKEY_R(28) = SUBR(27) ^ SUBR(29); - CAMELLIA_SUBKEY_L(29) = SUBL(28) ^ SUBL(30); /* round 22 */ - CAMELLIA_SUBKEY_R(29) = SUBR(28) ^ SUBR(30); - CAMELLIA_SUBKEY_L(30) = SUBL(29) ^ SUBL(31); /* round 23 */ - CAMELLIA_SUBKEY_R(30) = SUBR(29) ^ SUBR(31); - CAMELLIA_SUBKEY_L(31) = SUBL(30); /* round 24 */ - CAMELLIA_SUBKEY_R(31) = SUBR(30); - CAMELLIA_SUBKEY_L(32) = SUBL(32) ^ SUBL(31); /* kw3 */ - CAMELLIA_SUBKEY_R(32) = SUBR(32) ^ SUBR(31); - - /* apply the inverse of the last half of P-function */ - dw = CAMELLIA_SUBKEY_L(2) ^ CAMELLIA_SUBKEY_R(2), - dw = CAMELLIA_RL8(dw);/* round 1 */ - CAMELLIA_SUBKEY_R(2) = CAMELLIA_SUBKEY_L(2) ^ dw, - CAMELLIA_SUBKEY_L(2) = dw; - dw = CAMELLIA_SUBKEY_L(3) ^ CAMELLIA_SUBKEY_R(3), - dw = CAMELLIA_RL8(dw);/* round 2 */ - CAMELLIA_SUBKEY_R(3) = CAMELLIA_SUBKEY_L(3) ^ dw, - CAMELLIA_SUBKEY_L(3) = dw; - dw = CAMELLIA_SUBKEY_L(4) ^ CAMELLIA_SUBKEY_R(4), - dw = CAMELLIA_RL8(dw);/* round 3 */ - CAMELLIA_SUBKEY_R(4) = CAMELLIA_SUBKEY_L(4) ^ dw, - CAMELLIA_SUBKEY_L(4) = dw; - dw = CAMELLIA_SUBKEY_L(5) ^ CAMELLIA_SUBKEY_R(5), - dw = CAMELLIA_RL8(dw);/* round 4 */ - CAMELLIA_SUBKEY_R(5) = CAMELLIA_SUBKEY_L(5) ^ dw, - CAMELLIA_SUBKEY_L(5) = dw; - dw = CAMELLIA_SUBKEY_L(6) ^ CAMELLIA_SUBKEY_R(6), - dw = CAMELLIA_RL8(dw);/* round 5 */ - CAMELLIA_SUBKEY_R(6) = CAMELLIA_SUBKEY_L(6) ^ dw, - CAMELLIA_SUBKEY_L(6) = dw; - dw = CAMELLIA_SUBKEY_L(7) ^ CAMELLIA_SUBKEY_R(7), - dw = CAMELLIA_RL8(dw);/* round 6 */ - CAMELLIA_SUBKEY_R(7) = CAMELLIA_SUBKEY_L(7) ^ dw, - CAMELLIA_SUBKEY_L(7) = dw; - dw = CAMELLIA_SUBKEY_L(10) ^ CAMELLIA_SUBKEY_R(10), - dw = CAMELLIA_RL8(dw);/* round 7 */ - CAMELLIA_SUBKEY_R(10) = CAMELLIA_SUBKEY_L(10) ^ dw, - CAMELLIA_SUBKEY_L(10) = dw; - dw = CAMELLIA_SUBKEY_L(11) ^ CAMELLIA_SUBKEY_R(11), - dw = CAMELLIA_RL8(dw);/* round 8 */ - CAMELLIA_SUBKEY_R(11) = CAMELLIA_SUBKEY_L(11) ^ dw, - CAMELLIA_SUBKEY_L(11) = dw; - dw = CAMELLIA_SUBKEY_L(12) ^ CAMELLIA_SUBKEY_R(12), - dw = CAMELLIA_RL8(dw);/* round 9 */ - CAMELLIA_SUBKEY_R(12) = CAMELLIA_SUBKEY_L(12) ^ dw, - CAMELLIA_SUBKEY_L(12) = dw; - dw = CAMELLIA_SUBKEY_L(13) ^ CAMELLIA_SUBKEY_R(13), - dw = CAMELLIA_RL8(dw);/* round 10 */ - CAMELLIA_SUBKEY_R(13) = CAMELLIA_SUBKEY_L(13) ^ dw, - CAMELLIA_SUBKEY_L(13) = dw; - dw = CAMELLIA_SUBKEY_L(14) ^ CAMELLIA_SUBKEY_R(14), - dw = CAMELLIA_RL8(dw);/* round 11 */ - CAMELLIA_SUBKEY_R(14) = CAMELLIA_SUBKEY_L(14) ^ dw, - CAMELLIA_SUBKEY_L(14) = dw; - dw = CAMELLIA_SUBKEY_L(15) ^ CAMELLIA_SUBKEY_R(15), - dw = CAMELLIA_RL8(dw);/* round 12 */ - CAMELLIA_SUBKEY_R(15) = CAMELLIA_SUBKEY_L(15) ^ dw, - CAMELLIA_SUBKEY_L(15) = dw; - dw = CAMELLIA_SUBKEY_L(18) ^ CAMELLIA_SUBKEY_R(18), - dw = CAMELLIA_RL8(dw);/* round 13 */ - CAMELLIA_SUBKEY_R(18) = CAMELLIA_SUBKEY_L(18) ^ dw, - CAMELLIA_SUBKEY_L(18) = dw; - dw = CAMELLIA_SUBKEY_L(19) ^ CAMELLIA_SUBKEY_R(19), - dw = CAMELLIA_RL8(dw);/* round 14 */ - CAMELLIA_SUBKEY_R(19) = CAMELLIA_SUBKEY_L(19) ^ dw, - CAMELLIA_SUBKEY_L(19) = dw; - dw = CAMELLIA_SUBKEY_L(20) ^ CAMELLIA_SUBKEY_R(20), - dw = CAMELLIA_RL8(dw);/* round 15 */ - CAMELLIA_SUBKEY_R(20) = CAMELLIA_SUBKEY_L(20) ^ dw, - CAMELLIA_SUBKEY_L(20) = dw; - dw = CAMELLIA_SUBKEY_L(21) ^ CAMELLIA_SUBKEY_R(21), - dw = CAMELLIA_RL8(dw);/* round 16 */ - CAMELLIA_SUBKEY_R(21) = CAMELLIA_SUBKEY_L(21) ^ dw, - CAMELLIA_SUBKEY_L(21) = dw; - dw = CAMELLIA_SUBKEY_L(22) ^ CAMELLIA_SUBKEY_R(22), - dw = CAMELLIA_RL8(dw);/* round 17 */ - CAMELLIA_SUBKEY_R(22) = CAMELLIA_SUBKEY_L(22) ^ dw, - CAMELLIA_SUBKEY_L(22) = dw; - dw = CAMELLIA_SUBKEY_L(23) ^ CAMELLIA_SUBKEY_R(23), - dw = CAMELLIA_RL8(dw);/* round 18 */ - CAMELLIA_SUBKEY_R(23) = CAMELLIA_SUBKEY_L(23) ^ dw, - CAMELLIA_SUBKEY_L(23) = dw; - dw = CAMELLIA_SUBKEY_L(26) ^ CAMELLIA_SUBKEY_R(26), - dw = CAMELLIA_RL8(dw);/* round 19 */ - CAMELLIA_SUBKEY_R(26) = CAMELLIA_SUBKEY_L(26) ^ dw, - CAMELLIA_SUBKEY_L(26) = dw; - dw = CAMELLIA_SUBKEY_L(27) ^ CAMELLIA_SUBKEY_R(27), - dw = CAMELLIA_RL8(dw);/* round 20 */ - CAMELLIA_SUBKEY_R(27) = CAMELLIA_SUBKEY_L(27) ^ dw, - CAMELLIA_SUBKEY_L(27) = dw; - dw = CAMELLIA_SUBKEY_L(28) ^ CAMELLIA_SUBKEY_R(28), - dw = CAMELLIA_RL8(dw);/* round 21 */ - CAMELLIA_SUBKEY_R(28) = CAMELLIA_SUBKEY_L(28) ^ dw, - CAMELLIA_SUBKEY_L(28) = dw; - dw = CAMELLIA_SUBKEY_L(29) ^ CAMELLIA_SUBKEY_R(29), - dw = CAMELLIA_RL8(dw);/* round 22 */ - CAMELLIA_SUBKEY_R(29) = CAMELLIA_SUBKEY_L(29) ^ dw, - CAMELLIA_SUBKEY_L(29) = dw; - dw = CAMELLIA_SUBKEY_L(30) ^ CAMELLIA_SUBKEY_R(30), - dw = CAMELLIA_RL8(dw);/* round 23 */ - CAMELLIA_SUBKEY_R(30) = CAMELLIA_SUBKEY_L(30) ^ dw, - CAMELLIA_SUBKEY_L(30) = dw; - dw = CAMELLIA_SUBKEY_L(31) ^ CAMELLIA_SUBKEY_R(31), - dw = CAMELLIA_RL8(dw);/* round 24 */ - CAMELLIA_SUBKEY_R(31) = CAMELLIA_SUBKEY_L(31) ^ dw, - CAMELLIA_SUBKEY_L(31) = dw; - - return; -} - -static void camellia_setup192(const unsigned char *key, u32 *subkey) -{ - unsigned char kk[32]; - u32 krll, krlr, krrl,krrr; - - memcpy(kk, key, 24); - memcpy((unsigned char *)&krll, key+16,4); - memcpy((unsigned char *)&krlr, key+20,4); - krrl = ~krll; - krrr = ~krlr; - memcpy(kk+24, (unsigned char *)&krrl, 4); - memcpy(kk+28, (unsigned char *)&krrr, 4); - camellia_setup256(kk, subkey); - return; -} - - -/** - * Stuff related to camellia encryption/decryption - */ -static void camellia_encrypt128(const u32 *subkey, __be32 *io_text) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - u32 io[4]; - - io[0] = be32_to_cpu(io_text[0]); - io[1] = be32_to_cpu(io_text[1]); - io[2] = be32_to_cpu(io_text[2]); - io[3] = be32_to_cpu(io_text[3]); - - /* pre whitening but absorb kw2*/ - io[0] ^= CAMELLIA_SUBKEY_L(0); - io[1] ^= CAMELLIA_SUBKEY_R(0); - /* main iteration */ - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8), - CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16), - CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CAMELLIA_SUBKEY_L(24); - io[3] ^= CAMELLIA_SUBKEY_R(24); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - io_text[0] = cpu_to_be32(io[0]); - io_text[1] = cpu_to_be32(io[1]); - io_text[2] = cpu_to_be32(io[2]); - io_text[3] = cpu_to_be32(io[3]); - - return; -} - -static void camellia_decrypt128(const u32 *subkey, __be32 *io_text) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - u32 io[4]; - - io[0] = be32_to_cpu(io_text[0]); - io[1] = be32_to_cpu(io_text[1]); - io[2] = be32_to_cpu(io_text[2]); - io[3] = be32_to_cpu(io_text[3]); - - /* pre whitening but absorb kw2*/ - io[0] ^= CAMELLIA_SUBKEY_L(24); - io[1] ^= CAMELLIA_SUBKEY_R(24); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17), - CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9), - CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CAMELLIA_SUBKEY_L(0); - io[3] ^= CAMELLIA_SUBKEY_R(0); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - io_text[0] = cpu_to_be32(io[0]); - io_text[1] = cpu_to_be32(io[1]); - io_text[2] = cpu_to_be32(io[2]); - io_text[3] = cpu_to_be32(io[3]); - - return; -} - - -/** - * stuff for 192 and 256bit encryption/decryption - */ -static void camellia_encrypt256(const u32 *subkey, __be32 *io_text) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - u32 io[4]; - - io[0] = be32_to_cpu(io_text[0]); - io[1] = be32_to_cpu(io_text[1]); - io[2] = be32_to_cpu(io_text[2]); - io[3] = be32_to_cpu(io_text[3]); - - /* pre whitening but absorb kw2*/ - io[0] ^= CAMELLIA_SUBKEY_L(0); - io[1] ^= CAMELLIA_SUBKEY_R(0); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8), - CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16), - CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(24),CAMELLIA_SUBKEY_R(24), - CAMELLIA_SUBKEY_L(25),CAMELLIA_SUBKEY_R(25), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(26),CAMELLIA_SUBKEY_R(26), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(27),CAMELLIA_SUBKEY_R(27), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(28),CAMELLIA_SUBKEY_R(28), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(29),CAMELLIA_SUBKEY_R(29), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(30),CAMELLIA_SUBKEY_R(30), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(31),CAMELLIA_SUBKEY_R(31), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CAMELLIA_SUBKEY_L(32); - io[3] ^= CAMELLIA_SUBKEY_R(32); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - io_text[0] = cpu_to_be32(io[0]); - io_text[1] = cpu_to_be32(io[1]); - io_text[2] = cpu_to_be32(io[2]); - io_text[3] = cpu_to_be32(io[3]); - - return; -} - - -static void camellia_decrypt256(const u32 *subkey, __be32 *io_text) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - u32 io[4]; - - io[0] = be32_to_cpu(io_text[0]); - io[1] = be32_to_cpu(io_text[1]); - io[2] = be32_to_cpu(io_text[2]); - io[3] = be32_to_cpu(io_text[3]); - - /* pre whitening but absorb kw2*/ - io[0] ^= CAMELLIA_SUBKEY_L(32); - io[1] ^= CAMELLIA_SUBKEY_R(32); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(31),CAMELLIA_SUBKEY_R(31), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(30),CAMELLIA_SUBKEY_R(30), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(29),CAMELLIA_SUBKEY_R(29), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(28),CAMELLIA_SUBKEY_R(28), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(27),CAMELLIA_SUBKEY_R(27), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(26),CAMELLIA_SUBKEY_R(26), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(25),CAMELLIA_SUBKEY_R(25), - CAMELLIA_SUBKEY_L(24),CAMELLIA_SUBKEY_R(24), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17), - CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9), - CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CAMELLIA_SUBKEY_L(0); - io[3] ^= CAMELLIA_SUBKEY_R(0); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - io_text[0] = cpu_to_be32(io[0]); - io_text[1] = cpu_to_be32(io[1]); - io_text[2] = cpu_to_be32(io[2]); - io_text[3] = cpu_to_be32(io[3]); - - return; -} - - -static int -camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len) -{ - struct camellia_ctx *cctx = crypto_tfm_ctx(tfm); - const unsigned char *key = (const unsigned char *)in_key; - u32 *flags = &tfm->crt_flags; - - if (key_len != 16 && key_len != 24 && key_len != 32) { - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; - return -EINVAL; - } - - cctx->key_length = key_len; - - switch(key_len) { - case 16: - camellia_setup128(key, cctx->key_table); - break; - case 24: - camellia_setup192(key, cctx->key_table); - break; - case 32: - camellia_setup256(key, cctx->key_table); - break; - default: - break; - } - - return 0; -} - - -static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) -{ - const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm); - const __be32 *src = (const __be32 *)in; - __be32 *dst = (__be32 *)out; - - __be32 tmp[4]; - - memcpy(tmp, src, CAMELLIA_BLOCK_SIZE); - - switch (cctx->key_length) { - case 16: - camellia_encrypt128(cctx->key_table, tmp); - break; - case 24: - /* fall through */ - case 32: - camellia_encrypt256(cctx->key_table, tmp); - break; - default: - break; - } - - memcpy(dst, tmp, CAMELLIA_BLOCK_SIZE); -} - - -static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) -{ - const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm); - const __be32 *src = (const __be32 *)in; - __be32 *dst = (__be32 *)out; - - __be32 tmp[4]; - - memcpy(tmp, src, CAMELLIA_BLOCK_SIZE); - - switch (cctx->key_length) { - case 16: - camellia_decrypt128(cctx->key_table, tmp); - break; - case 24: - /* fall through */ - case 32: - camellia_decrypt256(cctx->key_table, tmp); - break; - default: - break; - } - - memcpy(dst, tmp, CAMELLIA_BLOCK_SIZE); -} - - -static struct crypto_alg camellia_alg = { - .cra_name = "camellia", - .cra_driver_name = "camellia-generic", - .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, - .cra_blocksize = CAMELLIA_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct camellia_ctx), - .cra_alignmask = 3, - .cra_module = THIS_MODULE, - .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list), - .cra_u = { - .cipher = { - .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE, - .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE, - .cia_setkey = camellia_set_key, - .cia_encrypt = camellia_encrypt, - .cia_decrypt = camellia_decrypt - } - } -}; - -static int __init camellia_init(void) -{ - return crypto_register_alg(&camellia_alg); -} - - -static void __exit camellia_fini(void) -{ - crypto_unregister_alg(&camellia_alg); -} - - -module_init(camellia_init); -module_exit(camellia_fini); - - -MODULE_DESCRIPTION("Camellia Cipher Algorithm"); -MODULE_LICENSE("GPL"); diff --git a/trunk/crypto/cbc.c b/trunk/crypto/cbc.c index 136fea7e7000..f5542b4db387 100644 --- a/trunk/crypto/cbc.c +++ b/trunk/crypto/cbc.c @@ -243,7 +243,6 @@ static int crypto_cbc_init_tfm(struct crypto_tfm *tfm) struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct crypto_cbc_ctx *ctx = crypto_tfm_ctx(tfm); - struct crypto_cipher *cipher; switch (crypto_tfm_alg_blocksize(tfm)) { case 8: @@ -261,11 +260,11 @@ static int crypto_cbc_init_tfm(struct crypto_tfm *tfm) ctx->xor = xor_quad; } - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - ctx->child = cipher; + ctx->child = crypto_cipher_cast(tfm); return 0; } diff --git a/trunk/crypto/cipher.c b/trunk/crypto/cipher.c index 333aab2f0277..9e03701cfdcc 100644 --- a/trunk/crypto/cipher.c +++ b/trunk/crypto/cipher.c @@ -12,13 +12,274 @@ * any later version. * */ - +#include #include #include #include -#include +#include +#include #include +#include #include "internal.h" +#include "scatterwalk.h" + +struct cipher_alg_compat { + unsigned int cia_min_keysize; + unsigned int cia_max_keysize; + int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen); + void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); + void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); + + unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); +}; + +static inline void xor_64(u8 *a, const u8 *b) +{ + ((u32 *)a)[0] ^= ((u32 *)b)[0]; + ((u32 *)a)[1] ^= ((u32 *)b)[1]; +} + +static inline void xor_128(u8 *a, const u8 *b) +{ + ((u32 *)a)[0] ^= ((u32 *)b)[0]; + ((u32 *)a)[1] ^= ((u32 *)b)[1]; + ((u32 *)a)[2] ^= ((u32 *)b)[2]; + ((u32 *)a)[3] ^= ((u32 *)b)[3]; +} + +static unsigned int crypt_slow(const struct cipher_desc *desc, + struct scatter_walk *in, + struct scatter_walk *out, unsigned int bsize) +{ + unsigned long alignmask = crypto_tfm_alg_alignmask(desc->tfm); + u8 buffer[bsize * 2 + alignmask]; + u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + u8 *dst = src + bsize; + + scatterwalk_copychunks(src, in, bsize, 0); + desc->prfn(desc, dst, src, bsize); + scatterwalk_copychunks(dst, out, bsize, 1); + + return bsize; +} + +static inline unsigned int crypt_fast(const struct cipher_desc *desc, + struct scatter_walk *in, + struct scatter_walk *out, + unsigned int nbytes, u8 *tmp) +{ + u8 *src, *dst; + u8 *real_src, *real_dst; + + real_src = scatterwalk_map(in, 0); + real_dst = scatterwalk_map(out, 1); + + src = real_src; + dst = scatterwalk_samebuf(in, out) ? src : real_dst; + + if (tmp) { + memcpy(tmp, src, nbytes); + src = tmp; + dst = tmp; + } + + nbytes = desc->prfn(desc, dst, src, nbytes); + + if (tmp) + memcpy(real_dst, tmp, nbytes); + + scatterwalk_unmap(real_src, 0); + scatterwalk_unmap(real_dst, 1); + + scatterwalk_advance(in, nbytes); + scatterwalk_advance(out, nbytes); + + return nbytes; +} + +/* + * Generic encrypt/decrypt wrapper for ciphers, handles operations across + * multiple page boundaries by using temporary blocks. In user context, + * the kernel is given a chance to schedule us once per page. + */ +static int crypt(const struct cipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct scatter_walk walk_in, walk_out; + struct crypto_tfm *tfm = desc->tfm; + const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); + unsigned long buffer = 0; + + if (!nbytes) + return 0; + + if (nbytes % bsize) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; + return -EINVAL; + } + + scatterwalk_start(&walk_in, src); + scatterwalk_start(&walk_out, dst); + + for(;;) { + unsigned int n = nbytes; + u8 *tmp = NULL; + + if (!scatterwalk_aligned(&walk_in, alignmask) || + !scatterwalk_aligned(&walk_out, alignmask)) { + if (!buffer) { + buffer = __get_free_page(GFP_ATOMIC); + if (!buffer) + n = 0; + } + tmp = (u8 *)buffer; + } + + n = scatterwalk_clamp(&walk_in, n); + n = scatterwalk_clamp(&walk_out, n); + + if (likely(n >= bsize)) + n = crypt_fast(desc, &walk_in, &walk_out, n, tmp); + else + n = crypt_slow(desc, &walk_in, &walk_out, bsize); + + nbytes -= n; + + scatterwalk_done(&walk_in, 0, nbytes); + scatterwalk_done(&walk_out, 1, nbytes); + + if (!nbytes) + break; + + crypto_yield(tfm->crt_flags); + } + + if (buffer) + free_page(buffer); + + return 0; +} + +static int crypt_iv_unaligned(struct cipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); + u8 *iv = desc->info; + + if (unlikely(((unsigned long)iv & alignmask))) { + unsigned int ivsize = tfm->crt_cipher.cit_ivsize; + u8 buffer[ivsize + alignmask]; + u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + int err; + + desc->info = memcpy(tmp, iv, ivsize); + err = crypt(desc, dst, src, nbytes); + memcpy(iv, tmp, ivsize); + + return err; + } + + return crypt(desc, dst, src, nbytes); +} + +static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; + int bsize = crypto_tfm_alg_blocksize(tfm); + + void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + u8 *iv = desc->info; + unsigned int done = 0; + + nbytes -= bsize; + + do { + xor(iv, src); + fn(tfm, dst, iv); + memcpy(iv, dst, bsize); + + src += bsize; + dst += bsize; + } while ((done += bsize) <= nbytes); + + return done; +} + +static unsigned int cbc_process_decrypt(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; + int bsize = crypto_tfm_alg_blocksize(tfm); + unsigned long alignmask = crypto_tfm_alg_alignmask(desc->tfm); + + u8 stack[src == dst ? bsize + alignmask : 0]; + u8 *buf = (u8 *)ALIGN((unsigned long)stack, alignmask + 1); + u8 **dst_p = src == dst ? &buf : &dst; + + void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + u8 *iv = desc->info; + unsigned int done = 0; + + nbytes -= bsize; + + do { + u8 *tmp_dst = *dst_p; + + fn(tfm, tmp_dst, src); + xor(tmp_dst, iv); + memcpy(iv, src, bsize); + if (tmp_dst != dst) + memcpy(dst, tmp_dst, bsize); + + src += bsize; + dst += bsize; + } while ((done += bsize) <= nbytes); + + return done; +} + +static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst, + const u8 *src, unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + int bsize = crypto_tfm_alg_blocksize(tfm); + void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + unsigned int done = 0; + + nbytes -= bsize; + + do { + fn(tfm, dst, src); + + src += bsize; + dst += bsize; + } while ((done += bsize) <= nbytes); + + return done; +} static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { @@ -32,6 +293,122 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) return cia->cia_setkey(tfm, key, keylen); } +static int ecb_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_ecb ?: ecb_process; + + return crypt(&desc, dst, src, nbytes); +} + +static int ecb_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_ecb ?: ecb_process; + + return crypt(&desc, dst, src, nbytes); +} + +static int cbc_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; + desc.info = tfm->crt_cipher.cit_iv; + + return crypt(&desc, dst, src, nbytes); +} + +static int cbc_encrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; + desc.info = iv; + + return crypt_iv_unaligned(&desc, dst, src, nbytes); +} + +static int cbc_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; + desc.info = tfm->crt_cipher.cit_iv; + + return crypt(&desc, dst, src, nbytes); +} + +static int cbc_decrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; + desc.info = iv; + + return crypt_iv_unaligned(&desc, dst, src, nbytes); +} + +static int nocrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return -ENOSYS; +} + +static int nocrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + return -ENOSYS; +} + +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags) +{ + u32 mode = flags & CRYPTO_TFM_MODE_MASK; + tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB; + return 0; +} + static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *, const u8 *), struct crypto_tfm *tfm, @@ -77,6 +454,7 @@ static void cipher_decrypt_unaligned(struct crypto_tfm *tfm, int crypto_init_cipher_ops(struct crypto_tfm *tfm) { + int ret = 0; struct cipher_tfm *ops = &tfm->crt_cipher; struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; @@ -86,7 +464,70 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm) ops->cit_decrypt_one = crypto_tfm_alg_alignmask(tfm) ? cipher_decrypt_unaligned : cipher->cia_decrypt; - return 0; + switch (tfm->crt_cipher.cit_mode) { + case CRYPTO_TFM_MODE_ECB: + ops->cit_encrypt = ecb_encrypt; + ops->cit_decrypt = ecb_decrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + case CRYPTO_TFM_MODE_CBC: + ops->cit_encrypt = cbc_encrypt; + ops->cit_decrypt = cbc_decrypt; + ops->cit_encrypt_iv = cbc_encrypt_iv; + ops->cit_decrypt_iv = cbc_decrypt_iv; + break; + + case CRYPTO_TFM_MODE_CFB: + ops->cit_encrypt = nocrypt; + ops->cit_decrypt = nocrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + case CRYPTO_TFM_MODE_CTR: + ops->cit_encrypt = nocrypt; + ops->cit_decrypt = nocrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + default: + BUG(); + } + + if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) { + unsigned long align; + unsigned long addr; + + switch (crypto_tfm_alg_blocksize(tfm)) { + case 8: + ops->cit_xor_block = xor_64; + break; + + case 16: + ops->cit_xor_block = xor_128; + break; + + default: + printk(KERN_WARNING "%s: block size %u not supported\n", + crypto_tfm_alg_name(tfm), + crypto_tfm_alg_blocksize(tfm)); + ret = -EINVAL; + goto out; + } + + ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm); + align = crypto_tfm_alg_alignmask(tfm) + 1; + addr = (unsigned long)crypto_tfm_ctx(tfm); + addr = ALIGN(addr, align); + addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align); + ops->cit_iv = (void *)addr; + } + +out: + return ret; } void crypto_exit_cipher_ops(struct crypto_tfm *tfm) diff --git a/trunk/crypto/compress.c b/trunk/crypto/compress.c index 0a6570048c1e..eca182aa3380 100644 --- a/trunk/crypto/compress.c +++ b/trunk/crypto/compress.c @@ -34,6 +34,11 @@ static int crypto_decompress(struct crypto_tfm *tfm, dlen); } +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags) +{ + return flags ? -EINVAL : 0; +} + int crypto_init_compress_ops(struct crypto_tfm *tfm) { struct compress_tfm *ops = &tfm->crt_compress; diff --git a/trunk/crypto/digest.c b/trunk/crypto/digest.c index 1bf7414aeb9e..8f4593268ce0 100644 --- a/trunk/crypto/digest.c +++ b/trunk/crypto/digest.c @@ -14,9 +14,7 @@ #include #include -#include #include -#include #include #include @@ -31,8 +29,8 @@ static int init(struct hash_desc *desc) return 0; } -static int update2(struct hash_desc *desc, - struct scatterlist *sg, unsigned int nbytes) +static int update(struct hash_desc *desc, + struct scatterlist *sg, unsigned int nbytes) { struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm); unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); @@ -83,14 +81,6 @@ static int update2(struct hash_desc *desc, return 0; } -static int update(struct hash_desc *desc, - struct scatterlist *sg, unsigned int nbytes) -{ - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - return update2(desc, sg, nbytes); -} - static int final(struct hash_desc *desc, u8 *out) { struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm); @@ -128,14 +118,16 @@ static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen) static int digest(struct hash_desc *desc, struct scatterlist *sg, unsigned int nbytes, u8 *out) { - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - init(desc); - update2(desc, sg, nbytes); + update(desc, sg, nbytes); return final(desc, out); } +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) +{ + return flags ? -EINVAL : 0; +} + int crypto_init_digest_ops(struct crypto_tfm *tfm) { struct hash_tfm *ops = &tfm->crt_hash; diff --git a/trunk/crypto/ecb.c b/trunk/crypto/ecb.c index 839a0aed8c22..f239aa9c4017 100644 --- a/trunk/crypto/ecb.c +++ b/trunk/crypto/ecb.c @@ -99,13 +99,12 @@ static int crypto_ecb_init_tfm(struct crypto_tfm *tfm) struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(tfm); - struct crypto_cipher *cipher; - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - ctx->child = cipher; + ctx->child = crypto_cipher_cast(tfm); return 0; } diff --git a/trunk/crypto/fcrypt.c b/trunk/crypto/fcrypt.c deleted file mode 100644 index 9c2bb535b09a..000000000000 --- a/trunk/crypto/fcrypt.c +++ /dev/null @@ -1,423 +0,0 @@ -/* FCrypt encryption algorithm - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Based on code: - * - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#define ROUNDS 16 - -struct fcrypt_ctx { - u32 sched[ROUNDS]; -}; - -/* Rotate right two 32 bit numbers as a 56 bit number */ -#define ror56(hi, lo, n) \ -do { \ - u32 t = lo & ((1 << n) - 1); \ - lo = (lo >> n) | ((hi & ((1 << n) - 1)) << (32 - n)); \ - hi = (hi >> n) | (t << (24-n)); \ -} while(0) - -/* Rotate right one 64 bit number as a 56 bit number */ -#define ror56_64(k, n) \ -do { \ - k = (k >> n) | ((k & ((1 << n) - 1)) << (56 - n)); \ -} while(0) - -/* - * Sboxes for Feistel network derived from - * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h - */ -#undef Z -#define Z(x) __constant_be32_to_cpu(x << 3) -static const u32 sbox0[256] = { - Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11), - Z(0xcd), Z(0x86), Z(0x86), Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06), - Z(0x0e), Z(0x06), Z(0xd2), Z(0x65), Z(0x73), Z(0xc5), Z(0x28), Z(0x60), - Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda), Z(0x9f), Z(0xe3), - Z(0xd2), Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a), - Z(0x35), Z(0xac), Z(0xaa), Z(0x5f), Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53), - Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3), Z(0xdc), Z(0x09), Z(0x32), Z(0x10), - Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf), Z(0xfd), - Z(0x3b), Z(0x95), Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80), - Z(0x9c), Z(0xf3), Z(0xec), Z(0xda), Z(0x9f), Z(0x26), Z(0x76), Z(0x15), - Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84), Z(0xee), Z(0xad), Z(0xc7), - Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24), - Z(0x0b), Z(0x8a), Z(0x83), Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8), - Z(0xb1), Z(0xd4), Z(0x01), Z(0xd8), Z(0x70), Z(0x64), Z(0xf0), Z(0x51), - Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5), Z(0x64), Z(0xef), - Z(0x10), Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44), - Z(0x3d), Z(0xe5), Z(0xb3), Z(0x5b), Z(0xae), Z(0xd5), Z(0xad), Z(0x1d), - Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33), Z(0xab), Z(0x93), Z(0xa2), Z(0xb7), - Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63), Z(0x44), - Z(0xb6), Z(0x69), Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0), - Z(0x17), Z(0xbb), Z(0xc7), Z(0xf3), Z(0x3f), Z(0x36), Z(0xba), Z(0x71), - Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69), Z(0xb6), Z(0xf6), Z(0xe6), - Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95), - Z(0x22), Z(0x99), Z(0xfd), Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1), - Z(0xb6), Z(0x5b), Z(0xae), Z(0x54), Z(0xb3), Z(0x70), Z(0xff), Z(0xc6), - Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e), Z(0x76), Z(0xe5), - Z(0x36), Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6), - Z(0x93), Z(0xc4), Z(0xaa), Z(0x26), Z(0x49), Z(0xe0), Z(0x21), Z(0x64), - Z(0x07), Z(0x9f), Z(0x64), Z(0x81), Z(0x9c), Z(0xbf), Z(0xf9), Z(0xd1), - Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75), Z(0x03), - Z(0xe4), Z(0xb0), Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39), - Z(0x72), Z(0x12), Z(0xf6), Z(0xba), Z(0x0c), Z(0x0d), Z(0x42), Z(0x2e) -}; - -#undef Z -#define Z(x) __constant_be32_to_cpu((x << 27) | (x >> 5)) -static const u32 sbox1[256] = { - Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e), - Z(0x67), Z(0x6c), Z(0xa1), Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85), - Z(0x6c), Z(0x7b), Z(0x67), Z(0xc6), Z(0x23), Z(0xe3), Z(0xf2), Z(0x89), - Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6), Z(0xe1), Z(0x39), - Z(0x31), Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6), - Z(0x23), Z(0x83), Z(0x98), Z(0x7d), Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99), - Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20), Z(0x03), Z(0x7c), Z(0x5f), Z(0xad), - Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd), Z(0xb6), - Z(0xb8), Z(0xa1), Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b), - Z(0x16), Z(0x74), Z(0x31), Z(0x8a), Z(0x23), Z(0x17), Z(0x04), Z(0xfa), - Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13), Z(0xab), Z(0xb5), Z(0x2e), - Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc), - Z(0xe2), Z(0xaf), Z(0x45), Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd), - Z(0x00), Z(0x92), Z(0x7d), Z(0x97), Z(0x7a), Z(0x18), Z(0x60), Z(0x3d), - Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6), Z(0xbb), Z(0x8b), - Z(0x06), Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17), - Z(0x89), Z(0xd0), Z(0xa9), Z(0xc1), Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5), - Z(0x43), Z(0xf4), Z(0x68), Z(0xc8), Z(0xd3), Z(0x84), Z(0x28), Z(0x0a), - Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f), Z(0x7a), - Z(0x31), Z(0xf7), Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5), - Z(0x24), Z(0x66), Z(0xfc), Z(0xb3), Z(0x57), Z(0x25), Z(0xbe), Z(0x89), - Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23), Z(0x3c), Z(0x12), Z(0x52), - Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8), - Z(0x69), Z(0x10), Z(0x9d), Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30), - Z(0x05), Z(0x5e), Z(0x32), Z(0xc0), Z(0xd5), Z(0x19), Z(0xbd), Z(0x45), - Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c), Z(0xa9), Z(0x96), - Z(0xef), Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad), - Z(0x80), Z(0x48), Z(0x81), Z(0xb7), Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7), - Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a), Z(0x59), Z(0x7c), Z(0x57), Z(0xc1), - Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4), Z(0x78), - Z(0x16), Z(0x06), Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4), - Z(0x70), Z(0x03), Z(0xe0), Z(0x2f), Z(0x96), Z(0x91), Z(0x82), Z(0x80) -}; - -#undef Z -#define Z(x) __constant_be32_to_cpu(x << 11) -static const u32 sbox2[256] = { - Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86), - Z(0xd1), Z(0xec), Z(0x50), Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d), - Z(0xbf), Z(0x80), Z(0x87), Z(0x27), Z(0x95), Z(0xe2), Z(0xc5), Z(0x5d), - Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e), Z(0xe7), Z(0x24), - Z(0xc8), Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9), - Z(0xe8), Z(0xdc), Z(0xb7), Z(0xd9), Z(0x45), Z(0x20), Z(0x1b), Z(0xce), - Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd), Z(0x0e), Z(0x8f), Z(0xa3), Z(0xa9), - Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1), Z(0x68), - Z(0x84), Z(0xbc), Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6), - Z(0x13), Z(0x5e), Z(0x07), Z(0xb8), Z(0x95), Z(0x02), Z(0xc0), Z(0xd0), - Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6), Z(0xfd), Z(0xfe), Z(0x17), - Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d), - Z(0x6d), Z(0x1c), Z(0x6c), Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e), - Z(0x8b), Z(0x6b), Z(0xbe), Z(0x29), Z(0xeb), Z(0x12), Z(0x19), Z(0x34), - Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b), Z(0xd5), Z(0xae), - Z(0x2a), Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc), - Z(0x2c), Z(0xd0), Z(0x22), Z(0x4b), Z(0xb1), Z(0x85), Z(0x59), Z(0x80), - Z(0xc0), Z(0x30), Z(0x9f), Z(0x73), Z(0xd3), Z(0x14), Z(0x48), Z(0x40), - Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b), Z(0x5e), - Z(0xb7), Z(0x5e), Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15), - Z(0x05), Z(0xe8), Z(0x02), Z(0x77), Z(0xa9), Z(0xc7), Z(0x40), Z(0x45), - Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c), Z(0x79), Z(0x2a), Z(0x99), - Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f), - Z(0xdc), Z(0xff), Z(0xfd), Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a), - Z(0xec), Z(0x8e), Z(0x19), Z(0x18), Z(0xb4), Z(0x6e), Z(0x3d), Z(0xfd), - Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8), Z(0xbc), Z(0x1f), - Z(0x56), Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5), - Z(0xf3), Z(0x8e), Z(0xde), Z(0xae), Z(0x37), Z(0x49), Z(0xb7), Z(0xfa), - Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0), Z(0x2a), Z(0x9b), Z(0x15), Z(0xd1), - Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84), Z(0x59), - Z(0x56), Z(0x68), Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f), - Z(0x8c), Z(0x8a), Z(0x73), Z(0x80), Z(0x76), Z(0xb4), Z(0x10), Z(0x86) -}; - -#undef Z -#define Z(x) __constant_be32_to_cpu(x << 19) -static const u32 sbox3[256] = { - Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2), - Z(0xb5), Z(0xb7), Z(0x42), Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12), - Z(0x44), Z(0x48), Z(0x6d), Z(0x28), Z(0xaa), Z(0x20), Z(0x6d), Z(0x57), - Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92), Z(0x5a), Z(0x1b), - Z(0x53), Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66), - Z(0xa1), Z(0x01), Z(0xa5), Z(0x41), Z(0x97), Z(0x41), Z(0x31), Z(0x82), - Z(0xf1), Z(0x14), Z(0xcf), Z(0x53), Z(0x0d), Z(0xa0), Z(0x10), Z(0xcc), - Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb), Z(0x16), - Z(0x47), Z(0xf6), Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a), - Z(0xa7), Z(0xdf), Z(0x29), Z(0x43), Z(0x01), Z(0x54), Z(0x70), Z(0xa4), - Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44), Z(0x60), Z(0x9e), Z(0x23), - Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2), - Z(0x2a), Z(0x41), Z(0xb2), Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d), - Z(0x13), Z(0x3a), Z(0x3c), Z(0x6e), Z(0x35), Z(0xdc), Z(0x60), Z(0x65), - Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f), Z(0x9f), Z(0x87), - Z(0x96), Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4), - Z(0x5a), Z(0x83), Z(0xbf), Z(0x92), Z(0x1b), Z(0x94), Z(0x00), Z(0x42), - Z(0xcf), Z(0x4b), Z(0x00), Z(0x75), Z(0xba), Z(0x8f), Z(0x76), Z(0x5f), - Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38), Z(0x95), - Z(0x17), Z(0xe4), Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85), - Z(0x82), Z(0x4c), Z(0x9d), Z(0x2f), Z(0x3b), Z(0x66), Z(0xa1), Z(0x34), - Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5), Z(0x31), Z(0xcf), Z(0x05), - Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a), - Z(0x19), Z(0xf1), Z(0xa1), Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0), - Z(0x98), Z(0x8d), Z(0x0b), Z(0x23), Z(0xc3), Z(0x3a), Z(0x2d), Z(0x20), - Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d), Z(0x6c), Z(0x2f), - Z(0x47), Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79), - Z(0x3d), Z(0xa2), Z(0x54), Z(0xbd), Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3), - Z(0x05), Z(0x28), Z(0xf1), Z(0x16), Z(0x46), Z(0x40), Z(0xb0), Z(0x11), - Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d), Z(0x8f), - Z(0xd8), Z(0xe1), Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9), - Z(0xa1), Z(0xc2), Z(0xc5), Z(0xe3), Z(0xba), Z(0xfc), Z(0x0e), Z(0x25) -}; - -/* - * This is a 16 round Feistel network with permutation F_ENCRYPT - */ -#define F_ENCRYPT(R, L, sched) \ -do { \ - union lc4 { u32 l; u8 c[4]; } u; \ - u.l = sched ^ R; \ - L ^= sbox0[u.c[0]] ^ sbox1[u.c[1]] ^ sbox2[u.c[2]] ^ sbox3[u.c[3]]; \ -} while(0) - -/* - * encryptor - */ -static void fcrypt_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ - const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm); - struct { - u32 l, r; - } X; - - memcpy(&X, src, sizeof(X)); - - F_ENCRYPT(X.r, X.l, ctx->sched[0x0]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x1]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x2]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x3]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x4]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x5]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x6]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x7]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x8]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x9]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xa]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xb]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xc]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xd]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xe]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xf]); - - memcpy(dst, &X, sizeof(X)); -} - -/* - * decryptor - */ -static void fcrypt_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ - const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm); - struct { - u32 l, r; - } X; - - memcpy(&X, src, sizeof(X)); - - F_ENCRYPT(X.l, X.r, ctx->sched[0xf]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xe]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xd]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xc]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xb]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xa]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x9]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x8]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x7]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x6]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x5]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x4]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x3]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x2]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x1]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x0]); - - memcpy(dst, &X, sizeof(X)); -} - -/* - * Generate a key schedule from key, the least significant bit in each key byte - * is parity and shall be ignored. This leaves 56 significant bits in the key - * to scatter over the 16 key schedules. For each schedule extract the low - * order 32 bits and use as schedule, then rotate right by 11 bits. - */ -static int fcrypt_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) -{ - struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm); - -#if BITS_PER_LONG == 64 /* the 64-bit version can also be used for 32-bit - * kernels - it seems to be faster but the code is - * larger */ - - u64 k; /* k holds all 56 non-parity bits */ - - /* discard the parity bits */ - k = (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key) >> 1; - - /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */ - ctx->sched[0x0] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x1] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x2] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x3] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x4] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x5] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x6] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x7] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x8] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x9] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xa] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xb] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xc] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xd] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xe] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xf] = be32_to_cpu(k); - - return 0; -#else - u32 hi, lo; /* hi is upper 24 bits and lo lower 32, total 56 */ - - /* discard the parity bits */ - lo = (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - hi = lo >> 4; - lo &= 0xf; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key) >> 1; - - /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */ - ctx->sched[0x0] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x1] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x2] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x3] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x4] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x5] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x6] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x7] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x8] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x9] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xa] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xb] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xc] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xd] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xe] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xf] = be32_to_cpu(lo); - return 0; -#endif -} - -static struct crypto_alg fcrypt_alg = { - .cra_name = "fcrypt", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, - .cra_blocksize = 8, - .cra_ctxsize = sizeof(struct fcrypt_ctx), - .cra_module = THIS_MODULE, - .cra_alignmask = 3, - .cra_list = LIST_HEAD_INIT(fcrypt_alg.cra_list), - .cra_u = { .cipher = { - .cia_min_keysize = 8, - .cia_max_keysize = 8, - .cia_setkey = fcrypt_setkey, - .cia_encrypt = fcrypt_encrypt, - .cia_decrypt = fcrypt_decrypt } } -}; - -static int __init init(void) -{ - return crypto_register_alg(&fcrypt_alg); -} - -static void __exit fini(void) -{ - crypto_unregister_alg(&fcrypt_alg); -} - -module_init(init); -module_exit(fini); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("FCrypt Cipher Algorithm"); -MODULE_AUTHOR("David Howells "); diff --git a/trunk/crypto/hash.c b/trunk/crypto/hash.c index 12c4514f3478..cdec23d885fe 100644 --- a/trunk/crypto/hash.c +++ b/trunk/crypto/hash.c @@ -16,13 +16,12 @@ #include "internal.h" -static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg, u32 type, - u32 mask) +static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg) { return alg->cra_ctxsize; } -static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +static int crypto_init_hash_ops(struct crypto_tfm *tfm) { struct hash_tfm *crt = &tfm->crt_hash; struct hash_alg *alg = &tfm->__crt_alg->cra_hash; diff --git a/trunk/crypto/hmac.c b/trunk/crypto/hmac.c index 44187c5ee593..b521bcd2b2c6 100644 --- a/trunk/crypto/hmac.c +++ b/trunk/crypto/hmac.c @@ -172,16 +172,15 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, static int hmac_init_tfm(struct crypto_tfm *tfm) { - struct crypto_hash *hash; struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct hmac_ctx *ctx = hmac_ctx(__crypto_hash_cast(tfm)); - hash = crypto_spawn_hash(spawn); - if (IS_ERR(hash)) - return PTR_ERR(hash); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - ctx->child = hash; + ctx->child = crypto_hash_cast(tfm); return 0; } diff --git a/trunk/crypto/internal.h b/trunk/crypto/internal.h index 60acad9788c5..2da6ad4f3593 100644 --- a/trunk/crypto/internal.h +++ b/trunk/crypto/internal.h @@ -83,7 +83,8 @@ static inline void crypto_exit_proc(void) { } #endif -static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg) +static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg, + int flags) { unsigned int len = alg->cra_ctxsize; @@ -95,12 +96,23 @@ static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg) return len; } -static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg) +static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg, + int flags) { - return alg->cra_ctxsize; + unsigned int len = alg->cra_ctxsize; + + switch (flags & CRYPTO_TFM_MODE_MASK) { + case CRYPTO_TFM_MODE_CBC: + len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1); + len += alg->cra_blocksize; + break; + } + + return len; } -static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg) +static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg, + int flags) { return alg->cra_ctxsize; } @@ -109,6 +121,10 @@ struct crypto_alg *crypto_mod_get(struct crypto_alg *alg); struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask); struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask); +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags); + int crypto_init_digest_ops(struct crypto_tfm *tfm); int crypto_init_cipher_ops(struct crypto_tfm *tfm); int crypto_init_compress_ops(struct crypto_tfm *tfm); @@ -120,8 +136,7 @@ void crypto_exit_compress_ops(struct crypto_tfm *tfm); void crypto_larval_error(const char *name, u32 type, u32 mask); void crypto_shoot_alg(struct crypto_alg *alg); -struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, - u32 mask); +struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags); int crypto_register_instance(struct crypto_template *tmpl, struct crypto_instance *inst); diff --git a/trunk/crypto/lrw.c b/trunk/crypto/lrw.c index b4105080ac7a..56642586d84f 100644 --- a/trunk/crypto/lrw.c +++ b/trunk/crypto/lrw.c @@ -201,22 +201,21 @@ static int decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, static int init_tfm(struct crypto_tfm *tfm) { - struct crypto_cipher *cipher; struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct priv *ctx = crypto_tfm_ctx(tfm); u32 *flags = &tfm->crt_flags; - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - if (crypto_cipher_blocksize(cipher) != 16) { + if (crypto_tfm_alg_blocksize(tfm) != 16) { *flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; return -EINVAL; } - ctx->child = cipher; + ctx->child = crypto_cipher_cast(tfm); return 0; } diff --git a/trunk/crypto/pcbc.c b/trunk/crypto/pcbc.c deleted file mode 100644 index 5174d7fdad6e..000000000000 --- a/trunk/crypto/pcbc.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * PCBC: Propagating Cipher Block Chaining mode - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * Derived from cbc.c - * - Copyright (c) 2006 Herbert Xu - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -struct crypto_pcbc_ctx { - struct crypto_cipher *child; - void (*xor)(u8 *dst, const u8 *src, unsigned int bs); -}; - -static int crypto_pcbc_setkey(struct crypto_tfm *parent, const u8 *key, - unsigned int keylen) -{ - struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(parent); - struct crypto_cipher *child = ctx->child; - int err; - - crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); - crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) & - CRYPTO_TFM_REQ_MASK); - err = crypto_cipher_setkey(child, key, keylen); - crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) & - CRYPTO_TFM_RES_MASK); - return err; -} - -static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc, - struct blkcipher_walk *walk, - struct crypto_cipher *tfm, - void (*xor)(u8 *, const u8 *, - unsigned int)) -{ - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = - crypto_cipher_alg(tfm)->cia_encrypt; - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; - u8 *iv = walk->iv; - - do { - xor(iv, src, bsize); - fn(crypto_cipher_tfm(tfm), dst, iv); - memcpy(iv, dst, bsize); - xor(iv, src, bsize); - - src += bsize; - dst += bsize; - } while ((nbytes -= bsize) >= bsize); - - return nbytes; -} - -static int crypto_pcbc_encrypt_inplace(struct blkcipher_desc *desc, - struct blkcipher_walk *walk, - struct crypto_cipher *tfm, - void (*xor)(u8 *, const u8 *, - unsigned int)) -{ - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = - crypto_cipher_alg(tfm)->cia_encrypt; - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *src = walk->src.virt.addr; - u8 *iv = walk->iv; - u8 tmpbuf[bsize]; - - do { - memcpy(tmpbuf, src, bsize); - xor(iv, tmpbuf, bsize); - fn(crypto_cipher_tfm(tfm), src, iv); - memcpy(iv, src, bsize); - xor(iv, tmpbuf, bsize); - - src += bsize; - } while ((nbytes -= bsize) >= bsize); - - memcpy(walk->iv, iv, bsize); - - return nbytes; -} - -static int crypto_pcbc_encrypt(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - struct blkcipher_walk walk; - struct crypto_blkcipher *tfm = desc->tfm; - struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm); - struct crypto_cipher *child = ctx->child; - void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - if (walk.src.virt.addr == walk.dst.virt.addr) - nbytes = crypto_pcbc_encrypt_inplace(desc, &walk, child, - xor); - else - nbytes = crypto_pcbc_encrypt_segment(desc, &walk, child, - xor); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc, - struct blkcipher_walk *walk, - struct crypto_cipher *tfm, - void (*xor)(u8 *, const u8 *, - unsigned int)) -{ - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = - crypto_cipher_alg(tfm)->cia_decrypt; - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; - u8 *iv = walk->iv; - - do { - fn(crypto_cipher_tfm(tfm), dst, src); - xor(dst, iv, bsize); - memcpy(iv, src, bsize); - xor(iv, dst, bsize); - - src += bsize; - dst += bsize; - } while ((nbytes -= bsize) >= bsize); - - memcpy(walk->iv, iv, bsize); - - return nbytes; -} - -static int crypto_pcbc_decrypt_inplace(struct blkcipher_desc *desc, - struct blkcipher_walk *walk, - struct crypto_cipher *tfm, - void (*xor)(u8 *, const u8 *, - unsigned int)) -{ - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = - crypto_cipher_alg(tfm)->cia_decrypt; - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *src = walk->src.virt.addr; - u8 *iv = walk->iv; - u8 tmpbuf[bsize]; - - do { - memcpy(tmpbuf, src, bsize); - fn(crypto_cipher_tfm(tfm), src, src); - xor(src, iv, bsize); - memcpy(iv, tmpbuf, bsize); - xor(iv, src, bsize); - - src += bsize; - } while ((nbytes -= bsize) >= bsize); - - memcpy(walk->iv, iv, bsize); - - return nbytes; -} - -static int crypto_pcbc_decrypt(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - struct blkcipher_walk walk; - struct crypto_blkcipher *tfm = desc->tfm; - struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm); - struct crypto_cipher *child = ctx->child; - void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - if (walk.src.virt.addr == walk.dst.virt.addr) - nbytes = crypto_pcbc_decrypt_inplace(desc, &walk, child, - xor); - else - nbytes = crypto_pcbc_decrypt_segment(desc, &walk, child, - xor); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static void xor_byte(u8 *a, const u8 *b, unsigned int bs) -{ - do { - *a++ ^= *b++; - } while (--bs); -} - -static void xor_quad(u8 *dst, const u8 *src, unsigned int bs) -{ - u32 *a = (u32 *)dst; - u32 *b = (u32 *)src; - - do { - *a++ ^= *b++; - } while ((bs -= 4)); -} - -static void xor_64(u8 *a, const u8 *b, unsigned int bs) -{ - ((u32 *)a)[0] ^= ((u32 *)b)[0]; - ((u32 *)a)[1] ^= ((u32 *)b)[1]; -} - -static void xor_128(u8 *a, const u8 *b, unsigned int bs) -{ - ((u32 *)a)[0] ^= ((u32 *)b)[0]; - ((u32 *)a)[1] ^= ((u32 *)b)[1]; - ((u32 *)a)[2] ^= ((u32 *)b)[2]; - ((u32 *)a)[3] ^= ((u32 *)b)[3]; -} - -static int crypto_pcbc_init_tfm(struct crypto_tfm *tfm) -{ - struct crypto_instance *inst = (void *)tfm->__crt_alg; - struct crypto_spawn *spawn = crypto_instance_ctx(inst); - struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm); - struct crypto_cipher *cipher; - - switch (crypto_tfm_alg_blocksize(tfm)) { - case 8: - ctx->xor = xor_64; - break; - - case 16: - ctx->xor = xor_128; - break; - - default: - if (crypto_tfm_alg_blocksize(tfm) % 4) - ctx->xor = xor_byte; - else - ctx->xor = xor_quad; - } - - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); - - ctx->child = cipher; - return 0; -} - -static void crypto_pcbc_exit_tfm(struct crypto_tfm *tfm) -{ - struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm); - crypto_free_cipher(ctx->child); -} - -static struct crypto_instance *crypto_pcbc_alloc(void *param, unsigned int len) -{ - struct crypto_instance *inst; - struct crypto_alg *alg; - - alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, - CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); - if (IS_ERR(alg)) - return ERR_PTR(PTR_ERR(alg)); - - inst = crypto_alloc_instance("pcbc", alg); - if (IS_ERR(inst)) - goto out_put_alg; - - inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; - inst->alg.cra_priority = alg->cra_priority; - inst->alg.cra_blocksize = alg->cra_blocksize; - inst->alg.cra_alignmask = alg->cra_alignmask; - inst->alg.cra_type = &crypto_blkcipher_type; - - if (!(alg->cra_blocksize % 4)) - inst->alg.cra_alignmask |= 3; - inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize; - inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize; - inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize; - - inst->alg.cra_ctxsize = sizeof(struct crypto_pcbc_ctx); - - inst->alg.cra_init = crypto_pcbc_init_tfm; - inst->alg.cra_exit = crypto_pcbc_exit_tfm; - - inst->alg.cra_blkcipher.setkey = crypto_pcbc_setkey; - inst->alg.cra_blkcipher.encrypt = crypto_pcbc_encrypt; - inst->alg.cra_blkcipher.decrypt = crypto_pcbc_decrypt; - -out_put_alg: - crypto_mod_put(alg); - return inst; -} - -static void crypto_pcbc_free(struct crypto_instance *inst) -{ - crypto_drop_spawn(crypto_instance_ctx(inst)); - kfree(inst); -} - -static struct crypto_template crypto_pcbc_tmpl = { - .name = "pcbc", - .alloc = crypto_pcbc_alloc, - .free = crypto_pcbc_free, - .module = THIS_MODULE, -}; - -static int __init crypto_pcbc_module_init(void) -{ - return crypto_register_template(&crypto_pcbc_tmpl); -} - -static void __exit crypto_pcbc_module_exit(void) -{ - crypto_unregister_template(&crypto_pcbc_tmpl); -} - -module_init(crypto_pcbc_module_init); -module_exit(crypto_pcbc_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("PCBC block cipher algorithm"); diff --git a/trunk/crypto/tcrypt.c b/trunk/crypto/tcrypt.c index f5e9da319ece..d671e8942b1f 100644 --- a/trunk/crypto/tcrypt.c +++ b/trunk/crypto/tcrypt.c @@ -12,7 +12,6 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests * 2004-08-09 Added cipher speed tests (Reyk Floeter ) * 2003-09-14 Rewritten by Kartikey Mahendra Bhatt * @@ -72,8 +71,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", - "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", - "camellia", NULL + "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", NULL }; static void hexdump(unsigned char *buf, unsigned int len) @@ -767,7 +765,7 @@ static void test_deflate(void) memcpy(tvmem, deflate_comp_tv_template, tsize); tv = (void *)tvmem; - tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_tfm("deflate", 0); if (tfm == NULL) { printk("failed to load transform for deflate\n"); return; @@ -966,26 +964,6 @@ static void do_test(void) test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS); - //FCrypt - test_cipher("pcbc(fcrypt)", ENCRYPT, fcrypt_pcbc_enc_tv_template, - FCRYPT_ENC_TEST_VECTORS); - test_cipher("pcbc(fcrypt)", DECRYPT, fcrypt_pcbc_dec_tv_template, - FCRYPT_DEC_TEST_VECTORS); - - //CAMELLIA - test_cipher("ecb(camellia)", ENCRYPT, - camellia_enc_tv_template, - CAMELLIA_ENC_TEST_VECTORS); - test_cipher("ecb(camellia)", DECRYPT, - camellia_dec_tv_template, - CAMELLIA_DEC_TEST_VECTORS); - test_cipher("cbc(camellia)", ENCRYPT, - camellia_cbc_enc_tv_template, - CAMELLIA_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(camellia)", DECRYPT, - camellia_cbc_dec_tv_template, - CAMELLIA_CBC_DEC_TEST_VECTORS); - test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); @@ -1002,10 +980,6 @@ static void do_test(void) HMAC_SHA1_TEST_VECTORS); test_hash("hmac(sha256)", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); - test_hash("hmac(sha384)", hmac_sha384_tv_template, - HMAC_SHA384_TEST_VECTORS); - test_hash("hmac(sha512)", hmac_sha512_tv_template, - HMAC_SHA512_TEST_VECTORS); test_hash("xcbc(aes)", aes_xcbc128_tv_template, XCBC_AES_TEST_VECTORS); @@ -1203,28 +1177,6 @@ static void do_test(void) XETA_DEC_TEST_VECTORS); break; - case 31: - test_cipher("pcbc(fcrypt)", ENCRYPT, fcrypt_pcbc_enc_tv_template, - FCRYPT_ENC_TEST_VECTORS); - test_cipher("pcbc(fcrypt)", DECRYPT, fcrypt_pcbc_dec_tv_template, - FCRYPT_DEC_TEST_VECTORS); - break; - - case 32: - test_cipher("ecb(camellia)", ENCRYPT, - camellia_enc_tv_template, - CAMELLIA_ENC_TEST_VECTORS); - test_cipher("ecb(camellia)", DECRYPT, - camellia_dec_tv_template, - CAMELLIA_DEC_TEST_VECTORS); - test_cipher("cbc(camellia)", ENCRYPT, - camellia_cbc_enc_tv_template, - CAMELLIA_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(camellia)", DECRYPT, - camellia_cbc_dec_tv_template, - CAMELLIA_CBC_DEC_TEST_VECTORS); - break; - case 100: test_hash("hmac(md5)", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); @@ -1240,16 +1192,6 @@ static void do_test(void) HMAC_SHA256_TEST_VECTORS); break; - case 103: - test_hash("hmac(sha384)", hmac_sha384_tv_template, - HMAC_SHA384_TEST_VECTORS); - break; - - case 104: - test_hash("hmac(sha512)", hmac_sha512_tv_template, - HMAC_SHA512_TEST_VECTORS); - break; - case 200: test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, @@ -1318,17 +1260,6 @@ static void do_test(void) des_speed_template); break; - case 205: - test_cipher_speed("ecb(camellia)", ENCRYPT, sec, NULL, 0, - camellia_speed_template); - test_cipher_speed("ecb(camellia)", DECRYPT, sec, NULL, 0, - camellia_speed_template); - test_cipher_speed("cbc(camellia)", ENCRYPT, sec, NULL, 0, - camellia_speed_template); - test_cipher_speed("cbc(camellia)", DECRYPT, sec, NULL, 0, - camellia_speed_template); - break; - case 300: /* fall through */ diff --git a/trunk/crypto/tcrypt.h b/trunk/crypto/tcrypt.h index 887527bd5bc6..48a81362cb85 100644 --- a/trunk/crypto/tcrypt.h +++ b/trunk/crypto/tcrypt.h @@ -12,7 +12,6 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests * 2004-08-09 Cipher speed tests by Reyk Floeter * 2003-09-14 Changes by Kartikey Mahendra Bhatt * @@ -28,7 +27,7 @@ struct hash_testvec { /* only used with keyed hash algorithms */ - char key[132] __attribute__ ((__aligned__(4))); + char key[128] __attribute__ ((__aligned__(4))); char plaintext[240]; char digest[MAX_DIGEST_SIZE]; unsigned char tap[MAX_TAP]; @@ -1002,248 +1001,6 @@ static struct hash_testvec aes_xcbc128_tv_template[] = { } }; -/* - * SHA384 HMAC test vectors from RFC4231 - */ - -#define HMAC_SHA384_TEST_VECTORS 4 - -static struct hash_testvec hmac_sha384_tv_template[] = { - { - .key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b }, // (20 bytes) - .ksize = 20, - .plaintext = { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 }, // ("Hi There") - .psize = 8, - .digest = { 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62, - 0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f, - 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6, - 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c, - 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f, - 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 }, - }, { - .key = { 0x4a, 0x65, 0x66, 0x65 }, // ("Jefe") - .ksize = 4, - .plaintext = { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, - 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, // ("what do ya want ") - 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, - 0x69, 0x6e, 0x67, 0x3f }, // ("for nothing?") - .psize = 28, - .digest = { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31, - 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b, - 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47, - 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e, - 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7, - 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 }, - .np = 4, - .tap = { 7, 7, 7, 7 } - }, { - .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa }, // (131 bytes) - .ksize = 131, - .plaintext = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, - 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, // ("Test Using Large") - 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, // ("r Than Block-Siz") - 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20, - 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, // ("e Key - Hash Key") - 0x20, 0x46, 0x69, 0x72, 0x73, 0x74 }, // (" First") - .psize = 54, - .digest = { 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90, - 0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4, - 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f, - 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6, - 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82, - 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 }, - }, { - .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa }, // (131 bytes) - .ksize = 131, - .plaintext = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, // ("This is a test u") - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c, - 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, // ("sing a larger th") - 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, // ("an block-size ke") - 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, - 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, // ("y and a larger t") - 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, // ("han block-size d") - 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, - 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, // ("ata. The key nee") - 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, - 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, // ("ds to be hashed ") - 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, - 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, // ("before being use") - 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, // ("d by the HMAC al") - 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e }, // ("gorithm.") - .psize = 152, - .digest = { 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d, - 0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c, - 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a, - 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5, - 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d, - 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e }, - }, -}; - -/* - * SHA512 HMAC test vectors from RFC4231 - */ - -#define HMAC_SHA512_TEST_VECTORS 4 - -static struct hash_testvec hmac_sha512_tv_template[] = { - { - .key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b }, // (20 bytes) - .ksize = 20, - .plaintext = { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 }, // ("Hi There") - .psize = 8, - .digest = { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, - 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0, - 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78, - 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde, - 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02, - 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4, - 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70, - 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 }, - }, { - .key = { 0x4a, 0x65, 0x66, 0x65 }, // ("Jefe") - .ksize = 4, - .plaintext = { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, - 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, // ("what do ya want ") - 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, - 0x69, 0x6e, 0x67, 0x3f }, // ("for nothing?") - .psize = 28, - .digest = { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, - 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3, - 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6, - 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54, - 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a, - 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd, - 0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b, - 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 }, - .np = 4, - .tap = { 7, 7, 7, 7 } - }, { - .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa }, // (131 bytes) - .ksize = 131, - .plaintext = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, - 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, // ("Test Using Large") - 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, // ("r Than Block-Siz") - 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20, - 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, // ("e Key - Hash Key") - 0x20, 0x46, 0x69, 0x72, 0x73, 0x74 }, // (" First") - .psize = 54, - .digest = { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, - 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4, - 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1, - 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52, - 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98, - 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52, - 0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec, - 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 }, - }, { - .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa }, // (131 bytes) - .ksize = 131, - .plaintext = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, // ("This is a test u") - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c, - 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, // ("sing a larger th") - 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, // ("an block-size ke") - 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, - 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, // ("y and a larger t") - 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, // ("han block-size d") - 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, - 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, // ("ata. The key nee") - 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, - 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, // ("ds to be hashed ") - 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, - 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, // ("before being use") - 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, // ("d by the HMAC al") - 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e }, // ("gorithm.") - .psize = 152, - .digest = { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba, - 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd, - 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86, - 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44, - 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1, - 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15, - 0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60, - 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 }, - }, -}; - /* * DES test vectors. */ @@ -3559,278 +3316,6 @@ static struct cipher_testvec xeta_dec_tv_template[] = { } }; -/* - * FCrypt test vectors - */ -#define FCRYPT_ENC_TEST_VECTORS ARRAY_SIZE(fcrypt_pcbc_enc_tv_template) -#define FCRYPT_DEC_TEST_VECTORS ARRAY_SIZE(fcrypt_pcbc_dec_tv_template) - -static struct cipher_testvec fcrypt_pcbc_enc_tv_template[] = { - { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */ - .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .klen = 8, - .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .ilen = 8, - .result = { 0x0E, 0x09, 0x00, 0xC7, 0x3E, 0xF7, 0xED, 0x41 }, - .rlen = 8, - }, { - .key = { 0x11, 0x44, 0x77, 0xAA, 0xDD, 0x00, 0x33, 0x66 }, - .klen = 8, - .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .input = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 }, - .ilen = 8, - .result = { 0xD8, 0xED, 0x78, 0x74, 0x77, 0xEC, 0x06, 0x80 }, - .rlen = 8, - }, { /* From Arla */ - .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .klen = 8, - .iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .input = "The quick brown fox jumps over the lazy dogs.\0\0", - .ilen = 48, - .result = { 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82, - 0xee, 0xac, 0x98, 0x62, 0x44, 0x51, 0xe4, 0x84, - 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7, - 0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, - 0x23, 0xb5, 0x62, 0xd7, 0x0c, 0xf5, 0x27, 0xd1, - 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef }, - .rlen = 48, - }, { - .key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 8, - .iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .input = "The quick brown fox jumps over the lazy dogs.\0\0", - .ilen = 48, - .result = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, - 0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d, - 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, - 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, - 0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94, - 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }, - .rlen = 48, - }, { /* split-page version */ - .key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 8, - .iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .input = "The quick brown fox jumps over the lazy dogs.\0\0", - .ilen = 48, - .result = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, - 0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d, - 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, - 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, - 0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94, - 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }, - .rlen = 48, - .np = 2, - .tap = { 20, 28 }, - } -}; - -static struct cipher_testvec fcrypt_pcbc_dec_tv_template[] = { - { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */ - .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .klen = 8, - .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .input = { 0x0E, 0x09, 0x00, 0xC7, 0x3E, 0xF7, 0xED, 0x41 }, - .ilen = 8, - .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .rlen = 8, - }, { - .key = { 0x11, 0x44, 0x77, 0xAA, 0xDD, 0x00, 0x33, 0x66 }, - .klen = 8, - .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .input = { 0xD8, 0xED, 0x78, 0x74, 0x77, 0xEC, 0x06, 0x80 }, - .ilen = 8, - .result = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 }, - .rlen = 8, - }, { /* From Arla */ - .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .klen = 8, - .iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .input = { 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82, - 0xee, 0xac, 0x98, 0x62, 0x44, 0x51, 0xe4, 0x84, - 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7, - 0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, - 0x23, 0xb5, 0x62, 0xd7, 0x0c, 0xf5, 0x27, 0xd1, - 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef }, - .ilen = 48, - .result = "The quick brown fox jumps over the lazy dogs.\0\0", - .rlen = 48, - }, { - .key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 8, - .iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .input = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, - 0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d, - 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, - 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, - 0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94, - 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }, - .ilen = 48, - .result = "The quick brown fox jumps over the lazy dogs.\0\0", - .rlen = 48, - }, { /* split-page version */ - .key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 8, - .iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .input = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, - 0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d, - 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, - 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, - 0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94, - 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }, - .ilen = 48, - .result = "The quick brown fox jumps over the lazy dogs.\0\0", - .rlen = 48, - .np = 2, - .tap = { 20, 28 }, - } -}; - -/* - * CAMELLIA test vectors. - */ -#define CAMELLIA_ENC_TEST_VECTORS 3 -#define CAMELLIA_DEC_TEST_VECTORS 3 -#define CAMELLIA_CBC_ENC_TEST_VECTORS 2 -#define CAMELLIA_CBC_DEC_TEST_VECTORS 2 - -static struct cipher_testvec camellia_enc_tv_template[] = { - { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 16, - .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .ilen = 16, - .result = { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, - 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, - .rlen = 16, - }, { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - .klen = 24, - .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .ilen = 16, - .result = { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, - 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, - .rlen = 16, - }, { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - .klen = 32, - .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .ilen = 16, - .result = { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, - 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, - .rlen = 16, - }, -}; - -static struct cipher_testvec camellia_dec_tv_template[] = { - { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 16, - .input = { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, - 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, - .ilen = 16, - .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .rlen = 16, - }, { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - .klen = 24, - .input = { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, - 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, - .ilen = 16, - .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .rlen = 16, - }, { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - .klen = 32, - .input = { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, - 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, - .ilen = 16, - .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .rlen = 16, - }, -}; - -static struct cipher_testvec camellia_cbc_enc_tv_template[] = { - { - .key = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, - 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 }, - .klen = 16, - .iv = { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30, - 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 }, - .input = { "Single block msg" }, - .ilen = 16, - .result = { 0xea, 0x32, 0x12, 0x76, 0x3b, 0x50, 0x10, 0xe7, - 0x18, 0xf6, 0xfd, 0x5d, 0xf6, 0x8f, 0x13, 0x51 }, - .rlen = 16, - }, { - .key = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, - 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a }, - .klen = 16, - .iv = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, - 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 }, - .input = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - .ilen = 32, - .result = { 0xa5, 0xdf, 0x6e, 0x50, 0xda, 0x70, 0x6c, 0x01, - 0x4a, 0xab, 0xf3, 0xf2, 0xd6, 0xfc, 0x6c, 0xfd, - 0x19, 0xb4, 0x3e, 0x57, 0x1c, 0x02, 0x5e, 0xa0, - 0x15, 0x78, 0xe0, 0x5e, 0xf2, 0xcb, 0x87, 0x16 }, - .rlen = 32, - }, -}; - -static struct cipher_testvec camellia_cbc_dec_tv_template[] = { - { - .key = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, - 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 }, - .klen = 16, - .iv = { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30, - 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 }, - .input = { 0xea, 0x32, 0x12, 0x76, 0x3b, 0x50, 0x10, 0xe7, - 0x18, 0xf6, 0xfd, 0x5d, 0xf6, 0x8f, 0x13, 0x51 }, - .ilen = 16, - .result = { "Single block msg" }, - .rlen = 16, - }, { - .key = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, - 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a }, - .klen = 16, - .iv = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, - 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 }, - .input = { 0xa5, 0xdf, 0x6e, 0x50, 0xda, 0x70, 0x6c, 0x01, - 0x4a, 0xab, 0xf3, 0xf2, 0xd6, 0xfc, 0x6c, 0xfd, - 0x19, 0xb4, 0x3e, 0x57, 0x1c, 0x02, 0x5e, 0xa0, - 0x15, 0x78, 0xe0, 0x5e, 0xf2, 0xcb, 0x87, 0x16 }, - .ilen = 32, - .result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - .rlen = 32, - }, -}; - /* * Compression stuff. */ @@ -4284,25 +3769,4 @@ static struct hash_speed generic_hash_speed_template[] = { { .blen = 0, .plen = 0, } }; -static struct cipher_speed camellia_speed_template[] = { - { .klen = 16, .blen = 16, }, - { .klen = 16, .blen = 64, }, - { .klen = 16, .blen = 256, }, - { .klen = 16, .blen = 1024, }, - { .klen = 16, .blen = 8192, }, - { .klen = 24, .blen = 16, }, - { .klen = 24, .blen = 64, }, - { .klen = 24, .blen = 256, }, - { .klen = 24, .blen = 1024, }, - { .klen = 24, .blen = 8192, }, - { .klen = 32, .blen = 16, }, - { .klen = 32, .blen = 64, }, - { .klen = 32, .blen = 256, }, - { .klen = 32, .blen = 1024, }, - { .klen = 32, .blen = 8192, }, - - /* End marker */ - { .klen = 0, .blen = 0, } -}; - #endif /* _CRYPTO_TCRYPT_H */ diff --git a/trunk/crypto/xcbc.c b/trunk/crypto/xcbc.c index 53e8ccbf0f5f..9347eb6bcf69 100644 --- a/trunk/crypto/xcbc.c +++ b/trunk/crypto/xcbc.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -48,7 +47,7 @@ static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101, * +------------------------ */ struct crypto_xcbc_ctx { - struct crypto_cipher *child; + struct crypto_tfm *child; u8 *odds; u8 *prev; u8 *key; @@ -76,7 +75,8 @@ static int _crypto_xcbc_digest_setkey(struct crypto_hash *parent, if ((err = crypto_cipher_setkey(ctx->child, ctx->key, ctx->keylen))) return err; - crypto_cipher_encrypt_one(ctx->child, key1, ctx->consts); + ctx->child->__crt_alg->cra_cipher.cia_encrypt(ctx->child, key1, + ctx->consts); return crypto_cipher_setkey(ctx->child, key1, bs); } @@ -86,7 +86,7 @@ static int crypto_xcbc_digest_setkey(struct crypto_hash *parent, { struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); - if (keylen != crypto_cipher_blocksize(ctx->child)) + if (keylen != crypto_tfm_alg_blocksize(ctx->child)) return -EINVAL; ctx->keylen = keylen; @@ -108,13 +108,13 @@ static int crypto_xcbc_digest_init(struct hash_desc *pdesc) return 0; } -static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, - struct scatterlist *sg, - unsigned int nbytes) +static int crypto_xcbc_digest_update(struct hash_desc *pdesc, + struct scatterlist *sg, + unsigned int nbytes) { struct crypto_hash *parent = pdesc->tfm; struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); - struct crypto_cipher *tfm = ctx->child; + struct crypto_tfm *tfm = ctx->child; int bs = crypto_hash_blocksize(parent); unsigned int i = 0; @@ -142,7 +142,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, offset += len; crypto_kunmap(p, 0); - crypto_yield(pdesc->flags); + crypto_yield(tfm->crt_flags); continue; } @@ -152,7 +152,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, p += bs - ctx->len; ctx->xor(ctx->prev, ctx->odds, bs); - crypto_cipher_encrypt_one(tfm, ctx->prev, ctx->prev); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, ctx->prev, ctx->prev); /* clearing the length */ ctx->len = 0; @@ -160,8 +160,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, /* encrypting the rest of data */ while (len > bs) { ctx->xor(ctx->prev, p, bs); - crypto_cipher_encrypt_one(tfm, ctx->prev, - ctx->prev); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, ctx->prev, ctx->prev); p += bs; len -= bs; } @@ -172,7 +171,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, ctx->len = len; } crypto_kunmap(p, 0); - crypto_yield(pdesc->flags); + crypto_yield(tfm->crt_flags); slen -= min(slen, ((unsigned int)(PAGE_SIZE)) - offset); offset = 0; pg++; @@ -184,20 +183,11 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, return 0; } -static int crypto_xcbc_digest_update(struct hash_desc *pdesc, - struct scatterlist *sg, - unsigned int nbytes) -{ - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - return crypto_xcbc_digest_update2(pdesc, sg, nbytes); -} - static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) { struct crypto_hash *parent = pdesc->tfm; struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); - struct crypto_cipher *tfm = ctx->child; + struct crypto_tfm *tfm = ctx->child; int bs = crypto_hash_blocksize(parent); int err = 0; @@ -207,14 +197,13 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0) return err; - crypto_cipher_encrypt_one(tfm, key2, - (u8 *)(ctx->consts + bs)); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key2, (const u8*)(ctx->consts+bs)); ctx->xor(ctx->prev, ctx->odds, bs); ctx->xor(ctx->prev, key2, bs); _crypto_xcbc_digest_setkey(parent, ctx); - crypto_cipher_encrypt_one(tfm, out, ctx->prev); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, ctx->prev); } else { u8 key3[bs]; unsigned int rlen; @@ -229,15 +218,14 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0) return err; - crypto_cipher_encrypt_one(tfm, key3, - (u8 *)(ctx->consts + bs * 2)); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key3, (const u8*)(ctx->consts+bs*2)); ctx->xor(ctx->prev, ctx->odds, bs); ctx->xor(ctx->prev, key3, bs); _crypto_xcbc_digest_setkey(parent, ctx); - crypto_cipher_encrypt_one(tfm, out, ctx->prev); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, ctx->prev); } return 0; @@ -246,25 +234,21 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) static int crypto_xcbc_digest(struct hash_desc *pdesc, struct scatterlist *sg, unsigned int nbytes, u8 *out) { - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - crypto_xcbc_digest_init(pdesc); - crypto_xcbc_digest_update2(pdesc, sg, nbytes); + crypto_xcbc_digest_update(pdesc, sg, nbytes); return crypto_xcbc_digest_final(pdesc, out); } static int xcbc_init_tfm(struct crypto_tfm *tfm) { - struct crypto_cipher *cipher; struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(__crypto_hash_cast(tfm)); int bs = crypto_hash_blocksize(__crypto_hash_cast(tfm)); - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); switch(bs) { case 16: @@ -274,7 +258,7 @@ static int xcbc_init_tfm(struct crypto_tfm *tfm) return -EINVAL; } - ctx->child = cipher; + ctx->child = crypto_cipher_cast(tfm); ctx->odds = (u8*)(ctx+1); ctx->prev = ctx->odds + bs; ctx->key = ctx->prev + bs; diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index f28dcb4ec8b3..0dd96d1afd39 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -30,7 +30,7 @@ obj-$(CONFIG_PARPORT) += parport/ obj-y += base/ block/ misc/ mfd/ net/ media/ obj-$(CONFIG_NUBUS) += nubus/ obj-$(CONFIG_ATM) += atm/ -obj-y += macintosh/ +obj-$(CONFIG_PPC_PMAC) += macintosh/ obj-$(CONFIG_IDE) += ide/ obj-$(CONFIG_FC4) += fc4/ obj-$(CONFIG_SCSI) += scsi/ diff --git a/trunk/drivers/acpi/bay.c b/trunk/drivers/acpi/bay.c index 91082ce6f5d1..667fa1dfa1a3 100644 --- a/trunk/drivers/acpi/bay.c +++ b/trunk/drivers/acpi/bay.c @@ -296,7 +296,7 @@ static int bay_add(acpi_handle handle, int id) /* * Initialize bay device structure */ - new_bay = kzalloc(sizeof(*new_bay), GFP_ATOMIC); + new_bay = kzalloc(GFP_ATOMIC, sizeof(*new_bay)); INIT_LIST_HEAD(&new_bay->list); new_bay->handle = handle; new_bay->name = (char *)nbuffer.pointer; diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index e2796fb40eb7..48616c6fee9d 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -1173,7 +1173,7 @@ static void ahci_host_intr(struct ata_port *ap) * dangerous, we need to know more about them. Print * more of it. */ - const __le32 *f = pp->rx_fis + RX_FIS_SDB; + const u32 *f = pp->rx_fis + RX_FIS_SDB; ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c index 5f4e82ade6cd..46d8a94669b4 100644 --- a/trunk/drivers/ata/sata_svw.c +++ b/trunk/drivers/ata/sata_svw.c @@ -116,7 +116,7 @@ static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) return 0xffffffffU; - return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); + return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -125,7 +125,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, { if (sc_reg > SCR_CONTROL) return; - writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); + writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -262,7 +262,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) static u8 k2_stat_check_status(struct ata_port *ap) { - return readl((void __iomem *) ap->ioaddr.status_addr); + return readl((void *) ap->ioaddr.status_addr); } #ifdef CONFIG_PPC_OF diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 0326ca1a848a..ae8567cc529c 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -60,6 +60,8 @@ obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o obj-$(CONFIG_PRINTER) += lp.o obj-$(CONFIG_TIPAR) += tipar.o +obj-$(CONFIG_APM_EMULATION) += apm-emulation.o + obj-$(CONFIG_DTLK) += dtlk.o obj-$(CONFIG_R3964) += n_r3964.o obj-$(CONFIG_APPLICOM) += applicom.o diff --git a/trunk/drivers/char/apm-emulation.c b/trunk/drivers/char/apm-emulation.c new file mode 100644 index 000000000000..179c7a3b6e75 --- /dev/null +++ b/trunk/drivers/char/apm-emulation.c @@ -0,0 +1,672 @@ +/* + * bios-less APM driver for ARM Linux + * Jamey Hicks + * adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com) + * + * APM 1.2 Reference: + * Intel Corporation, Microsoft Corporation. Advanced Power Management + * (APM) BIOS Interface Specification, Revision 1.2, February 1996. + * + * [This document is available from Microsoft at: + * http://www.microsoft.com/hwdev/busbios/amp_12.htm] + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * The apm_bios device is one of the misc char devices. + * This is its minor number. + */ +#define APM_MINOR_DEV 134 + +/* + * See Documentation/Config.help for the configuration options. + * + * Various options can be changed at boot time as follows: + * (We allow underscores for compatibility with the modules code) + * apm=on/off enable/disable APM + */ + +/* + * Maximum number of events stored + */ +#define APM_MAX_EVENTS 16 + +struct apm_queue { + unsigned int event_head; + unsigned int event_tail; + apm_event_t events[APM_MAX_EVENTS]; +}; + +/* + * The per-file APM data + */ +struct apm_user { + struct list_head list; + + unsigned int suser: 1; + unsigned int writer: 1; + unsigned int reader: 1; + + int suspend_result; + unsigned int suspend_state; +#define SUSPEND_NONE 0 /* no suspend pending */ +#define SUSPEND_PENDING 1 /* suspend pending read */ +#define SUSPEND_READ 2 /* suspend read, pending ack */ +#define SUSPEND_ACKED 3 /* suspend acked */ +#define SUSPEND_WAIT 4 /* waiting for suspend */ +#define SUSPEND_DONE 5 /* suspend completed */ + + struct apm_queue queue; +}; + +/* + * Local variables + */ +static int suspends_pending; +static int apm_disabled; +static struct task_struct *kapmd_tsk; + +static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); +static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); + +/* + * This is a list of everyone who has opened /dev/apm_bios + */ +static DECLARE_RWSEM(user_list_lock); +static LIST_HEAD(apm_user_list); + +/* + * kapmd info. kapmd provides us a process context to handle + * "APM" events within - specifically necessary if we're going + * to be suspending the system. + */ +static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); +static DEFINE_SPINLOCK(kapmd_queue_lock); +static struct apm_queue kapmd_queue; + +static DEFINE_MUTEX(state_lock); + +static const char driver_version[] = "1.13"; /* no spaces */ + + + +/* + * Compatibility cruft until the IPAQ people move over to the new + * interface. + */ +static void __apm_get_power_status(struct apm_power_info *info) +{ +} + +/* + * This allows machines to provide their own "apm get power status" function. + */ +void (*apm_get_power_status)(struct apm_power_info *) = __apm_get_power_status; +EXPORT_SYMBOL(apm_get_power_status); + + +/* + * APM event queue management. + */ +static inline int queue_empty(struct apm_queue *q) +{ + return q->event_head == q->event_tail; +} + +static inline apm_event_t queue_get_event(struct apm_queue *q) +{ + q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS; + return q->events[q->event_tail]; +} + +static void queue_add_event(struct apm_queue *q, apm_event_t event) +{ + q->event_head = (q->event_head + 1) % APM_MAX_EVENTS; + if (q->event_head == q->event_tail) { + static int notified; + + if (notified++ == 0) + printk(KERN_ERR "apm: an event queue overflowed\n"); + q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS; + } + q->events[q->event_head] = event; +} + +static void queue_event(apm_event_t event) +{ + struct apm_user *as; + + down_read(&user_list_lock); + list_for_each_entry(as, &apm_user_list, list) { + if (as->reader) + queue_add_event(&as->queue, event); + } + up_read(&user_list_lock); + wake_up_interruptible(&apm_waitqueue); +} + +/* + * queue_suspend_event - queue an APM suspend event. + * + * Check that we're in a state where we can suspend. If not, + * return -EBUSY. Otherwise, queue an event to all "writer" + * users. If there are no "writer" users, return '1' to + * indicate that we can immediately suspend. + */ +static int queue_suspend_event(apm_event_t event, struct apm_user *sender) +{ + struct apm_user *as; + int ret = 1; + + mutex_lock(&state_lock); + down_read(&user_list_lock); + + /* + * If a thread is still processing, we can't suspend, so reject + * the request. + */ + list_for_each_entry(as, &apm_user_list, list) { + if (as != sender && as->reader && as->writer && as->suser && + as->suspend_state != SUSPEND_NONE) { + ret = -EBUSY; + goto out; + } + } + + list_for_each_entry(as, &apm_user_list, list) { + if (as != sender && as->reader && as->writer && as->suser) { + as->suspend_state = SUSPEND_PENDING; + suspends_pending++; + queue_add_event(&as->queue, event); + ret = 0; + } + } + out: + up_read(&user_list_lock); + mutex_unlock(&state_lock); + wake_up_interruptible(&apm_waitqueue); + return ret; +} + +static void apm_suspend(void) +{ + struct apm_user *as; + int err = pm_suspend(PM_SUSPEND_MEM); + + /* + * Anyone on the APM queues will think we're still suspended. + * Send a message so everyone knows we're now awake again. + */ + queue_event(APM_NORMAL_RESUME); + + /* + * Finally, wake up anyone who is sleeping on the suspend. + */ + mutex_lock(&state_lock); + down_read(&user_list_lock); + list_for_each_entry(as, &apm_user_list, list) { + if (as->suspend_state == SUSPEND_WAIT || + as->suspend_state == SUSPEND_ACKED) { + as->suspend_result = err; + as->suspend_state = SUSPEND_DONE; + } + } + up_read(&user_list_lock); + mutex_unlock(&state_lock); + + wake_up(&apm_suspend_waitqueue); +} + +static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) +{ + struct apm_user *as = fp->private_data; + apm_event_t event; + int i = count, ret = 0; + + if (count < sizeof(apm_event_t)) + return -EINVAL; + + if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK) + return -EAGAIN; + + wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue)); + + while ((i >= sizeof(event)) && !queue_empty(&as->queue)) { + event = queue_get_event(&as->queue); + + ret = -EFAULT; + if (copy_to_user(buf, &event, sizeof(event))) + break; + + mutex_lock(&state_lock); + if (as->suspend_state == SUSPEND_PENDING && + (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND)) + as->suspend_state = SUSPEND_READ; + mutex_unlock(&state_lock); + + buf += sizeof(event); + i -= sizeof(event); + } + + if (i < count) + ret = count - i; + + return ret; +} + +static unsigned int apm_poll(struct file *fp, poll_table * wait) +{ + struct apm_user *as = fp->private_data; + + poll_wait(fp, &apm_waitqueue, wait); + return queue_empty(&as->queue) ? 0 : POLLIN | POLLRDNORM; +} + +/* + * apm_ioctl - handle APM ioctl + * + * APM_IOC_SUSPEND + * This IOCTL is overloaded, and performs two functions. It is used to: + * - initiate a suspend + * - acknowledge a suspend read from /dev/apm_bios. + * Only when everyone who has opened /dev/apm_bios with write permission + * has acknowledge does the actual suspend happen. + */ +static int +apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) +{ + struct apm_user *as = filp->private_data; + unsigned long flags; + int err = -EINVAL; + + if (!as->suser || !as->writer) + return -EPERM; + + switch (cmd) { + case APM_IOC_SUSPEND: + mutex_lock(&state_lock); + + as->suspend_result = -EINTR; + + if (as->suspend_state == SUSPEND_READ) { + int pending; + + /* + * If we read a suspend command from /dev/apm_bios, + * then the corresponding APM_IOC_SUSPEND ioctl is + * interpreted as an acknowledge. + */ + as->suspend_state = SUSPEND_ACKED; + suspends_pending--; + pending = suspends_pending == 0; + mutex_unlock(&state_lock); + + /* + * If there are no further acknowledges required, + * suspend the system. + */ + if (pending) + apm_suspend(); + + /* + * Wait for the suspend/resume to complete. If there + * are pending acknowledges, we wait here for them. + * + * Note: we need to ensure that the PM subsystem does + * not kick us out of the wait when it suspends the + * threads. + */ + flags = current->flags; + current->flags |= PF_NOFREEZE; + + wait_event(apm_suspend_waitqueue, + as->suspend_state == SUSPEND_DONE); + } else { + as->suspend_state = SUSPEND_WAIT; + mutex_unlock(&state_lock); + + /* + * Otherwise it is a request to suspend the system. + * Queue an event for all readers, and expect an + * acknowledge from all writers who haven't already + * acknowledged. + */ + err = queue_suspend_event(APM_USER_SUSPEND, as); + if (err < 0) { + /* + * Avoid taking the lock here - this + * should be fine. + */ + as->suspend_state = SUSPEND_NONE; + break; + } + + if (err > 0) + apm_suspend(); + + /* + * Wait for the suspend/resume to complete. If there + * are pending acknowledges, we wait here for them. + * + * Note: we need to ensure that the PM subsystem does + * not kick us out of the wait when it suspends the + * threads. + */ + flags = current->flags; + current->flags |= PF_NOFREEZE; + + wait_event_interruptible(apm_suspend_waitqueue, + as->suspend_state == SUSPEND_DONE); + } + + current->flags = flags; + + mutex_lock(&state_lock); + err = as->suspend_result; + as->suspend_state = SUSPEND_NONE; + mutex_unlock(&state_lock); + break; + } + + return err; +} + +static int apm_release(struct inode * inode, struct file * filp) +{ + struct apm_user *as = filp->private_data; + int pending = 0; + + filp->private_data = NULL; + + down_write(&user_list_lock); + list_del(&as->list); + up_write(&user_list_lock); + + /* + * We are now unhooked from the chain. As far as new + * events are concerned, we no longer exist. However, we + * need to balance suspends_pending, which means the + * possibility of sleeping. + */ + mutex_lock(&state_lock); + if (as->suspend_state != SUSPEND_NONE) { + suspends_pending -= 1; + pending = suspends_pending == 0; + } + mutex_unlock(&state_lock); + if (pending) + apm_suspend(); + + kfree(as); + return 0; +} + +static int apm_open(struct inode * inode, struct file * filp) +{ + struct apm_user *as; + + as = kzalloc(sizeof(*as), GFP_KERNEL); + if (as) { + /* + * XXX - this is a tiny bit broken, when we consider BSD + * process accounting. If the device is opened by root, we + * instantly flag that we used superuser privs. Who knows, + * we might close the device immediately without doing a + * privileged operation -- cevans + */ + as->suser = capable(CAP_SYS_ADMIN); + as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE; + as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ; + + down_write(&user_list_lock); + list_add(&as->list, &apm_user_list); + up_write(&user_list_lock); + + filp->private_data = as; + } + + return as ? 0 : -ENOMEM; +} + +static struct file_operations apm_bios_fops = { + .owner = THIS_MODULE, + .read = apm_read, + .poll = apm_poll, + .ioctl = apm_ioctl, + .open = apm_open, + .release = apm_release, +}; + +static struct miscdevice apm_device = { + .minor = APM_MINOR_DEV, + .name = "apm_bios", + .fops = &apm_bios_fops +}; + + +#ifdef CONFIG_PROC_FS +/* + * Arguments, with symbols from linux/apm_bios.h. + * + * 0) Linux driver version (this will change if format changes) + * 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2. + * 2) APM flags from APM Installation Check (0x00): + * bit 0: APM_16_BIT_SUPPORT + * bit 1: APM_32_BIT_SUPPORT + * bit 2: APM_IDLE_SLOWS_CLOCK + * bit 3: APM_BIOS_DISABLED + * bit 4: APM_BIOS_DISENGAGED + * 3) AC line status + * 0x00: Off-line + * 0x01: On-line + * 0x02: On backup power (BIOS >= 1.1 only) + * 0xff: Unknown + * 4) Battery status + * 0x00: High + * 0x01: Low + * 0x02: Critical + * 0x03: Charging + * 0x04: Selected battery not present (BIOS >= 1.2 only) + * 0xff: Unknown + * 5) Battery flag + * bit 0: High + * bit 1: Low + * bit 2: Critical + * bit 3: Charging + * bit 7: No system battery + * 0xff: Unknown + * 6) Remaining battery life (percentage of charge): + * 0-100: valid + * -1: Unknown + * 7) Remaining battery life (time units): + * Number of remaining minutes or seconds + * -1: Unknown + * 8) min = minutes; sec = seconds + */ +static int apm_get_info(char *buf, char **start, off_t fpos, int length) +{ + struct apm_power_info info; + char *units; + int ret; + + info.ac_line_status = 0xff; + info.battery_status = 0xff; + info.battery_flag = 0xff; + info.battery_life = -1; + info.time = -1; + info.units = -1; + + if (apm_get_power_status) + apm_get_power_status(&info); + + switch (info.units) { + default: units = "?"; break; + case 0: units = "min"; break; + case 1: units = "sec"; break; + } + + ret = sprintf(buf, "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", + driver_version, APM_32_BIT_SUPPORT, + info.ac_line_status, info.battery_status, + info.battery_flag, info.battery_life, + info.time, units); + + return ret; +} +#endif + +static int kapmd(void *arg) +{ + do { + apm_event_t event; + int ret; + + wait_event_interruptible(kapmd_wait, + !queue_empty(&kapmd_queue) || kthread_should_stop()); + + if (kthread_should_stop()) + break; + + spin_lock_irq(&kapmd_queue_lock); + event = 0; + if (!queue_empty(&kapmd_queue)) + event = queue_get_event(&kapmd_queue); + spin_unlock_irq(&kapmd_queue_lock); + + switch (event) { + case 0: + break; + + case APM_LOW_BATTERY: + case APM_POWER_STATUS_CHANGE: + queue_event(event); + break; + + case APM_USER_SUSPEND: + case APM_SYS_SUSPEND: + ret = queue_suspend_event(event, NULL); + if (ret < 0) { + /* + * We were busy. Try again in 50ms. + */ + queue_add_event(&kapmd_queue, event); + msleep(50); + } + if (ret > 0) + apm_suspend(); + break; + + case APM_CRITICAL_SUSPEND: + apm_suspend(); + break; + } + } while (1); + + return 0; +} + +static int __init apm_init(void) +{ + int ret; + + if (apm_disabled) { + printk(KERN_NOTICE "apm: disabled on user request.\n"); + return -ENODEV; + } + + kapmd_tsk = kthread_create(kapmd, NULL, "kapmd"); + if (IS_ERR(kapmd_tsk)) { + ret = PTR_ERR(kapmd_tsk); + kapmd_tsk = NULL; + return ret; + } + kapmd_tsk->flags |= PF_NOFREEZE; + wake_up_process(kapmd_tsk); + +#ifdef CONFIG_PROC_FS + create_proc_info_entry("apm", 0, NULL, apm_get_info); +#endif + + ret = misc_register(&apm_device); + if (ret != 0) { + remove_proc_entry("apm", NULL); + kthread_stop(kapmd_tsk); + } + + return ret; +} + +static void __exit apm_exit(void) +{ + misc_deregister(&apm_device); + remove_proc_entry("apm", NULL); + + kthread_stop(kapmd_tsk); +} + +module_init(apm_init); +module_exit(apm_exit); + +MODULE_AUTHOR("Stephen Rothwell"); +MODULE_DESCRIPTION("Advanced Power Management"); +MODULE_LICENSE("GPL"); + +#ifndef MODULE +static int __init apm_setup(char *str) +{ + while ((str != NULL) && (*str != '\0')) { + if (strncmp(str, "off", 3) == 0) + apm_disabled = 1; + if (strncmp(str, "on", 2) == 0) + apm_disabled = 0; + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); + } + return 1; +} + +__setup("apm=", apm_setup); +#endif + +/** + * apm_queue_event - queue an APM event for kapmd + * @event: APM event + * + * Queue an APM event for kapmd to process and ultimately take the + * appropriate action. Only a subset of events are handled: + * %APM_LOW_BATTERY + * %APM_POWER_STATUS_CHANGE + * %APM_USER_SUSPEND + * %APM_SYS_SUSPEND + * %APM_CRITICAL_SUSPEND + */ +void apm_queue_event(apm_event_t event) +{ + unsigned long flags; + + spin_lock_irqsave(&kapmd_queue_lock, flags); + queue_add_event(&kapmd_queue, event); + spin_unlock_irqrestore(&kapmd_queue_lock, flags); + + wake_up_interruptible(&kapmd_wait); +} +EXPORT_SYMBOL(apm_queue_event); diff --git a/trunk/drivers/char/watchdog/machzwd.c b/trunk/drivers/char/watchdog/machzwd.c index 4d730fdbd528..276577d08fba 100644 --- a/trunk/drivers/char/watchdog/machzwd.c +++ b/trunk/drivers/char/watchdog/machzwd.c @@ -325,7 +325,7 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return put_user(0, p); case WDIOC_KEEPALIVE: - zf_ping(NULL); + zf_ping(0); break; default: diff --git a/trunk/drivers/crypto/geode-aes.c b/trunk/drivers/crypto/geode-aes.c index 31ea405f2eeb..43a68398656f 100644 --- a/trunk/drivers/crypto/geode-aes.c +++ b/trunk/drivers/crypto/geode-aes.c @@ -457,7 +457,7 @@ static struct pci_driver geode_aes_driver = { static int __init geode_aes_init(void) { - return pci_register_driver(&geode_aes_driver); + return pci_module_init(&geode_aes_driver); } static void __exit diff --git a/trunk/drivers/hwmon/ams/ams-input.c b/trunk/drivers/hwmon/ams/ams-input.c index 18210164e307..f126aa485134 100644 --- a/trunk/drivers/hwmon/ams/ams-input.c +++ b/trunk/drivers/hwmon/ams/ams-input.c @@ -153,7 +153,7 @@ int ams_input_init(void) } /* Call with ams_info.lock held! */ -void ams_input_exit(void) +void ams_input_exit() { ams_input_disable(); device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick); diff --git a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c index 89e37283c836..0a7d1ab60e6d 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c @@ -567,7 +567,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc, opcode = hdr->opcode & ISCSI_OPCODE_MASK; if (opcode == ISCSI_OP_SCSI_CMD_RSP) { - itt = get_itt(hdr->itt); /* mask out cid and age bits */ + itt = hdr->itt & ISCSI_ITT_MASK; /* mask out cid and age bits */ if (!(itt < session->cmds_max)) iser_err("itt can't be matched to task!!!" "conn %p opcode %d cmds_max %d itt %d\n", @@ -625,7 +625,7 @@ void iser_snd_completion(struct iser_desc *tx_desc) /* this arithmetic is legal by libiscsi dd_data allocation */ mtask = (void *) ((long)(void *)tx_desc - sizeof(struct iscsi_mgmt_task)); - if (mtask->hdr->itt == RESERVED_ITT) { + if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) { struct iscsi_session *session = conn->session; spin_lock(&conn->session->lock); diff --git a/trunk/drivers/input/touchscreen/ucb1400_ts.c b/trunk/drivers/input/touchscreen/ucb1400_ts.c index c7db4032ef02..4358a0a78eaa 100644 --- a/trunk/drivers/input/touchscreen/ucb1400_ts.c +++ b/trunk/drivers/input/touchscreen/ucb1400_ts.c @@ -83,7 +83,7 @@ struct ucb1400 { - struct snd_ac97 *ac97; + ac97_t *ac97; struct input_dev *ts_idev; int irq; diff --git a/trunk/drivers/kvm/kvm_main.c b/trunk/drivers/kvm/kvm_main.c index 099f0afd394d..b10972ed0c9f 100644 --- a/trunk/drivers/kvm/kvm_main.c +++ b/trunk/drivers/kvm/kvm_main.c @@ -62,7 +62,7 @@ static struct kvm_stats_debugfs_item { { "halt_exits", &kvm_stat.halt_exits }, { "request_irq", &kvm_stat.request_irq_exits }, { "irq_exits", &kvm_stat.irq_exits }, - { NULL, NULL } + { 0, 0 } }; static struct dentry *debugfs_dir; @@ -205,7 +205,7 @@ static struct kvm_vcpu *vcpu_load(struct kvm *kvm, int vcpu_slot) mutex_lock(&vcpu->mutex); if (unlikely(!vcpu->vmcs)) { mutex_unlock(&vcpu->mutex); - return NULL; + return 0; } return kvm_arch_ops->vcpu_load(vcpu); } @@ -257,9 +257,9 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free, if (!dont || free->dirty_bitmap != dont->dirty_bitmap) vfree(free->dirty_bitmap); - free->phys_mem = NULL; + free->phys_mem = 0; free->npages = 0; - free->dirty_bitmap = NULL; + free->dirty_bitmap = 0; } static void kvm_free_physmem(struct kvm *kvm) @@ -267,7 +267,7 @@ static void kvm_free_physmem(struct kvm *kvm) int i; for (i = 0; i < kvm->nmemslots; ++i) - kvm_free_physmem_slot(&kvm->memslots[i], NULL); + kvm_free_physmem_slot(&kvm->memslots[i], 0); } static void kvm_free_vcpu(struct kvm_vcpu *vcpu) @@ -640,11 +640,11 @@ static int kvm_dev_ioctl_set_memory_region(struct kvm *kvm, /* Deallocate if slot is being removed */ if (!npages) - new.phys_mem = NULL; + new.phys_mem = 0; /* Free page dirty bitmap if unneeded */ if (!(new.flags & KVM_MEM_LOG_DIRTY_PAGES)) - new.dirty_bitmap = NULL; + new.dirty_bitmap = 0; r = -ENOMEM; @@ -799,14 +799,14 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) && gfn < memslot->base_gfn + memslot->npages) return memslot; } - return NULL; + return 0; } EXPORT_SYMBOL_GPL(gfn_to_memslot); void mark_page_dirty(struct kvm *kvm, gfn_t gfn) { int i; - struct kvm_memory_slot *memslot = NULL; + struct kvm_memory_slot *memslot = 0; unsigned long rel_gfn; for (i = 0; i < kvm->nmemslots; ++i) { @@ -1778,7 +1778,6 @@ static long kvm_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { struct kvm *kvm = filp->private_data; - void __user *argp = (void __user *)arg; int r = -EINVAL; switch (ioctl) { @@ -1795,12 +1794,12 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_run kvm_run; r = -EFAULT; - if (copy_from_user(&kvm_run, argp, sizeof kvm_run)) + if (copy_from_user(&kvm_run, (void *)arg, sizeof kvm_run)) goto out; r = kvm_dev_ioctl_run(kvm, &kvm_run); if (r < 0 && r != -EINTR) goto out; - if (copy_to_user(argp, &kvm_run, sizeof kvm_run)) { + if (copy_to_user((void *)arg, &kvm_run, sizeof kvm_run)) { r = -EFAULT; goto out; } @@ -1810,13 +1809,13 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_regs kvm_regs; r = -EFAULT; - if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs)) + if (copy_from_user(&kvm_regs, (void *)arg, sizeof kvm_regs)) goto out; r = kvm_dev_ioctl_get_regs(kvm, &kvm_regs); if (r) goto out; r = -EFAULT; - if (copy_to_user(argp, &kvm_regs, sizeof kvm_regs)) + if (copy_to_user((void *)arg, &kvm_regs, sizeof kvm_regs)) goto out; r = 0; break; @@ -1825,7 +1824,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_regs kvm_regs; r = -EFAULT; - if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs)) + if (copy_from_user(&kvm_regs, (void *)arg, sizeof kvm_regs)) goto out; r = kvm_dev_ioctl_set_regs(kvm, &kvm_regs); if (r) @@ -1837,13 +1836,13 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_sregs kvm_sregs; r = -EFAULT; - if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs)) + if (copy_from_user(&kvm_sregs, (void *)arg, sizeof kvm_sregs)) goto out; r = kvm_dev_ioctl_get_sregs(kvm, &kvm_sregs); if (r) goto out; r = -EFAULT; - if (copy_to_user(argp, &kvm_sregs, sizeof kvm_sregs)) + if (copy_to_user((void *)arg, &kvm_sregs, sizeof kvm_sregs)) goto out; r = 0; break; @@ -1852,7 +1851,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_sregs kvm_sregs; r = -EFAULT; - if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs)) + if (copy_from_user(&kvm_sregs, (void *)arg, sizeof kvm_sregs)) goto out; r = kvm_dev_ioctl_set_sregs(kvm, &kvm_sregs); if (r) @@ -1864,13 +1863,13 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_translation tr; r = -EFAULT; - if (copy_from_user(&tr, argp, sizeof tr)) + if (copy_from_user(&tr, (void *)arg, sizeof tr)) goto out; r = kvm_dev_ioctl_translate(kvm, &tr); if (r) goto out; r = -EFAULT; - if (copy_to_user(argp, &tr, sizeof tr)) + if (copy_to_user((void *)arg, &tr, sizeof tr)) goto out; r = 0; break; @@ -1879,7 +1878,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_interrupt irq; r = -EFAULT; - if (copy_from_user(&irq, argp, sizeof irq)) + if (copy_from_user(&irq, (void *)arg, sizeof irq)) goto out; r = kvm_dev_ioctl_interrupt(kvm, &irq); if (r) @@ -1891,7 +1890,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_debug_guest dbg; r = -EFAULT; - if (copy_from_user(&dbg, argp, sizeof dbg)) + if (copy_from_user(&dbg, (void *)arg, sizeof dbg)) goto out; r = kvm_dev_ioctl_debug_guest(kvm, &dbg); if (r) @@ -1903,7 +1902,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_memory_region kvm_mem; r = -EFAULT; - if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem)) + if (copy_from_user(&kvm_mem, (void *)arg, sizeof kvm_mem)) goto out; r = kvm_dev_ioctl_set_memory_region(kvm, &kvm_mem); if (r) @@ -1914,7 +1913,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_dirty_log log; r = -EFAULT; - if (copy_from_user(&log, argp, sizeof log)) + if (copy_from_user(&log, (void *)arg, sizeof log)) goto out; r = kvm_dev_ioctl_get_dirty_log(kvm, &log); if (r) @@ -1922,13 +1921,13 @@ static long kvm_dev_ioctl(struct file *filp, break; } case KVM_GET_MSRS: - r = msr_io(kvm, argp, get_msr, 1); + r = msr_io(kvm, (void __user *)arg, get_msr, 1); break; case KVM_SET_MSRS: - r = msr_io(kvm, argp, do_set_msr, 0); + r = msr_io(kvm, (void __user *)arg, do_set_msr, 0); break; case KVM_GET_MSR_INDEX_LIST: { - struct kvm_msr_list __user *user_msr_list = argp; + struct kvm_msr_list __user *user_msr_list = (void __user *)arg; struct kvm_msr_list msr_list; unsigned n; @@ -2015,7 +2014,7 @@ static int kvm_reboot(struct notifier_block *notifier, unsigned long val, * in vmx root mode. */ printk(KERN_INFO "kvm: exiting hardware virtualization\n"); - on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1); } return NOTIFY_OK; } @@ -2029,7 +2028,7 @@ static __init void kvm_init_debug(void) { struct kvm_stats_debugfs_item *p; - debugfs_dir = debugfs_create_dir("kvm", NULL); + debugfs_dir = debugfs_create_dir("kvm", 0); for (p = debugfs_entries; p->name; ++p) p->dentry = debugfs_create_u32(p->name, 0444, debugfs_dir, p->data); @@ -2070,7 +2069,7 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) if (r < 0) return r; - on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_enable, 0, 0, 1); register_reboot_notifier(&kvm_reboot_notifier); kvm_chardev_ops.owner = module; @@ -2085,7 +2084,7 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) out_free: unregister_reboot_notifier(&kvm_reboot_notifier); - on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1); kvm_arch_ops->hardware_unsetup(); return r; } @@ -2095,7 +2094,7 @@ void kvm_exit_arch(void) misc_deregister(&kvm_dev); unregister_reboot_notifier(&kvm_reboot_notifier); - on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1); kvm_arch_ops->hardware_unsetup(); kvm_arch_ops = NULL; } diff --git a/trunk/drivers/kvm/mmu.c b/trunk/drivers/kvm/mmu.c index be793770f31b..22c426cd8cb2 100644 --- a/trunk/drivers/kvm/mmu.c +++ b/trunk/drivers/kvm/mmu.c @@ -333,7 +333,7 @@ static void rmap_desc_remove_entry(struct kvm_vcpu *vcpu, for (j = RMAP_EXT - 1; !desc->shadow_ptes[j] && j > i; --j) ; desc->shadow_ptes[i] = desc->shadow_ptes[j]; - desc->shadow_ptes[j] = NULL; + desc->shadow_ptes[j] = 0; if (j != 0) return; if (!prev_desc && !desc->more) diff --git a/trunk/drivers/kvm/svm.c b/trunk/drivers/kvm/svm.c index 85f61dd1e936..c79df79307ed 100644 --- a/trunk/drivers/kvm/svm.c +++ b/trunk/drivers/kvm/svm.c @@ -274,7 +274,7 @@ static void svm_hardware_disable(void *garbage) wrmsrl(MSR_VM_HSAVE_PA, 0); rdmsrl(MSR_EFER, efer); wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK); - per_cpu(svm_data, raw_smp_processor_id()) = NULL; + per_cpu(svm_data, raw_smp_processor_id()) = 0; __free_page(svm_data->save_area); kfree(svm_data); } @@ -642,7 +642,7 @@ static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg) case VCPU_SREG_LDTR: return &save->ldtr; } BUG(); - return NULL; + return 0; } static u64 svm_get_segment_base(struct kvm_vcpu *vcpu, int seg) @@ -934,7 +934,7 @@ static int io_get_override(struct kvm_vcpu *vcpu, return 0; *addr_override = 0; - *seg = NULL; + *seg = 0; for (i = 0; i < ins_length; i++) switch (inst[i]) { case 0xf0: @@ -1087,7 +1087,7 @@ static int cpuid_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { - if (emulate_instruction(vcpu, NULL, 0, 0) != EMULATE_DONE) + if (emulate_instruction(vcpu, 0, 0, 0) != EMULATE_DONE) printk(KERN_ERR "%s: failed\n", __FUNCTION__); return 1; } diff --git a/trunk/drivers/kvm/vmx.c b/trunk/drivers/kvm/vmx.c index 27e05a77e21a..54c35c0b3181 100644 --- a/trunk/drivers/kvm/vmx.c +++ b/trunk/drivers/kvm/vmx.c @@ -98,7 +98,7 @@ static struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr) for (i = 0; i < vcpu->nmsrs; ++i) if (vcpu->guest_msrs[i].index == msr) return &vcpu->guest_msrs[i]; - return NULL; + return 0; } static void vmcs_clear(struct vmcs *vmcs) diff --git a/trunk/drivers/macintosh/Kconfig b/trunk/drivers/macintosh/Kconfig index 1a86387e23be..a9e747c39791 100644 --- a/trunk/drivers/macintosh/Kconfig +++ b/trunk/drivers/macintosh/Kconfig @@ -1,6 +1,6 @@ menu "Macintosh device drivers" - depends on PPC || MAC || X86 + depends on PPC || MAC config ADB bool "Apple Desktop Bus (ADB) support" diff --git a/trunk/drivers/macintosh/rack-meter.c b/trunk/drivers/macintosh/rack-meter.c index f83fad2a3ff4..5ed41fe84e57 100644 --- a/trunk/drivers/macintosh/rack-meter.c +++ b/trunk/drivers/macintosh/rack-meter.c @@ -171,11 +171,11 @@ static void rackmeter_setup_dbdma(struct rackmeter *rm) /* Make sure dbdma is reset */ DBDMA_DO_RESET(rm->dma_regs); - pr_debug("rackmeter: mark offset=0x%zx\n", + pr_debug("rackmeter: mark offset=0x%lx\n", offsetof(struct rackmeter_dma, mark)); - pr_debug("rackmeter: buf1 offset=0x%zx\n", + pr_debug("rackmeter: buf1 offset=0x%lx\n", offsetof(struct rackmeter_dma, buf1)); - pr_debug("rackmeter: buf2 offset=0x%zx\n", + pr_debug("rackmeter: buf2 offset=0x%lx\n", offsetof(struct rackmeter_dma, buf2)); /* Prepare 4 dbdma commands for the 2 buffers */ diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 059704fbb753..11108165e264 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -1160,22 +1160,6 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect return 0; } - if (unlikely((*bmc & COUNTER_MAX) == COUNTER_MAX)) { - DEFINE_WAIT(__wait); - /* note that it is safe to do the prepare_to_wait - * after the test as long as we do it before dropping - * the spinlock. - */ - prepare_to_wait(&bitmap->overflow_wait, &__wait, - TASK_UNINTERRUPTIBLE); - spin_unlock_irq(&bitmap->lock); - bitmap->mddev->queue - ->unplug_fn(bitmap->mddev->queue); - schedule(); - finish_wait(&bitmap->overflow_wait, &__wait); - continue; - } - switch(*bmc) { case 0: bitmap_file_set_bit(bitmap, offset); @@ -1185,7 +1169,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect case 1: *bmc = 2; } - + BUG_ON((*bmc & COUNTER_MAX) == COUNTER_MAX); (*bmc)++; spin_unlock_irq(&bitmap->lock); @@ -1223,9 +1207,6 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto if (!success && ! (*bmc & NEEDED_MASK)) *bmc |= NEEDED_MASK; - if ((*bmc & COUNTER_MAX) == COUNTER_MAX) - wake_up(&bitmap->overflow_wait); - (*bmc)--; if (*bmc <= 2) { set_page_attr(bitmap, @@ -1450,7 +1431,6 @@ int bitmap_create(mddev_t *mddev) spin_lock_init(&bitmap->lock); atomic_set(&bitmap->pending_writes, 0); init_waitqueue_head(&bitmap->write_wait); - init_waitqueue_head(&bitmap->overflow_wait); bitmap->mddev = mddev; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 11c3d7bfa797..467c16982d02 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -2620,7 +2620,7 @@ static struct bio *remove_bio_from_retry(raid5_conf_t *conf) } bi = conf->retry_read_aligned_list; if(bi) { - conf->retry_read_aligned_list = bi->bi_next; + conf->retry_read_aligned = bi->bi_next; bi->bi_next = NULL; bi->bi_phys_segments = 1; /* biased count of active stripes */ bi->bi_hw_segments = 0; /* count of processed stripes */ @@ -2669,27 +2669,6 @@ static int raid5_align_endio(struct bio *bi, unsigned int bytes, int error) return 0; } -static int bio_fits_rdev(struct bio *bi) -{ - request_queue_t *q = bdev_get_queue(bi->bi_bdev); - - if ((bi->bi_size>>9) > q->max_sectors) - return 0; - blk_recount_segments(q, bi); - if (bi->bi_phys_segments > q->max_phys_segments || - bi->bi_hw_segments > q->max_hw_segments) - return 0; - - if (q->merge_bvec_fn) - /* it's too hard to apply the merge_bvec_fn at this stage, - * just just give up - */ - return 0; - - return 1; -} - - static int chunk_aligned_read(request_queue_t *q, struct bio * raid_bio) { mddev_t *mddev = q->queuedata; @@ -2736,13 +2715,6 @@ static int chunk_aligned_read(request_queue_t *q, struct bio * raid_bio) align_bi->bi_flags &= ~(1 << BIO_SEG_VALID); align_bi->bi_sector += rdev->data_offset; - if (!bio_fits_rdev(align_bi)) { - /* too big in some way */ - bio_put(align_bi); - rdev_dec_pending(rdev, mddev); - return 0; - } - spin_lock_irq(&conf->device_lock); wait_event_lock_irq(conf->wait_for_stripe, conf->quiesce == 0, @@ -3135,9 +3107,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) last_sector = raid_bio->bi_sector + (raid_bio->bi_size>>9); for (; logical_sector < last_sector; - logical_sector += STRIPE_SECTORS, - sector += STRIPE_SECTORS, - scnt++) { + logical_sector += STRIPE_SECTORS, scnt++) { if (scnt < raid_bio->bi_hw_segments) /* already done this stripe */ @@ -3153,13 +3123,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) } set_bit(R5_ReadError, &sh->dev[dd_idx].flags); - if (!add_stripe_bio(sh, raid_bio, dd_idx, 0)) { - release_stripe(sh); - raid_bio->bi_hw_segments = scnt; - conf->retry_read_aligned = raid_bio; - return handled; - } - + add_stripe_bio(sh, raid_bio, dd_idx, 0); handle_stripe(sh, NULL); release_stripe(sh); handled++; diff --git a/trunk/drivers/media/common/ir-keymaps.c b/trunk/drivers/media/common/ir-keymaps.c index 0e948a5c5a03..f51e02fe3655 100644 --- a/trunk/drivers/media/common/ir-keymaps.c +++ b/trunk/drivers/media/common/ir-keymaps.c @@ -698,6 +698,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { [ 0x29 ] = KEY_TEXT, [ 0x2a ] = KEY_MEDIA, [ 0x18 ] = KEY_EPG, + [ 0x27 ] = KEY_RECORD, }; EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); diff --git a/trunk/drivers/media/video/usbvision/usbvision-video.c b/trunk/drivers/media/video/usbvision/usbvision-video.c index bdd6301d2a47..7243337b771a 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-video.c +++ b/trunk/drivers/media/video/usbvision/usbvision-video.c @@ -1072,7 +1072,7 @@ static int usbvision_v4l2_ioctl(struct inode *inode, struct file *file, } -static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, +static ssize_t usbvision_v4l2_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct video_device *dev = video_devdata(file); diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index bedae4ad3f74..89bba277da5f 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -42,7 +42,7 @@ config SGI_IOC4 config TIFM_CORE tristate "TI Flash Media interface support (EXPERIMENTAL)" - depends on EXPERIMENTAL && PCI + depends on EXPERIMENTAL help If you want support for Texas Instruments(R) Flash Media adapters you should select this option and then also choose an appropriate diff --git a/trunk/drivers/misc/lkdtm.c b/trunk/drivers/misc/lkdtm.c index 552b7957a92a..db9d7df75ae0 100644 --- a/trunk/drivers/misc/lkdtm.c +++ b/trunk/drivers/misc/lkdtm.c @@ -108,8 +108,8 @@ static struct jprobe lkdtm; static int lkdtm_parse_commandline(void); static void lkdtm_handler(void); -static char* cpoint_name; -static char* cpoint_type; +static char* cpoint_name = INVALID; +static char* cpoint_type = NONE; static int cpoint_count = DEFAULT_COUNT; static int recur_count = REC_NUM_DEFAULT; diff --git a/trunk/drivers/mmc/Kconfig b/trunk/drivers/mmc/Kconfig index 12af9c718764..4224686fdf2a 100644 --- a/trunk/drivers/mmc/Kconfig +++ b/trunk/drivers/mmc/Kconfig @@ -111,7 +111,7 @@ config MMC_IMX config MMC_TIFM_SD tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" - depends on MMC && EXPERIMENTAL && PCI + depends on MMC && EXPERIMENTAL select TIFM_CORE help Say Y here if you want to be able to access MMC/SD cards with diff --git a/trunk/drivers/net/3c503.c b/trunk/drivers/net/3c503.c index bc7e906571d3..7e34c4f07b70 100644 --- a/trunk/drivers/net/3c503.c +++ b/trunk/drivers/net/3c503.c @@ -600,7 +600,8 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring count -= semi_count; memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count); } else { - memcpy_fromio(skb->data, base + ring_offset, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, base + ring_offset, count, 0); } return; } diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 38f41a593b12..ad92b6a76ee6 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2335,17 +2335,6 @@ config QLA3XXX To compile this driver as a module, choose M here: the module will be called qla3xxx. -config ATL1 - tristate "Attansic L1 Gigabit Ethernet support (EXPERIMENTAL)" - depends on NET_PCI && PCI && EXPERIMENTAL - select CRC32 - select MII - help - This driver supports the Attansic L1 gigabit ethernet adapter. - - To compile this driver as a module, choose M here. The module - will be called atl1. - endmenu # @@ -2545,7 +2534,7 @@ config RIONET_RX_SIZE config FDDI bool "FDDI driver support" - depends on (PCI || EISA || TC) + depends on (PCI || EISA) help Fiber Distributed Data Interface is a high speed local area network design; essentially a replacement for high speed Ethernet. FDDI can @@ -2555,31 +2544,11 @@ config FDDI will say N. config DEFXX - tristate "Digital DEFTA/DEFEA/DEFPA adapter support" - depends on FDDI && (PCI || EISA || TC) - ---help--- - This is support for the DIGITAL series of TURBOchannel (DEFTA), - EISA (DEFEA) and PCI (DEFPA) controllers which can connect you - to a local FDDI network. - - To compile this driver as a module, choose M here: the module - will be called defxx. If unsure, say N. - -config DEFXX_MMIO - bool - prompt "Use MMIO instead of PIO" if PCI || EISA - depends on DEFXX - default n if PCI || EISA - default y - ---help--- - This instructs the driver to use EISA or PCI memory-mapped I/O - (MMIO) as appropriate instead of programmed I/O ports (PIO). - Enabling this gives an improvement in processing time in parts - of the driver, but it may cause problems with EISA (DEFEA) - adapters. TURBOchannel does not have the concept of I/O ports, - so MMIO is always used for these (DEFTA) adapters. - - If unsure, say N. + tristate "Digital DEFEA and DEFPA adapter support" + depends on FDDI && (PCI || EISA) + help + This is support for the DIGITAL series of EISA (DEFEA) and PCI + (DEFPA) controllers which can connect you to a local FDDI network. config SKFP tristate "SysKonnect FDDI PCI support" diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 33af833667da..0878e3df5174 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/ obj-$(CONFIG_CHELSIO_T3) += cxgb3/ obj-$(CONFIG_EHEA) += ehea/ obj-$(CONFIG_BONDING) += bonding/ -obj-$(CONFIG_ATL1) += atl1/ obj-$(CONFIG_GIANFAR) += gianfar_driver.o gianfar_driver-objs := gianfar.o \ diff --git a/trunk/drivers/net/ac3200.c b/trunk/drivers/net/ac3200.c index 644c408515df..c01f87f5bed7 100644 --- a/trunk/drivers/net/ac3200.c +++ b/trunk/drivers/net/ac3200.c @@ -327,7 +327,8 @@ static void ac_block_input(struct net_device *dev, int count, struct sk_buff *sk memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES*256, count); } else { - memcpy_fromio(skb->data, start, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, start, count, 0); } } diff --git a/trunk/drivers/net/atl1/Makefile b/trunk/drivers/net/atl1/Makefile deleted file mode 100644 index a6b707e4e69e..000000000000 --- a/trunk/drivers/net/atl1/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_ATL1) += atl1.o -atl1-y += atl1_main.o atl1_hw.o atl1_ethtool.o atl1_param.o diff --git a/trunk/drivers/net/atl1/atl1.h b/trunk/drivers/net/atl1/atl1.h deleted file mode 100644 index b1c6034e68fa..000000000000 --- a/trunk/drivers/net/atl1/atl1.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _ATL1_H_ -#define _ATL1_H_ - -#include -#include - -#include "atl1_hw.h" - -/* function prototypes needed by multiple files */ -s32 atl1_up(struct atl1_adapter *adapter); -void atl1_down(struct atl1_adapter *adapter); -int atl1_reset(struct atl1_adapter *adapter); -s32 atl1_setup_ring_resources(struct atl1_adapter *adapter); -void atl1_free_ring_resources(struct atl1_adapter *adapter); - -extern char atl1_driver_name[]; -extern char atl1_driver_version[]; -extern const struct ethtool_ops atl1_ethtool_ops; - -struct atl1_adapter; - -#define ATL1_MAX_INTR 3 - -#define ATL1_DEFAULT_TPD 256 -#define ATL1_MAX_TPD 1024 -#define ATL1_MIN_TPD 64 -#define ATL1_DEFAULT_RFD 512 -#define ATL1_MIN_RFD 128 -#define ATL1_MAX_RFD 2048 - -#define ATL1_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i])) -#define ATL1_RFD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_free_desc) -#define ATL1_TPD_DESC(R, i) ATL1_GET_DESC(R, i, struct tx_packet_desc) -#define ATL1_RRD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_return_desc) - -/* - * Some workarounds require millisecond delays and are run during interrupt - * context. Most notably, when establishing link, the phy may need tweaking - * but cannot process phy register reads/writes faster than millisecond - * intervals...and we establish link due to a "link status change" interrupt. - */ - -/* - * wrapper around a pointer to a socket buffer, - * so a DMA handle can be stored along with the buffer - */ -struct atl1_buffer { - struct sk_buff *skb; - u16 length; - u16 alloced; - dma_addr_t dma; -}; - -#define MAX_TX_BUF_LEN 0x3000 /* 12KB */ - -struct atl1_tpd_ring { - void *desc; /* pointer to the descriptor ring memory */ - dma_addr_t dma; /* physical adress of the descriptor ring */ - u16 size; /* length of descriptor ring in bytes */ - u16 count; /* number of descriptors in the ring */ - u16 hw_idx; /* hardware index */ - atomic_t next_to_clean; - atomic_t next_to_use; - struct atl1_buffer *buffer_info; -}; - -struct atl1_rfd_ring { - void *desc; - dma_addr_t dma; - u16 size; - u16 count; - atomic_t next_to_use; - u16 next_to_clean; - struct atl1_buffer *buffer_info; -}; - -struct atl1_rrd_ring { - void *desc; - dma_addr_t dma; - unsigned int size; - u16 count; - u16 next_to_use; - atomic_t next_to_clean; -}; - -struct atl1_ring_header { - void *desc; /* pointer to the descriptor ring memory */ - dma_addr_t dma; /* physical adress of the descriptor ring */ - unsigned int size; /* length of descriptor ring in bytes */ -}; - -struct atl1_cmb { - struct coals_msg_block *cmb; - dma_addr_t dma; -}; - -struct atl1_smb { - struct stats_msg_block *smb; - dma_addr_t dma; -}; - -/* Statistics counters */ -struct atl1_sft_stats { - u64 rx_packets; - u64 tx_packets; - u64 rx_bytes; - u64 tx_bytes; - u64 multicast; - u64 collisions; - u64 rx_errors; - u64 rx_length_errors; - u64 rx_crc_errors; - u64 rx_frame_errors; - u64 rx_fifo_errors; - u64 rx_missed_errors; - u64 tx_errors; - u64 tx_fifo_errors; - u64 tx_aborted_errors; - u64 tx_window_errors; - u64 tx_carrier_errors; - - u64 tx_pause; /* num Pause packet transmitted. */ - u64 excecol; /* num tx packets aborted due to excessive collisions. */ - u64 deffer; /* num deferred tx packets */ - u64 scc; /* num packets subsequently transmitted successfully w/ single prior collision. */ - u64 mcc; /* num packets subsequently transmitted successfully w/ multiple prior collisions. */ - u64 latecol; /* num tx packets w/ late collisions. */ - u64 tx_underun; /* num tx packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */ - u64 tx_trunc; /* num tx packets truncated due to size exceeding MTU, regardless whether truncated by Selene or not. (The name doesn't really reflect the meaning in this case.) */ - u64 rx_pause; /* num Pause packets received. */ - u64 rx_rrd_ov; - u64 rx_trunc; -}; - -/* board specific private data structure */ -#define ATL1_REGS_LEN 8 - -/* Structure containing variables used by the shared code */ -struct atl1_hw { - u8 __iomem *hw_addr; - struct atl1_adapter *back; - enum atl1_dma_order dma_ord; - enum atl1_dma_rcb rcb_value; - enum atl1_dma_req_block dmar_block; - enum atl1_dma_req_block dmaw_block; - u8 preamble_len; - u8 max_retry; /* Retransmission maximum, after which the packet will be discarded */ - u8 jam_ipg; /* IPG to start JAM for collision based flow control in half-duplex mode. In units of 8-bit time */ - u8 ipgt; /* Desired back to back inter-packet gap. The default is 96-bit time */ - u8 min_ifg; /* Minimum number of IFG to enforce in between RX frames. Frame gap below such IFP is dropped */ - u8 ipgr1; /* 64bit Carrier-Sense window */ - u8 ipgr2; /* 96-bit IPG window */ - u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. Each TPD is 16 bytes long */ - u8 rfd_burst; /* Number of RFD to prefetch in cache-aligned burst. Each RFD is 12 bytes long */ - u8 rfd_fetch_gap; - u8 rrd_burst; /* Threshold number of RRDs that can be retired in a burst. Each RRD is 16 bytes long */ - u8 tpd_fetch_th; - u8 tpd_fetch_gap; - u16 tx_jumbo_task_th; - u16 txf_burst; /* Number of data bytes to read in a cache-aligned burst. Each SRAM entry is - 8 bytes long */ - u16 rx_jumbo_th; /* Jumbo packet size for non-VLAN packet. VLAN packets should add 4 bytes */ - u16 rx_jumbo_lkah; - u16 rrd_ret_timer; /* RRD retirement timer. Decrement by 1 after every 512ns passes. */ - u16 lcol; /* Collision Window */ - - u16 cmb_tpd; - u16 cmb_rrd; - u16 cmb_rx_timer; - u16 cmb_tx_timer; - u32 smb_timer; - u16 media_type; - u16 autoneg_advertised; - u16 pci_cmd_word; - - u16 mii_autoneg_adv_reg; - u16 mii_1000t_ctrl_reg; - - u32 mem_rang; - u32 txcw; - u32 max_frame_size; - u32 min_frame_size; - u32 mc_filter_type; - u32 num_mc_addrs; - u32 collision_delta; - u32 tx_packet_delta; - u16 phy_spd_default; - - u16 dev_rev; - u8 revision_id; - - /* spi flash */ - u8 flash_vendor; - - u8 dma_fairness; - u8 mac_addr[ETH_ALEN]; - u8 perm_mac_addr[ETH_ALEN]; - - /* bool phy_preamble_sup; */ - bool phy_configured; -}; - -struct atl1_adapter { - /* OS defined structs */ - struct net_device *netdev; - struct pci_dev *pdev; - struct net_device_stats net_stats; - struct atl1_sft_stats soft_stats; - - struct vlan_group *vlgrp; - u32 rx_buffer_len; - u32 wol; - u16 link_speed; - u16 link_duplex; - spinlock_t lock; - atomic_t irq_sem; - struct work_struct tx_timeout_task; - struct work_struct link_chg_task; - struct work_struct pcie_dma_to_rst_task; - struct timer_list watchdog_timer; - struct timer_list phy_config_timer; - bool phy_timer_pending; - - bool mac_disabled; - - /* All descriptor rings' memory */ - struct atl1_ring_header ring_header; - - /* TX */ - struct atl1_tpd_ring tpd_ring; - spinlock_t mb_lock; - - /* RX */ - struct atl1_rfd_ring rfd_ring; - struct atl1_rrd_ring rrd_ring; - u64 hw_csum_err; - u64 hw_csum_good; - - u32 gorcl; - u64 gorcl_old; - - /* Interrupt Moderator timer ( 2us resolution) */ - u16 imt; - /* Interrupt Clear timer (2us resolution) */ - u16 ict; - - /* MII interface info */ - struct mii_if_info mii; - - /* structs defined in atl1_hw.h */ - u32 bd_number; /* board number */ - bool pci_using_64; - struct atl1_hw hw; - struct atl1_smb smb; - struct atl1_cmb cmb; - - u32 pci_state[16]; -}; - -#endif /* _ATL1_H_ */ diff --git a/trunk/drivers/net/atl1/atl1_ethtool.c b/trunk/drivers/net/atl1/atl1_ethtool.c deleted file mode 100644 index c11c27798e5c..000000000000 --- a/trunk/drivers/net/atl1/atl1_ethtool.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include "atl1.h" - -struct atl1_stats { - char stat_string[ETH_GSTRING_LEN]; - int sizeof_stat; - int stat_offset; -}; - -#define ATL1_STAT(m) sizeof(((struct atl1_adapter *)0)->m), \ - offsetof(struct atl1_adapter, m) - -static struct atl1_stats atl1_gstrings_stats[] = { - {"rx_packets", ATL1_STAT(soft_stats.rx_packets)}, - {"tx_packets", ATL1_STAT(soft_stats.tx_packets)}, - {"rx_bytes", ATL1_STAT(soft_stats.rx_bytes)}, - {"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)}, - {"rx_errors", ATL1_STAT(soft_stats.rx_errors)}, - {"tx_errors", ATL1_STAT(soft_stats.tx_errors)}, - {"rx_dropped", ATL1_STAT(net_stats.rx_dropped)}, - {"tx_dropped", ATL1_STAT(net_stats.tx_dropped)}, - {"multicast", ATL1_STAT(soft_stats.multicast)}, - {"collisions", ATL1_STAT(soft_stats.collisions)}, - {"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)}, - {"rx_over_errors", ATL1_STAT(soft_stats.rx_missed_errors)}, - {"rx_crc_errors", ATL1_STAT(soft_stats.rx_crc_errors)}, - {"rx_frame_errors", ATL1_STAT(soft_stats.rx_frame_errors)}, - {"rx_fifo_errors", ATL1_STAT(soft_stats.rx_fifo_errors)}, - {"rx_missed_errors", ATL1_STAT(soft_stats.rx_missed_errors)}, - {"tx_aborted_errors", ATL1_STAT(soft_stats.tx_aborted_errors)}, - {"tx_carrier_errors", ATL1_STAT(soft_stats.tx_carrier_errors)}, - {"tx_fifo_errors", ATL1_STAT(soft_stats.tx_fifo_errors)}, - {"tx_window_errors", ATL1_STAT(soft_stats.tx_window_errors)}, - {"tx_abort_exce_coll", ATL1_STAT(soft_stats.excecol)}, - {"tx_abort_late_coll", ATL1_STAT(soft_stats.latecol)}, - {"tx_deferred_ok", ATL1_STAT(soft_stats.deffer)}, - {"tx_single_coll_ok", ATL1_STAT(soft_stats.scc)}, - {"tx_multi_coll_ok", ATL1_STAT(soft_stats.mcc)}, - {"tx_underun", ATL1_STAT(soft_stats.tx_underun)}, - {"tx_trunc", ATL1_STAT(soft_stats.tx_trunc)}, - {"tx_pause", ATL1_STAT(soft_stats.tx_pause)}, - {"rx_pause", ATL1_STAT(soft_stats.rx_pause)}, - {"rx_rrd_ov", ATL1_STAT(soft_stats.rx_rrd_ov)}, - {"rx_trunc", ATL1_STAT(soft_stats.rx_trunc)} -}; - -static void atl1_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, u64 *data) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - int i; - char *p; - - for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) { - p = (char *)adapter+atl1_gstrings_stats[i].stat_offset; - data[i] = (atl1_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; - } - -} - -static int atl1_get_stats_count(struct net_device *netdev) -{ - return ARRAY_SIZE(atl1_gstrings_stats); -} - -static int atl1_get_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - - ecmd->supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | SUPPORTED_TP); - ecmd->advertising = ADVERTISED_TP; - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) { - ecmd->advertising |= ADVERTISED_Autoneg; - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR) { - ecmd->advertising |= ADVERTISED_Autoneg; - ecmd->advertising |= - (ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Full); - } - else - ecmd->advertising |= (ADVERTISED_1000baseT_Full); - } - ecmd->port = PORT_TP; - ecmd->phy_address = 0; - ecmd->transceiver = XCVR_INTERNAL; - - if (netif_carrier_ok(adapter->netdev)) { - u16 link_speed, link_duplex; - atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex); - ecmd->speed = link_speed; - if (link_duplex == FULL_DUPLEX) - ecmd->duplex = DUPLEX_FULL; - else - ecmd->duplex = DUPLEX_HALF; - } else { - ecmd->speed = -1; - ecmd->duplex = -1; - } - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) - ecmd->autoneg = AUTONEG_ENABLE; - else - ecmd->autoneg = AUTONEG_DISABLE; - - return 0; -} - -static int atl1_set_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - u16 phy_data; - int ret_val = 0; - u16 old_media_type = hw->media_type; - - if (netif_running(adapter->netdev)) { - printk(KERN_DEBUG "%s: ethtool shutting down adapter\n", - atl1_driver_name); - atl1_down(adapter); - } - - if (ecmd->autoneg == AUTONEG_ENABLE) - hw->media_type = MEDIA_TYPE_AUTO_SENSOR; - else { - if (ecmd->speed == SPEED_1000) { - if (ecmd->duplex != DUPLEX_FULL) { - printk(KERN_WARNING - "%s: can't force to 1000M half duplex\n", - atl1_driver_name); - ret_val = -EINVAL; - goto exit_sset; - } - hw->media_type = MEDIA_TYPE_1000M_FULL; - } else if (ecmd->speed == SPEED_100) { - if (ecmd->duplex == DUPLEX_FULL) { - hw->media_type = MEDIA_TYPE_100M_FULL; - } else - hw->media_type = MEDIA_TYPE_100M_HALF; - } else { - if (ecmd->duplex == DUPLEX_FULL) - hw->media_type = MEDIA_TYPE_10M_FULL; - else - hw->media_type = MEDIA_TYPE_10M_HALF; - } - } - switch (hw->media_type) { - case MEDIA_TYPE_AUTO_SENSOR: - ecmd->advertising = - ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | ADVERTISED_TP; - break; - case MEDIA_TYPE_1000M_FULL: - ecmd->advertising = - ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | ADVERTISED_TP; - break; - default: - ecmd->advertising = 0; - break; - } - if (atl1_phy_setup_autoneg_adv(hw)) { - ret_val = -EINVAL; - printk(KERN_WARNING - "%s: invalid ethtool speed/duplex setting\n", - atl1_driver_name); - goto exit_sset; - } - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) - phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN; - else { - switch (hw->media_type) { - case MEDIA_TYPE_100M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 | - MII_CR_RESET; - break; - case MEDIA_TYPE_100M_HALF: - phy_data = MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_10M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET; - break; - default: /* MEDIA_TYPE_10M_HALF: */ - phy_data = MII_CR_SPEED_10 | MII_CR_RESET; - break; - } - } - atl1_write_phy_reg(hw, MII_BMCR, phy_data); -exit_sset: - if (ret_val) - hw->media_type = old_media_type; - - if (netif_running(adapter->netdev)) { - printk(KERN_DEBUG "%s: ethtool starting adapter\n", - atl1_driver_name); - atl1_up(adapter); - } else if (!ret_val) { - printk(KERN_DEBUG "%s: ethtool resetting adapter\n", - atl1_driver_name); - atl1_reset(adapter); - } - return ret_val; -} - -static void atl1_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - - strncpy(drvinfo->driver, atl1_driver_name, sizeof(drvinfo->driver)); - strncpy(drvinfo->version, atl1_driver_version, - sizeof(drvinfo->version)); - strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); - strncpy(drvinfo->bus_info, pci_name(adapter->pdev), - sizeof(drvinfo->bus_info)); - drvinfo->eedump_len = ATL1_EEDUMP_LEN; -} - -static void atl1_get_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - - wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; - wol->wolopts = 0; - if (adapter->wol & ATL1_WUFC_EX) - wol->wolopts |= WAKE_UCAST; - if (adapter->wol & ATL1_WUFC_MC) - wol->wolopts |= WAKE_MCAST; - if (adapter->wol & ATL1_WUFC_BC) - wol->wolopts |= WAKE_BCAST; - if (adapter->wol & ATL1_WUFC_MAG) - wol->wolopts |= WAKE_MAGIC; - return; -} - -static int atl1_set_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - - if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) - return -EOPNOTSUPP; - adapter->wol = 0; - if (wol->wolopts & WAKE_UCAST) - adapter->wol |= ATL1_WUFC_EX; - if (wol->wolopts & WAKE_MCAST) - adapter->wol |= ATL1_WUFC_MC; - if (wol->wolopts & WAKE_BCAST) - adapter->wol |= ATL1_WUFC_BC; - if (wol->wolopts & WAKE_MAGIC) - adapter->wol |= ATL1_WUFC_MAG; - return 0; -} - -static void atl1_get_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_tpd_ring *txdr = &adapter->tpd_ring; - struct atl1_rfd_ring *rxdr = &adapter->rfd_ring; - - ring->rx_max_pending = ATL1_MAX_RFD; - ring->tx_max_pending = ATL1_MAX_TPD; - ring->rx_mini_max_pending = 0; - ring->rx_jumbo_max_pending = 0; - ring->rx_pending = rxdr->count; - ring->tx_pending = txdr->count; - ring->rx_mini_pending = 0; - ring->rx_jumbo_pending = 0; -} - -static int atl1_set_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_tpd_ring *tpdr = &adapter->tpd_ring; - struct atl1_rrd_ring *rrdr = &adapter->rrd_ring; - struct atl1_rfd_ring *rfdr = &adapter->rfd_ring; - - struct atl1_tpd_ring tpd_old, tpd_new; - struct atl1_rfd_ring rfd_old, rfd_new; - struct atl1_rrd_ring rrd_old, rrd_new; - struct atl1_ring_header rhdr_old, rhdr_new; - int err; - - tpd_old = adapter->tpd_ring; - rfd_old = adapter->rfd_ring; - rrd_old = adapter->rrd_ring; - rhdr_old = adapter->ring_header; - - if (netif_running(adapter->netdev)) - atl1_down(adapter); - - rfdr->count = (u16) max(ring->rx_pending, (u32) ATL1_MIN_RFD); - rfdr->count = rfdr->count > ATL1_MAX_RFD ? ATL1_MAX_RFD : - rfdr->count; - rfdr->count = (rfdr->count + 3) & ~3; - rrdr->count = rfdr->count; - - tpdr->count = (u16) max(ring->tx_pending, (u32) ATL1_MIN_TPD); - tpdr->count = tpdr->count > ATL1_MAX_TPD ? ATL1_MAX_TPD : - tpdr->count; - tpdr->count = (tpdr->count + 3) & ~3; - - if (netif_running(adapter->netdev)) { - /* try to get new resources before deleting old */ - err = atl1_setup_ring_resources(adapter); - if (err) - goto err_setup_ring; - - /* - * save the new, restore the old in order to free it, - * then restore the new back again - */ - - rfd_new = adapter->rfd_ring; - rrd_new = adapter->rrd_ring; - tpd_new = adapter->tpd_ring; - rhdr_new = adapter->ring_header; - adapter->rfd_ring = rfd_old; - adapter->rrd_ring = rrd_old; - adapter->tpd_ring = tpd_old; - adapter->ring_header = rhdr_old; - atl1_free_ring_resources(adapter); - adapter->rfd_ring = rfd_new; - adapter->rrd_ring = rrd_new; - adapter->tpd_ring = tpd_new; - adapter->ring_header = rhdr_new; - - err = atl1_up(adapter); - if (err) - return err; - } - return 0; - -err_setup_ring: - adapter->rfd_ring = rfd_old; - adapter->rrd_ring = rrd_old; - adapter->tpd_ring = tpd_old; - adapter->ring_header = rhdr_old; - atl1_up(adapter); - return err; -} - -static void atl1_get_pauseparam(struct net_device *netdev, - struct ethtool_pauseparam *epause) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) { - epause->autoneg = AUTONEG_ENABLE; - } else { - epause->autoneg = AUTONEG_DISABLE; - } - epause->rx_pause = 1; - epause->tx_pause = 1; -} - -static int atl1_set_pauseparam(struct net_device *netdev, - struct ethtool_pauseparam *epause) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) { - epause->autoneg = AUTONEG_ENABLE; - } else { - epause->autoneg = AUTONEG_DISABLE; - } - - epause->rx_pause = 1; - epause->tx_pause = 1; - - return 0; -} - -static u32 atl1_get_rx_csum(struct net_device *netdev) -{ - return 1; -} - -static void atl1_get_strings(struct net_device *netdev, u32 stringset, - u8 *data) -{ - u8 *p = data; - int i; - - switch (stringset) { - case ETH_SS_STATS: - for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) { - memcpy(p, atl1_gstrings_stats[i].stat_string, - ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; - } - break; - } -} - -static int atl1_nway_reset(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - - if (netif_running(netdev)) { - u16 phy_data; - atl1_down(adapter); - - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) { - phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN; - } else { - switch (hw->media_type) { - case MEDIA_TYPE_100M_FULL: - phy_data = MII_CR_FULL_DUPLEX | - MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_100M_HALF: - phy_data = MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_10M_FULL: - phy_data = MII_CR_FULL_DUPLEX | - MII_CR_SPEED_10 | MII_CR_RESET; - break; - default: /* MEDIA_TYPE_10M_HALF */ - phy_data = MII_CR_SPEED_10 | MII_CR_RESET; - } - } - atl1_write_phy_reg(hw, MII_BMCR, phy_data); - atl1_up(adapter); - } - return 0; -} - -const struct ethtool_ops atl1_ethtool_ops = { - .get_settings = atl1_get_settings, - .set_settings = atl1_set_settings, - .get_drvinfo = atl1_get_drvinfo, - .get_wol = atl1_get_wol, - .set_wol = atl1_set_wol, - .get_ringparam = atl1_get_ringparam, - .set_ringparam = atl1_set_ringparam, - .get_pauseparam = atl1_get_pauseparam, - .set_pauseparam = atl1_set_pauseparam, - .get_rx_csum = atl1_get_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .get_link = ethtool_op_get_link, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_strings = atl1_get_strings, - .nway_reset = atl1_nway_reset, - .get_ethtool_stats = atl1_get_ethtool_stats, - .get_stats_count = atl1_get_stats_count, - .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, -}; diff --git a/trunk/drivers/net/atl1/atl1_hw.c b/trunk/drivers/net/atl1/atl1_hw.c deleted file mode 100644 index 08b2d785469d..000000000000 --- a/trunk/drivers/net/atl1/atl1_hw.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "atl1.h" - -/* - * Reset the transmit and receive units; mask and clear all interrupts. - * hw - Struct containing variables accessed by shared code - * return : ATL1_SUCCESS or idle status (if error) - */ -s32 atl1_reset_hw(struct atl1_hw *hw) -{ - u32 icr; - int i; - - /* - * Clear Interrupt mask to stop board from generating - * interrupts & Clear any pending interrupt events - */ - /* - * iowrite32(0, hw->hw_addr + REG_IMR); - * iowrite32(0xffffffff, hw->hw_addr + REG_ISR); - */ - - /* - * Issue Soft Reset to the MAC. This will reset the chip's - * transmit, receive, DMA. It will not effect - * the current PCI configuration. The global reset bit is self- - * clearing, and should clear within a microsecond. - */ - iowrite32(MASTER_CTRL_SOFT_RST, hw->hw_addr + REG_MASTER_CTRL); - ioread32(hw->hw_addr + REG_MASTER_CTRL); - - iowrite16(1, hw->hw_addr + REG_GPHY_ENABLE); - ioread16(hw->hw_addr + REG_GPHY_ENABLE); - - msleep(1); /* delay about 1ms */ - - /* Wait at least 10ms for All module to be Idle */ - for (i = 0; i < 10; i++) { - icr = ioread32(hw->hw_addr + REG_IDLE_STATUS); - if (!icr) - break; - msleep(1); /* delay 1 ms */ - cpu_relax(); /* FIXME: is this still the right way to do this? */ - } - - if (icr) { - printk (KERN_DEBUG "icr = %x\n", icr); - return icr; - } - - return ATL1_SUCCESS; -} - -/* function about EEPROM - * - * check_eeprom_exist - * return 0 if eeprom exist - */ -static int atl1_check_eeprom_exist(struct atl1_hw *hw) -{ - u32 value; - value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL); - if (value & SPI_FLASH_CTRL_EN_VPD) { - value &= ~SPI_FLASH_CTRL_EN_VPD; - iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL); - } - - value = ioread16(hw->hw_addr + REG_PCIE_CAP_LIST); - return ((value & 0xFF00) == 0x6C00) ? 0 : 1; -} - -static bool atl1_read_eeprom(struct atl1_hw *hw, u32 offset, u32 *p_value) -{ - int i; - u32 control; - - if (offset & 3) - return false; /* address do not align */ - - iowrite32(0, hw->hw_addr + REG_VPD_DATA); - control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT; - iowrite32(control, hw->hw_addr + REG_VPD_CAP); - ioread32(hw->hw_addr + REG_VPD_CAP); - - for (i = 0; i < 10; i++) { - msleep(2); - control = ioread32(hw->hw_addr + REG_VPD_CAP); - if (control & VPD_CAP_VPD_FLAG) - break; - } - if (control & VPD_CAP_VPD_FLAG) { - *p_value = ioread32(hw->hw_addr + REG_VPD_DATA); - return true; - } - return false; /* timeout */ -} - -/* - * Reads the value from a PHY register - * hw - Struct containing variables accessed by shared code - * reg_addr - address of the PHY register to read - */ -s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data) -{ - u32 val; - int i; - - val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | - MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 << - MDIO_CLK_SEL_SHIFT; - iowrite32(val, hw->hw_addr + REG_MDIO_CTRL); - ioread32(hw->hw_addr + REG_MDIO_CTRL); - - for (i = 0; i < MDIO_WAIT_TIMES; i++) { - udelay(2); - val = ioread32(hw->hw_addr + REG_MDIO_CTRL); - if (!(val & (MDIO_START | MDIO_BUSY))) - break; - } - if (!(val & (MDIO_START | MDIO_BUSY))) { - *phy_data = (u16) val; - return ATL1_SUCCESS; - } - return ATL1_ERR_PHY; -} - -#define CUSTOM_SPI_CS_SETUP 2 -#define CUSTOM_SPI_CLK_HI 2 -#define CUSTOM_SPI_CLK_LO 2 -#define CUSTOM_SPI_CS_HOLD 2 -#define CUSTOM_SPI_CS_HI 3 - -static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf) -{ - int i; - u32 value; - - iowrite32(0, hw->hw_addr + REG_SPI_DATA); - iowrite32(addr, hw->hw_addr + REG_SPI_ADDR); - - value = SPI_FLASH_CTRL_WAIT_READY | - (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) << - SPI_FLASH_CTRL_CS_SETUP_SHIFT | (CUSTOM_SPI_CLK_HI & - SPI_FLASH_CTRL_CLK_HI_MASK) << - SPI_FLASH_CTRL_CLK_HI_SHIFT | (CUSTOM_SPI_CLK_LO & - SPI_FLASH_CTRL_CLK_LO_MASK) << - SPI_FLASH_CTRL_CLK_LO_SHIFT | (CUSTOM_SPI_CS_HOLD & - SPI_FLASH_CTRL_CS_HOLD_MASK) << - SPI_FLASH_CTRL_CS_HOLD_SHIFT | (CUSTOM_SPI_CS_HI & - SPI_FLASH_CTRL_CS_HI_MASK) << - SPI_FLASH_CTRL_CS_HI_SHIFT | (1 & SPI_FLASH_CTRL_INS_MASK) << - SPI_FLASH_CTRL_INS_SHIFT; - - iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL); - - value |= SPI_FLASH_CTRL_START; - iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL); - ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL); - - for (i = 0; i < 10; i++) { - msleep(1); /* 1ms */ - value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL); - if (!(value & SPI_FLASH_CTRL_START)) - break; - } - - if (value & SPI_FLASH_CTRL_START) - return false; - - *buf = ioread32(hw->hw_addr + REG_SPI_DATA); - - return true; -} - -/* - * get_permanent_address - * return 0 if get valid mac address, - */ -static int atl1_get_permanent_address(struct atl1_hw *hw) -{ - u32 addr[2]; - u32 i, control; - u16 reg; - u8 eth_addr[ETH_ALEN]; - bool key_valid; - - if (is_valid_ether_addr(hw->perm_mac_addr)) - return 0; - - /* init */ - addr[0] = addr[1] = 0; - - if (!atl1_check_eeprom_exist(hw)) { /* eeprom exist */ - reg = 0; - key_valid = false; - /* Read out all EEPROM content */ - i = 0; - while (1) { - if (atl1_read_eeprom(hw, i + 0x100, &control)) { - if (key_valid) { - if (reg == REG_MAC_STA_ADDR) - addr[0] = control; - else if (reg == (REG_MAC_STA_ADDR + 4)) - addr[1] = control; - key_valid = false; - } else if ((control & 0xff) == 0x5A) { - key_valid = true; - reg = (u16) (control >> 16); - } else - break; /* assume data end while encount an invalid KEYWORD */ - } else - break; /* read error */ - i += 4; - } - -/* - * The following 2 lines are the Attansic originals. Saving for posterity. - * *(u32 *) & eth_addr[2] = LONGSWAP(addr[0]); - * *(u16 *) & eth_addr[0] = SHORTSWAP(*(u16 *) & addr[1]); - */ - *(u32 *) & eth_addr[2] = swab32(addr[0]); - *(u16 *) & eth_addr[0] = swab16(*(u16 *) & addr[1]); - - if (is_valid_ether_addr(eth_addr)) { - memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); - return 0; - } - return 1; - } - - /* see if SPI FLAGS exist ? */ - addr[0] = addr[1] = 0; - reg = 0; - key_valid = false; - i = 0; - while (1) { - if (atl1_spi_read(hw, i + 0x1f000, &control)) { - if (key_valid) { - if (reg == REG_MAC_STA_ADDR) - addr[0] = control; - else if (reg == (REG_MAC_STA_ADDR + 4)) - addr[1] = control; - key_valid = false; - } else if ((control & 0xff) == 0x5A) { - key_valid = true; - reg = (u16) (control >> 16); - } else - break; /* data end */ - } else - break; /* read error */ - i += 4; - } - -/* - * The following 2 lines are the Attansic originals. Saving for posterity. - * *(u32 *) & eth_addr[2] = LONGSWAP(addr[0]); - * *(u16 *) & eth_addr[0] = SHORTSWAP(*(u16 *) & addr[1]); - */ - *(u32 *) & eth_addr[2] = swab32(addr[0]); - *(u16 *) & eth_addr[0] = swab16(*(u16 *) & addr[1]); - if (is_valid_ether_addr(eth_addr)) { - memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); - return 0; - } - return 1; -} - -/* - * Reads the adapter's MAC address from the EEPROM - * hw - Struct containing variables accessed by shared code - */ -s32 atl1_read_mac_addr(struct atl1_hw *hw) -{ - u16 i; - - if (atl1_get_permanent_address(hw)) - random_ether_addr(hw->perm_mac_addr); - - for (i = 0; i < ETH_ALEN; i++) - hw->mac_addr[i] = hw->perm_mac_addr[i]; - return ATL1_SUCCESS; -} - -/* - * Hashes an address to determine its location in the multicast table - * hw - Struct containing variables accessed by shared code - * mc_addr - the multicast address to hash - * - * atl1_hash_mc_addr - * purpose - * set hash value for a multicast address - * hash calcu processing : - * 1. calcu 32bit CRC for multicast address - * 2. reverse crc with MSB to LSB - */ -u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr) -{ - u32 crc32, value = 0; - int i; - - crc32 = ether_crc_le(6, mc_addr); - crc32 = ~crc32; - for (i = 0; i < 32; i++) - value |= (((crc32 >> i) & 1) << (31 - i)); - - return value; -} - -/* - * Sets the bit in the multicast table corresponding to the hash value. - * hw - Struct containing variables accessed by shared code - * hash_value - Multicast address hash value - */ -void atl1_hash_set(struct atl1_hw *hw, u32 hash_value) -{ - u32 hash_bit, hash_reg; - u32 mta; - - /* - * The HASH Table is a register array of 2 32-bit registers. - * It is treated like an array of 64 bits. We want to set - * bit BitArray[hash_value]. So we figure out what register - * the bit is in, read it, OR in the new bit, then write - * back the new value. The register is determined by the - * upper 7 bits of the hash value and the bit within that - * register are determined by the lower 5 bits of the value. - */ - hash_reg = (hash_value >> 31) & 0x1; - hash_bit = (hash_value >> 26) & 0x1F; - mta = ioread32((hw + REG_RX_HASH_TABLE) + (hash_reg << 2)); - mta |= (1 << hash_bit); - iowrite32(mta, (hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2)); -} - -/* - * Writes a value to a PHY register - * hw - Struct containing variables accessed by shared code - * reg_addr - address of the PHY register to write - * data - data to write to the PHY - */ -s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data) -{ - int i; - u32 val; - - val = ((u32) (phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT | - (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT | - MDIO_SUP_PREAMBLE | - MDIO_START | MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; - iowrite32(val, hw->hw_addr + REG_MDIO_CTRL); - ioread32(hw->hw_addr + REG_MDIO_CTRL); - - for (i = 0; i < MDIO_WAIT_TIMES; i++) { - udelay(2); - val = ioread32(hw->hw_addr + REG_MDIO_CTRL); - if (!(val & (MDIO_START | MDIO_BUSY))) - break; - } - - if (!(val & (MDIO_START | MDIO_BUSY))) - return ATL1_SUCCESS; - - return ATL1_ERR_PHY; -} - -/* - * Make L001's PHY out of Power Saving State (bug) - * hw - Struct containing variables accessed by shared code - * when power on, L001's PHY always on Power saving State - * (Gigabit Link forbidden) - */ -static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw) -{ - s32 ret; - ret = atl1_write_phy_reg(hw, 29, 0x0029); - if (ret) - return ret; - return atl1_write_phy_reg(hw, 30, 0); -} - -/* - *TODO: do something or get rid of this - */ -s32 atl1_phy_enter_power_saving(struct atl1_hw *hw) -{ -/* s32 ret_val; - * u16 phy_data; - */ - -/* - ret_val = atl1_write_phy_reg(hw, ...); - ret_val = atl1_write_phy_reg(hw, ...); - .... -*/ - return ATL1_SUCCESS; -} - -/* - * Resets the PHY and make all config validate - * hw - Struct containing variables accessed by shared code - * - * Sets bit 15 and 12 of the MII Control regiser (for F001 bug) - */ -static s32 atl1_phy_reset(struct atl1_hw *hw) -{ - s32 ret_val; - u16 phy_data; - - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) - phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN; - else { - switch (hw->media_type) { - case MEDIA_TYPE_100M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 | - MII_CR_RESET; - break; - case MEDIA_TYPE_100M_HALF: - phy_data = MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_10M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET; - break; - default: /* MEDIA_TYPE_10M_HALF: */ - phy_data = MII_CR_SPEED_10 | MII_CR_RESET; - break; - } - } - - ret_val = atl1_write_phy_reg(hw, MII_BMCR, phy_data); - if (ret_val) { - u32 val; - int i; - /* pcie serdes link may be down! */ - printk(KERN_DEBUG "%s: autoneg caused pcie phy link down\n", - atl1_driver_name); - - for (i = 0; i < 25; i++) { - msleep(1); - val = ioread32(hw->hw_addr + REG_MDIO_CTRL); - if (!(val & (MDIO_START | MDIO_BUSY))) - break; - } - - if ((val & (MDIO_START | MDIO_BUSY)) != 0) { - printk(KERN_WARNING - "%s: pcie link down at least for 25ms\n", - atl1_driver_name); - return ret_val; - } - } - return ATL1_SUCCESS; -} - -/* - * Configures PHY autoneg and flow control advertisement settings - * hw - Struct containing variables accessed by shared code - */ -s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw) -{ - s32 ret_val; - s16 mii_autoneg_adv_reg; - s16 mii_1000t_ctrl_reg; - - /* Read the MII Auto-Neg Advertisement Register (Address 4). */ - mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK; - - /* Read the MII 1000Base-T Control Register (Address 9). */ - mii_1000t_ctrl_reg = MII_AT001_CR_1000T_DEFAULT_CAP_MASK; - - /* - * First we clear all the 10/100 mb speed bits in the Auto-Neg - * Advertisement Register (Address 4) and the 1000 mb speed bits in - * the 1000Base-T Control Register (Address 9). - */ - mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK; - mii_1000t_ctrl_reg &= ~MII_AT001_CR_1000T_SPEED_MASK; - - /* - * Need to parse media_type and set up - * the appropriate PHY registers. - */ - switch (hw->media_type) { - case MEDIA_TYPE_AUTO_SENSOR: - mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS | - MII_AR_10T_FD_CAPS | - MII_AR_100TX_HD_CAPS | - MII_AR_100TX_FD_CAPS); - mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS; - break; - - case MEDIA_TYPE_1000M_FULL: - mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS; - break; - - case MEDIA_TYPE_100M_FULL: - mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS; - break; - - case MEDIA_TYPE_100M_HALF: - mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS; - break; - - case MEDIA_TYPE_10M_FULL: - mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS; - break; - - default: - mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS; - break; - } - - /* flow control fixed to enable all */ - mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE); - - hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg; - hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg; - - ret_val = atl1_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg); - if (ret_val) - return ret_val; - - ret_val = atl1_write_phy_reg(hw, MII_AT001_CR, mii_1000t_ctrl_reg); - if (ret_val) - return ret_val; - - return ATL1_SUCCESS; -} - -/* - * Configures link settings. - * hw - Struct containing variables accessed by shared code - * Assumes the hardware has previously been reset and the - * transmitter and receiver are not enabled. - */ -static s32 atl1_setup_link(struct atl1_hw *hw) -{ - s32 ret_val; - - /* - * Options: - * PHY will advertise value(s) parsed from - * autoneg_advertised and fc - * no matter what autoneg is , We will not wait link result. - */ - ret_val = atl1_phy_setup_autoneg_adv(hw); - if (ret_val) { - printk(KERN_DEBUG "%s: error setting up autonegotiation\n", - atl1_driver_name); - return ret_val; - } - /* SW.Reset , En-Auto-Neg if needed */ - ret_val = atl1_phy_reset(hw); - if (ret_val) { - printk(KERN_DEBUG "%s: error resetting the phy\n", - atl1_driver_name); - return ret_val; - } - hw->phy_configured = true; - return ret_val; -} - -static struct atl1_spi_flash_dev flash_table[] = { -/* MFR_NAME WRSR READ PRGM WREN WRDI RDSR RDID SECTOR_ERASE CHIP_ERASE */ - {"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62}, - {"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60}, - {"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7}, -}; - -static void atl1_init_flash_opcode(struct atl1_hw *hw) -{ - if (hw->flash_vendor >= sizeof(flash_table) / sizeof(flash_table[0])) - hw->flash_vendor = 0; /* ATMEL */ - - /* Init OP table */ - iowrite8(flash_table[hw->flash_vendor].cmd_program, - hw->hw_addr + REG_SPI_FLASH_OP_PROGRAM); - iowrite8(flash_table[hw->flash_vendor].cmd_sector_erase, - hw->hw_addr + REG_SPI_FLASH_OP_SC_ERASE); - iowrite8(flash_table[hw->flash_vendor].cmd_chip_erase, - hw->hw_addr + REG_SPI_FLASH_OP_CHIP_ERASE); - iowrite8(flash_table[hw->flash_vendor].cmd_rdid, - hw->hw_addr + REG_SPI_FLASH_OP_RDID); - iowrite8(flash_table[hw->flash_vendor].cmd_wren, - hw->hw_addr + REG_SPI_FLASH_OP_WREN); - iowrite8(flash_table[hw->flash_vendor].cmd_rdsr, - hw->hw_addr + REG_SPI_FLASH_OP_RDSR); - iowrite8(flash_table[hw->flash_vendor].cmd_wrsr, - hw->hw_addr + REG_SPI_FLASH_OP_WRSR); - iowrite8(flash_table[hw->flash_vendor].cmd_read, - hw->hw_addr + REG_SPI_FLASH_OP_READ); -} - -/* - * Performs basic configuration of the adapter. - * hw - Struct containing variables accessed by shared code - * Assumes that the controller has previously been reset and is in a - * post-reset uninitialized state. Initializes multicast table, - * and Calls routines to setup link - * Leaves the transmit and receive units disabled and uninitialized. - */ -s32 atl1_init_hw(struct atl1_hw *hw) -{ - u32 ret_val = 0; - - /* Zero out the Multicast HASH table */ - iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE); - /* clear the old settings from the multicast hash table */ - iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2)); - - atl1_init_flash_opcode(hw); - - if (!hw->phy_configured) { - /* enable GPHY LinkChange Interrrupt */ - ret_val = atl1_write_phy_reg(hw, 18, 0xC00); - if (ret_val) - return ret_val; - /* make PHY out of power-saving state */ - ret_val = atl1_phy_leave_power_saving(hw); - if (ret_val) - return ret_val; - /* Call a subroutine to configure the link */ - ret_val = atl1_setup_link(hw); - } - return ret_val; -} - -/* - * Detects the current speed and duplex settings of the hardware. - * hw - Struct containing variables accessed by shared code - * speed - Speed of the connection - * duplex - Duplex setting of the connection - */ -s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex) -{ - s32 ret_val; - u16 phy_data; - - /* ; --- Read PHY Specific Status Register (17) */ - ret_val = atl1_read_phy_reg(hw, MII_AT001_PSSR, &phy_data); - if (ret_val) - return ret_val; - - if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED)) - return ATL1_ERR_PHY_RES; - - switch (phy_data & MII_AT001_PSSR_SPEED) { - case MII_AT001_PSSR_1000MBS: - *speed = SPEED_1000; - break; - case MII_AT001_PSSR_100MBS: - *speed = SPEED_100; - break; - case MII_AT001_PSSR_10MBS: - *speed = SPEED_10; - break; - default: - printk(KERN_DEBUG "%s: error getting speed\n", - atl1_driver_name); - return ATL1_ERR_PHY_SPEED; - break; - } - if (phy_data & MII_AT001_PSSR_DPLX) - *duplex = FULL_DUPLEX; - else - *duplex = HALF_DUPLEX; - - return ATL1_SUCCESS; -} - -void atl1_set_mac_addr(struct atl1_hw *hw) -{ - u32 value; - /* - * 00-0B-6A-F6-00-DC - * 0: 6AF600DC 1: 000B - * low dword - */ - value = (((u32) hw->mac_addr[2]) << 24) | - (((u32) hw->mac_addr[3]) << 16) | - (((u32) hw->mac_addr[4]) << 8) | (((u32) hw->mac_addr[5])); - iowrite32(value, hw->hw_addr + REG_MAC_STA_ADDR); - /* high dword */ - value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1])); - iowrite32(value, (hw->hw_addr + REG_MAC_STA_ADDR) + (1 << 2)); -} diff --git a/trunk/drivers/net/atl1/atl1_hw.h b/trunk/drivers/net/atl1/atl1_hw.h deleted file mode 100644 index 100c09c66e64..000000000000 --- a/trunk/drivers/net/atl1/atl1_hw.h +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * There are a lot of defines in here that are unused and/or have cryptic - * names. Please leave them alone, as they're the closest thing we have - * to a spec from Attansic at present. *ahem* -- CHS - */ - -#ifndef _ATL1_HW_H_ -#define _ATL1_HW_H_ - -#include -#include - -struct atl1_adapter; -struct atl1_hw; - -/* function prototypes needed by multiple files */ -s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw); -s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data); -s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex); -s32 atl1_read_mac_addr(struct atl1_hw *hw); -s32 atl1_init_hw(struct atl1_hw *hw); -s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex); -s32 atl1_set_speed_and_duplex(struct atl1_hw *hw, u16 speed, u16 duplex); -u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr); -void atl1_hash_set(struct atl1_hw *hw, u32 hash_value); -s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data); -void atl1_set_mac_addr(struct atl1_hw *hw); -s32 atl1_phy_enter_power_saving(struct atl1_hw *hw); -s32 atl1_reset_hw(struct atl1_hw *hw); -void atl1_check_options(struct atl1_adapter *adapter); - -/* register definitions */ -#define REG_PCIE_CAP_LIST 0x58 - -#define REG_VPD_CAP 0x6C -#define VPD_CAP_ID_MASK 0xff -#define VPD_CAP_ID_SHIFT 0 -#define VPD_CAP_NEXT_PTR_MASK 0xFF -#define VPD_CAP_NEXT_PTR_SHIFT 8 -#define VPD_CAP_VPD_ADDR_MASK 0x7FFF -#define VPD_CAP_VPD_ADDR_SHIFT 16 -#define VPD_CAP_VPD_FLAG 0x80000000 - -#define REG_VPD_DATA 0x70 - -#define REG_SPI_FLASH_CTRL 0x200 -#define SPI_FLASH_CTRL_STS_NON_RDY 0x1 -#define SPI_FLASH_CTRL_STS_WEN 0x2 -#define SPI_FLASH_CTRL_STS_WPEN 0x80 -#define SPI_FLASH_CTRL_DEV_STS_MASK 0xFF -#define SPI_FLASH_CTRL_DEV_STS_SHIFT 0 -#define SPI_FLASH_CTRL_INS_MASK 0x7 -#define SPI_FLASH_CTRL_INS_SHIFT 8 -#define SPI_FLASH_CTRL_START 0x800 -#define SPI_FLASH_CTRL_EN_VPD 0x2000 -#define SPI_FLASH_CTRL_LDSTART 0x8000 -#define SPI_FLASH_CTRL_CS_HI_MASK 0x3 -#define SPI_FLASH_CTRL_CS_HI_SHIFT 16 -#define SPI_FLASH_CTRL_CS_HOLD_MASK 0x3 -#define SPI_FLASH_CTRL_CS_HOLD_SHIFT 18 -#define SPI_FLASH_CTRL_CLK_LO_MASK 0x3 -#define SPI_FLASH_CTRL_CLK_LO_SHIFT 20 -#define SPI_FLASH_CTRL_CLK_HI_MASK 0x3 -#define SPI_FLASH_CTRL_CLK_HI_SHIFT 22 -#define SPI_FLASH_CTRL_CS_SETUP_MASK 0x3 -#define SPI_FLASH_CTRL_CS_SETUP_SHIFT 24 -#define SPI_FLASH_CTRL_EROM_PGSZ_MASK 0x3 -#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26 -#define SPI_FLASH_CTRL_WAIT_READY 0x10000000 - -#define REG_SPI_ADDR 0x204 - -#define REG_SPI_DATA 0x208 - -#define REG_SPI_FLASH_CONFIG 0x20C -#define SPI_FLASH_CONFIG_LD_ADDR_MASK 0xFFFFFF -#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0 -#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3 -#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24 -#define SPI_FLASH_CONFIG_LD_EXIST 0x4000000 - -#define REG_SPI_FLASH_OP_PROGRAM 0x210 -#define REG_SPI_FLASH_OP_SC_ERASE 0x211 -#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212 -#define REG_SPI_FLASH_OP_RDID 0x213 -#define REG_SPI_FLASH_OP_WREN 0x214 -#define REG_SPI_FLASH_OP_RDSR 0x215 -#define REG_SPI_FLASH_OP_WRSR 0x216 -#define REG_SPI_FLASH_OP_READ 0x217 - -#define REG_TWSI_CTRL 0x218 -#define TWSI_CTRL_LD_OFFSET_MASK 0xFF -#define TWSI_CTRL_LD_OFFSET_SHIFT 0 -#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7 -#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8 -#define TWSI_CTRL_SW_LDSTART 0x800 -#define TWSI_CTRL_HW_LDSTART 0x1000 -#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F -#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15 -#define TWSI_CTRL_LD_EXIST 0x400000 -#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3 -#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23 -#define TWSI_CTRL_FREQ_SEL_100K 0 -#define TWSI_CTRL_FREQ_SEL_200K 1 -#define TWSI_CTRL_FREQ_SEL_300K 2 -#define TWSI_CTRL_FREQ_SEL_400K 3 -#define TWSI_CTRL_SMB_SLV_ADDR -#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3 -#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24 - -#define REG_PCIE_DEV_MISC_CTRL 0x21C -#define PCIE_DEV_MISC_CTRL_EXT_PIPE 0x2 -#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1 -#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4 -#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN 0x8 -#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN 0x10 - -/* Selene Master Control Register */ -#define REG_MASTER_CTRL 0x1400 -#define MASTER_CTRL_SOFT_RST 0x1 -#define MASTER_CTRL_MTIMER_EN 0x2 -#define MASTER_CTRL_ITIMER_EN 0x4 -#define MASTER_CTRL_MANUAL_INT 0x8 -#define MASTER_CTRL_REV_NUM_SHIFT 16 -#define MASTER_CTRL_REV_NUM_MASK 0xff -#define MASTER_CTRL_DEV_ID_SHIFT 24 -#define MASTER_CTRL_DEV_ID_MASK 0xff - -/* Timer Initial Value Register */ -#define REG_MANUAL_TIMER_INIT 0x1404 - -/* IRQ ModeratorTimer Initial Value Register */ -#define REG_IRQ_MODU_TIMER_INIT 0x1408 - -#define REG_GPHY_ENABLE 0x140C - -/* IRQ Anti-Lost Timer Initial Value Register */ -#define REG_CMBDISDMA_TIMER 0x140E - -/* Block IDLE Status Register */ -#define REG_IDLE_STATUS 0x1410 -#define IDLE_STATUS_RXMAC 1 -#define IDLE_STATUS_TXMAC 2 -#define IDLE_STATUS_RXQ 4 -#define IDLE_STATUS_TXQ 8 -#define IDLE_STATUS_DMAR 0x10 -#define IDLE_STATUS_DMAW 0x20 -#define IDLE_STATUS_SMB 0x40 -#define IDLE_STATUS_CMB 0x80 - -/* MDIO Control Register */ -#define REG_MDIO_CTRL 0x1414 -#define MDIO_DATA_MASK 0xffff -#define MDIO_DATA_SHIFT 0 -#define MDIO_REG_ADDR_MASK 0x1f -#define MDIO_REG_ADDR_SHIFT 16 -#define MDIO_RW 0x200000 -#define MDIO_SUP_PREAMBLE 0x400000 -#define MDIO_START 0x800000 -#define MDIO_CLK_SEL_SHIFT 24 -#define MDIO_CLK_25_4 0 -#define MDIO_CLK_25_6 2 -#define MDIO_CLK_25_8 3 -#define MDIO_CLK_25_10 4 -#define MDIO_CLK_25_14 5 -#define MDIO_CLK_25_20 6 -#define MDIO_CLK_25_28 7 -#define MDIO_BUSY 0x8000000 -#define MDIO_WAIT_TIMES 30 - -/* MII PHY Status Register */ -#define REG_PHY_STATUS 0x1418 - -/* BIST Control and Status Register0 (for the Packet Memory) */ -#define REG_BIST0_CTRL 0x141c -#define BIST0_NOW 0x1 -#define BIST0_SRAM_FAIL 0x2 -#define BIST0_FUSE_FLAG 0x4 -#define REG_BIST1_CTRL 0x1420 -#define BIST1_NOW 0x1 -#define BIST1_SRAM_FAIL 0x2 -#define BIST1_FUSE_FLAG 0x4 - -/* MAC Control Register */ -#define REG_MAC_CTRL 0x1480 -#define MAC_CTRL_TX_EN 1 -#define MAC_CTRL_RX_EN 2 -#define MAC_CTRL_TX_FLOW 4 -#define MAC_CTRL_RX_FLOW 8 -#define MAC_CTRL_LOOPBACK 0x10 -#define MAC_CTRL_DUPLX 0x20 -#define MAC_CTRL_ADD_CRC 0x40 -#define MAC_CTRL_PAD 0x80 -#define MAC_CTRL_LENCHK 0x100 -#define MAC_CTRL_HUGE_EN 0x200 -#define MAC_CTRL_PRMLEN_SHIFT 10 -#define MAC_CTRL_PRMLEN_MASK 0xf -#define MAC_CTRL_RMV_VLAN 0x4000 -#define MAC_CTRL_PROMIS_EN 0x8000 -#define MAC_CTRL_TX_PAUSE 0x10000 -#define MAC_CTRL_SCNT 0x20000 -#define MAC_CTRL_SRST_TX 0x40000 -#define MAC_CTRL_TX_SIMURST 0x80000 -#define MAC_CTRL_SPEED_SHIFT 20 -#define MAC_CTRL_SPEED_MASK 0x300000 -#define MAC_CTRL_SPEED_1000 2 -#define MAC_CTRL_SPEED_10_100 1 -#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000 -#define MAC_CTRL_TX_HUGE 0x800000 -#define MAC_CTRL_RX_CHKSUM_EN 0x1000000 -#define MAC_CTRL_MC_ALL_EN 0x2000000 -#define MAC_CTRL_BC_EN 0x4000000 -#define MAC_CTRL_DBG 0x8000000 - -/* MAC IPG/IFG Control Register */ -#define REG_MAC_IPG_IFG 0x1484 -#define MAC_IPG_IFG_IPGT_SHIFT 0 -#define MAC_IPG_IFG_IPGT_MASK 0x7f -#define MAC_IPG_IFG_MIFG_SHIFT 8 -#define MAC_IPG_IFG_MIFG_MASK 0xff -#define MAC_IPG_IFG_IPGR1_SHIFT 16 -#define MAC_IPG_IFG_IPGR1_MASK 0x7f -#define MAC_IPG_IFG_IPGR2_SHIFT 24 -#define MAC_IPG_IFG_IPGR2_MASK 0x7f - -/* MAC STATION ADDRESS */ -#define REG_MAC_STA_ADDR 0x1488 - -/* Hash table for multicast address */ -#define REG_RX_HASH_TABLE 0x1490 - -/* MAC Half-Duplex Control Register */ -#define REG_MAC_HALF_DUPLX_CTRL 0x1498 -#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 -#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff -#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12 -#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf -#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000 -#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000 -#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 -#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 -#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 -#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf -#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 -#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf - -/* Maximum Frame Length Control Register */ -#define REG_MTU 0x149c - -/* Wake-On-Lan control register */ -#define REG_WOL_CTRL 0x14a0 -#define WOL_PATTERN_EN 0x00000001 -#define WOL_PATTERN_PME_EN 0x00000002 -#define WOL_MAGIC_EN 0x00000004 -#define WOL_MAGIC_PME_EN 0x00000008 -#define WOL_LINK_CHG_EN 0x00000010 -#define WOL_LINK_CHG_PME_EN 0x00000020 -#define WOL_PATTERN_ST 0x00000100 -#define WOL_MAGIC_ST 0x00000200 -#define WOL_LINKCHG_ST 0x00000400 -#define WOL_CLK_SWITCH_EN 0x00008000 -#define WOL_PT0_EN 0x00010000 -#define WOL_PT1_EN 0x00020000 -#define WOL_PT2_EN 0x00040000 -#define WOL_PT3_EN 0x00080000 -#define WOL_PT4_EN 0x00100000 -#define WOL_PT5_EN 0x00200000 -#define WOL_PT6_EN 0x00400000 - -/* WOL Length ( 2 DWORD ) */ -#define REG_WOL_PATTERN_LEN 0x14a4 -#define WOL_PT_LEN_MASK 0x7f -#define WOL_PT0_LEN_SHIFT 0 -#define WOL_PT1_LEN_SHIFT 8 -#define WOL_PT2_LEN_SHIFT 16 -#define WOL_PT3_LEN_SHIFT 24 -#define WOL_PT4_LEN_SHIFT 0 -#define WOL_PT5_LEN_SHIFT 8 -#define WOL_PT6_LEN_SHIFT 16 - -/* Internal SRAM Partition Register */ -#define REG_SRAM_RFD_ADDR 0x1500 -#define REG_SRAM_RFD_LEN (REG_SRAM_RFD_ADDR+ 4) -#define REG_SRAM_RRD_ADDR (REG_SRAM_RFD_ADDR+ 8) -#define REG_SRAM_RRD_LEN (REG_SRAM_RFD_ADDR+12) -#define REG_SRAM_TPD_ADDR (REG_SRAM_RFD_ADDR+16) -#define REG_SRAM_TPD_LEN (REG_SRAM_RFD_ADDR+20) -#define REG_SRAM_TRD_ADDR (REG_SRAM_RFD_ADDR+24) -#define REG_SRAM_TRD_LEN (REG_SRAM_RFD_ADDR+28) -#define REG_SRAM_RXF_ADDR (REG_SRAM_RFD_ADDR+32) -#define REG_SRAM_RXF_LEN (REG_SRAM_RFD_ADDR+36) -#define REG_SRAM_TXF_ADDR (REG_SRAM_RFD_ADDR+40) -#define REG_SRAM_TXF_LEN (REG_SRAM_RFD_ADDR+44) -#define REG_SRAM_TCPH_PATH_ADDR (REG_SRAM_RFD_ADDR+48) -#define SRAM_TCPH_ADDR_MASK 0x0fff -#define SRAM_TCPH_ADDR_SHIFT 0 -#define SRAM_PATH_ADDR_MASK 0x0fff -#define SRAM_PATH_ADDR_SHIFT 16 - -/* Load Ptr Register */ -#define REG_LOAD_PTR (REG_SRAM_RFD_ADDR+52) - -/* Descriptor Control register */ -#define REG_DESC_BASE_ADDR_HI 0x1540 -#define REG_DESC_RFD_ADDR_LO (REG_DESC_BASE_ADDR_HI+4) -#define REG_DESC_RRD_ADDR_LO (REG_DESC_BASE_ADDR_HI+8) -#define REG_DESC_TPD_ADDR_LO (REG_DESC_BASE_ADDR_HI+12) -#define REG_DESC_CMB_ADDR_LO (REG_DESC_BASE_ADDR_HI+16) -#define REG_DESC_SMB_ADDR_LO (REG_DESC_BASE_ADDR_HI+20) -#define REG_DESC_RFD_RRD_RING_SIZE (REG_DESC_BASE_ADDR_HI+24) -#define DESC_RFD_RING_SIZE_MASK 0x7ff -#define DESC_RFD_RING_SIZE_SHIFT 0 -#define DESC_RRD_RING_SIZE_MASK 0x7ff -#define DESC_RRD_RING_SIZE_SHIFT 16 -#define REG_DESC_TPD_RING_SIZE (REG_DESC_BASE_ADDR_HI+28) -#define DESC_TPD_RING_SIZE_MASK 0x3ff -#define DESC_TPD_RING_SIZE_SHIFT 0 - -/* TXQ Control Register */ -#define REG_TXQ_CTRL 0x1580 -#define TXQ_CTRL_TPD_BURST_NUM_SHIFT 0 -#define TXQ_CTRL_TPD_BURST_NUM_MASK 0x1f -#define TXQ_CTRL_EN 0x20 -#define TXQ_CTRL_ENH_MODE 0x40 -#define TXQ_CTRL_TPD_FETCH_TH_SHIFT 8 -#define TXQ_CTRL_TPD_FETCH_TH_MASK 0x3f -#define TXQ_CTRL_TXF_BURST_NUM_SHIFT 16 -#define TXQ_CTRL_TXF_BURST_NUM_MASK 0xffff - -/* Jumbo packet Threshold for task offload */ -#define REG_TX_JUMBO_TASK_TH_TPD_IPG 0x1584 -#define TX_JUMBO_TASK_TH_MASK 0x7ff -#define TX_JUMBO_TASK_TH_SHIFT 0 -#define TX_TPD_MIN_IPG_MASK 0x1f -#define TX_TPD_MIN_IPG_SHIFT 16 - -/* RXQ Control Register */ -#define REG_RXQ_CTRL 0x15a0 -#define RXQ_CTRL_RFD_BURST_NUM_SHIFT 0 -#define RXQ_CTRL_RFD_BURST_NUM_MASK 0xff -#define RXQ_CTRL_RRD_BURST_THRESH_SHIFT 8 -#define RXQ_CTRL_RRD_BURST_THRESH_MASK 0xff -#define RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT 16 -#define RXQ_CTRL_RFD_PREF_MIN_IPG_MASK 0x1f -#define RXQ_CTRL_CUT_THRU_EN 0x40000000 -#define RXQ_CTRL_EN 0x80000000 - -/* Rx jumbo packet threshold and rrd retirement timer */ -#define REG_RXQ_JMBOSZ_RRDTIM (REG_RXQ_CTRL+ 4) -#define RXQ_JMBOSZ_TH_MASK 0x7ff -#define RXQ_JMBOSZ_TH_SHIFT 0 -#define RXQ_JMBO_LKAH_MASK 0xf -#define RXQ_JMBO_LKAH_SHIFT 11 -#define RXQ_RRD_TIMER_MASK 0xffff -#define RXQ_RRD_TIMER_SHIFT 16 - -/* RFD flow control register */ -#define REG_RXQ_RXF_PAUSE_THRESH (REG_RXQ_CTRL+ 8) -#define RXQ_RXF_PAUSE_TH_HI_SHIFT 16 -#define RXQ_RXF_PAUSE_TH_HI_MASK 0xfff -#define RXQ_RXF_PAUSE_TH_LO_SHIFT 0 -#define RXQ_RXF_PAUSE_TH_LO_MASK 0xfff - -/* RRD flow control register */ -#define REG_RXQ_RRD_PAUSE_THRESH (REG_RXQ_CTRL+12) -#define RXQ_RRD_PAUSE_TH_HI_SHIFT 0 -#define RXQ_RRD_PAUSE_TH_HI_MASK 0xfff -#define RXQ_RRD_PAUSE_TH_LO_SHIFT 16 -#define RXQ_RRD_PAUSE_TH_LO_MASK 0xfff - -/* DMA Engine Control Register */ -#define REG_DMA_CTRL 0x15c0 -#define DMA_CTRL_DMAR_IN_ORDER 0x1 -#define DMA_CTRL_DMAR_ENH_ORDER 0x2 -#define DMA_CTRL_DMAR_OUT_ORDER 0x4 -#define DMA_CTRL_RCB_VALUE 0x8 -#define DMA_CTRL_DMAR_BURST_LEN_SHIFT 4 -#define DMA_CTRL_DMAR_BURST_LEN_MASK 7 -#define DMA_CTRL_DMAW_BURST_LEN_SHIFT 7 -#define DMA_CTRL_DMAW_BURST_LEN_MASK 7 -#define DMA_CTRL_DMAR_EN 0x400 -#define DMA_CTRL_DMAW_EN 0x800 - -/* CMB/SMB Control Register */ -#define REG_CSMB_CTRL 0x15d0 -#define CSMB_CTRL_CMB_NOW 1 -#define CSMB_CTRL_SMB_NOW 2 -#define CSMB_CTRL_CMB_EN 4 -#define CSMB_CTRL_SMB_EN 8 - -/* CMB DMA Write Threshold Register */ -#define REG_CMB_WRITE_TH (REG_CSMB_CTRL+ 4) -#define CMB_RRD_TH_SHIFT 0 -#define CMB_RRD_TH_MASK 0x7ff -#define CMB_TPD_TH_SHIFT 16 -#define CMB_TPD_TH_MASK 0x7ff - -/* RX/TX count-down timer to trigger CMB-write. 2us resolution. */ -#define REG_CMB_WRITE_TIMER (REG_CSMB_CTRL+ 8) -#define CMB_RX_TM_SHIFT 0 -#define CMB_RX_TM_MASK 0xffff -#define CMB_TX_TM_SHIFT 16 -#define CMB_TX_TM_MASK 0xffff - -/* Number of packet received since last CMB write */ -#define REG_CMB_RX_PKT_CNT (REG_CSMB_CTRL+12) - -/* Number of packet transmitted since last CMB write */ -#define REG_CMB_TX_PKT_CNT (REG_CSMB_CTRL+16) - -/* SMB auto DMA timer register */ -#define REG_SMB_TIMER (REG_CSMB_CTRL+20) - -/* Mailbox Register */ -#define REG_MAILBOX 0x15f0 -#define MB_RFD_PROD_INDX_SHIFT 0 -#define MB_RFD_PROD_INDX_MASK 0x7ff -#define MB_RRD_CONS_INDX_SHIFT 11 -#define MB_RRD_CONS_INDX_MASK 0x7ff -#define MB_TPD_PROD_INDX_SHIFT 22 -#define MB_TPD_PROD_INDX_MASK 0x3ff - -/* Interrupt Status Register */ -#define REG_ISR 0x1600 -#define ISR_SMB 1 -#define ISR_TIMER 2 -#define ISR_MANUAL 4 -#define ISR_RXF_OV 8 -#define ISR_RFD_UNRUN 0x10 -#define ISR_RRD_OV 0x20 -#define ISR_TXF_UNRUN 0x40 -#define ISR_LINK 0x80 -#define ISR_HOST_RFD_UNRUN 0x100 -#define ISR_HOST_RRD_OV 0x200 -#define ISR_DMAR_TO_RST 0x400 -#define ISR_DMAW_TO_RST 0x800 -#define ISR_GPHY 0x1000 -#define ISR_RX_PKT 0x10000 -#define ISR_TX_PKT 0x20000 -#define ISR_TX_DMA 0x40000 -#define ISR_RX_DMA 0x80000 -#define ISR_CMB_RX 0x100000 -#define ISR_CMB_TX 0x200000 -#define ISR_MAC_RX 0x400000 -#define ISR_MAC_TX 0x800000 -#define ISR_UR_DETECTED 0x1000000 -#define ISR_FERR_DETECTED 0x2000000 -#define ISR_NFERR_DETECTED 0x4000000 -#define ISR_CERR_DETECTED 0x8000000 -#define ISR_PHY_LINKDOWN 0x10000000 -#define ISR_DIS_SMB 0x20000000 -#define ISR_DIS_DMA 0x40000000 -#define ISR_DIS_INT 0x80000000 - -/* Interrupt Mask Register */ -#define REG_IMR 0x1604 - -/* Normal Interrupt mask */ -#define IMR_NORMAL_MASK (\ - ISR_SMB |\ - ISR_GPHY |\ - ISR_PHY_LINKDOWN|\ - ISR_DMAR_TO_RST |\ - ISR_DMAW_TO_RST |\ - ISR_CMB_TX |\ - ISR_CMB_RX ) - -/* Debug Interrupt Mask (enable all interrupt) */ -#define IMR_DEBUG_MASK (\ - ISR_SMB |\ - ISR_TIMER |\ - ISR_MANUAL |\ - ISR_RXF_OV |\ - ISR_RFD_UNRUN |\ - ISR_RRD_OV |\ - ISR_TXF_UNRUN |\ - ISR_LINK |\ - ISR_CMB_TX |\ - ISR_CMB_RX |\ - ISR_RX_PKT |\ - ISR_TX_PKT |\ - ISR_MAC_RX |\ - ISR_MAC_TX ) - -/* Interrupt Status Register */ -#define REG_RFD_RRD_IDX 0x1800 -#define REG_TPD_IDX 0x1804 - -/* MII definition */ -/* PHY Common Register */ -#define MII_AT001_CR 0x09 -#define MII_AT001_SR 0x0A -#define MII_AT001_ESR 0x0F -#define MII_AT001_PSCR 0x10 -#define MII_AT001_PSSR 0x11 - -/* PHY Control Register */ -#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ -#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ -#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ -#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ -#define MII_CR_POWER_DOWN 0x0800 /* Power down */ -#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ -#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ -#define MII_CR_SPEED_MASK 0x2040 -#define MII_CR_SPEED_1000 0x0040 -#define MII_CR_SPEED_100 0x2000 -#define MII_CR_SPEED_10 0x0000 - -/* PHY Status Register */ -#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ -#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ -#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ -#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ -#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ -#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ -#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ -#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ -#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ -#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ -#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ -#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ -#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ -#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ -#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ - -/* Link partner ability register. */ -#define MII_LPA_SLCT 0x001f /* Same as advertise selector */ -#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ -#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ -#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ -#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ -#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */ -#define MII_LPA_PAUSE 0x0400 /* PAUSE */ -#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */ -#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */ -#define MII_LPA_LPACK 0x4000 /* Link partner acked us */ -#define MII_LPA_NPAGE 0x8000 /* Next page bit */ - -/* Autoneg Advertisement Register */ -#define MII_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ -#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ -#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ -#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ -#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ -#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ -#define MII_AR_PAUSE 0x0400 /* Pause operation desired */ -#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ -#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ -#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ -#define MII_AR_SPEED_MASK 0x01E0 -#define MII_AR_DEFAULT_CAP_MASK 0x0DE0 - -/* 1000BASE-T Control Register */ -#define MII_AT001_CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ -#define MII_AT001_CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ -#define MII_AT001_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port, 0=DTE device */ -#define MII_AT001_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master, 0=Configure PHY as Slave */ -#define MII_AT001_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value, 0=Automatic Master/Slave config */ -#define MII_AT001_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ -#define MII_AT001_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ -#define MII_AT001_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ -#define MII_AT001_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ -#define MII_AT001_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ -#define MII_AT001_CR_1000T_SPEED_MASK 0x0300 -#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK 0x0300 - -/* 1000BASE-T Status Register */ -#define MII_AT001_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ -#define MII_AT001_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ -#define MII_AT001_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ -#define MII_AT001_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ -#define MII_AT001_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ -#define MII_AT001_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ -#define MII_AT001_SR_1000T_REMOTE_RX_STATUS_SHIFT 12 -#define MII_AT001_SR_1000T_LOCAL_RX_STATUS_SHIFT 13 - -/* Extended Status Register */ -#define MII_AT001_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */ -#define MII_AT001_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */ -#define MII_AT001_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */ -#define MII_AT001_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */ - -/* AT001 PHY Specific Control Register */ -#define MII_AT001_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ -#define MII_AT001_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ -#define MII_AT001_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */ -#define MII_AT001_PSCR_MAC_POWERDOWN 0x0008 -#define MII_AT001_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low, 0=CLK125 toggling */ -#define MII_AT001_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5, Manual MDI configuration */ -#define MII_AT001_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ -#define MII_AT001_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ -#define MII_AT001_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled all speeds. */ -#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE 0x0080 /* 1=Enable Extended 10BASE-T distance (Lower 10BASE-T RX Threshold), 0=Normal 10BASE-T RX Threshold */ -#define MII_AT001_PSCR_MII_5BIT_ENABLE 0x0100 /* 1=5-Bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */ -#define MII_AT001_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ -#define MII_AT001_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ -#define MII_AT001_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ -#define MII_AT001_PSCR_POLARITY_REVERSAL_SHIFT 1 -#define MII_AT001_PSCR_AUTO_X_MODE_SHIFT 5 -#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7 - -/* AT001 PHY Specific Status Register */ -#define MII_AT001_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ -#define MII_AT001_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ -#define MII_AT001_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ -#define MII_AT001_PSSR_10MBS 0x0000 /* 00=10Mbs */ -#define MII_AT001_PSSR_100MBS 0x4000 /* 01=100Mbs */ -#define MII_AT001_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ - -/* PCI Command Register Bit Definitions */ -#define PCI_REG_COMMAND 0x04 /* PCI Command Register */ -#define CMD_IO_SPACE 0x0001 -#define CMD_MEMORY_SPACE 0x0002 -#define CMD_BUS_MASTER 0x0004 - -/* Wake Up Filter Control */ -#define ATL1_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ -#define ATL1_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ -#define ATL1_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ -#define ATL1_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */ -#define ATL1_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ - -/* Error Codes */ -#define ATL1_SUCCESS 0 -#define ATL1_ERR_EEPROM 1 -#define ATL1_ERR_PHY 2 -#define ATL1_ERR_CONFIG 3 -#define ATL1_ERR_PARAM 4 -#define ATL1_ERR_MAC_TYPE 5 -#define ATL1_ERR_PHY_TYPE 6 -#define ATL1_ERR_PHY_SPEED 7 -#define ATL1_ERR_PHY_RES 8 - -#define SPEED_0 0xffff -#define SPEED_10 10 -#define SPEED_100 100 -#define SPEED_1000 1000 -#define HALF_DUPLEX 1 -#define FULL_DUPLEX 2 - -#define MEDIA_TYPE_AUTO_SENSOR 0 -#define MEDIA_TYPE_1000M_FULL 1 -#define MEDIA_TYPE_100M_FULL 2 -#define MEDIA_TYPE_100M_HALF 3 -#define MEDIA_TYPE_10M_FULL 4 -#define MEDIA_TYPE_10M_HALF 5 - -#define ADVERTISE_10_HALF 0x0001 -#define ADVERTISE_10_FULL 0x0002 -#define ADVERTISE_100_HALF 0x0004 -#define ADVERTISE_100_FULL 0x0008 -#define ADVERTISE_1000_HALF 0x0010 -#define ADVERTISE_1000_FULL 0x0020 -#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */ -#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds */ -#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds */ - -/* The size (in bytes) of a ethernet packet */ -#define ENET_HEADER_SIZE 14 -#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* with FCS */ -#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* with FCS */ -#define ETHERNET_FCS_SIZE 4 -#define MAX_JUMBO_FRAME_SIZE 0x2800 - -#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */ -#define PHY_FORCE_TIME 20 /* 2.0 Seconds */ - -/* For checksumming , the sum of all words in the EEPROM should equal 0xBABA */ -#define EEPROM_SUM 0xBABA - -#define ATL1_EEDUMP_LEN 48 - -/* Statistics counters collected by the MAC */ -struct stats_msg_block { - /* rx */ - u32 rx_ok; /* The number of good packet received. */ - u32 rx_bcast; /* The number of good broadcast packet received. */ - u32 rx_mcast; /* The number of good multicast packet received. */ - u32 rx_pause; /* The number of Pause packet received. */ - u32 rx_ctrl; /* The number of Control packet received other than Pause frame. */ - u32 rx_fcs_err; /* The number of packets with bad FCS. */ - u32 rx_len_err; /* The number of packets with mismatch of length field and actual size. */ - u32 rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */ - u32 rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */ - u32 rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */ - u32 rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */ - u32 rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */ - u32 rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */ - u32 rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */ - u32 rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */ - u32 rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */ - u32 rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */ - u32 rx_sz_ov; /* The number of good and bad packets received that are more than MTU size Å¡C truncated by Selene. */ - u32 rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */ - u32 rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */ - u32 rx_align_err; /* Alignment Error */ - u32 rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */ - u32 rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */ - u32 rx_err_addr; /* The number of packets dropped due to address filtering. */ - - /* tx */ - u32 tx_ok; /* The number of good packet transmitted. */ - u32 tx_bcast; /* The number of good broadcast packet transmitted. */ - u32 tx_mcast; /* The number of good multicast packet transmitted. */ - u32 tx_pause; /* The number of Pause packet transmitted. */ - u32 tx_exc_defer; /* The number of packets transmitted with excessive deferral. */ - u32 tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */ - u32 tx_defer; /* The number of packets transmitted that is deferred. */ - u32 tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */ - u32 tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */ - u32 tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */ - u32 tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */ - u32 tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */ - u32 tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */ - u32 tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */ - u32 tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */ - u32 tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */ - u32 tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */ - u32 tx_late_col; /* The number of packets transmitted with late collisions. */ - u32 tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */ - u32 tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */ - u32 tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */ - u32 tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */ - u32 tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */ - u32 tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */ - u32 tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */ - u32 smb_updated; /* 1: SMB Updated. This is used by software as the indication of the statistics update. - * Software should clear this bit as soon as retrieving the statistics information. */ -}; - -/* Coalescing Message Block */ -struct coals_msg_block { - u32 int_stats; /* interrupt status */ - u16 rrd_prod_idx; /* TRD Producer Index. */ - u16 rfd_cons_idx; /* RFD Consumer Index. */ - u16 update; /* Selene sets this bit every time it DMA the CMB to host memory. - * Software supposes to clear this bit when CMB information is processed. */ - u16 tpd_cons_idx; /* TPD Consumer Index. */ -}; - -/* RRD descriptor */ -struct rx_return_desc { - u8 num_buf; /* Number of RFD buffers used by the received packet */ - u8 resved; - u16 buf_indx; /* RFD Index of the first buffer */ - union { - u32 valid; - struct { - u16 rx_chksum; - u16 pkt_size; - } xsum_sz; - } xsz; - - u16 pkt_flg; /* Packet flags */ - u16 err_flg; /* Error flags */ - u16 resved2; - u16 vlan_tag; /* VLAN TAG */ -}; - -#define PACKET_FLAG_ETH_TYPE 0x0080 -#define PACKET_FLAG_VLAN_INS 0x0100 -#define PACKET_FLAG_ERR 0x0200 -#define PACKET_FLAG_IPV4 0x0400 -#define PACKET_FLAG_UDP 0x0800 -#define PACKET_FLAG_TCP 0x1000 -#define PACKET_FLAG_BCAST 0x2000 -#define PACKET_FLAG_MCAST 0x4000 -#define PACKET_FLAG_PAUSE 0x8000 - -#define ERR_FLAG_CRC 0x0001 -#define ERR_FLAG_CODE 0x0002 -#define ERR_FLAG_DRIBBLE 0x0004 -#define ERR_FLAG_RUNT 0x0008 -#define ERR_FLAG_OV 0x0010 -#define ERR_FLAG_TRUNC 0x0020 -#define ERR_FLAG_IP_CHKSUM 0x0040 -#define ERR_FLAG_L4_CHKSUM 0x0080 -#define ERR_FLAG_LEN 0x0100 -#define ERR_FLAG_DES_ADDR 0x0200 - -/* RFD descriptor */ -struct rx_free_desc { - __le64 buffer_addr; /* Address of the descriptor's data buffer */ - __le16 buf_len; /* Size of the receive buffer in host memory, in byte */ - u16 coalese; /* Update consumer index to host after the reception of this frame */ - /* __attribute__ ((packed)) is required */ -} __attribute__ ((packed)); - -/* tsopu defines */ -#define TSO_PARAM_BUFLEN_MASK 0x3FFF -#define TSO_PARAM_BUFLEN_SHIFT 0 -#define TSO_PARAM_DMAINT_MASK 0x0001 -#define TSO_PARAM_DMAINT_SHIFT 14 -#define TSO_PARAM_PKTNT_MASK 0x0001 -#define TSO_PARAM_PKTINT_SHIFT 15 -#define TSO_PARAM_VLANTAG_MASK 0xFFFF -#define TSO_PARAM_VLAN_SHIFT 16 - -/* tsopl defines */ -#define TSO_PARAM_EOP_MASK 0x0001 -#define TSO_PARAM_EOP_SHIFT 0 -#define TSO_PARAM_COALESCE_MASK 0x0001 -#define TSO_PARAM_COALESCE_SHIFT 1 -#define TSO_PARAM_INSVLAG_MASK 0x0001 -#define TSO_PARAM_INSVLAG_SHIFT 2 -#define TSO_PARAM_CUSTOMCKSUM_MASK 0x0001 -#define TSO_PARAM_CUSTOMCKSUM_SHIFT 3 -#define TSO_PARAM_SEGMENT_MASK 0x0001 -#define TSO_PARAM_SEGMENT_SHIFT 4 -#define TSO_PARAM_IPCKSUM_MASK 0x0001 -#define TSO_PARAM_IPCKSUM_SHIFT 5 -#define TSO_PARAM_TCPCKSUM_MASK 0x0001 -#define TSO_PARAM_TCPCKSUM_SHIFT 6 -#define TSO_PARAM_UDPCKSUM_MASK 0x0001 -#define TSO_PARAM_UDPCKSUM_SHIFT 7 -#define TSO_PARAM_VLANTAGGED_MASK 0x0001 -#define TSO_PARAM_VLANTAGGED_SHIFT 8 -#define TSO_PARAM_ETHTYPE_MASK 0x0001 -#define TSO_PARAM_ETHTYPE_SHIFT 9 -#define TSO_PARAM_IPHL_MASK 0x000F -#define TSO_PARAM_IPHL_SHIFT 10 -#define TSO_PARAM_TCPHDRLEN_MASK 0x000F -#define TSO_PARAM_TCPHDRLEN_SHIFT 14 -#define TSO_PARAM_HDRFLAG_MASK 0x0001 -#define TSO_PARAM_HDRFLAG_SHIFT 18 -#define TSO_PARAM_MSS_MASK 0x1FFF -#define TSO_PARAM_MSS_SHIFT 19 - -/* csumpu defines */ -#define CSUM_PARAM_BUFLEN_MASK 0x3FFF -#define CSUM_PARAM_BUFLEN_SHIFT 0 -#define CSUM_PARAM_DMAINT_MASK 0x0001 -#define CSUM_PARAM_DMAINT_SHIFT 14 -#define CSUM_PARAM_PKTINT_MASK 0x0001 -#define CSUM_PARAM_PKTINT_SHIFT 15 -#define CSUM_PARAM_VALANTAG_MASK 0xFFFF -#define CSUM_PARAM_VALAN_SHIFT 16 - -/* csumpl defines*/ -#define CSUM_PARAM_EOP_MASK 0x0001 -#define CSUM_PARAM_EOP_SHIFT 0 -#define CSUM_PARAM_COALESCE_MASK 0x0001 -#define CSUM_PARAM_COALESCE_SHIFT 1 -#define CSUM_PARAM_INSVLAG_MASK 0x0001 -#define CSUM_PARAM_INSVLAG_SHIFT 2 -#define CSUM_PARAM_CUSTOMCKSUM_MASK 0x0001 -#define CSUM_PARAM_CUSTOMCKSUM_SHIFT 3 -#define CSUM_PARAM_SEGMENT_MASK 0x0001 -#define CSUM_PARAM_SEGMENT_SHIFT 4 -#define CSUM_PARAM_IPCKSUM_MASK 0x0001 -#define CSUM_PARAM_IPCKSUM_SHIFT 5 -#define CSUM_PARAM_TCPCKSUM_MASK 0x0001 -#define CSUM_PARAM_TCPCKSUM_SHIFT 6 -#define CSUM_PARAM_UDPCKSUM_MASK 0x0001 -#define CSUM_PARAM_UDPCKSUM_SHIFT 7 -#define CSUM_PARAM_VLANTAGGED_MASK 0x0001 -#define CSUM_PARAM_VLANTAGGED_SHIFT 8 -#define CSUM_PARAM_ETHTYPE_MASK 0x0001 -#define CSUM_PARAM_ETHTYPE_SHIFT 9 -#define CSUM_PARAM_IPHL_MASK 0x000F -#define CSUM_PARAM_IPHL_SHIFT 10 -#define CSUM_PARAM_PLOADOFFSET_MASK 0x00FF -#define CSUM_PARAM_PLOADOFFSET_SHIFT 16 -#define CSUM_PARAM_XSUMOFFSET_MASK 0x00FF -#define CSUM_PARAM_XSUMOFFSET_SHIFT 24 - -/* TPD descriptor */ -struct tso_param { - /* The order of these declarations is important -- don't change it */ - u32 tsopu; /* tso_param upper word */ - u32 tsopl; /* tso_param lower word */ -}; - -struct csum_param { - /* The order of these declarations is important -- don't change it */ - u32 csumpu; /* csum_param upper word */ - u32 csumpl; /* csum_param lower word */ -}; - -union tpd_descr { - u64 data; - struct csum_param csum; - struct tso_param tso; -}; - -struct tx_packet_desc { - __le64 buffer_addr; - union tpd_descr desc; -}; - -/* DMA Order Settings */ -enum atl1_dma_order { - atl1_dma_ord_in = 1, - atl1_dma_ord_enh = 2, - atl1_dma_ord_out = 4 -}; - -enum atl1_dma_rcb { - atl1_rcb_64 = 0, - atl1_rcb_128 = 1 -}; - -enum atl1_dma_req_block { - atl1_dma_req_128 = 0, - atl1_dma_req_256 = 1, - atl1_dma_req_512 = 2, - atl1_dam_req_1024 = 3, - atl1_dam_req_2048 = 4, - atl1_dma_req_4096 = 5 -}; - -struct atl1_spi_flash_dev { - const char *manu_name; /* manufacturer id */ - /* op-code */ - u8 cmd_wrsr; - u8 cmd_read; - u8 cmd_program; - u8 cmd_wren; - u8 cmd_wrdi; - u8 cmd_rdsr; - u8 cmd_rdid; - u8 cmd_sector_erase; - u8 cmd_chip_erase; -}; - -#endif /* _ATL1_HW_H_ */ diff --git a/trunk/drivers/net/atl1/atl1_main.c b/trunk/drivers/net/atl1/atl1_main.c deleted file mode 100644 index 6655640eb4ca..000000000000 --- a/trunk/drivers/net/atl1/atl1_main.c +++ /dev/null @@ -1,2468 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The full GNU General Public License is included in this distribution in the - * file called COPYING. - * - * Contact Information: - * Xiong Huang - * Attansic Technology Corp. 3F 147, Xianzheng 9th Road, Zhubei, - * Xinzhu 302, TAIWAN, REPUBLIC OF CHINA - * - * Chris Snook - * Jay Cliburn - * - * This version is adapted from the Attansic reference driver for - * inclusion in the Linux kernel. It is currently under heavy development. - * A very incomplete list of things that need to be dealt with: - * - * TODO: - * Fix TSO; tx performance is horrible with TSO enabled. - * Wake on LAN. - * Add more ethtool functions, including set ring parameters. - * Fix abstruse irq enable/disable condition described here: - * http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2 - * - * NEEDS TESTING: - * VLAN - * multicast - * promiscuous mode - * interrupt coalescing - * SMP torture testing - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "atl1.h" - -#define RUN_REALTIME 0 -#define DRIVER_VERSION "2.0.6" - -char atl1_driver_name[] = "atl1"; -static const char atl1_driver_string[] = "Attansic L1 Ethernet Network Driver"; -static const char atl1_copyright[] = "Copyright(c) 2005-2006 Attansic Corporation."; -char atl1_driver_version[] = DRIVER_VERSION; - -MODULE_AUTHOR - ("Attansic Corporation , Chris Snook , Jay Cliburn "); -MODULE_DESCRIPTION("Attansic 1000M Ethernet Network Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); - -/* - * atl1_pci_tbl - PCI Device ID Table - */ -static const struct pci_device_id atl1_pci_tbl[] = { - {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1048)}, - /* required last entry */ - {0,} -}; - -MODULE_DEVICE_TABLE(pci, atl1_pci_tbl); - -/* - * atl1_sw_init - Initialize general software structures (struct atl1_adapter) - * @adapter: board private structure to initialize - * - * atl1_sw_init initializes the Adapter private data structure. - * Fields are initialized based on PCI device information and - * OS network device settings (MTU size). - */ -static int __devinit atl1_sw_init(struct atl1_adapter *adapter) -{ - struct atl1_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - - /* PCI config space info */ - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); - - hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; - - adapter->wol = 0; - adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7; - adapter->ict = 50000; /* 100ms */ - adapter->link_speed = SPEED_0; /* hardware init */ - adapter->link_duplex = FULL_DUPLEX; - - hw->phy_configured = false; - hw->preamble_len = 7; - hw->ipgt = 0x60; - hw->min_ifg = 0x50; - hw->ipgr1 = 0x40; - hw->ipgr2 = 0x60; - hw->max_retry = 0xf; - hw->lcol = 0x37; - hw->jam_ipg = 7; - hw->rfd_burst = 8; - hw->rrd_burst = 8; - hw->rfd_fetch_gap = 1; - hw->rx_jumbo_th = adapter->rx_buffer_len / 8; - hw->rx_jumbo_lkah = 1; - hw->rrd_ret_timer = 16; - hw->tpd_burst = 4; - hw->tpd_fetch_th = 16; - hw->txf_burst = 0x100; - hw->tx_jumbo_task_th = (hw->max_frame_size + 7) >> 3; - hw->tpd_fetch_gap = 1; - hw->rcb_value = atl1_rcb_64; - hw->dma_ord = atl1_dma_ord_enh; - hw->dmar_block = atl1_dma_req_256; - hw->dmaw_block = atl1_dma_req_256; - hw->cmb_rrd = 4; - hw->cmb_tpd = 4; - hw->cmb_rx_timer = 1; /* about 2us */ - hw->cmb_tx_timer = 1; /* about 2us */ - hw->smb_timer = 100000; /* about 200ms */ - - atomic_set(&adapter->irq_sem, 0); - spin_lock_init(&adapter->lock); - spin_lock_init(&adapter->mb_lock); - - return 0; -} - -/* - * atl1_setup_mem_resources - allocate Tx / RX descriptor resources - * @adapter: board private structure - * - * Return 0 on success, negative on failure - */ -s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) -{ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring; - struct atl1_ring_header *ring_header = &adapter->ring_header; - struct pci_dev *pdev = adapter->pdev; - int size; - u8 offset = 0; - - size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count); - tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL); - if (unlikely(!tpd_ring->buffer_info)) { - printk(KERN_WARNING "%s: kzalloc failed , size = D%d\n", - atl1_driver_name, size); - goto err_nomem; - } - rfd_ring->buffer_info = - (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count); - - /* real ring DMA buffer */ - ring_header->size = size = sizeof(struct tx_packet_desc) * - tpd_ring->count - + sizeof(struct rx_free_desc) * rfd_ring->count - + sizeof(struct rx_return_desc) * rrd_ring->count - + sizeof(struct coals_msg_block) - + sizeof(struct stats_msg_block) - + 40; /* "40: for 8 bytes align" huh? -- CHS */ - - ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, - &ring_header->dma); - if (unlikely(!ring_header->desc)) { - printk(KERN_WARNING - "%s: pci_alloc_consistent failed, size = D%d\n", - atl1_driver_name, size); - goto err_nomem; - } - - memset(ring_header->desc, 0, ring_header->size); - - /* init TPD ring */ - tpd_ring->dma = ring_header->dma; - offset = (tpd_ring->dma & 0x7) ? (8 - (ring_header->dma & 0x7)) : 0; - tpd_ring->dma += offset; - tpd_ring->desc = (u8 *) ring_header->desc + offset; - tpd_ring->size = sizeof(struct tx_packet_desc) * tpd_ring->count; - atomic_set(&tpd_ring->next_to_use, 0); - atomic_set(&tpd_ring->next_to_clean, 0); - - /* init RFD ring */ - rfd_ring->dma = tpd_ring->dma + tpd_ring->size; - offset = (rfd_ring->dma & 0x7) ? (8 - (rfd_ring->dma & 0x7)) : 0; - rfd_ring->dma += offset; - rfd_ring->desc = (u8 *) tpd_ring->desc + (tpd_ring->size + offset); - rfd_ring->size = sizeof(struct rx_free_desc) * rfd_ring->count; - rfd_ring->next_to_clean = 0; - /* rfd_ring->next_to_use = rfd_ring->count - 1; */ - atomic_set(&rfd_ring->next_to_use, 0); - - /* init RRD ring */ - rrd_ring->dma = rfd_ring->dma + rfd_ring->size; - offset = (rrd_ring->dma & 0x7) ? (8 - (rrd_ring->dma & 0x7)) : 0; - rrd_ring->dma += offset; - rrd_ring->desc = (u8 *) rfd_ring->desc + (rfd_ring->size + offset); - rrd_ring->size = sizeof(struct rx_return_desc) * rrd_ring->count; - rrd_ring->next_to_use = 0; - atomic_set(&rrd_ring->next_to_clean, 0); - - /* init CMB */ - adapter->cmb.dma = rrd_ring->dma + rrd_ring->size; - offset = (adapter->cmb.dma & 0x7) ? (8 - (adapter->cmb.dma & 0x7)) : 0; - adapter->cmb.dma += offset; - adapter->cmb.cmb = - (struct coals_msg_block *) ((u8 *) rrd_ring->desc + - (rrd_ring->size + offset)); - - /* init SMB */ - adapter->smb.dma = adapter->cmb.dma + sizeof(struct coals_msg_block); - offset = (adapter->smb.dma & 0x7) ? (8 - (adapter->smb.dma & 0x7)) : 0; - adapter->smb.dma += offset; - adapter->smb.smb = (struct stats_msg_block *) - ((u8 *) adapter->cmb.cmb + (sizeof(struct coals_msg_block) + offset)); - - return ATL1_SUCCESS; - -err_nomem: - kfree(tpd_ring->buffer_info); - return -ENOMEM; -} - -/* - * atl1_irq_enable - Enable default interrupt generation settings - * @adapter: board private structure - */ -static void atl1_irq_enable(struct atl1_adapter *adapter) -{ - if (likely(!atomic_dec_and_test(&adapter->irq_sem))) - iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR); -} - -static void atl1_clear_phy_int(struct atl1_adapter *adapter) -{ - u16 phy_data; - unsigned long flags; - - spin_lock_irqsave(&adapter->lock, flags); - atl1_read_phy_reg(&adapter->hw, 19, &phy_data); - spin_unlock_irqrestore(&adapter->lock, flags); -} - -static void atl1_inc_smb(struct atl1_adapter *adapter) -{ - struct stats_msg_block *smb = adapter->smb.smb; - - /* Fill out the OS statistics structure */ - adapter->soft_stats.rx_packets += smb->rx_ok; - adapter->soft_stats.tx_packets += smb->tx_ok; - adapter->soft_stats.rx_bytes += smb->rx_byte_cnt; - adapter->soft_stats.tx_bytes += smb->tx_byte_cnt; - adapter->soft_stats.multicast += smb->rx_mcast; - adapter->soft_stats.collisions += (smb->tx_1_col + - smb->tx_2_col * 2 + - smb->tx_late_col + - smb->tx_abort_col * - adapter->hw.max_retry); - - /* Rx Errors */ - adapter->soft_stats.rx_errors += (smb->rx_frag + - smb->rx_fcs_err + - smb->rx_len_err + - smb->rx_sz_ov + - smb->rx_rxf_ov + - smb->rx_rrd_ov + smb->rx_align_err); - adapter->soft_stats.rx_fifo_errors += smb->rx_rxf_ov; - adapter->soft_stats.rx_length_errors += smb->rx_len_err; - adapter->soft_stats.rx_crc_errors += smb->rx_fcs_err; - adapter->soft_stats.rx_frame_errors += smb->rx_align_err; - adapter->soft_stats.rx_missed_errors += (smb->rx_rrd_ov + - smb->rx_rxf_ov); - - adapter->soft_stats.rx_pause += smb->rx_pause; - adapter->soft_stats.rx_rrd_ov += smb->rx_rrd_ov; - adapter->soft_stats.rx_trunc += smb->rx_sz_ov; - - /* Tx Errors */ - adapter->soft_stats.tx_errors += (smb->tx_late_col + - smb->tx_abort_col + - smb->tx_underrun + smb->tx_trunc); - adapter->soft_stats.tx_fifo_errors += smb->tx_underrun; - adapter->soft_stats.tx_aborted_errors += smb->tx_abort_col; - adapter->soft_stats.tx_window_errors += smb->tx_late_col; - - adapter->soft_stats.excecol += smb->tx_abort_col; - adapter->soft_stats.deffer += smb->tx_defer; - adapter->soft_stats.scc += smb->tx_1_col; - adapter->soft_stats.mcc += smb->tx_2_col; - adapter->soft_stats.latecol += smb->tx_late_col; - adapter->soft_stats.tx_underun += smb->tx_underrun; - adapter->soft_stats.tx_trunc += smb->tx_trunc; - adapter->soft_stats.tx_pause += smb->tx_pause; - - adapter->net_stats.rx_packets = adapter->soft_stats.rx_packets; - adapter->net_stats.tx_packets = adapter->soft_stats.tx_packets; - adapter->net_stats.rx_bytes = adapter->soft_stats.rx_bytes; - adapter->net_stats.tx_bytes = adapter->soft_stats.tx_bytes; - adapter->net_stats.multicast = adapter->soft_stats.multicast; - adapter->net_stats.collisions = adapter->soft_stats.collisions; - adapter->net_stats.rx_errors = adapter->soft_stats.rx_errors; - adapter->net_stats.rx_over_errors = - adapter->soft_stats.rx_missed_errors; - adapter->net_stats.rx_length_errors = - adapter->soft_stats.rx_length_errors; - adapter->net_stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors; - adapter->net_stats.rx_frame_errors = - adapter->soft_stats.rx_frame_errors; - adapter->net_stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors; - adapter->net_stats.rx_missed_errors = - adapter->soft_stats.rx_missed_errors; - adapter->net_stats.tx_errors = adapter->soft_stats.tx_errors; - adapter->net_stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors; - adapter->net_stats.tx_aborted_errors = - adapter->soft_stats.tx_aborted_errors; - adapter->net_stats.tx_window_errors = - adapter->soft_stats.tx_window_errors; - adapter->net_stats.tx_carrier_errors = - adapter->soft_stats.tx_carrier_errors; -} - -static void atl1_rx_checksum(struct atl1_adapter *adapter, - struct rx_return_desc *rrd, - struct sk_buff *skb) -{ - skb->ip_summed = CHECKSUM_NONE; - - if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { - if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC | - ERR_FLAG_CODE | ERR_FLAG_OV)) { - adapter->hw_csum_err++; - printk(KERN_DEBUG "%s: rx checksum error\n", - atl1_driver_name); - return; - } - } - - /* not IPv4 */ - if (!(rrd->pkt_flg & PACKET_FLAG_IPV4)) - /* checksum is invalid, but it's not an IPv4 pkt, so ok */ - return; - - /* IPv4 packet */ - if (likely(!(rrd->err_flg & - (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM)))) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - adapter->hw_csum_good++; - return; - } - - /* IPv4, but hardware thinks its checksum is wrong */ - printk(KERN_DEBUG "%s: hw csum wrong pkt_flag:%x, err_flag:%x\n", - atl1_driver_name, rrd->pkt_flg, rrd->err_flg); - skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum); - adapter->hw_csum_err++; - return; -} - -/* - * atl1_alloc_rx_buffers - Replace used receive buffers - * @adapter: address of board private structure - */ -static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter) -{ - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - struct page *page; - unsigned long offset; - struct atl1_buffer *buffer_info, *next_info; - struct sk_buff *skb; - u16 num_alloc = 0; - u16 rfd_next_to_use, next_next; - struct rx_free_desc *rfd_desc; - - next_next = rfd_next_to_use = atomic_read(&rfd_ring->next_to_use); - if (++next_next == rfd_ring->count) - next_next = 0; - buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; - next_info = &rfd_ring->buffer_info[next_next]; - - while (!buffer_info->alloced && !next_info->alloced) { - if (buffer_info->skb) { - buffer_info->alloced = 1; - goto next; - } - - rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use); - - skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN); - if (unlikely(!skb)) { /* Better luck next round */ - adapter->net_stats.rx_dropped++; - break; - } - - /* - * Make buffer alignment 2 beyond a 16 byte boundary - * this will result in a 16 byte aligned IP header after - * the 14 byte MAC header is removed - */ - skb_reserve(skb, NET_IP_ALIGN); - skb->dev = netdev; - - buffer_info->alloced = 1; - buffer_info->skb = skb; - buffer_info->length = (u16) adapter->rx_buffer_len; - page = virt_to_page(skb->data); - offset = (unsigned long)skb->data & ~PAGE_MASK; - buffer_info->dma = pci_map_page(pdev, page, offset, - adapter->rx_buffer_len, - PCI_DMA_FROMDEVICE); - rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); - rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len); - rfd_desc->coalese = 0; - -next: - rfd_next_to_use = next_next; - if (unlikely(++next_next == rfd_ring->count)) - next_next = 0; - - buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; - next_info = &rfd_ring->buffer_info[next_next]; - num_alloc++; - } - - if (num_alloc) { - /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). - */ - wmb(); - atomic_set(&rfd_ring->next_to_use, (int)rfd_next_to_use); - } - return num_alloc; -} - -static void atl1_intr_rx(struct atl1_adapter *adapter) -{ - int i, count; - u16 length; - u16 rrd_next_to_clean; - u32 value; - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring; - struct atl1_buffer *buffer_info; - struct rx_return_desc *rrd; - struct sk_buff *skb; - - count = 0; - - rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean); - - while (1) { - rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean); - i = 1; - if (likely(rrd->xsz.valid)) { /* packet valid */ -chk_rrd: - /* check rrd status */ - if (likely(rrd->num_buf == 1)) - goto rrd_ok; - - /* rrd seems to be bad */ - if (unlikely(i-- > 0)) { - /* rrd may not be DMAed completely */ - printk(KERN_DEBUG - "%s: RRD may not be DMAed completely\n", - atl1_driver_name); - udelay(1); - goto chk_rrd; - } - /* bad rrd */ - printk(KERN_DEBUG "%s: bad RRD\n", atl1_driver_name); - /* see if update RFD index */ - if (rrd->num_buf > 1) { - u16 num_buf; - num_buf = - (rrd->xsz.xsum_sz.pkt_size + - adapter->rx_buffer_len - - 1) / adapter->rx_buffer_len; - if (rrd->num_buf == num_buf) { - /* clean alloc flag for bad rrd */ - while (rfd_ring->next_to_clean != - (rrd->buf_indx + num_buf)) { - rfd_ring->buffer_info[rfd_ring-> - next_to_clean].alloced = 0; - if (++rfd_ring->next_to_clean == - rfd_ring->count) { - rfd_ring-> - next_to_clean = 0; - } - } - } - } - - /* update rrd */ - rrd->xsz.valid = 0; - if (++rrd_next_to_clean == rrd_ring->count) - rrd_next_to_clean = 0; - count++; - continue; - } else { /* current rrd still not be updated */ - - break; - } -rrd_ok: - /* clean alloc flag for bad rrd */ - while (rfd_ring->next_to_clean != rrd->buf_indx) { - rfd_ring->buffer_info[rfd_ring->next_to_clean].alloced = - 0; - if (++rfd_ring->next_to_clean == rfd_ring->count) - rfd_ring->next_to_clean = 0; - } - - buffer_info = &rfd_ring->buffer_info[rrd->buf_indx]; - if (++rfd_ring->next_to_clean == rfd_ring->count) - rfd_ring->next_to_clean = 0; - - /* update rrd next to clean */ - if (++rrd_next_to_clean == rrd_ring->count) - rrd_next_to_clean = 0; - count++; - - if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { - if (!(rrd->err_flg & - (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM - | ERR_FLAG_LEN))) { - /* packet error, don't need upstream */ - buffer_info->alloced = 0; - rrd->xsz.valid = 0; - continue; - } - } - - /* Good Receive */ - pci_unmap_page(adapter->pdev, buffer_info->dma, - buffer_info->length, PCI_DMA_FROMDEVICE); - skb = buffer_info->skb; - length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); - - skb_put(skb, length - ETHERNET_FCS_SIZE); - - /* Receive Checksum Offload */ - atl1_rx_checksum(adapter, rrd, skb); - skb->protocol = eth_type_trans(skb, adapter->netdev); - - if (adapter->vlgrp && (rrd->pkt_flg & PACKET_FLAG_VLAN_INS)) { - u16 vlan_tag = (rrd->vlan_tag >> 4) | - ((rrd->vlan_tag & 7) << 13) | - ((rrd->vlan_tag & 8) << 9); - vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag); - } else - netif_rx(skb); - - /* let protocol layer free skb */ - buffer_info->skb = NULL; - buffer_info->alloced = 0; - rrd->xsz.valid = 0; - - adapter->netdev->last_rx = jiffies; - } - - atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean); - - atl1_alloc_rx_buffers(adapter); - - /* update mailbox ? */ - if (count) { - u32 tpd_next_to_use; - u32 rfd_next_to_use; - u32 rrd_next_to_clean; - - spin_lock(&adapter->mb_lock); - - tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use); - rfd_next_to_use = - atomic_read(&adapter->rfd_ring.next_to_use); - rrd_next_to_clean = - atomic_read(&adapter->rrd_ring.next_to_clean); - value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) << - MB_RFD_PROD_INDX_SHIFT) | - ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) << - MB_RRD_CONS_INDX_SHIFT) | - ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) << - MB_TPD_PROD_INDX_SHIFT); - iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX); - spin_unlock(&adapter->mb_lock); - } -} - -static void atl1_intr_tx(struct atl1_adapter *adapter) -{ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_buffer *buffer_info; - u16 sw_tpd_next_to_clean; - u16 cmb_tpd_next_to_clean; - u8 update = 0; - - sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean); - cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx); - - while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) { - struct tx_packet_desc *tpd; - update = 1; - tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean); - buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean]; - if (buffer_info->dma) { - pci_unmap_page(adapter->pdev, buffer_info->dma, - buffer_info->length, PCI_DMA_TODEVICE); - buffer_info->dma = 0; - } - - if (buffer_info->skb) { - dev_kfree_skb_irq(buffer_info->skb); - buffer_info->skb = NULL; - } - tpd->buffer_addr = 0; - tpd->desc.data = 0; - - if (++sw_tpd_next_to_clean == tpd_ring->count) - sw_tpd_next_to_clean = 0; - } - atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean); - - if (netif_queue_stopped(adapter->netdev) - && netif_carrier_ok(adapter->netdev)) - netif_wake_queue(adapter->netdev); -} - -static void atl1_check_for_link(struct atl1_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - u16 phy_data = 0; - - spin_lock(&adapter->lock); - adapter->phy_timer_pending = false; - atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); - atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); - spin_unlock(&adapter->lock); - - /* notify upper layer link down ASAP */ - if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */ - if (netif_carrier_ok(netdev)) { /* old link state: Up */ - printk(KERN_INFO "%s: %s link is down\n", - atl1_driver_name, netdev->name); - adapter->link_speed = SPEED_0; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - } - schedule_work(&adapter->link_chg_task); -} - -/* - * atl1_intr - Interrupt Handler - * @irq: interrupt number - * @data: pointer to a network interface device structure - * @pt_regs: CPU registers structure - */ -static irqreturn_t atl1_intr(int irq, void *data) -{ - /*struct atl1_adapter *adapter = ((struct net_device *)data)->priv;*/ - struct atl1_adapter *adapter = netdev_priv(data); - u32 status; - u8 update_rx; - int max_ints = 10; - - status = adapter->cmb.cmb->int_stats; - if (!status) - return IRQ_NONE; - - update_rx = 0; - - do { - /* clear CMB interrupt status at once */ - adapter->cmb.cmb->int_stats = 0; - - if (status & ISR_GPHY) /* clear phy status */ - atl1_clear_phy_int(adapter); - - /* clear ISR status, and Enable CMB DMA/Disable Interrupt */ - iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR); - - /* check if SMB intr */ - if (status & ISR_SMB) - atl1_inc_smb(adapter); - - /* check if PCIE PHY Link down */ - if (status & ISR_PHY_LINKDOWN) { - printk(KERN_DEBUG "%s: pcie phy link down %x\n", - atl1_driver_name, status); - if (netif_running(adapter->netdev)) { /* reset MAC */ - iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->pcie_dma_to_rst_task); - return IRQ_HANDLED; - } - } - - /* check if DMA read/write error ? */ - if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) { - printk(KERN_DEBUG - "%s: pcie DMA r/w error (status = 0x%x)\n", - atl1_driver_name, status); - iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->pcie_dma_to_rst_task); - return IRQ_HANDLED; - } - - /* link event */ - if (status & ISR_GPHY) { - adapter->soft_stats.tx_carrier_errors++; - atl1_check_for_link(adapter); - } - - /* transmit event */ - if (status & ISR_CMB_TX) - atl1_intr_tx(adapter); - - /* rx exception */ - if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | - ISR_RRD_OV | ISR_HOST_RFD_UNRUN | - ISR_HOST_RRD_OV | ISR_CMB_RX))) { - if (status & - (ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV | - ISR_HOST_RFD_UNRUN | ISR_HOST_RRD_OV)) - printk(KERN_INFO - "%s: rx exception: status = 0x%x\n", - atl1_driver_name, status); - atl1_intr_rx(adapter); - } - - if (--max_ints < 0) - break; - - } while ((status = adapter->cmb.cmb->int_stats)); - - /* re-enable Interrupt */ - iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR); - return IRQ_HANDLED; -} - -/* - * atl1_set_multi - Multicast and Promiscuous mode set - * @netdev: network interface device structure - * - * The set_multi entry point is called whenever the multicast address - * list or the network interface flags are updated. This routine is - * responsible for configuring the hardware for proper multicast, - * promiscuous mode, and all-multi behavior. - */ -static void atl1_set_multi(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - struct dev_mc_list *mc_ptr; - u32 rctl; - u32 hash_value; - - /* Check for Promiscuous and All Multicast modes */ - rctl = ioread32(hw->hw_addr + REG_MAC_CTRL); - if (netdev->flags & IFF_PROMISC) - rctl |= MAC_CTRL_PROMIS_EN; - else if (netdev->flags & IFF_ALLMULTI) { - rctl |= MAC_CTRL_MC_ALL_EN; - rctl &= ~MAC_CTRL_PROMIS_EN; - } else - rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN); - - iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL); - - /* clear the old settings from the multicast hash table */ - iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE); - iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2)); - - /* compute mc addresses' hash value ,and put it into hash table */ - for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { - hash_value = atl1_hash_mc_addr(hw, mc_ptr->dmi_addr); - atl1_hash_set(hw, hash_value); - } -} - -static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter) -{ - u32 value; - struct atl1_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - /* Config MAC CTRL Register */ - value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN; - /* duplex */ - if (FULL_DUPLEX == adapter->link_duplex) - value |= MAC_CTRL_DUPLX; - /* speed */ - value |= ((u32) ((SPEED_1000 == adapter->link_speed) ? - MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) << - MAC_CTRL_SPEED_SHIFT); - /* flow control */ - value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW); - /* PAD & CRC */ - value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); - /* preamble length */ - value |= (((u32) adapter->hw.preamble_len - & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - /* vlan */ - if (adapter->vlgrp) - value |= MAC_CTRL_RMV_VLAN; - /* rx checksum - if (adapter->rx_csum) - value |= MAC_CTRL_RX_CHKSUM_EN; - */ - /* filter mode */ - value |= MAC_CTRL_BC_EN; - if (netdev->flags & IFF_PROMISC) - value |= MAC_CTRL_PROMIS_EN; - else if (netdev->flags & IFF_ALLMULTI) - value |= MAC_CTRL_MC_ALL_EN; - /* value |= MAC_CTRL_LOOPBACK; */ - iowrite32(value, hw->hw_addr + REG_MAC_CTRL); -} - -static u32 atl1_check_link(struct atl1_adapter *adapter) -{ - struct atl1_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - u32 ret_val; - u16 speed, duplex, phy_data; - int reconfig = 0; - - /* MII_BMSR must read twice */ - atl1_read_phy_reg(hw, MII_BMSR, &phy_data); - atl1_read_phy_reg(hw, MII_BMSR, &phy_data); - if (!(phy_data & BMSR_LSTATUS)) { /* link down */ - if (netif_carrier_ok(netdev)) { /* old link state: Up */ - printk(KERN_INFO "%s: link is down\n", - atl1_driver_name); - adapter->link_speed = SPEED_0; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - return ATL1_SUCCESS; - } - - /* Link Up */ - ret_val = atl1_get_speed_and_duplex(hw, &speed, &duplex); - if (ret_val) - return ret_val; - - switch (hw->media_type) { - case MEDIA_TYPE_1000M_FULL: - if (speed != SPEED_1000 || duplex != FULL_DUPLEX) - reconfig = 1; - break; - case MEDIA_TYPE_100M_FULL: - if (speed != SPEED_100 || duplex != FULL_DUPLEX) - reconfig = 1; - break; - case MEDIA_TYPE_100M_HALF: - if (speed != SPEED_100 || duplex != HALF_DUPLEX) - reconfig = 1; - break; - case MEDIA_TYPE_10M_FULL: - if (speed != SPEED_10 || duplex != FULL_DUPLEX) - reconfig = 1; - break; - case MEDIA_TYPE_10M_HALF: - if (speed != SPEED_10 || duplex != HALF_DUPLEX) - reconfig = 1; - break; - } - - /* link result is our setting */ - if (!reconfig) { - if (adapter->link_speed != speed - || adapter->link_duplex != duplex) { - adapter->link_speed = speed; - adapter->link_duplex = duplex; - atl1_setup_mac_ctrl(adapter); - printk(KERN_INFO "%s: %s link is up %d Mbps %s\n", - atl1_driver_name, netdev->name, - adapter->link_speed, - adapter->link_duplex == - FULL_DUPLEX ? "full duplex" : "half duplex"); - } - if (!netif_carrier_ok(netdev)) { /* Link down -> Up */ - netif_carrier_on(netdev); - netif_wake_queue(netdev); - } - return ATL1_SUCCESS; - } - - /* change orignal link status */ - if (netif_carrier_ok(netdev)) { - adapter->link_speed = SPEED_0; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - - if (hw->media_type != MEDIA_TYPE_AUTO_SENSOR && - hw->media_type != MEDIA_TYPE_1000M_FULL) { - switch (hw->media_type) { - case MEDIA_TYPE_100M_FULL: - phy_data = MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 | - MII_CR_RESET; - break; - case MEDIA_TYPE_100M_HALF: - phy_data = MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_10M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET; - break; - default: /* MEDIA_TYPE_10M_HALF: */ - phy_data = MII_CR_SPEED_10 | MII_CR_RESET; - break; - } - atl1_write_phy_reg(hw, MII_BMCR, phy_data); - return ATL1_SUCCESS; - } - - /* auto-neg, insert timer to re-config phy */ - if (!adapter->phy_timer_pending) { - adapter->phy_timer_pending = true; - mod_timer(&adapter->phy_config_timer, jiffies + 3 * HZ); - } - - return ATL1_SUCCESS; -} - -static void set_flow_ctrl_old(struct atl1_adapter *adapter) -{ - u32 hi, lo, value; - - /* RFD Flow Control */ - value = adapter->rfd_ring.count; - hi = value / 16; - if (hi < 2) - hi = 2; - lo = value * 7 / 8; - - value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) | - ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT); - iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RXF_PAUSE_THRESH); - - /* RRD Flow Control */ - value = adapter->rrd_ring.count; - lo = value / 16; - hi = value * 7 / 8; - if (lo < 2) - lo = 2; - value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) | - ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT); - iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RRD_PAUSE_THRESH); -} - -static void set_flow_ctrl_new(struct atl1_hw *hw) -{ - u32 hi, lo, value; - - /* RXF Flow Control */ - value = ioread32(hw->hw_addr + REG_SRAM_RXF_LEN); - lo = value / 16; - if (lo < 192) - lo = 192; - hi = value * 7 / 8; - if (hi < lo) - hi = lo + 16; - value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) | - ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT); - iowrite32(value, hw->hw_addr + REG_RXQ_RXF_PAUSE_THRESH); - - /* RRD Flow Control */ - value = ioread32(hw->hw_addr + REG_SRAM_RRD_LEN); - lo = value / 8; - hi = value * 7 / 8; - if (lo < 2) - lo = 2; - if (hi < lo) - hi = lo + 3; - value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) | - ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT); - iowrite32(value, hw->hw_addr + REG_RXQ_RRD_PAUSE_THRESH); -} - -/* - * atl1_configure - Configure Transmit&Receive Unit after Reset - * @adapter: board private structure - * - * Configure the Tx /Rx unit of the MAC after a reset. - */ -static u32 atl1_configure(struct atl1_adapter *adapter) -{ - struct atl1_hw *hw = &adapter->hw; - u32 value; - - /* clear interrupt status */ - iowrite32(0xffffffff, adapter->hw.hw_addr + REG_ISR); - - /* set MAC Address */ - value = (((u32) hw->mac_addr[2]) << 24) | - (((u32) hw->mac_addr[3]) << 16) | - (((u32) hw->mac_addr[4]) << 8) | - (((u32) hw->mac_addr[5])); - iowrite32(value, hw->hw_addr + REG_MAC_STA_ADDR); - value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1])); - iowrite32(value, hw->hw_addr + (REG_MAC_STA_ADDR + 4)); - - /* tx / rx ring */ - - /* HI base address */ - iowrite32((u32) ((adapter->tpd_ring.dma & 0xffffffff00000000ULL) >> 32), - hw->hw_addr + REG_DESC_BASE_ADDR_HI); - /* LO base address */ - iowrite32((u32) (adapter->rfd_ring.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_RFD_ADDR_LO); - iowrite32((u32) (adapter->rrd_ring.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_RRD_ADDR_LO); - iowrite32((u32) (adapter->tpd_ring.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_TPD_ADDR_LO); - iowrite32((u32) (adapter->cmb.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_CMB_ADDR_LO); - iowrite32((u32) (adapter->smb.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_SMB_ADDR_LO); - - /* element count */ - value = adapter->rrd_ring.count; - value <<= 16; - value += adapter->rfd_ring.count; - iowrite32(value, hw->hw_addr + REG_DESC_RFD_RRD_RING_SIZE); - iowrite32(adapter->tpd_ring.count, hw->hw_addr + REG_DESC_TPD_RING_SIZE); - - /* Load Ptr */ - iowrite32(1, hw->hw_addr + REG_LOAD_PTR); - - /* config Mailbox */ - value = ((atomic_read(&adapter->tpd_ring.next_to_use) - & MB_TPD_PROD_INDX_MASK) << MB_TPD_PROD_INDX_SHIFT) | - ((atomic_read(&adapter->rrd_ring.next_to_clean) - & MB_RRD_CONS_INDX_MASK) << MB_RRD_CONS_INDX_SHIFT) | - ((atomic_read(&adapter->rfd_ring.next_to_use) - & MB_RFD_PROD_INDX_MASK) << MB_RFD_PROD_INDX_SHIFT); - iowrite32(value, hw->hw_addr + REG_MAILBOX); - - /* config IPG/IFG */ - value = (((u32) hw->ipgt & MAC_IPG_IFG_IPGT_MASK) - << MAC_IPG_IFG_IPGT_SHIFT) | - (((u32) hw->min_ifg & MAC_IPG_IFG_MIFG_MASK) - << MAC_IPG_IFG_MIFG_SHIFT) | - (((u32) hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK) - << MAC_IPG_IFG_IPGR1_SHIFT) | - (((u32) hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK) - << MAC_IPG_IFG_IPGR2_SHIFT); - iowrite32(value, hw->hw_addr + REG_MAC_IPG_IFG); - - /* config Half-Duplex Control */ - value = ((u32) hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) | - (((u32) hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK) - << MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) | - MAC_HALF_DUPLX_CTRL_EXC_DEF_EN | - (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) | - (((u32) hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK) - << MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT); - iowrite32(value, hw->hw_addr + REG_MAC_HALF_DUPLX_CTRL); - - /* set Interrupt Moderator Timer */ - iowrite16(adapter->imt, hw->hw_addr + REG_IRQ_MODU_TIMER_INIT); - iowrite32(MASTER_CTRL_ITIMER_EN, hw->hw_addr + REG_MASTER_CTRL); - - /* set Interrupt Clear Timer */ - iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER); - - /* set MTU, 4 : VLAN */ - iowrite32(hw->max_frame_size + 4, hw->hw_addr + REG_MTU); - - /* jumbo size & rrd retirement timer */ - value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK) - << RXQ_JMBOSZ_TH_SHIFT) | - (((u32) hw->rx_jumbo_lkah & RXQ_JMBO_LKAH_MASK) - << RXQ_JMBO_LKAH_SHIFT) | - (((u32) hw->rrd_ret_timer & RXQ_RRD_TIMER_MASK) - << RXQ_RRD_TIMER_SHIFT); - iowrite32(value, hw->hw_addr + REG_RXQ_JMBOSZ_RRDTIM); - - /* Flow Control */ - switch (hw->dev_rev) { - case 0x8001: - case 0x9001: - case 0x9002: - case 0x9003: - set_flow_ctrl_old(adapter); - break; - default: - set_flow_ctrl_new(hw); - break; - } - - /* config TXQ */ - value = (((u32) hw->tpd_burst & TXQ_CTRL_TPD_BURST_NUM_MASK) - << TXQ_CTRL_TPD_BURST_NUM_SHIFT) | - (((u32) hw->txf_burst & TXQ_CTRL_TXF_BURST_NUM_MASK) - << TXQ_CTRL_TXF_BURST_NUM_SHIFT) | - (((u32) hw->tpd_fetch_th & TXQ_CTRL_TPD_FETCH_TH_MASK) - << TXQ_CTRL_TPD_FETCH_TH_SHIFT) | TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN; - iowrite32(value, hw->hw_addr + REG_TXQ_CTRL); - - /* min tpd fetch gap & tx jumbo packet size threshold for taskoffload */ - value = (((u32) hw->tx_jumbo_task_th & TX_JUMBO_TASK_TH_MASK) - << TX_JUMBO_TASK_TH_SHIFT) | - (((u32) hw->tpd_fetch_gap & TX_TPD_MIN_IPG_MASK) - << TX_TPD_MIN_IPG_SHIFT); - iowrite32(value, hw->hw_addr + REG_TX_JUMBO_TASK_TH_TPD_IPG); - - /* config RXQ */ - value = (((u32) hw->rfd_burst & RXQ_CTRL_RFD_BURST_NUM_MASK) - << RXQ_CTRL_RFD_BURST_NUM_SHIFT) | - (((u32) hw->rrd_burst & RXQ_CTRL_RRD_BURST_THRESH_MASK) - << RXQ_CTRL_RRD_BURST_THRESH_SHIFT) | - (((u32) hw->rfd_fetch_gap & RXQ_CTRL_RFD_PREF_MIN_IPG_MASK) - << RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT) | - RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN; - iowrite32(value, hw->hw_addr + REG_RXQ_CTRL); - - /* config DMA Engine */ - value = ((((u32) hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK) - << DMA_CTRL_DMAR_BURST_LEN_SHIFT) | - ((((u32) hw->dmaw_block) & DMA_CTRL_DMAR_BURST_LEN_MASK) - << DMA_CTRL_DMAR_BURST_LEN_SHIFT) | - DMA_CTRL_DMAR_EN | DMA_CTRL_DMAW_EN; - value |= (u32) hw->dma_ord; - if (atl1_rcb_128 == hw->rcb_value) - value |= DMA_CTRL_RCB_VALUE; - iowrite32(value, hw->hw_addr + REG_DMA_CTRL); - - /* config CMB / SMB */ - value = hw->cmb_rrd | ((u32) hw->cmb_tpd << 16); - iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TH); - value = hw->cmb_rx_timer | ((u32) hw->cmb_tx_timer << 16); - iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TIMER); - iowrite32(hw->smb_timer, hw->hw_addr + REG_SMB_TIMER); - - /* --- enable CMB / SMB */ - value = CSMB_CTRL_CMB_EN | CSMB_CTRL_SMB_EN; - iowrite32(value, hw->hw_addr + REG_CSMB_CTRL); - - value = ioread32(adapter->hw.hw_addr + REG_ISR); - if (unlikely((value & ISR_PHY_LINKDOWN) != 0)) - value = 1; /* config failed */ - else - value = 0; - - /* clear all interrupt status */ - iowrite32(0x3fffffff, adapter->hw.hw_addr + REG_ISR); - iowrite32(0, adapter->hw.hw_addr + REG_ISR); - return value; -} - -/* - * atl1_irq_disable - Mask off interrupt generation on the NIC - * @adapter: board private structure - */ -static void atl1_irq_disable(struct atl1_adapter *adapter) -{ - atomic_inc(&adapter->irq_sem); - iowrite32(0, adapter->hw.hw_addr + REG_IMR); - ioread32(adapter->hw.hw_addr + REG_IMR); - synchronize_irq(adapter->pdev->irq); -} - -static void atl1_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - u32 ctrl; - - spin_lock_irqsave(&adapter->lock, flags); - /* atl1_irq_disable(adapter); */ - adapter->vlgrp = grp; - - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); - ctrl |= MAC_CTRL_RMV_VLAN; - iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); - } else { - /* disable VLAN tag insert/strip */ - ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_RMV_VLAN; - iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); - } - - /* atl1_irq_enable(adapter); */ - spin_unlock_irqrestore(&adapter->lock, flags); -} - -/* FIXME: justify or remove -- CHS */ -static void atl1_vlan_rx_add_vid(struct net_device *netdev, u16 vid) -{ - /* We don't do Vlan filtering */ - return; -} - -/* FIXME: this looks wrong too -- CHS */ -static void atl1_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - - spin_lock_irqsave(&adapter->lock, flags); - /* atl1_irq_disable(adapter); */ - if (adapter->vlgrp) - adapter->vlgrp->vlan_devices[vid] = NULL; - /* atl1_irq_enable(adapter); */ - spin_unlock_irqrestore(&adapter->lock, flags); - /* We don't do Vlan filtering */ - return; -} - -static void atl1_restore_vlan(struct atl1_adapter *adapter) -{ - atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp); - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { - if (!adapter->vlgrp->vlan_devices[vid]) - continue; - atl1_vlan_rx_add_vid(adapter->netdev, vid); - } - } -} - -static u16 tpd_avail(struct atl1_tpd_ring *tpd_ring) -{ - u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); - u16 next_to_use = atomic_read(&tpd_ring->next_to_use); - return ((next_to_clean > - next_to_use) ? next_to_clean - next_to_use - - 1 : tpd_ring->count + next_to_clean - next_to_use - 1); -} - -static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, - struct tso_param *tso) -{ - /* We enter this function holding a spinlock. */ - u8 ipofst; - int err; - - if (skb_shinfo(skb)->gso_size) { - if (skb_header_cloned(skb)) { - err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); - if (unlikely(err)) - return err; - } - - if (skb->protocol == ntohs(ETH_P_IP)) { - skb->nh.iph->tot_len = 0; - skb->nh.iph->check = 0; - skb->h.th->check = - ~csum_tcpudp_magic(skb->nh.iph->saddr, - skb->nh.iph->daddr, 0, - IPPROTO_TCP, 0); - ipofst = skb->nh.raw - skb->data; - if (ipofst != ENET_HEADER_SIZE) /* 802.3 frame */ - tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT; - - tso->tsopl |= (skb->nh.iph->ihl & - CSUM_PARAM_IPHL_MASK) << CSUM_PARAM_IPHL_SHIFT; - tso->tsopl |= ((skb->h.th->doff << 2) & - TSO_PARAM_TCPHDRLEN_MASK) << TSO_PARAM_TCPHDRLEN_SHIFT; - tso->tsopl |= (skb_shinfo(skb)->gso_size & - TSO_PARAM_MSS_MASK) << TSO_PARAM_MSS_SHIFT; - tso->tsopl |= 1 << TSO_PARAM_IPCKSUM_SHIFT; - tso->tsopl |= 1 << TSO_PARAM_TCPCKSUM_SHIFT; - tso->tsopl |= 1 << TSO_PARAM_SEGMENT_SHIFT; - return true; - } - } - return false; -} - -static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, - struct csum_param *csum) -{ - u8 css, cso; - - if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { - cso = skb->h.raw - skb->data; - css = (skb->h.raw + skb->csum) - skb->data; - if (unlikely(cso & 0x1)) { - printk(KERN_DEBUG "%s: payload offset != even number\n", - atl1_driver_name); - return -1; - } - csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) << - CSUM_PARAM_PLOADOFFSET_SHIFT; - csum->csumpl |= (css & CSUM_PARAM_XSUMOFFSET_MASK) << - CSUM_PARAM_XSUMOFFSET_SHIFT; - csum->csumpl |= 1 << CSUM_PARAM_CUSTOMCKSUM_SHIFT; - return true; - } - - return true; -} - -static void atl1_tx_map(struct atl1_adapter *adapter, - struct sk_buff *skb, bool tcp_seg) -{ - /* We enter this function holding a spinlock. */ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_buffer *buffer_info; - struct page *page; - int first_buf_len = skb->len; - unsigned long offset; - unsigned int nr_frags; - unsigned int f; - u16 tpd_next_to_use; - u16 proto_hdr_len; - u16 i, m, len12; - - first_buf_len -= skb->data_len; - nr_frags = skb_shinfo(skb)->nr_frags; - tpd_next_to_use = atomic_read(&tpd_ring->next_to_use); - buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; - if (unlikely(buffer_info->skb)) - BUG(); - buffer_info->skb = NULL; /* put skb in last TPD */ - - if (tcp_seg) { - /* TSO/GSO */ - proto_hdr_len = - ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - buffer_info->length = proto_hdr_len; - page = virt_to_page(skb->data); - offset = (unsigned long)skb->data & ~PAGE_MASK; - buffer_info->dma = pci_map_page(adapter->pdev, page, - offset, proto_hdr_len, - PCI_DMA_TODEVICE); - - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - - if (first_buf_len > proto_hdr_len) { - len12 = first_buf_len - proto_hdr_len; - m = (len12 + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; - for (i = 0; i < m; i++) { - buffer_info = - &tpd_ring->buffer_info[tpd_next_to_use]; - buffer_info->skb = NULL; - buffer_info->length = - (MAX_TX_BUF_LEN >= - len12) ? MAX_TX_BUF_LEN : len12; - len12 -= buffer_info->length; - page = virt_to_page(skb->data + - (proto_hdr_len + - i * MAX_TX_BUF_LEN)); - offset = (unsigned long)(skb->data + - (proto_hdr_len + - i * MAX_TX_BUF_LEN)) & - ~PAGE_MASK; - buffer_info->dma = - pci_map_page(adapter->pdev, page, offset, - buffer_info->length, - PCI_DMA_TODEVICE); - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - } - } - } else { - /* not TSO/GSO */ - buffer_info->length = first_buf_len; - page = virt_to_page(skb->data); - offset = (unsigned long)skb->data & ~PAGE_MASK; - buffer_info->dma = pci_map_page(adapter->pdev, page, - offset, first_buf_len, - PCI_DMA_TODEVICE); - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - } - - for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; - u16 lenf, i, m; - - frag = &skb_shinfo(skb)->frags[f]; - lenf = frag->size; - - m = (lenf + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; - for (i = 0; i < m; i++) { - buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; - if (unlikely(buffer_info->skb)) - BUG(); - buffer_info->skb = NULL; - buffer_info->length = - (lenf > MAX_TX_BUF_LEN) ? MAX_TX_BUF_LEN : lenf; - lenf -= buffer_info->length; - buffer_info->dma = - pci_map_page(adapter->pdev, frag->page, - frag->page_offset + i * MAX_TX_BUF_LEN, - buffer_info->length, PCI_DMA_TODEVICE); - - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - } - } - - /* last tpd's buffer-info */ - buffer_info->skb = skb; -} - -static void atl1_tx_queue(struct atl1_adapter *adapter, int count, - union tpd_descr *descr) -{ - /* We enter this function holding a spinlock. */ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - int j; - u32 val; - struct atl1_buffer *buffer_info; - struct tx_packet_desc *tpd; - u16 tpd_next_to_use = atomic_read(&tpd_ring->next_to_use); - - for (j = 0; j < count; j++) { - buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; - tpd = ATL1_TPD_DESC(&adapter->tpd_ring, tpd_next_to_use); - tpd->desc.csum.csumpu = descr->csum.csumpu; - tpd->desc.csum.csumpl = descr->csum.csumpl; - tpd->desc.tso.tsopu = descr->tso.tsopu; - tpd->desc.tso.tsopl = descr->tso.tsopl; - tpd->buffer_addr = cpu_to_le64(buffer_info->dma); - tpd->desc.data = descr->data; - tpd->desc.csum.csumpu |= (cpu_to_le16(buffer_info->length) & - CSUM_PARAM_BUFLEN_MASK) << CSUM_PARAM_BUFLEN_SHIFT; - - val = (descr->tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) & - TSO_PARAM_SEGMENT_MASK; - if (val && !j) - tpd->desc.tso.tsopl |= 1 << TSO_PARAM_HDRFLAG_SHIFT; - - if (j == (count - 1)) - tpd->desc.csum.csumpl |= 1 << CSUM_PARAM_EOP_SHIFT; - - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - } - /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). - */ - wmb(); - - atomic_set(&tpd_ring->next_to_use, (int)tpd_next_to_use); -} - -static void atl1_update_mailbox(struct atl1_adapter *adapter) -{ - unsigned long flags; - u32 tpd_next_to_use; - u32 rfd_next_to_use; - u32 rrd_next_to_clean; - u32 value; - - spin_lock_irqsave(&adapter->mb_lock, flags); - - tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use); - rfd_next_to_use = atomic_read(&adapter->rfd_ring.next_to_use); - rrd_next_to_clean = atomic_read(&adapter->rrd_ring.next_to_clean); - - value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) << - MB_RFD_PROD_INDX_SHIFT) | - ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) << - MB_RRD_CONS_INDX_SHIFT) | - ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) << - MB_TPD_PROD_INDX_SHIFT); - iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX); - - spin_unlock_irqrestore(&adapter->mb_lock, flags); -} - -static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - int len = skb->len; - int tso; - int count = 1; - int ret_val; - u32 val; - union tpd_descr param; - u16 frag_size; - u16 vlan_tag; - unsigned long flags; - unsigned int nr_frags = 0; - unsigned int mss = 0; - unsigned int f; - unsigned int proto_hdr_len; - - len -= skb->data_len; - - if (unlikely(skb->len == 0)) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - - param.data = 0; - param.tso.tsopu = 0; - param.tso.tsopl = 0; - param.csum.csumpu = 0; - param.csum.csumpl = 0; - - /* nr_frags will be nonzero if we're doing scatter/gather (SG) */ - nr_frags = skb_shinfo(skb)->nr_frags; - for (f = 0; f < nr_frags; f++) { - frag_size = skb_shinfo(skb)->frags[f].size; - if (frag_size) - count += - (frag_size + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; - } - - /* mss will be nonzero if we're doing segment offload (TSO/GSO) */ - mss = skb_shinfo(skb)->gso_size; - if (mss) { - if (skb->protocol == ntohs(ETH_P_IP)) { - proto_hdr_len = ((skb->h.raw - skb->data) + - (skb->h.th->doff << 2)); - if (unlikely(proto_hdr_len > len)) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - /* need additional TPD ? */ - if (proto_hdr_len != len) - count += (len - proto_hdr_len + - MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; - } - } - - local_irq_save(flags); - if (!spin_trylock(&adapter->lock)) { - /* Can't get lock - tell upper layer to requeue */ - local_irq_restore(flags); - printk(KERN_DEBUG "%s: TX locked\n", atl1_driver_name); - return NETDEV_TX_LOCKED; - } - - if (tpd_avail(&adapter->tpd_ring) < count) { - /* not enough descriptors */ - netif_stop_queue(netdev); - spin_unlock_irqrestore(&adapter->lock, flags); - printk(KERN_DEBUG "%s: TX busy\n", atl1_driver_name); - return NETDEV_TX_BUSY; - } - - param.data = 0; - - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { - vlan_tag = vlan_tx_tag_get(skb); - vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | - ((vlan_tag >> 9) & 0x8); - param.csum.csumpl |= 1 << CSUM_PARAM_INSVLAG_SHIFT; - param.csum.csumpu |= (vlan_tag & CSUM_PARAM_VALANTAG_MASK) << - CSUM_PARAM_VALAN_SHIFT; - } - - tso = atl1_tso(adapter, skb, ¶m.tso); - if (tso < 0) { - spin_unlock_irqrestore(&adapter->lock, flags); - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - - if (!tso) { - ret_val = atl1_tx_csum(adapter, skb, ¶m.csum); - if (ret_val < 0) { - spin_unlock_irqrestore(&adapter->lock, flags); - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - } - - val = (param.csum.csumpl >> CSUM_PARAM_SEGMENT_SHIFT) & - CSUM_PARAM_SEGMENT_MASK; - atl1_tx_map(adapter, skb, 1 == val); - atl1_tx_queue(adapter, count, ¶m); - netdev->trans_start = jiffies; - spin_unlock_irqrestore(&adapter->lock, flags); - atl1_update_mailbox(adapter); - return NETDEV_TX_OK; -} - -/* - * atl1_get_stats - Get System Network Statistics - * @netdev: network interface device structure - * - * Returns the address of the device statistics structure. - * The statistics are actually updated from the timer callback. - */ -static struct net_device_stats *atl1_get_stats(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - return &adapter->net_stats; -} - -/* - * atl1_clean_rx_ring - Free RFD Buffers - * @adapter: board private structure - */ -static void atl1_clean_rx_ring(struct atl1_adapter *adapter) -{ - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring; - struct atl1_buffer *buffer_info; - struct pci_dev *pdev = adapter->pdev; - unsigned long size; - unsigned int i; - - /* Free all the Rx ring sk_buffs */ - for (i = 0; i < rfd_ring->count; i++) { - buffer_info = &rfd_ring->buffer_info[i]; - if (buffer_info->dma) { - pci_unmap_page(pdev, - buffer_info->dma, - buffer_info->length, - PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; - } - if (buffer_info->skb) { - dev_kfree_skb(buffer_info->skb); - buffer_info->skb = NULL; - } - } - - size = sizeof(struct atl1_buffer) * rfd_ring->count; - memset(rfd_ring->buffer_info, 0, size); - - /* Zero out the descriptor ring */ - memset(rfd_ring->desc, 0, rfd_ring->size); - - rfd_ring->next_to_clean = 0; - atomic_set(&rfd_ring->next_to_use, 0); - - rrd_ring->next_to_use = 0; - atomic_set(&rrd_ring->next_to_clean, 0); -} - -/* - * atl1_clean_tx_ring - Free Tx Buffers - * @adapter: board private structure - */ -static void atl1_clean_tx_ring(struct atl1_adapter *adapter) -{ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_buffer *buffer_info; - struct pci_dev *pdev = adapter->pdev; - unsigned long size; - unsigned int i; - - /* Free all the Tx ring sk_buffs */ - for (i = 0; i < tpd_ring->count; i++) { - buffer_info = &tpd_ring->buffer_info[i]; - if (buffer_info->dma) { - pci_unmap_page(pdev, buffer_info->dma, - buffer_info->length, PCI_DMA_TODEVICE); - buffer_info->dma = 0; - } - } - - for (i = 0; i < tpd_ring->count; i++) { - buffer_info = &tpd_ring->buffer_info[i]; - if (buffer_info->skb) { - dev_kfree_skb_any(buffer_info->skb); - buffer_info->skb = NULL; - } - } - - size = sizeof(struct atl1_buffer) * tpd_ring->count; - memset(tpd_ring->buffer_info, 0, size); - - /* Zero out the descriptor ring */ - memset(tpd_ring->desc, 0, tpd_ring->size); - - atomic_set(&tpd_ring->next_to_use, 0); - atomic_set(&tpd_ring->next_to_clean, 0); -} - -/* - * atl1_free_ring_resources - Free Tx / RX descriptor Resources - * @adapter: board private structure - * - * Free all transmit software resources - */ -void atl1_free_ring_resources(struct atl1_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring; - struct atl1_ring_header *ring_header = &adapter->ring_header; - - atl1_clean_tx_ring(adapter); - atl1_clean_rx_ring(adapter); - - kfree(tpd_ring->buffer_info); - pci_free_consistent(pdev, ring_header->size, ring_header->desc, - ring_header->dma); - - tpd_ring->buffer_info = NULL; - tpd_ring->desc = NULL; - tpd_ring->dma = 0; - - rfd_ring->buffer_info = NULL; - rfd_ring->desc = NULL; - rfd_ring->dma = 0; - - rrd_ring->desc = NULL; - rrd_ring->dma = 0; -} - -s32 atl1_up(struct atl1_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - int err; - int irq_flags = IRQF_SAMPLE_RANDOM; - - /* hardware has been reset, we need to reload some things */ - atl1_set_multi(netdev); - atl1_restore_vlan(adapter); - err = atl1_alloc_rx_buffers(adapter); - if (unlikely(!err)) /* no RX BUFFER allocated */ - return -ENOMEM; - - if (unlikely(atl1_configure(adapter))) { - err = -EIO; - goto err_up; - } - - err = pci_enable_msi(adapter->pdev); - if (err) { - dev_info(&adapter->pdev->dev, - "Unable to enable MSI: %d\n", err); - irq_flags |= IRQF_SHARED; - } - - err = request_irq(adapter->pdev->irq, &atl1_intr, irq_flags, - netdev->name, netdev); - if (unlikely(err)) - goto err_up; - - mod_timer(&adapter->watchdog_timer, jiffies); - atl1_irq_enable(adapter); - atl1_check_link(adapter); - return 0; - - /* FIXME: unreachable code! -- CHS */ - /* free irq disable any interrupt */ - iowrite32(0, adapter->hw.hw_addr + REG_IMR); - free_irq(adapter->pdev->irq, netdev); - -err_up: - pci_disable_msi(adapter->pdev); - /* free rx_buffers */ - atl1_clean_rx_ring(adapter); - return err; -} - -void atl1_down(struct atl1_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - - del_timer_sync(&adapter->watchdog_timer); - del_timer_sync(&adapter->phy_config_timer); - adapter->phy_timer_pending = false; - - atl1_irq_disable(adapter); - free_irq(adapter->pdev->irq, netdev); - pci_disable_msi(adapter->pdev); - atl1_reset_hw(&adapter->hw); - adapter->cmb.cmb->int_stats = 0; - - adapter->link_speed = SPEED_0; - adapter->link_duplex = -1; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - - atl1_clean_tx_ring(adapter); - atl1_clean_rx_ring(adapter); -} - -/* - * atl1_change_mtu - Change the Maximum Transfer Unit - * @netdev: network interface device structure - * @new_mtu: new value for maximum frame size - * - * Returns 0 on success, negative on failure - */ -static int atl1_change_mtu(struct net_device *netdev, int new_mtu) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - int old_mtu = netdev->mtu; - int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - - if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || - (max_frame > MAX_JUMBO_FRAME_SIZE)) { - printk(KERN_WARNING "%s: invalid MTU setting\n", - atl1_driver_name); - return -EINVAL; - } - - adapter->hw.max_frame_size = max_frame; - adapter->hw.tx_jumbo_task_th = (max_frame + 7) >> 3; - adapter->rx_buffer_len = (max_frame + 7) & ~7; - adapter->hw.rx_jumbo_th = adapter->rx_buffer_len / 8; - - netdev->mtu = new_mtu; - if ((old_mtu != new_mtu) && netif_running(netdev)) { - atl1_down(adapter); - atl1_up(adapter); - } - - return 0; -} - -/* - * atl1_set_mac - Change the Ethernet Address of the NIC - * @netdev: network interface device structure - * @p: pointer to an address structure - * - * Returns 0 on success, negative on failure - */ -static int atl1_set_mac(struct net_device *netdev, void *p) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct sockaddr *addr = p; - - if (netif_running(netdev)) - return -EBUSY; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len); - - atl1_set_mac_addr(&adapter->hw); - return 0; -} - -/* - * atl1_watchdog - Timer Call-back - * @data: pointer to netdev cast into an unsigned long - */ -static void atl1_watchdog(unsigned long data) -{ - struct atl1_adapter *adapter = (struct atl1_adapter *)data; - - /* Reset the timer */ - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); -} - -static int mdio_read(struct net_device *netdev, int phy_id, int reg_num) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - u16 result; - - atl1_read_phy_reg(&adapter->hw, reg_num & 0x1f, &result); - - return result; -} - -static void mdio_write(struct net_device *netdev, int phy_id, int reg_num, int val) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - - atl1_write_phy_reg(&adapter->hw, reg_num, val); -} - -/* - * atl1_mii_ioctl - - * @netdev: - * @ifreq: - * @cmd: - */ -static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - int retval; - - if (!netif_running(netdev)) - return -EINVAL; - - spin_lock_irqsave(&adapter->lock, flags); - retval = generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL); - spin_unlock_irqrestore(&adapter->lock, flags); - - return retval; -} - -/* - * atl1_ioctl - - * @netdev: - * @ifreq: - * @cmd: - */ -static int atl1_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) -{ - switch (cmd) { - case SIOCGMIIPHY: - case SIOCGMIIREG: - case SIOCSMIIREG: - return atl1_mii_ioctl(netdev, ifr, cmd); - default: - return -EOPNOTSUPP; - } -} - -/* - * atl1_tx_timeout - Respond to a Tx Hang - * @netdev: network interface device structure - */ -static void atl1_tx_timeout(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - /* Do the reset outside of interrupt context */ - schedule_work(&adapter->tx_timeout_task); -} - -/* - * atl1_phy_config - Timer Call-back - * @data: pointer to netdev cast into an unsigned long - */ -static void atl1_phy_config(unsigned long data) -{ - struct atl1_adapter *adapter = (struct atl1_adapter *)data; - struct atl1_hw *hw = &adapter->hw; - unsigned long flags; - - spin_lock_irqsave(&adapter->lock, flags); - adapter->phy_timer_pending = false; - atl1_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg); - atl1_write_phy_reg(hw, MII_AT001_CR, hw->mii_1000t_ctrl_reg); - atl1_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN); - spin_unlock_irqrestore(&adapter->lock, flags); -} - -int atl1_reset(struct atl1_adapter *adapter) -{ - int ret; - - ret = atl1_reset_hw(&adapter->hw); - if (ret != ATL1_SUCCESS) - return ret; - return atl1_init_hw(&adapter->hw); -} - -/* - * atl1_open - Called when a network interface is made active - * @netdev: network interface device structure - * - * Returns 0 on success, negative value on failure - * - * The open entry point is called when a network interface is made - * active by the system (IFF_UP). At this point all resources needed - * for transmit and receive operations are allocated, the interrupt - * handler is registered with the OS, the watchdog timer is started, - * and the stack is notified that the interface is ready. - */ -static int atl1_open(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - int err; - - /* allocate transmit descriptors */ - err = atl1_setup_ring_resources(adapter); - if (err) - return err; - - err = atl1_up(adapter); - if (err) - goto err_up; - - return 0; - -err_up: - atl1_reset(adapter); - return err; -} - -/* - * atl1_close - Disables a network interface - * @netdev: network interface device structure - * - * Returns 0, this is not allowed to fail - * - * The close entry point is called when an interface is de-activated - * by the OS. The hardware is still under the drivers control, but - * needs to be disabled. A global MAC reset is issued to stop the - * hardware, and all transmit and receive resources are freed. - */ -static int atl1_close(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - atl1_down(adapter); - atl1_free_ring_resources(adapter); - return 0; -} - -/* - * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT - * will assert. We do soft reset <0x1400=1> according - * with the SPEC. BUT, it seemes that PCIE or DMA - * state-machine will not be reset. DMAR_TO_INT will - * assert again and again. - */ -static void atl1_tx_timeout_task(struct work_struct *work) -{ - struct atl1_adapter *adapter = - container_of(work, struct atl1_adapter, tx_timeout_task); - struct net_device *netdev = adapter->netdev; - - netif_device_detach(netdev); - atl1_down(adapter); - atl1_up(adapter); - netif_device_attach(netdev); -} - -/* - * atl1_link_chg_task - deal with link change event Out of interrupt context - */ -static void atl1_link_chg_task(struct work_struct *work) -{ - struct atl1_adapter *adapter = - container_of(work, struct atl1_adapter, link_chg_task); - unsigned long flags; - - spin_lock_irqsave(&adapter->lock, flags); - atl1_check_link(adapter); - spin_unlock_irqrestore(&adapter->lock, flags); -} - -/* - * atl1_pcie_patch - Patch for PCIE module - */ -static void atl1_pcie_patch(struct atl1_adapter *adapter) -{ - u32 value; - value = 0x6500; - iowrite32(value, adapter->hw.hw_addr + 0x12FC); - /* pcie flow control mode change */ - value = ioread32(adapter->hw.hw_addr + 0x1008); - value |= 0x8000; - iowrite32(value, adapter->hw.hw_addr + 0x1008); -} - -/* - * When ACPI resume on some VIA MotherBoard, the Interrupt Disable bit/0x400 - * on PCI Command register is disable. - * The function enable this bit. - * Brackett, 2006/03/15 - */ -static void atl1_via_workaround(struct atl1_adapter *adapter) -{ - unsigned long value; - - value = ioread16(adapter->hw.hw_addr + PCI_COMMAND); - if (value & PCI_COMMAND_INTX_DISABLE) - value &= ~PCI_COMMAND_INTX_DISABLE; - iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND); -} - -/* - * atl1_probe - Device Initialization Routine - * @pdev: PCI device information struct - * @ent: entry in atl1_pci_tbl - * - * Returns 0 on success, negative on failure - * - * atl1_probe initializes an adapter identified by a pci_dev structure. - * The OS initialization, configuring of the adapter private structure, - * and a hardware reset occur. - */ -static int __devinit atl1_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *netdev; - struct atl1_adapter *adapter; - static int cards_found = 0; - bool pci_using_64 = true; - int err; - - err = pci_enable_device(pdev); - if (err) - return err; - - err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); - if (err) { - err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (err) { - printk(KERN_DEBUG - "%s: no usable DMA configuration, aborting\n", - atl1_driver_name); - goto err_dma; - } - pci_using_64 = false; - } - /* Mark all PCI regions associated with PCI device - * pdev as being reserved by owner atl1_driver_name - */ - err = pci_request_regions(pdev, atl1_driver_name); - if (err) - goto err_request_regions; - - /* Enables bus-mastering on the device and calls - * pcibios_set_master to do the needed arch specific settings - */ - pci_set_master(pdev); - - netdev = alloc_etherdev(sizeof(struct atl1_adapter)); - if (!netdev) { - err = -ENOMEM; - goto err_alloc_etherdev; - } - SET_MODULE_OWNER(netdev); - SET_NETDEV_DEV(netdev, &pdev->dev); - - pci_set_drvdata(pdev, netdev); - adapter = netdev_priv(netdev); - adapter->netdev = netdev; - adapter->pdev = pdev; - adapter->hw.back = adapter; - - adapter->hw.hw_addr = pci_iomap(pdev, 0, 0); - if (!adapter->hw.hw_addr) { - err = -EIO; - goto err_pci_iomap; - } - /* get device revision number */ - adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + (REG_MASTER_CTRL + 2)); - - /* set default ring resource counts */ - adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD; - adapter->tpd_ring.count = ATL1_DEFAULT_TPD; - - adapter->mii.dev = netdev; - adapter->mii.mdio_read = mdio_read; - adapter->mii.mdio_write = mdio_write; - adapter->mii.phy_id_mask = 0x1f; - adapter->mii.reg_num_mask = 0x1f; - - netdev->open = &atl1_open; - netdev->stop = &atl1_close; - netdev->hard_start_xmit = &atl1_xmit_frame; - netdev->get_stats = &atl1_get_stats; - netdev->set_multicast_list = &atl1_set_multi; - netdev->set_mac_address = &atl1_set_mac; - netdev->change_mtu = &atl1_change_mtu; - netdev->do_ioctl = &atl1_ioctl; - netdev->tx_timeout = &atl1_tx_timeout; - netdev->watchdog_timeo = 5 * HZ; - netdev->vlan_rx_register = atl1_vlan_rx_register; - netdev->vlan_rx_add_vid = atl1_vlan_rx_add_vid; - netdev->vlan_rx_kill_vid = atl1_vlan_rx_kill_vid; - netdev->ethtool_ops = &atl1_ethtool_ops; - adapter->bd_number = cards_found; - adapter->pci_using_64 = pci_using_64; - - /* setup the private structure */ - err = atl1_sw_init(adapter); - if (err) - goto err_common; - - netdev->features = NETIF_F_HW_CSUM; - netdev->features |= NETIF_F_SG; - netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); - - /* - * FIXME - Until tso performance gets fixed, disable the feature. - * Enable it with ethtool -K if desired. - */ - /* netdev->features |= NETIF_F_TSO; */ - - if (pci_using_64) - netdev->features |= NETIF_F_HIGHDMA; - - netdev->features |= NETIF_F_LLTX; - - /* - * patch for some L1 of old version, - * the final version of L1 may not need these - * patches - */ - /* atl1_pcie_patch(adapter); */ - - /* really reset GPHY core */ - iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE); - - /* - * reset the controller to - * put the device in a known good starting state - */ - if (atl1_reset_hw(&adapter->hw)) { - err = -EIO; - goto err_common; - } - - /* copy the MAC address out of the EEPROM */ - atl1_read_mac_addr(&adapter->hw); - memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); - - if (!is_valid_ether_addr(netdev->dev_addr)) { - err = -EIO; - goto err_common; - } - - atl1_check_options(adapter); - - /* pre-init the MAC, and setup link */ - err = atl1_init_hw(&adapter->hw); - if (err) { - err = -EIO; - goto err_common; - } - - atl1_pcie_patch(adapter); - /* assume we have no link for now */ - netif_carrier_off(netdev); - netif_stop_queue(netdev); - - init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &atl1_watchdog; - adapter->watchdog_timer.data = (unsigned long)adapter; - - init_timer(&adapter->phy_config_timer); - adapter->phy_config_timer.function = &atl1_phy_config; - adapter->phy_config_timer.data = (unsigned long)adapter; - adapter->phy_timer_pending = false; - - INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); - - INIT_WORK(&adapter->link_chg_task, atl1_link_chg_task); - - INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); - - err = register_netdev(netdev); - if (err) - goto err_common; - - cards_found++; - atl1_via_workaround(adapter); - return 0; - -err_common: - pci_iounmap(pdev, adapter->hw.hw_addr); -err_pci_iomap: - free_netdev(netdev); -err_alloc_etherdev: - pci_release_regions(pdev); -err_dma: -err_request_regions: - pci_disable_device(pdev); - return err; -} - -/* - * atl1_remove - Device Removal Routine - * @pdev: PCI device information struct - * - * atl1_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. The could be caused by a - * Hot-Plug event, or because the driver is going to be removed from - * memory. - */ -static void __devexit atl1_remove(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct atl1_adapter *adapter; - /* Device not available. Return. */ - if (!netdev) - return; - - adapter = netdev_priv(netdev); - iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE); - unregister_netdev(netdev); - pci_iounmap(pdev, adapter->hw.hw_addr); - pci_release_regions(pdev); - free_netdev(netdev); - pci_disable_device(pdev); -} - -#ifdef CONFIG_PM -static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - u32 ctrl = 0; - u32 wufc = adapter->wol; - - netif_device_detach(netdev); - if (netif_running(netdev)) - atl1_down(adapter); - - atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); - atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); - if (ctrl & BMSR_LSTATUS) - wufc &= ~ATL1_WUFC_LNKC; - - /* reduce speed to 10/100M */ - if (wufc) { - atl1_phy_enter_power_saving(hw); - /* if resume, let driver to re- setup link */ - hw->phy_configured = false; - atl1_set_mac_addr(hw); - atl1_set_multi(netdev); - - ctrl = 0; - /* turn on magic packet wol */ - if (wufc & ATL1_WUFC_MAG) - ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN; - - /* turn on Link change WOL */ - if (wufc & ATL1_WUFC_LNKC) - ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); - iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); - - /* turn on all-multi mode if wake on multicast is enabled */ - ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_DBG; - ctrl &= ~MAC_CTRL_PROMIS_EN; - if (wufc & ATL1_WUFC_MC) - ctrl |= MAC_CTRL_MC_ALL_EN; - else - ctrl &= ~MAC_CTRL_MC_ALL_EN; - - /* turn on broadcast mode if wake on-BC is enabled */ - if (wufc & ATL1_WUFC_BC) - ctrl |= MAC_CTRL_BC_EN; - else - ctrl &= ~MAC_CTRL_BC_EN; - - /* enable RX */ - ctrl |= MAC_CTRL_RX_EN; - iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); /* 4 == D3 cold */ - } else { - iowrite32(0, hw->hw_addr + REG_WOL_CTRL); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); /* 4 == D3 cold */ - } - - pci_save_state(pdev); - pci_disable_device(pdev); - - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int atl1_resume(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct atl1_adapter *adapter = netdev_priv(netdev); - u32 ret_val; - - pci_set_power_state(pdev, 0); - pci_restore_state(pdev); - - ret_val = pci_enable_device(pdev); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - - iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); - atl1_reset(adapter); - - if (netif_running(netdev)) - atl1_up(adapter); - netif_device_attach(netdev); - - atl1_via_workaround(adapter); - - return 0; -} -#else -#define atl1_suspend NULL -#define atl1_resume NULL -#endif - -static struct pci_driver atl1_driver = { - .name = atl1_driver_name, - .id_table = atl1_pci_tbl, - .probe = atl1_probe, - .remove = __devexit_p(atl1_remove), - /* Power Managment Hooks */ - /* probably broken right now -- CHS */ - .suspend = atl1_suspend, - .resume = atl1_resume -}; - -/* - * atl1_exit_module - Driver Exit Cleanup Routine - * - * atl1_exit_module is called just before the driver is removed - * from memory. - */ -static void __exit atl1_exit_module(void) -{ - pci_unregister_driver(&atl1_driver); -} - -/* - * atl1_init_module - Driver Registration Routine - * - * atl1_init_module is the first routine called when the driver is - * loaded. All it does is register with the PCI subsystem. - */ -static int __init atl1_init_module(void) -{ - printk(KERN_INFO "%s - version %s\n", atl1_driver_string, DRIVER_VERSION); - printk(KERN_INFO "%s\n", atl1_copyright); - return pci_register_driver(&atl1_driver); -} - -module_init(atl1_init_module); -module_exit(atl1_exit_module); diff --git a/trunk/drivers/net/atl1/atl1_param.c b/trunk/drivers/net/atl1/atl1_param.c deleted file mode 100644 index c407214339f6..000000000000 --- a/trunk/drivers/net/atl1/atl1_param.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include "atl1.h" - -/* - * This is the only thing that needs to be changed to adjust the - * maximum number of ports that the driver can manage. - */ -#define ATL1_MAX_NIC 4 - -#define OPTION_UNSET -1 -#define OPTION_DISABLED 0 -#define OPTION_ENABLED 1 - -#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET } - -/* - * Interrupt Moderate Timer in units of 2 us - * - * Valid Range: 10-65535 - * - * Default Value: 100 (200us) - */ -static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; -static int num_int_mod_timer = 0; -module_param_array_named(int_mod_timer, int_mod_timer, int, &num_int_mod_timer, 0); -MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer"); - -/* - * flash_vendor - * - * Valid Range: 0-2 - * - * 0 - Atmel - * 1 - SST - * 2 - ST - * - * Default Value: 0 - */ -static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; -static int num_flash_vendor = 0; -module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0); -MODULE_PARM_DESC(flash_vendor, "SPI flash vendor"); - -#define DEFAULT_INT_MOD_CNT 100 /* 200us */ -#define MAX_INT_MOD_CNT 65000 -#define MIN_INT_MOD_CNT 50 - -#define FLASH_VENDOR_DEFAULT 0 -#define FLASH_VENDOR_MIN 0 -#define FLASH_VENDOR_MAX 2 - -struct atl1_option { - enum { enable_option, range_option, list_option } type; - char *name; - char *err; - int def; - union { - struct { /* range_option info */ - int min; - int max; - } r; - struct { /* list_option info */ - int nr; - struct atl1_opt_list { - int i; - char *str; - } *p; - } l; - } arg; -}; - -static int __devinit atl1_validate_option(int *value, struct atl1_option *opt) -{ - if (*value == OPTION_UNSET) { - *value = opt->def; - return 0; - } - - switch (opt->type) { - case enable_option: - switch (*value) { - case OPTION_ENABLED: - printk(KERN_INFO "%s: %s Enabled\n", atl1_driver_name, - opt->name); - return 0; - case OPTION_DISABLED: - printk(KERN_INFO "%s: %s Disabled\n", atl1_driver_name, - opt->name); - return 0; - } - break; - case range_option: - if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { - printk(KERN_INFO "%s: %s set to %i\n", - atl1_driver_name, opt->name, *value); - return 0; - } - break; - case list_option:{ - int i; - struct atl1_opt_list *ent; - - for (i = 0; i < opt->arg.l.nr; i++) { - ent = &opt->arg.l.p[i]; - if (*value == ent->i) { - if (ent->str[0] != '\0') - printk(KERN_INFO "%s: %s\n", - atl1_driver_name, ent->str); - return 0; - } - } - } - break; - - default: - break; - } - - printk(KERN_INFO "%s: invalid %s specified (%i) %s\n", - atl1_driver_name, opt->name, *value, opt->err); - *value = opt->def; - return -1; -} - -/* - * atl1_check_options - Range Checking for Command Line Parameters - * @adapter: board private structure - * - * This routine checks all command line parameters for valid user - * input. If an invalid value is given, or if no user specified - * value exists, a default value is used. The final value is stored - * in a variable in the adapter structure. - */ -void __devinit atl1_check_options(struct atl1_adapter *adapter) -{ - int bd = adapter->bd_number; - if (bd >= ATL1_MAX_NIC) { - printk(KERN_NOTICE "%s: warning: no configuration for board #%i\n", - atl1_driver_name, bd); - printk(KERN_NOTICE "%s: using defaults for all values\n", - atl1_driver_name); - } - { /* Interrupt Moderate Timer */ - struct atl1_option opt = { - .type = range_option, - .name = "Interrupt Moderator Timer", - .err = "using default of " - __MODULE_STRING(DEFAULT_INT_MOD_CNT), - .def = DEFAULT_INT_MOD_CNT, - .arg = {.r = - {.min = MIN_INT_MOD_CNT,.max = MAX_INT_MOD_CNT}} - }; - int val; - if (num_int_mod_timer > bd) { - val = int_mod_timer[bd]; - atl1_validate_option(&val, &opt); - adapter->imt = (u16) val; - } else - adapter->imt = (u16) (opt.def); - } - - { /* Flash Vendor */ - struct atl1_option opt = { - .type = range_option, - .name = "SPI Flash Vendor", - .err = "using default of " - __MODULE_STRING(FLASH_VENDOR_DEFAULT), - .def = DEFAULT_INT_MOD_CNT, - .arg = {.r = - {.min = FLASH_VENDOR_MIN,.max = - FLASH_VENDOR_MAX}} - }; - int val; - if (num_flash_vendor > bd) { - val = flash_vendor[bd]; - atl1_validate_option(&val, &opt); - adapter->hw.flash_vendor = (u8) val; - } else - adapter->hw.flash_vendor = (u8) (opt.def); - } -} diff --git a/trunk/drivers/net/bonding/bond_alb.c b/trunk/drivers/net/bonding/bond_alb.c index 217a2eedee0a..32923162179e 100644 --- a/trunk/drivers/net/bonding/bond_alb.c +++ b/trunk/drivers/net/bonding/bond_alb.c @@ -184,7 +184,7 @@ static int tlb_initialize(struct bonding *bond) spin_lock_init(&(bond_info->tx_hashtbl_lock)); - new_hashtbl = kzalloc(size, GFP_KERNEL); + new_hashtbl = kmalloc(size, GFP_KERNEL); if (!new_hashtbl) { printk(KERN_ERR DRV_NAME ": %s: Error: Failed to allocate TLB hash table\n", @@ -195,6 +195,8 @@ static int tlb_initialize(struct bonding *bond) bond_info->tx_hashtbl = new_hashtbl; + memset(bond_info->tx_hashtbl, 0, size); + for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) { tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1); } diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 8ce8fec615ba..d3801a00d3d5 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -1343,12 +1343,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) "inaccurate.\n", bond_dev->name, slave_dev->name); } - new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); + new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL); if (!new_slave) { res = -ENOMEM; goto err_undo_flags; } + memset(new_slave, 0, sizeof(struct slave)); + /* save slave's original flags before calling * netdev_set_master and dev_open */ diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index c67f7d3c2f92..dfa035a1ad45 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -74,6 +74,8 @@ enum { #define EEPROM_MAGIC 0x38E2F10C +#define to_net_dev(class) container_of(class, struct net_device, class_dev) + #define CH_DEVICE(devid, ssid, idx) \ { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx } @@ -432,12 +434,11 @@ static int setup_sge_qsets(struct adapter *adap) return 0; } -static ssize_t attr_show(struct device *d, struct device_attribute *attr, - char *buf, +static ssize_t attr_show(struct class_device *cd, char *buf, ssize_t(*format) (struct adapter *, char *)) { ssize_t len; - struct adapter *adap = to_net_dev(d)->priv; + struct adapter *adap = to_net_dev(cd)->priv; /* Synchronize with ioctls that may shut down the device */ rtnl_lock(); @@ -446,15 +447,14 @@ static ssize_t attr_show(struct device *d, struct device_attribute *attr, return len; } -static ssize_t attr_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t len, +static ssize_t attr_store(struct class_device *cd, const char *buf, size_t len, ssize_t(*set) (struct adapter *, unsigned int), unsigned int min_val, unsigned int max_val) { char *endp; ssize_t ret; unsigned int val; - struct adapter *adap = to_net_dev(d)->priv; + struct adapter *adap = to_net_dev(cd)->priv; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -476,10 +476,9 @@ static ssize_t format_##name(struct adapter *adap, char *buf) \ { \ return sprintf(buf, "%u\n", val_expr); \ } \ -static ssize_t show_##name(struct device *d, struct device_attribute *attr, \ - char *buf) \ +static ssize_t show_##name(struct class_device *cd, char *buf) \ { \ - return attr_show(d, attr, buf, format_##name); \ + return attr_show(cd, buf, format_##name); \ } static ssize_t set_nfilters(struct adapter *adap, unsigned int val) @@ -494,10 +493,10 @@ static ssize_t set_nfilters(struct adapter *adap, unsigned int val) return 0; } -static ssize_t store_nfilters(struct device *d, struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_nfilters(struct class_device *cd, const char *buf, + size_t len) { - return attr_store(d, attr, buf, len, set_nfilters, 0, ~0); + return attr_store(cd, buf, len, set_nfilters, 0, ~0); } static ssize_t set_nservers(struct adapter *adap, unsigned int val) @@ -510,39 +509,38 @@ static ssize_t set_nservers(struct adapter *adap, unsigned int val) return 0; } -static ssize_t store_nservers(struct device *d, struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_nservers(struct class_device *cd, const char *buf, + size_t len) { - return attr_store(d, attr, buf, len, set_nservers, 0, ~0); + return attr_store(cd, buf, len, set_nservers, 0, ~0); } #define CXGB3_ATTR_R(name, val_expr) \ CXGB3_SHOW(name, val_expr) \ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) #define CXGB3_ATTR_RW(name, val_expr, store_method) \ CXGB3_SHOW(name, val_expr) \ -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method) +static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method) CXGB3_ATTR_R(cam_size, t3_mc5_size(&adap->mc5)); CXGB3_ATTR_RW(nfilters, adap->params.mc5.nfilters, store_nfilters); CXGB3_ATTR_RW(nservers, adap->params.mc5.nservers, store_nservers); static struct attribute *cxgb3_attrs[] = { - &dev_attr_cam_size.attr, - &dev_attr_nfilters.attr, - &dev_attr_nservers.attr, + &class_device_attr_cam_size.attr, + &class_device_attr_nfilters.attr, + &class_device_attr_nservers.attr, NULL }; static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs }; -static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr, - char *buf, int sched) +static ssize_t tm_attr_show(struct class_device *cd, char *buf, int sched) { ssize_t len; unsigned int v, addr, bpt, cpt; - struct adapter *adap = to_net_dev(d)->priv; + struct adapter *adap = to_net_dev(cd)->priv; addr = A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2; rtnl_lock(); @@ -562,13 +560,13 @@ static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr, return len; } -static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t len, int sched) +static ssize_t tm_attr_store(struct class_device *cd, const char *buf, + size_t len, int sched) { char *endp; ssize_t ret; unsigned int val; - struct adapter *adap = to_net_dev(d)->priv; + struct adapter *adap = to_net_dev(cd)->priv; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -586,17 +584,15 @@ static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr, } #define TM_ATTR(name, sched) \ -static ssize_t show_##name(struct device *d, struct device_attribute *attr, \ - char *buf) \ +static ssize_t show_##name(struct class_device *cd, char *buf) \ { \ - return tm_attr_show(d, attr, buf, sched); \ + return tm_attr_show(cd, buf, sched); \ } \ -static ssize_t store_##name(struct device *d, struct device_attribute *attr, \ - const char *buf, size_t len) \ +static ssize_t store_##name(struct class_device *cd, const char *buf, size_t len) \ { \ - return tm_attr_store(d, attr, buf, len, sched); \ + return tm_attr_store(cd, buf, len, sched); \ } \ -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name) +static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name) TM_ATTR(sched0, 0); TM_ATTR(sched1, 1); @@ -608,14 +604,14 @@ TM_ATTR(sched6, 6); TM_ATTR(sched7, 7); static struct attribute *offload_attrs[] = { - &dev_attr_sched0.attr, - &dev_attr_sched1.attr, - &dev_attr_sched2.attr, - &dev_attr_sched3.attr, - &dev_attr_sched4.attr, - &dev_attr_sched5.attr, - &dev_attr_sched6.attr, - &dev_attr_sched7.attr, + &class_device_attr_sched0.attr, + &class_device_attr_sched1.attr, + &class_device_attr_sched2.attr, + &class_device_attr_sched3.attr, + &class_device_attr_sched4.attr, + &class_device_attr_sched5.attr, + &class_device_attr_sched6.attr, + &class_device_attr_sched7.attr, NULL }; @@ -840,7 +836,7 @@ static int offload_open(struct net_device *dev) init_smt(adapter); /* Never mind if the next step fails */ - sysfs_create_group(&tdev->lldev->dev.kobj, &offload_attr_group); + sysfs_create_group(&tdev->lldev->class_dev.kobj, &offload_attr_group); /* Call back all registered clients */ cxgb3_add_clients(tdev); @@ -865,7 +861,7 @@ static int offload_close(struct t3cdev *tdev) /* Call back all registered clients */ cxgb3_remove_clients(tdev); - sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group); + sysfs_remove_group(&tdev->lldev->class_dev.kobj, &offload_attr_group); tdev->lldev = NULL; cxgb3_set_dummy_ops(tdev); @@ -2424,7 +2420,7 @@ static int __devinit init_one(struct pci_dev *pdev, else if (msi > 0 && pci_enable_msi(pdev) == 0) adapter->flags |= USING_MSI; - err = sysfs_create_group(&adapter->port[0]->dev.kobj, + err = sysfs_create_group(&adapter->port[0]->class_dev.kobj, &cxgb3_attr_group); print_port_info(adapter, ai); @@ -2456,7 +2452,7 @@ static void __devexit remove_one(struct pci_dev *pdev) struct adapter *adapter = dev->priv; t3_sge_stop(adapter); - sysfs_remove_group(&adapter->port[0]->dev.kobj, + sysfs_remove_group(&adapter->port[0]->class_dev.kobj, &cxgb3_attr_group); for_each_port(adapter, i) diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.c b/trunk/drivers/net/cxgb3/cxgb3_offload.c index c6b726643185..c3a02d613382 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.c +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.c @@ -396,7 +396,7 @@ static int rx_offload_blackhole(struct t3cdev *dev, struct sk_buff **skbs, int n) { CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n", - n, ntohl(*(__be32 *)skbs[0]->data)); + n, ntohl(*(u32 *)skbs[0]->data)); while (n--) dev_kfree_skb_any(skbs[n]); return 0; @@ -755,7 +755,7 @@ static int do_trace(struct t3cdev *dev, struct sk_buff *skb) { struct cpl_trace_pkt *p = cplhdr(skb); - skb->protocol = htons(0xffff); + skb->protocol = 0xffff; skb->dev = dev->lldev; skb_pull(skb, sizeof(*p)); skb->mac.raw = skb->data; diff --git a/trunk/drivers/net/defxx.c b/trunk/drivers/net/defxx.c index 07d2731c1aa8..dc3ab3b5c8cb 100644 --- a/trunk/drivers/net/defxx.c +++ b/trunk/drivers/net/defxx.c @@ -10,12 +10,10 @@ * * Abstract: * A Linux device driver supporting the Digital Equipment Corporation - * FDDI TURBOchannel, EISA and PCI controller families. Supported - * adapters include: + * FDDI EISA and PCI controller families. Supported adapters include: * - * DEC FDDIcontroller/TURBOchannel (DEFTA) - * DEC FDDIcontroller/EISA (DEFEA) - * DEC FDDIcontroller/PCI (DEFPA) + * DEC FDDIcontroller/EISA (DEFEA) + * DEC FDDIcontroller/PCI (DEFPA) * * The original author: * LVS Lawrence V. Stefani @@ -195,27 +193,24 @@ * 14 Aug 2004 macro Fix device names reported. * 14 Jun 2005 macro Use irqreturn_t. * 23 Oct 2006 macro Big-endian host support. - * 14 Dec 2006 macro TURBOchannel support. */ /* Include files */ -#include -#include -#include -#include + +#include +#include +#include #include -#include -#include -#include #include -#include -#include -#include +#include +#include #include +#include +#include +#include +#include #include -#include -#include -#include +#include #include #include @@ -224,8 +219,8 @@ /* Version information string should be updated prior to each new release! */ #define DRV_NAME "defxx" -#define DRV_VERSION "v1.10" -#define DRV_RELDATE "2006/12/14" +#define DRV_VERSION "v1.09" +#define DRV_RELDATE "2006/10/23" static char version[] __devinitdata = DRV_NAME ": " DRV_VERSION " " DRV_RELDATE @@ -240,41 +235,12 @@ static char version[] __devinitdata = */ #define NEW_SKB_SIZE (PI_RCV_DATA_K_SIZE_MAX+128) -#define __unused __attribute__ ((unused)) - -#ifdef CONFIG_PCI -#define DFX_BUS_PCI(dev) (dev->bus == &pci_bus_type) -#else -#define DFX_BUS_PCI(dev) 0 -#endif - -#ifdef CONFIG_EISA -#define DFX_BUS_EISA(dev) (dev->bus == &eisa_bus_type) -#else -#define DFX_BUS_EISA(dev) 0 -#endif - -#ifdef CONFIG_TC -#define DFX_BUS_TC(dev) (dev->bus == &tc_bus_type) -#else -#define DFX_BUS_TC(dev) 0 -#endif - -#ifdef CONFIG_DEFXX_MMIO -#define DFX_MMIO 1 -#else -#define DFX_MMIO 0 -#endif - /* Define module-wide (static) routines */ static void dfx_bus_init(struct net_device *dev); -static void dfx_bus_uninit(struct net_device *dev); static void dfx_bus_config_check(DFX_board_t *bp); -static int dfx_driver_init(struct net_device *dev, - const char *print_name, - resource_size_t bar_start); +static int dfx_driver_init(struct net_device *dev, const char *print_name); static int dfx_adap_init(DFX_board_t *bp, int get_buffers); static int dfx_open(struct net_device *dev); @@ -307,13 +273,13 @@ static void dfx_xmt_flush(DFX_board_t *bp); /* Define module-wide (static) variables */ -static struct pci_driver dfx_pci_driver; -static struct eisa_driver dfx_eisa_driver; -static struct tc_driver dfx_tc_driver; +static struct net_device *root_dfx_eisa_dev; /* * ======================= + * = dfx_port_write_byte = + * = dfx_port_read_byte = * = dfx_port_write_long = * = dfx_port_read_long = * ======================= @@ -325,11 +291,12 @@ static struct tc_driver dfx_tc_driver; * None * * Arguments: - * bp - pointer to board information - * offset - register offset from base I/O address - * data - for dfx_port_write_long, this is a value to write; - * for dfx_port_read_long, this is a pointer to store - * the read value + * bp - pointer to board information + * offset - register offset from base I/O address + * data - for dfx_port_write_byte and dfx_port_write_long, this + * is a value to write. + * for dfx_port_read_byte and dfx_port_read_byte, this + * is a pointer to store the read value. * * Functional Description: * These routines perform the correct operation to read or write @@ -343,7 +310,7 @@ static struct tc_driver dfx_tc_driver; * registers using the register offsets defined in DEFXX.H. * * PCI port block base addresses are assigned by the PCI BIOS or system - * firmware. There is one 128 byte port block which can be accessed. It + * firmware. There is one 128 byte port block which can be accessed. It * allows for I/O mapping of both PDQ and PFI registers using the register * offsets defined in DEFXX.H. * @@ -351,7 +318,7 @@ static struct tc_driver dfx_tc_driver; * None * * Assumptions: - * bp->base is a valid base I/O address for this adapter. + * bp->base_addr is a valid base I/O address for this adapter. * offset is a valid register offset for this adapter. * * Side Effects: @@ -362,135 +329,69 @@ static struct tc_driver dfx_tc_driver; * advantage of strict data type checking. */ -static inline void dfx_writel(DFX_board_t *bp, int offset, u32 data) -{ - writel(data, bp->base.mem + offset); - mb(); -} - -static inline void dfx_outl(DFX_board_t *bp, int offset, u32 data) -{ - outl(data, bp->base.port + offset); -} +static inline void dfx_port_write_byte( + DFX_board_t *bp, + int offset, + u8 data + ) -static void dfx_port_write_long(DFX_board_t *bp, int offset, u32 data) -{ - struct device __unused *bdev = bp->bus_dev; - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; + { + u16 port = bp->base_addr + offset; - if (dfx_use_mmio) - dfx_writel(bp, offset, data); - else - dfx_outl(bp, offset, data); -} + outb(data, port); + } +static inline void dfx_port_read_byte( + DFX_board_t *bp, + int offset, + u8 *data + ) -static inline void dfx_readl(DFX_board_t *bp, int offset, u32 *data) -{ - mb(); - *data = readl(bp->base.mem + offset); -} + { + u16 port = bp->base_addr + offset; -static inline void dfx_inl(DFX_board_t *bp, int offset, u32 *data) -{ - *data = inl(bp->base.port + offset); -} + *data = inb(port); + } -static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data) -{ - struct device __unused *bdev = bp->bus_dev; - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; +static inline void dfx_port_write_long( + DFX_board_t *bp, + int offset, + u32 data + ) - if (dfx_use_mmio) - dfx_readl(bp, offset, data); - else - dfx_inl(bp, offset, data); -} + { + u16 port = bp->base_addr + offset; + outl(data, port); + } -/* - * ================ - * = dfx_get_bars = - * ================ - * - * Overview: - * Retrieves the address range used to access control and status - * registers. - * - * Returns: - * None - * - * Arguments: - * bdev - pointer to device information - * bar_start - pointer to store the start address - * bar_len - pointer to store the length of the area - * - * Assumptions: - * I am sure there are some. - * - * Side Effects: - * None - */ -static void dfx_get_bars(struct device *bdev, - resource_size_t *bar_start, resource_size_t *bar_len) -{ - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; +static inline void dfx_port_read_long( + DFX_board_t *bp, + int offset, + u32 *data + ) - if (dfx_bus_pci) { - int num = dfx_use_mmio ? 0 : 1; + { + u16 port = bp->base_addr + offset; - *bar_start = pci_resource_start(to_pci_dev(bdev), num); - *bar_len = pci_resource_len(to_pci_dev(bdev), num); - } - if (dfx_bus_eisa) { - unsigned long base_addr = to_eisa_device(bdev)->base_addr; - resource_size_t bar; - - if (dfx_use_mmio) { - bar = inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_2); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_1); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_0); - bar <<= 16; - *bar_start = bar; - bar = inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_2); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_1); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_0); - bar <<= 16; - *bar_len = (bar | PI_MEM_ADD_MASK_M) + 1; - } else { - *bar_start = base_addr; - *bar_len = PI_ESIC_K_CSR_IO_LEN; - } - } - if (dfx_bus_tc) { - *bar_start = to_tc_dev(bdev)->resource.start + - PI_TC_K_CSR_OFFSET; - *bar_len = PI_TC_K_CSR_LEN; + *data = inl(port); } -} + /* - * ================ - * = dfx_register = - * ================ + * ============= + * = dfx_init_one_pci_or_eisa = + * ============= * * Overview: - * Initializes a supported FDDI controller + * Initializes a supported FDDI EISA or PCI controller * * Returns: * Condition code * * Arguments: - * bdev - pointer to device information + * pdev - pointer to pci device information (NULL for EISA) + * ioaddr - pointer to port (NULL for PCI) * * Functional Description: * @@ -506,75 +407,57 @@ static void dfx_get_bars(struct device *bdev, * initialized and the board resources are read and stored in * the device structure. */ -static int __devinit dfx_register(struct device *bdev) +static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, long ioaddr) { static int version_disp; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - char *print_name = bdev->bus_id; + char *print_name = DRV_NAME; struct net_device *dev; DFX_board_t *bp; /* board pointer */ - resource_size_t bar_start = 0; /* pointer to port */ - resource_size_t bar_len = 0; /* resource length */ int alloc_size; /* total buffer size used */ - struct resource *region; - int err = 0; + int err; if (!version_disp) { /* display version info if adapter is found */ version_disp = 1; /* set display flag to TRUE so that */ printk(version); /* we only display this string ONCE */ } + if (pdev != NULL) + print_name = pci_name(pdev); + dev = alloc_fddidev(sizeof(*bp)); if (!dev) { - printk(KERN_ERR "%s: Unable to allocate fddidev, aborting\n", + printk(KERN_ERR "%s: unable to allocate fddidev, aborting\n", print_name); return -ENOMEM; } /* Enable PCI device. */ - if (dfx_bus_pci && pci_enable_device(to_pci_dev(bdev))) { - printk(KERN_ERR "%s: Cannot enable PCI device, aborting\n", - print_name); - goto err_out; + if (pdev != NULL) { + err = pci_enable_device (pdev); + if (err) goto err_out; + ioaddr = pci_resource_start (pdev, 1); } SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, bdev); - - bp = netdev_priv(dev); - bp->bus_dev = bdev; - dev_set_drvdata(bdev, dev); + if (pdev != NULL) + SET_NETDEV_DEV(dev, &pdev->dev); - dfx_get_bars(bdev, &bar_start, &bar_len); + bp = dev->priv; - if (dfx_use_mmio) - region = request_mem_region(bar_start, bar_len, print_name); - else - region = request_region(bar_start, bar_len, print_name); - if (!region) { + if (!request_region(ioaddr, + pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, + print_name)) { printk(KERN_ERR "%s: Cannot reserve I/O resource " - "0x%lx @ 0x%lx, aborting\n", - print_name, (long)bar_len, (long)bar_start); + "0x%x @ 0x%lx, aborting\n", print_name, + pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, ioaddr); err = -EBUSY; - goto err_out_disable; - } - - /* Set up I/O base address. */ - if (dfx_use_mmio) { - bp->base.mem = ioremap_nocache(bar_start, bar_len); - if (!bp->base.mem) { - printk(KERN_ERR "%s: Cannot map MMIO\n", print_name); - goto err_out_region; - } - } else { - bp->base.port = bar_start; - dev->base_addr = bar_start; + goto err_out; } /* Initialize new device structure */ + dev->base_addr = ioaddr; /* save port (I/O) base address */ + dev->get_stats = dfx_ctl_get_stats; dev->open = dfx_open; dev->stop = dfx_close; @@ -582,12 +465,22 @@ static int __devinit dfx_register(struct device *bdev) dev->set_multicast_list = dfx_ctl_set_multicast_list; dev->set_mac_address = dfx_ctl_set_mac_address; - if (dfx_bus_pci) - pci_set_master(to_pci_dev(bdev)); + if (pdev == NULL) { + /* EISA board */ + bp->bus_type = DFX_BUS_TYPE_EISA; + bp->next = root_dfx_eisa_dev; + root_dfx_eisa_dev = dev; + } else { + /* PCI board */ + bp->bus_type = DFX_BUS_TYPE_PCI; + bp->pci_dev = pdev; + pci_set_drvdata (pdev, dev); + pci_set_master (pdev); + } - if (dfx_driver_init(dev, print_name, bar_start) != DFX_K_SUCCESS) { + if (dfx_driver_init(dev, print_name) != DFX_K_SUCCESS) { err = -ENODEV; - goto err_out_unmap; + goto err_out_region; } err = register_netdev(dev); @@ -606,28 +499,44 @@ static int __devinit dfx_register(struct device *bdev) sizeof(PI_CONSUMER_BLOCK) + (PI_ALIGN_K_DESC_BLK - 1); if (bp->kmalloced) - dma_free_coherent(bdev, alloc_size, - bp->kmalloced, bp->kmalloced_dma); - -err_out_unmap: - if (dfx_use_mmio) - iounmap(bp->base.mem); - + pci_free_consistent(pdev, alloc_size, + bp->kmalloced, bp->kmalloced_dma); err_out_region: - if (dfx_use_mmio) - release_mem_region(bar_start, bar_len); - else - release_region(bar_start, bar_len); - -err_out_disable: - if (dfx_bus_pci) - pci_disable_device(to_pci_dev(bdev)); - + release_region(ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN); err_out: free_netdev(dev); return err; } +static int __devinit dfx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return dfx_init_one_pci_or_eisa(pdev, 0); +} + +static int __init dfx_eisa_init(void) +{ + int rc = -ENODEV; + int i; /* used in for loops */ + u16 port; /* temporary I/O (port) address */ + u32 slot_id; /* EISA hardware (slot) ID read from adapter */ + + DBG_printk("In dfx_eisa_init...\n"); + + /* Scan for FDDI EISA controllers */ + + for (i=0; i < DFX_MAX_EISA_SLOTS; i++) /* only scan for up to 16 EISA slots */ + { + port = (i << 12) + PI_ESIC_K_SLOT_ID; /* port = I/O address for reading slot ID */ + slot_id = inl(port); /* read EISA HW (slot) ID */ + if ((slot_id & 0xF0FFFFFF) == DEFEA_PRODUCT_ID) + { + port = (i << 12); /* recalc base addr */ + + if (dfx_init_one_pci_or_eisa(NULL, port) == 0) rc = 0; + } + } + return rc; +} /* * ================ @@ -635,7 +544,7 @@ static int __devinit dfx_register(struct device *bdev) * ================ * * Overview: - * Initializes the bus-specific controller logic. + * Initializes EISA and PCI controller bus-specific logic. * * Returns: * None @@ -651,7 +560,7 @@ static int __devinit dfx_register(struct device *bdev) * None * * Assumptions: - * bp->base has already been set with the proper + * dev->base_addr has already been set with the proper * base I/O address for this device. * * Side Effects: @@ -662,103 +571,87 @@ static int __devinit dfx_register(struct device *bdev) static void __devinit dfx_bus_init(struct net_device *dev) { - DFX_board_t *bp = netdev_priv(dev); - struct device *bdev = bp->bus_dev; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - u8 val; + DFX_board_t *bp = dev->priv; + u8 val; /* used for I/O read/writes */ DBG_printk("In dfx_bus_init...\n"); - /* Initialize a pointer back to the net_device struct */ + /* + * Initialize base I/O address field in bp structure + * + * Note: bp->base_addr is the same as dev->base_addr. + * It's useful because often we'll need to read + * or write registers where we already have the + * bp pointer instead of the dev pointer. Having + * the base address in the bp structure will + * save a pointer dereference. + * + * IMPORTANT!! This field must be defined before + * any of the dfx_port_* inline functions are + * called. + */ + + bp->base_addr = dev->base_addr; + + /* And a pointer back to the net_device struct */ bp->dev = dev; /* Initialize adapter based on bus type */ - if (dfx_bus_tc) - dev->irq = to_tc_dev(bdev)->interrupt; - if (dfx_bus_eisa) { - unsigned long base_addr = to_eisa_device(bdev)->base_addr; + if (bp->bus_type == DFX_BUS_TYPE_EISA) + { + /* Get the interrupt level from the ESIC chip */ - /* Get the interrupt level from the ESIC chip. */ - val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); - val &= PI_CONFIG_STAT_0_M_IRQ; - val >>= PI_CONFIG_STAT_0_V_IRQ; + dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &val); + switch ((val & PI_CONFIG_STAT_0_M_IRQ) >> PI_CONFIG_STAT_0_V_IRQ) + { + case PI_CONFIG_STAT_0_IRQ_K_9: + dev->irq = 9; + break; - switch (val) { - case PI_CONFIG_STAT_0_IRQ_K_9: - dev->irq = 9; - break; + case PI_CONFIG_STAT_0_IRQ_K_10: + dev->irq = 10; + break; - case PI_CONFIG_STAT_0_IRQ_K_10: - dev->irq = 10; - break; + case PI_CONFIG_STAT_0_IRQ_K_11: + dev->irq = 11; + break; - case PI_CONFIG_STAT_0_IRQ_K_11: - dev->irq = 11; - break; + case PI_CONFIG_STAT_0_IRQ_K_15: + dev->irq = 15; + break; + } - case PI_CONFIG_STAT_0_IRQ_K_15: - dev->irq = 15; - break; - } + /* Enable access to I/O on the board by writing 0x03 to Function Control Register */ - /* - * Enable memory decoding (MEMCS0) and/or port decoding - * (IOCS1/IOCS0) as appropriate in Function Control - * Register. One of the port chip selects seems to be - * used for the Burst Holdoff register, but this bit of - * documentation is missing and as yet it has not been - * determined which of the two. This is also the reason - * the size of the decoded port range is twice as large - * as one required by the PDQ. - */ + dfx_port_write_byte(bp, PI_ESIC_K_FUNCTION_CNTRL, PI_ESIC_K_FUNCTION_CNTRL_IO_ENB); - /* Set the decode range of the board. */ - val = ((bp->base.port >> 12) << PI_IO_CMP_V_SLOT); - outb(base_addr + PI_ESIC_K_IO_ADD_CMP_0_1, val); - outb(base_addr + PI_ESIC_K_IO_ADD_CMP_0_0, 0); - outb(base_addr + PI_ESIC_K_IO_ADD_CMP_1_1, val); - outb(base_addr + PI_ESIC_K_IO_ADD_CMP_1_0, 0); - val = PI_ESIC_K_CSR_IO_LEN - 1; - outb(base_addr + PI_ESIC_K_IO_ADD_MASK_0_1, (val >> 8) & 0xff); - outb(base_addr + PI_ESIC_K_IO_ADD_MASK_0_0, val & 0xff); - outb(base_addr + PI_ESIC_K_IO_ADD_MASK_1_1, (val >> 8) & 0xff); - outb(base_addr + PI_ESIC_K_IO_ADD_MASK_1_0, val & 0xff); - - /* Enable the decoders. */ - val = PI_FUNCTION_CNTRL_M_IOCS1 | PI_FUNCTION_CNTRL_M_IOCS0; - if (dfx_use_mmio) - val |= PI_FUNCTION_CNTRL_M_MEMCS0; - outb(base_addr + PI_ESIC_K_FUNCTION_CNTRL, val); + /* Set the I/O decode range of the board */ - /* - * Enable access to the rest of the module - * (including PDQ and packet memory). - */ - val = PI_SLOT_CNTRL_M_ENB; - outb(base_addr + PI_ESIC_K_SLOT_CNTRL, val); + val = ((dev->base_addr >> 12) << PI_IO_CMP_V_SLOT); + dfx_port_write_byte(bp, PI_ESIC_K_IO_CMP_0_1, val); + dfx_port_write_byte(bp, PI_ESIC_K_IO_CMP_1_1, val); + + /* Enable access to rest of module (including PDQ and packet memory) */ + + dfx_port_write_byte(bp, PI_ESIC_K_SLOT_CNTRL, PI_SLOT_CNTRL_M_ENB); /* - * Map PDQ registers into memory or port space. This is - * done with a bit in the Burst Holdoff register. + * Map PDQ registers into I/O space. This is done by clearing a bit + * in Burst Holdoff register. */ - val = inb(base_addr + PI_DEFEA_K_BURST_HOLDOFF); - if (dfx_use_mmio) - val |= PI_BURST_HOLDOFF_V_MEM_MAP; - else - val &= ~PI_BURST_HOLDOFF_V_MEM_MAP; - outb(base_addr + PI_DEFEA_K_BURST_HOLDOFF, val); + + dfx_port_read_byte(bp, PI_ESIC_K_BURST_HOLDOFF, &val); + dfx_port_write_byte(bp, PI_ESIC_K_BURST_HOLDOFF, (val & ~PI_BURST_HOLDOFF_M_MEM_MAP)); /* Enable interrupts at EISA bus interface chip (ESIC) */ - val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); - val |= PI_CONFIG_STAT_0_M_INT_ENB; - outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, val); - } - if (dfx_bus_pci) { - struct pci_dev *pdev = to_pci_dev(bdev); + + dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &val); + dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, (val | PI_CONFIG_STAT_0_M_INT_ENB)); + } + else + { + struct pci_dev *pdev = bp->pci_dev; /* Get the interrupt level from the PCI Configuration Table */ @@ -767,70 +660,17 @@ static void __devinit dfx_bus_init(struct net_device *dev) /* Check Latency Timer and set if less than minimal */ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &val); - if (val < PFI_K_LAT_TIMER_MIN) { + if (val < PFI_K_LAT_TIMER_MIN) /* if less than min, override with default */ + { val = PFI_K_LAT_TIMER_DEF; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, val); - } + } /* Enable interrupts at PCI bus interface chip (PFI) */ - val = PFI_MODE_M_PDQ_INT_ENB | PFI_MODE_M_DMA_ENB; - dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, val); - } -} -/* - * ================== - * = dfx_bus_uninit = - * ================== - * - * Overview: - * Uninitializes the bus-specific controller logic. - * - * Returns: - * None - * - * Arguments: - * dev - pointer to device information - * - * Functional Description: - * Perform bus-specific logic uninitialization. - * - * Return Codes: - * None - * - * Assumptions: - * bp->base has already been set with the proper - * base I/O address for this device. - * - * Side Effects: - * Interrupts are disabled at the adapter bus-specific logic. - */ - -static void __devinit dfx_bus_uninit(struct net_device *dev) -{ - DFX_board_t *bp = netdev_priv(dev); - struct device *bdev = bp->bus_dev; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - u8 val; - - DBG_printk("In dfx_bus_uninit...\n"); - - /* Uninitialize adapter based on bus type */ - - if (dfx_bus_eisa) { - unsigned long base_addr = to_eisa_device(bdev)->base_addr; - - /* Disable interrupts at EISA bus interface chip (ESIC) */ - val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); - val &= ~PI_CONFIG_STAT_0_M_INT_ENB; - outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, val); - } - if (dfx_bus_pci) { - /* Disable interrupts at PCI bus interface chip (PFI) */ - dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, 0); + dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, (PFI_MODE_M_PDQ_INT_ENB | PFI_MODE_M_DMA_ENB)); + } } -} /* @@ -865,16 +705,18 @@ static void __devinit dfx_bus_uninit(struct net_device *dev) static void __devinit dfx_bus_config_check(DFX_board_t *bp) { - struct device __unused *bdev = bp->bus_dev; - int dfx_bus_eisa = DFX_BUS_EISA(bdev); int status; /* return code from adapter port control call */ + u32 slot_id; /* EISA-bus hardware id (DEC3001, DEC3002,...) */ u32 host_data; /* LW data returned from port control call */ DBG_printk("In dfx_bus_config_check...\n"); /* Configuration check only valid for EISA adapter */ - if (dfx_bus_eisa) { + if (bp->bus_type == DFX_BUS_TYPE_EISA) + { + dfx_port_read_long(bp, PI_ESIC_K_SLOT_ID, &slot_id); + /* * First check if revision 2 EISA controller. Rev. 1 cards used * PDQ revision B, so no workaround needed in this case. Rev. 3 @@ -882,11 +724,14 @@ static void __devinit dfx_bus_config_check(DFX_board_t *bp) * case, either. Only Rev. 2 cards used either Rev. D or E * chips, so we must verify the chip revision on Rev. 2 cards. */ - if (to_eisa_device(bdev)->id.driver_data == DEFEA_PROD_ID_2) { + + if (slot_id == DEFEA_PROD_ID_2) + { /* - * Revision 2 FDDI EISA controller found, - * so let's check PDQ revision of adapter. + * Revision 2 FDDI EISA controller found, so let's check PDQ + * revision of adapter. */ + status = dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_SUB_CMD, PI_SUB_CMD_K_PDQ_REV_GET, @@ -960,20 +805,13 @@ static void __devinit dfx_bus_config_check(DFX_board_t *bp) */ static int __devinit dfx_driver_init(struct net_device *dev, - const char *print_name, - resource_size_t bar_start) + const char *print_name) { - DFX_board_t *bp = netdev_priv(dev); - struct device *bdev = bp->bus_dev; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - int alloc_size; /* total buffer size needed */ - char *top_v, *curr_v; /* virtual addrs into memory block */ - dma_addr_t top_p, curr_p; /* physical addrs into memory block */ - u32 data, le32; /* host data register value */ - char *board_name = NULL; + DFX_board_t *bp = dev->priv; + int alloc_size; /* total buffer size needed */ + char *top_v, *curr_v; /* virtual addrs into memory block */ + dma_addr_t top_p, curr_p; /* physical addrs into memory block */ + u32 data; /* host data register value */ DBG_printk("In dfx_driver_init...\n"); @@ -1022,8 +860,8 @@ static int __devinit dfx_driver_init(struct net_device *dev, print_name); return(DFX_K_FAILURE); } - le32 = cpu_to_le32(data); - memcpy(&bp->factory_mac_addr[0], &le32, sizeof(u32)); + data = cpu_to_le32(data); + memcpy(&bp->factory_mac_addr[0], &data, sizeof(u32)); if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_HI, 0, &data) != DFX_K_SUCCESS) { @@ -1031,8 +869,8 @@ static int __devinit dfx_driver_init(struct net_device *dev, print_name); return(DFX_K_FAILURE); } - le32 = cpu_to_le32(data); - memcpy(&bp->factory_mac_addr[4], &le32, sizeof(u16)); + data = cpu_to_le32(data); + memcpy(&bp->factory_mac_addr[4], &data, sizeof(u16)); /* * Set current address to factory address @@ -1042,18 +880,20 @@ static int __devinit dfx_driver_init(struct net_device *dev, */ memcpy(dev->dev_addr, bp->factory_mac_addr, FDDI_K_ALEN); - if (dfx_bus_tc) - board_name = "DEFTA"; - if (dfx_bus_eisa) - board_name = "DEFEA"; - if (dfx_bus_pci) - board_name = "DEFPA"; - pr_info("%s: %s at %saddr = 0x%llx, IRQ = %d, " - "Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", - print_name, board_name, dfx_use_mmio ? "" : "I/O ", - (long long)bar_start, dev->irq, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + if (bp->bus_type == DFX_BUS_TYPE_EISA) + printk("%s: DEFEA at I/O addr = 0x%lX, IRQ = %d, " + "Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", + print_name, dev->base_addr, dev->irq, + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5]); + else + printk("%s: DEFPA at I/O addr = 0x%lX, IRQ = %d, " + "Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", + print_name, dev->base_addr, dev->irq, + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5]); /* * Get memory for descriptor block, consumer block, and other buffers @@ -1068,9 +908,8 @@ static int __devinit dfx_driver_init(struct net_device *dev, #endif sizeof(PI_CONSUMER_BLOCK) + (PI_ALIGN_K_DESC_BLK - 1); - bp->kmalloced = top_v = dma_alloc_coherent(bp->bus_dev, alloc_size, - &bp->kmalloced_dma, - GFP_ATOMIC); + bp->kmalloced = top_v = pci_alloc_consistent(bp->pci_dev, alloc_size, + &bp->kmalloced_dma); if (top_v == NULL) { printk("%s: Could not allocate memory for host buffers " "and structures!\n", print_name); @@ -1380,15 +1219,14 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) static int dfx_open(struct net_device *dev) { - DFX_board_t *bp = netdev_priv(dev); int ret; + DFX_board_t *bp = dev->priv; DBG_printk("In dfx_open...\n"); /* Register IRQ - support shared interrupts by passing device ptr */ - ret = request_irq(dev->irq, dfx_interrupt, IRQF_SHARED, dev->name, - dev); + ret = request_irq(dev->irq, dfx_interrupt, IRQF_SHARED, dev->name, dev); if (ret) { printk(KERN_ERR "%s: Requested IRQ %d is busy\n", dev->name, dev->irq); return ret; @@ -1471,7 +1309,7 @@ static int dfx_open(struct net_device *dev) static int dfx_close(struct net_device *dev) { - DFX_board_t *bp = netdev_priv(dev); + DFX_board_t *bp = dev->priv; DBG_printk("In dfx_close...\n"); @@ -1807,7 +1645,7 @@ static void dfx_int_type_0_process(DFX_board_t *bp) static void dfx_int_common(struct net_device *dev) { - DFX_board_t *bp = netdev_priv(dev); + DFX_board_t *bp = dev->priv; PI_UINT32 port_status; /* Port Status register */ /* Process xmt interrupts - frequent case, so always call this routine */ @@ -1877,16 +1715,18 @@ static void dfx_int_common(struct net_device *dev) static irqreturn_t dfx_interrupt(int irq, void *dev_id) { - struct net_device *dev = dev_id; - DFX_board_t *bp = netdev_priv(dev); - struct device *bdev = bp->bus_dev; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); + struct net_device *dev = dev_id; + DFX_board_t *bp; /* private board structure pointer */ + + /* Get board pointer only if device structure is valid */ + + bp = dev->priv; + + /* See if we're already servicing an interrupt */ /* Service adapter interrupts */ - if (dfx_bus_pci) { + if (bp->bus_type == DFX_BUS_TYPE_PCI) { u32 status; dfx_port_read_long(bp, PFI_K_REG_STATUS, &status); @@ -1910,12 +1750,10 @@ static irqreturn_t dfx_interrupt(int irq, void *dev_id) PFI_MODE_M_DMA_ENB)); spin_unlock(&bp->lock); - } - if (dfx_bus_eisa) { - unsigned long base_addr = to_eisa_device(bdev)->base_addr; + } else { u8 status; - status = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); + dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &status); if (!(status & PI_CONFIG_STAT_0_M_PEND)) return IRQ_NONE; @@ -1923,35 +1761,15 @@ static irqreturn_t dfx_interrupt(int irq, void *dev_id) /* Disable interrupts at the ESIC */ status &= ~PI_CONFIG_STAT_0_M_INT_ENB; - outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, status); + dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status); /* Call interrupt service routine for this adapter */ dfx_int_common(dev); /* Reenable interrupts at the ESIC */ - status = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); + dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &status); status |= PI_CONFIG_STAT_0_M_INT_ENB; - outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, status); - - spin_unlock(&bp->lock); - } - if (dfx_bus_tc) { - u32 status; - - dfx_port_read_long(bp, PI_PDQ_K_REG_PORT_STATUS, &status); - if (!(status & (PI_PSTATUS_M_RCV_DATA_PENDING | - PI_PSTATUS_M_XMT_DATA_PENDING | - PI_PSTATUS_M_SMT_HOST_PENDING | - PI_PSTATUS_M_UNSOL_PENDING | - PI_PSTATUS_M_CMD_RSP_PENDING | - PI_PSTATUS_M_CMD_REQ_PENDING | - PI_PSTATUS_M_TYPE_0_PENDING))) - return IRQ_NONE; - - spin_lock(&bp->lock); - - /* Call interrupt service routine for this adapter */ - dfx_int_common(dev); + dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status); spin_unlock(&bp->lock); } @@ -2005,7 +1823,7 @@ static irqreturn_t dfx_interrupt(int irq, void *dev_id) static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) { - DFX_board_t *bp = netdev_priv(dev); + DFX_board_t *bp = dev->priv; /* Fill the bp->stats structure with driver-maintained counters */ @@ -2191,8 +2009,8 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) */ static void dfx_ctl_set_multicast_list(struct net_device *dev) -{ - DFX_board_t *bp = netdev_priv(dev); + { + DFX_board_t *bp = dev->priv; int i; /* used as index in for loop */ struct dev_mc_list *dmi; /* ptr to multicast addr entry */ @@ -2306,8 +2124,8 @@ static void dfx_ctl_set_multicast_list(struct net_device *dev) static int dfx_ctl_set_mac_address(struct net_device *dev, void *addr) { + DFX_board_t *bp = dev->priv; struct sockaddr *p_sockaddr = (struct sockaddr *)addr; - DFX_board_t *bp = netdev_priv(dev); /* Copy unicast address to driver-maintained structs and update count */ @@ -2946,9 +2764,9 @@ static int dfx_rcv_init(DFX_board_t *bp, int get_buffers) my_skb_align(newskb, 128); bp->descr_block_virt->rcv_data[i + j].long_1 = - (u32)dma_map_single(bp->bus_dev, newskb->data, + (u32)pci_map_single(bp->pci_dev, newskb->data, NEW_SKB_SIZE, - DMA_FROM_DEVICE); + PCI_DMA_FROMDEVICE); /* * p_rcv_buff_va is only used inside the * kernel so we put the skb pointer here. @@ -3062,17 +2880,17 @@ static void dfx_rcv_queue_process( my_skb_align(newskb, 128); skb = (struct sk_buff *)bp->p_rcv_buff_va[entry]; - dma_unmap_single(bp->bus_dev, + pci_unmap_single(bp->pci_dev, bp->descr_block_virt->rcv_data[entry].long_1, NEW_SKB_SIZE, - DMA_FROM_DEVICE); + PCI_DMA_FROMDEVICE); skb_reserve(skb, RCV_BUFF_K_PADDING); bp->p_rcv_buff_va[entry] = (char *)newskb; bp->descr_block_virt->rcv_data[entry].long_1 = - (u32)dma_map_single(bp->bus_dev, + (u32)pci_map_single(bp->pci_dev, newskb->data, NEW_SKB_SIZE, - DMA_FROM_DEVICE); + PCI_DMA_FROMDEVICE); } else skb = NULL; } else @@ -3192,7 +3010,7 @@ static int dfx_xmt_queue_pkt( ) { - DFX_board_t *bp = netdev_priv(dev); + DFX_board_t *bp = dev->priv; u8 prod; /* local transmit producer index */ PI_XMT_DESCR *p_xmt_descr; /* ptr to transmit descriptor block entry */ XMT_DRIVER_DESCR *p_xmt_drv_descr; /* ptr to transmit driver descriptor */ @@ -3298,8 +3116,8 @@ static int dfx_xmt_queue_pkt( */ p_xmt_descr->long_0 = (u32) (PI_XMT_DESCR_M_SOP | PI_XMT_DESCR_M_EOP | ((skb->len) << PI_XMT_DESCR_V_SEG_LEN)); - p_xmt_descr->long_1 = (u32)dma_map_single(bp->bus_dev, skb->data, - skb->len, DMA_TO_DEVICE); + p_xmt_descr->long_1 = (u32)pci_map_single(bp->pci_dev, skb->data, + skb->len, PCI_DMA_TODEVICE); /* * Verify that descriptor is actually available @@ -3402,10 +3220,10 @@ static int dfx_xmt_done(DFX_board_t *bp) /* Return skb to operating system */ comp = bp->rcv_xmt_reg.index.xmt_comp; - dma_unmap_single(bp->bus_dev, + pci_unmap_single(bp->pci_dev, bp->descr_block_virt->xmt_data[comp].long_1, p_xmt_drv_descr->p_skb->len, - DMA_TO_DEVICE); + PCI_DMA_TODEVICE); dev_kfree_skb_irq(p_xmt_drv_descr->p_skb); /* @@ -3526,10 +3344,10 @@ static void dfx_xmt_flush( DFX_board_t *bp ) /* Return skb to operating system */ comp = bp->rcv_xmt_reg.index.xmt_comp; - dma_unmap_single(bp->bus_dev, + pci_unmap_single(bp->pci_dev, bp->descr_block_virt->xmt_data[comp].long_1, p_xmt_drv_descr->p_skb->len, - DMA_TO_DEVICE); + PCI_DMA_TODEVICE); dev_kfree_skb(p_xmt_drv_descr->p_skb); /* Increment transmit error counter */ @@ -3557,44 +3375,13 @@ static void dfx_xmt_flush( DFX_board_t *bp ) bp->cons_block_virt->xmt_rcv_data = prod_cons; } -/* - * ================== - * = dfx_unregister = - * ================== - * - * Overview: - * Shuts down an FDDI controller - * - * Returns: - * Condition code - * - * Arguments: - * bdev - pointer to device information - * - * Functional Description: - * - * Return Codes: - * None - * - * Assumptions: - * It compiles so it should work :-( (PCI cards do :-) - * - * Side Effects: - * Device structures for FDDI adapters (fddi0, fddi1, etc) are - * freed. - */ -static void __devexit dfx_unregister(struct device *bdev) +static void __devexit dfx_remove_one_pci_or_eisa(struct pci_dev *pdev, struct net_device *dev) { - struct net_device *dev = dev_get_drvdata(bdev); - DFX_board_t *bp = netdev_priv(dev); - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - resource_size_t bar_start = 0; /* pointer to port */ - resource_size_t bar_len = 0; /* resource length */ + DFX_board_t *bp = dev->priv; int alloc_size; /* total buffer size used */ unregister_netdev(dev); + release_region(dev->base_addr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN ); alloc_size = sizeof(PI_DESCR_BLOCK) + PI_CMD_REQ_K_SIZE_MAX + PI_CMD_RSP_K_SIZE_MAX + @@ -3604,141 +3391,78 @@ static void __devexit dfx_unregister(struct device *bdev) sizeof(PI_CONSUMER_BLOCK) + (PI_ALIGN_K_DESC_BLK - 1); if (bp->kmalloced) - dma_free_coherent(bdev, alloc_size, - bp->kmalloced, bp->kmalloced_dma); - - dfx_bus_uninit(dev); - - dfx_get_bars(bdev, &bar_start, &bar_len); - if (dfx_use_mmio) { - iounmap(bp->base.mem); - release_mem_region(bar_start, bar_len); - } else - release_region(bar_start, bar_len); - - if (dfx_bus_pci) - pci_disable_device(to_pci_dev(bdev)); - + pci_free_consistent(pdev, alloc_size, bp->kmalloced, + bp->kmalloced_dma); free_netdev(dev); } +static void __devexit dfx_remove_one (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); -static int __devinit __unused dfx_dev_register(struct device *); -static int __devexit __unused dfx_dev_unregister(struct device *); - -#ifdef CONFIG_PCI -static int __devinit dfx_pci_register(struct pci_dev *, - const struct pci_device_id *); -static void __devexit dfx_pci_unregister(struct pci_dev *); + dfx_remove_one_pci_or_eisa(pdev, dev); + pci_set_drvdata(pdev, NULL); +} -static struct pci_device_id dfx_pci_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI) }, - { } +static struct pci_device_id dfx_pci_tbl[] = { + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI, PCI_ANY_ID, PCI_ANY_ID, }, + { 0, } }; -MODULE_DEVICE_TABLE(pci, dfx_pci_table); +MODULE_DEVICE_TABLE(pci, dfx_pci_tbl); -static struct pci_driver dfx_pci_driver = { +static struct pci_driver dfx_driver = { .name = "defxx", - .id_table = dfx_pci_table, - .probe = dfx_pci_register, - .remove = __devexit_p(dfx_pci_unregister), + .probe = dfx_init_one, + .remove = __devexit_p(dfx_remove_one), + .id_table = dfx_pci_tbl, }; -static __devinit int dfx_pci_register(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - return dfx_register(&pdev->dev); -} +static int dfx_have_pci; +static int dfx_have_eisa; -static void __devexit dfx_pci_unregister(struct pci_dev *pdev) -{ - dfx_unregister(&pdev->dev); -} -#endif /* CONFIG_PCI */ - -#ifdef CONFIG_EISA -static struct eisa_device_id dfx_eisa_table[] = { - { "DEC3001", DEFEA_PROD_ID_1 }, - { "DEC3002", DEFEA_PROD_ID_2 }, - { "DEC3003", DEFEA_PROD_ID_3 }, - { "DEC3004", DEFEA_PROD_ID_4 }, - { } -}; -MODULE_DEVICE_TABLE(eisa, dfx_eisa_table); - -static struct eisa_driver dfx_eisa_driver = { - .id_table = dfx_eisa_table, - .driver = { - .name = "defxx", - .bus = &eisa_bus_type, - .probe = dfx_dev_register, - .remove = __devexit_p(dfx_dev_unregister), - }, -}; -#endif /* CONFIG_EISA */ - -#ifdef CONFIG_TC -static struct tc_device_id const dfx_tc_table[] = { - { "DEC ", "PMAF-FA " }, - { "DEC ", "PMAF-FD " }, - { "DEC ", "PMAF-FS " }, - { "DEC ", "PMAF-FU " }, - { } -}; -MODULE_DEVICE_TABLE(tc, dfx_tc_table); - -static struct tc_driver dfx_tc_driver = { - .id_table = dfx_tc_table, - .driver = { - .name = "defxx", - .bus = &tc_bus_type, - .probe = dfx_dev_register, - .remove = __devexit_p(dfx_dev_unregister), - }, -}; -#endif /* CONFIG_TC */ -static int __devinit __unused dfx_dev_register(struct device *dev) +static void __exit dfx_eisa_cleanup(void) { - int status; + struct net_device *dev = root_dfx_eisa_dev; - status = dfx_register(dev); - if (!status) - get_device(dev); - return status; + while (dev) + { + struct net_device *tmp; + DFX_board_t *bp; + + bp = (DFX_board_t*)dev->priv; + tmp = bp->next; + dfx_remove_one_pci_or_eisa(NULL, dev); + dev = tmp; + } } -static int __devexit __unused dfx_dev_unregister(struct device *dev) +static int __init dfx_init(void) { - put_device(dev); - dfx_unregister(dev); - return 0; -} + int rc_pci, rc_eisa; + rc_pci = pci_register_driver(&dfx_driver); + if (rc_pci >= 0) dfx_have_pci = 1; -static int __devinit dfx_init(void) -{ - int status; - - status = pci_register_driver(&dfx_pci_driver); - if (!status) - status = eisa_driver_register(&dfx_eisa_driver); - if (!status) - status = tc_register_driver(&dfx_tc_driver); - return status; + rc_eisa = dfx_eisa_init(); + if (rc_eisa >= 0) dfx_have_eisa = 1; + + return ((rc_eisa < 0) ? 0 : rc_eisa) + ((rc_pci < 0) ? 0 : rc_pci); } -static void __devexit dfx_cleanup(void) +static void __exit dfx_cleanup(void) { - tc_unregister_driver(&dfx_tc_driver); - eisa_driver_unregister(&dfx_eisa_driver); - pci_unregister_driver(&dfx_pci_driver); + if (dfx_have_pci) + pci_unregister_driver(&dfx_driver); + if (dfx_have_eisa) + dfx_eisa_cleanup(); + } module_init(dfx_init); module_exit(dfx_cleanup); MODULE_AUTHOR("Lawrence V. Stefani"); -MODULE_DESCRIPTION("DEC FDDIcontroller TC/EISA/PCI (DEFTA/DEFEA/DEFPA) driver " +MODULE_DESCRIPTION("DEC FDDIcontroller EISA/PCI (DEFEA/DEFPA) driver " DRV_VERSION " " DRV_RELDATE); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/defxx.h b/trunk/drivers/net/defxx.h index 19a6f64df198..2ce8f97253eb 100644 --- a/trunk/drivers/net/defxx.h +++ b/trunk/drivers/net/defxx.h @@ -26,7 +26,6 @@ * 12-Sep-96 LVS Removed packet request header pointers. * 04 Aug 2003 macro Converted to the DMA API. * 23 Oct 2006 macro Big-endian host support. - * 14 Dec 2006 macro TURBOchannel support. */ #ifndef _DEFXX_H_ @@ -1472,17 +1471,9 @@ typedef union #endif /* __BIG_ENDIAN */ -/* Define TC PDQ CSR offset and length */ - -#define PI_TC_K_CSR_OFFSET 0x100000 -#define PI_TC_K_CSR_LEN 0x40 /* 64 bytes */ - /* Define EISA controller register offsets */ -#define PI_ESIC_K_CSR_IO_LEN 0x80 /* 128 bytes */ - -#define PI_DEFEA_K_BURST_HOLDOFF 0x040 - +#define PI_ESIC_K_BURST_HOLDOFF 0x040 #define PI_ESIC_K_SLOT_ID 0xC80 #define PI_ESIC_K_SLOT_CNTRL 0xC84 #define PI_ESIC_K_MEM_ADD_CMP_0 0xC85 @@ -1497,14 +1488,14 @@ typedef union #define PI_ESIC_K_MEM_ADD_LO_CMP_0 0xC8E #define PI_ESIC_K_MEM_ADD_LO_CMP_1 0xC8F #define PI_ESIC_K_MEM_ADD_LO_CMP_2 0xC90 -#define PI_ESIC_K_IO_ADD_CMP_0_0 0xC91 -#define PI_ESIC_K_IO_ADD_CMP_0_1 0xC92 -#define PI_ESIC_K_IO_ADD_CMP_1_0 0xC93 -#define PI_ESIC_K_IO_ADD_CMP_1_1 0xC94 -#define PI_ESIC_K_IO_ADD_CMP_2_0 0xC95 -#define PI_ESIC_K_IO_ADD_CMP_2_1 0xC96 -#define PI_ESIC_K_IO_ADD_CMP_3_0 0xC97 -#define PI_ESIC_K_IO_ADD_CMP_3_1 0xC98 +#define PI_ESIC_K_IO_CMP_0_0 0xC91 +#define PI_ESIC_K_IO_CMP_0_1 0xC92 +#define PI_ESIC_K_IO_CMP_1_0 0xC93 +#define PI_ESIC_K_IO_CMP_1_1 0xC94 +#define PI_ESIC_K_IO_CMP_2_0 0xC95 +#define PI_ESIC_K_IO_CMP_2_1 0xC96 +#define PI_ESIC_K_IO_CMP_3_0 0xC97 +#define PI_ESIC_K_IO_CMP_3_1 0xC98 #define PI_ESIC_K_IO_ADD_MASK_0_0 0xC99 #define PI_ESIC_K_IO_ADD_MASK_0_1 0xC9A #define PI_ESIC_K_IO_ADD_MASK_1_0 0xC9B @@ -1527,16 +1518,11 @@ typedef union #define PI_ESIC_K_INPUT_PORT 0xCAC #define PI_ESIC_K_OUTPUT_PORT 0xCAD #define PI_ESIC_K_FUNCTION_CNTRL 0xCAE +#define PI_ESIC_K_CSR_IO_LEN PI_ESIC_K_FUNCTION_CNTRL+1 /* always last reg + 1 */ -/* Define the bits in the function control register. */ +/* Define the value all drivers must write to the function control register. */ -#define PI_FUNCTION_CNTRL_M_IOCS0 0x01 -#define PI_FUNCTION_CNTRL_M_IOCS1 0x02 -#define PI_FUNCTION_CNTRL_M_IOCS2 0x04 -#define PI_FUNCTION_CNTRL_M_IOCS3 0x08 -#define PI_FUNCTION_CNTRL_M_MEMCS0 0x10 -#define PI_FUNCTION_CNTRL_M_MEMCS1 0x20 -#define PI_FUNCTION_CNTRL_M_DMA 0x80 +#define PI_ESIC_K_FUNCTION_CNTRL_IO_ENB 0x03 /* Define the bits in the slot control register. */ @@ -1554,10 +1540,6 @@ typedef union #define PI_BURST_HOLDOFF_V_RESERVED 1 #define PI_BURST_HOLDOFF_V_MEM_MAP 0 -/* Define the implicit mask of the Memory Address Mask Register. */ - -#define PI_MEM_ADD_MASK_M 0x3ff - /* * Define the fields in the IO Compare registers. * The driver must initialize the slot field with the slot ID shifted by the @@ -1595,7 +1577,6 @@ typedef union #define DEFEA_PROD_ID_1 0x0130A310 /* DEC product 300, rev 1 */ #define DEFEA_PROD_ID_2 0x0230A310 /* DEC product 300, rev 2 */ #define DEFEA_PROD_ID_3 0x0330A310 /* DEC product 300, rev 3 */ -#define DEFEA_PROD_ID_4 0x0430A310 /* DEC product 300, rev 4 */ /**********************************************/ /* Digital PFI Specification v1.0 Definitions */ @@ -1652,6 +1633,12 @@ typedef union #define PFI_STATUS_V_FIFO_EMPTY 1 #define PFI_STATUS_V_DMA_IN_PROGRESS 0 +#define DFX_MAX_EISA_SLOTS 16 /* maximum number of EISA slots to scan */ +#define DFX_MAX_NUM_BOARDS 8 /* maximum number of adapters supported */ + +#define DFX_BUS_TYPE_PCI 0 /* type code for DEC FDDIcontroller/PCI */ +#define DFX_BUS_TYPE_EISA 1 /* type code for DEC FDDIcontroller/EISA */ + #define DFX_FC_PRH2_PRH1_PRH0 0x54003820 /* Packet Request Header bytes + FC */ #define DFX_PRH0_BYTE 0x20 /* Packet Request Header byte 0 */ #define DFX_PRH1_BYTE 0x38 /* Packet Request Header byte 1 */ @@ -1769,11 +1756,10 @@ typedef struct DFX_board_tag /* Store device, bus-specific, and parameter information for this adapter */ struct net_device *dev; /* pointer to device structure */ - union { - void __iomem *mem; - int port; - } base; /* base address */ - struct device *bus_dev; + struct net_device *next; + u32 bus_type; /* bus type (0 == PCI, 1 == EISA) */ + u16 base_addr; /* base I/O address (same as dev->base_addr) */ + struct pci_dev * pci_dev; u32 full_duplex_enb; /* FDDI Full Duplex enable (1 == on, 2 == off) */ u32 req_ttrt; /* requested TTRT value (in 80ns units) */ u32 burst_size; /* adapter burst size (enumerated) */ diff --git a/trunk/drivers/net/e2100.c b/trunk/drivers/net/e2100.c index b2b0a96218ca..c62d9c6363c6 100644 --- a/trunk/drivers/net/e2100.c +++ b/trunk/drivers/net/e2100.c @@ -355,7 +355,8 @@ e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring mem_on(ioaddr, shared_mem, (ring_offset>>8)); - memcpy_fromio(skb->data, ei_status.mem + (ring_offset & 0xff), count); + /* Packet is always in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, ei_status.mem + (ring_offset & 0xff), count, 0); mem_off(ioaddr); } diff --git a/trunk/drivers/net/es3210.c b/trunk/drivers/net/es3210.c index 822e5bfd1a71..2d2ea94a00bb 100644 --- a/trunk/drivers/net/es3210.c +++ b/trunk/drivers/net/es3210.c @@ -375,7 +375,7 @@ static void es_block_input(struct net_device *dev, int count, struct sk_buff *sk memcpy_fromio(skb->data + semi_count, ei_status.mem, count); } else { /* Packet is in one chunk. */ - memcpy_fromio(skb->data, xfer_start, count); + eth_io_copy_and_sum(skb, xfer_start, count, 0); } } diff --git a/trunk/drivers/net/macsonic.c b/trunk/drivers/net/macsonic.c index 8ca57a0a4c11..24f6050fbf33 100644 --- a/trunk/drivers/net/macsonic.c +++ b/trunk/drivers/net/macsonic.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index d98e53efa2ef..b3bf86422734 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -2780,6 +2780,7 @@ static const struct ethtool_ops mv643xx_ethtool_ops = { .get_link = mv643xx_eth_get_link, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, + .get_strings = mv643xx_get_strings, .get_stats_count = mv643xx_get_stats_count, .get_ethtool_stats = mv643xx_get_ethtool_stats, .get_strings = mv643xx_get_strings, diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 5598d86380b4..577babd4c938 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -2016,7 +2016,7 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, if (!skb) goto err_out; - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); + skb_reserve(skb, (align - 1) & (u32)skb->data); *sk_buff = skb; mapping = pci_map_single(pdev, skb->data, rx_buf_sz, @@ -2487,7 +2487,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, skb = dev_alloc_skb(pkt_size + align); if (skb) { - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); + skb_reserve(skb, (align - 1) & (u32)skb->data); eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); *sk_buff = skb; rtl8169_mark_to_asic(desc, rx_buf_sz); diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 8646b64994ab..639fbc0f16f3 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -7298,7 +7298,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) { struct iphdr *ip = lro->iph; struct tcphdr *tcp = lro->tcph; - __sum16 nchk; + u16 nchk; struct stat_block *statinfo = sp->mac_control.stats_info; DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 0de0c65f945a..a5e1a513deb5 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -727,12 +727,12 @@ struct lro { struct iphdr *iph; struct tcphdr *tcph; u32 tcp_next_seq; - __be32 tcp_ack; + u32 tcp_ack; int total_len; int frags_len; int sg_num; int in_use; - __be16 window; + u16 window; u32 cur_tsval; u32 cur_tsecr; u8 saw_ts; @@ -1005,7 +1005,7 @@ static int s2io_set_swapper(struct s2io_nic * sp); static void s2io_card_down(struct s2io_nic *nic); static int s2io_card_up(struct s2io_nic *nic); static int get_xena_rev_id(struct pci_dev *pdev); -static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit); +static int wait_for_cmd_complete(void *addr, u64 busy_bit); static int s2io_add_isr(struct s2io_nic * sp); static void s2io_rem_isr(struct s2io_nic * sp); diff --git a/trunk/drivers/net/slip.c b/trunk/drivers/net/slip.c index 2f4b1de7a2b4..a0806d262fc6 100644 --- a/trunk/drivers/net/slip.c +++ b/trunk/drivers/net/slip.c @@ -1343,12 +1343,15 @@ static int __init slip_init(void) printk(KERN_INFO "SLIP linefill/keepalive option.\n"); #endif - slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); + slip_devs = kmalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); if (!slip_devs) { printk(KERN_ERR "SLIP: Can't allocate slip devices array! Uaargh! (-> No SLIP available)\n"); return -ENOMEM; } + /* Clear the pointer array, we allocate devices when we need them */ + memset(slip_devs, 0, sizeof(struct net_device *)*slip_maxdev); + /* Fill in our line protocol discipline, and register it */ if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) { printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status); diff --git a/trunk/drivers/net/smc-mca.c b/trunk/drivers/net/smc-mca.c index ae1ae343beed..7122932eac90 100644 --- a/trunk/drivers/net/smc-mca.c +++ b/trunk/drivers/net/smc-mca.c @@ -482,7 +482,8 @@ static void ultramca_block_input(struct net_device *dev, int count, struct sk_bu count -= semi_count; memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); } else { - memcpy_fromio(skb->data, xfer_start, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, xfer_start, count, 0); } } diff --git a/trunk/drivers/net/smc-ultra.c b/trunk/drivers/net/smc-ultra.c index a52b22d7db65..d70bc9795346 100644 --- a/trunk/drivers/net/smc-ultra.c +++ b/trunk/drivers/net/smc-ultra.c @@ -454,7 +454,8 @@ ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ri count -= semi_count; memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); } else { - memcpy_fromio(skb->data, xfer_start, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, xfer_start, count, 0); } outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ diff --git a/trunk/drivers/net/smc-ultra32.c b/trunk/drivers/net/smc-ultra32.c index 88a30e56c64c..2c5319c62fa5 100644 --- a/trunk/drivers/net/smc-ultra32.c +++ b/trunk/drivers/net/smc-ultra32.c @@ -395,7 +395,8 @@ static void ultra32_block_input(struct net_device *dev, memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); } } else { - memcpy_fromio(skb->data, xfer_start, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, xfer_start, count, 0); } } diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 64ed8ff5b03a..bf6ff39e02bb 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -1907,7 +1907,7 @@ spider_net_stop(struct net_device *netdev) spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); /* free_irq(netdev->irq, netdev);*/ - free_irq(to_pci_dev(netdev->dev.parent)->irq, netdev); + free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, SPIDER_NET_DMA_TX_FEND_VALUE); diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index e136bae61970..135c0987deae 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -3380,7 +3380,7 @@ static int tg3_rx(struct tg3 *tp, int budget) } next_pkt_nopost: sw_idx++; - sw_idx &= (TG3_RX_RCB_RING_SIZE(tp) - 1); + sw_idx %= TG3_RX_RCB_RING_SIZE(tp); /* Refresh hw_idx to see if there is new work */ if (sw_idx == hw_idx) { diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index 31c97a6591a4..abb8611c5a91 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -1709,13 +1709,75 @@ static void adjust_link(struct net_device *dev) if (mii_info->speed != ugeth->oldspeed) { switch (mii_info->speed) { case 1000: - ugeth->ug_info->enet_interface = ENET_1000_RGMII; +#ifdef CONFIG_PPC_MPC836x +/* FIXME: This code is for 100Mbs BUG fixing, +remove this when it is fixed!!! */ + if (ugeth->ug_info->enet_interface == + ENET_1000_GMII) + /* Run the commands which initialize the PHY */ + { + tempval = + (u32) mii_info->mdio_read(ugeth-> + dev, mii_info->mii_id, 0x1b); + tempval |= 0x000f; + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, 0x1b, + (u16) tempval); + tempval = + (u32) mii_info->mdio_read(ugeth-> + dev, mii_info->mii_id, + MII_BMCR); + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, MII_BMCR, + (u16) (tempval | BMCR_RESET)); + } else if (ugeth->ug_info->enet_interface == + ENET_1000_RGMII) + /* Run the commands which initialize the PHY */ + { + tempval = + (u32) mii_info->mdio_read(ugeth-> + dev, mii_info->mii_id, 0x1b); + tempval = (tempval & ~0x000f) | 0x000b; + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, 0x1b, + (u16) tempval); + tempval = + (u32) mii_info->mdio_read(ugeth-> + dev, mii_info->mii_id, + MII_BMCR); + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, MII_BMCR, + (u16) (tempval | BMCR_RESET)); + } + msleep(4000); +#endif /* CONFIG_MPC8360 */ + adjust_enet_interface(ugeth); break; case 100: - ugeth->ug_info->enet_interface = ENET_100_RGMII; - break; case 10: - ugeth->ug_info->enet_interface = ENET_10_RGMII; +#ifdef CONFIG_PPC_MPC836x +/* FIXME: This code is for 100Mbs BUG fixing, +remove this lines when it will be fixed!!! */ + ugeth->ug_info->enet_interface = ENET_100_RGMII; + tempval = + (u32) mii_info->mdio_read(ugeth->dev, + mii_info->mii_id, + 0x1b); + tempval = (tempval & ~0x000f) | 0x000b; + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, 0x1b, + (u16) tempval); + tempval = + (u32) mii_info->mdio_read(ugeth->dev, + mii_info->mii_id, + MII_BMCR); + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, MII_BMCR, + (u16) (tempval | + BMCR_RESET)); + msleep(4000); +#endif /* CONFIG_MPC8360 */ + adjust_enet_interface(ugeth); break; default: ugeth_warn @@ -1723,7 +1785,6 @@ static void adjust_link(struct net_device *dev) dev->name, mii_info->speed); break; } - adjust_enet_interface(ugeth); ugeth_info("%s: Speed %dBT", dev->name, mii_info->speed); @@ -4072,7 +4133,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma static int mii_mng_configured = 0; const phandle *ph; const unsigned int *prop; - const void *mac_addr; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -4198,12 +4258,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ugeth->ug_info = ug_info; ugeth->dev = dev; - - mac_addr = get_property(np, "mac-address", NULL); - if (mac_addr == NULL) - mac_addr = get_property(np, "local-mac-address", NULL); - if (mac_addr) - memcpy(dev->dev_addr, mac_addr, 6); + memcpy(dev->dev_addr, get_property(np, "mac-address", NULL), 6); return 0; } diff --git a/trunk/drivers/net/ucc_geth_phy.c b/trunk/drivers/net/ucc_geth_phy.c index 6fda6d88be49..3c86592ce03c 100644 --- a/trunk/drivers/net/ucc_geth_phy.c +++ b/trunk/drivers/net/ucc_geth_phy.c @@ -376,8 +376,6 @@ static int marvell_init(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); ucc_geth_phy_write(mii_info, 0x14, 0x0cd2); - ucc_geth_phy_write(mii_info, 0x1b, - (ucc_geth_phy_read(mii_info, 0x1b) & ~0x000f) | 0x000b); ucc_geth_phy_write(mii_info, MII_BMCR, ucc_geth_phy_read(mii_info, MII_BMCR) | BMCR_RESET); msleep(4000); diff --git a/trunk/drivers/net/wan/pc300too.c b/trunk/drivers/net/wan/pc300too.c index bc156b51678a..79b2d5454d6b 100644 --- a/trunk/drivers/net/wan/pc300too.c +++ b/trunk/drivers/net/wan/pc300too.c @@ -101,8 +101,8 @@ typedef struct port_s { typedef struct card_s { int type; /* RSV, X21, etc. */ int n_ports; /* 1 or 2 ports */ - u8 __iomem *rambase; /* buffer memory base (virtual) */ - u8 __iomem *scabase; /* SCA memory base (virtual) */ + u8* __iomem rambase; /* buffer memory base (virtual) */ + u8* __iomem scabase; /* SCA memory base (virtual) */ plx9050 __iomem *plxbase; /* PLX registers memory base (virtual) */ u32 init_ctrl_value; /* Saved value - 9050 bug workaround */ u16 rx_ring_buffers; /* number of buffers in a ring */ @@ -134,7 +134,7 @@ typedef struct card_s { static void pc300_set_iface(port_t *port) { card_t *card = port->card; - u32 __iomem * init_ctrl = &card->plxbase->init_ctrl; + u32* init_ctrl = &card->plxbase->init_ctrl; u16 msci = get_msci(port); u8 rxs = port->rxs & CLK_BRG_MASK; u8 txs = port->txs & CLK_BRG_MASK; @@ -393,7 +393,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, /* PLX PCI 9050 workaround for local configuration register read bug */ pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, scaphys); - card->init_ctrl_value = readl(&((plx9050 __iomem *)card->scabase)->init_ctrl); + card->init_ctrl_value = readl(&((plx9050*)card->scabase)->init_ctrl); pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, plxphys); /* Reset PLX */ @@ -519,10 +519,10 @@ static struct pci_device_id pc300_pci_tbl[] __devinitdata = { static struct pci_driver pc300_pci_driver = { - .name = "PC300", - .id_table = pc300_pci_tbl, - .probe = pc300_pci_init_one, - .remove = pc300_pci_remove_one, + name: "PC300", + id_table: pc300_pci_tbl, + probe: pc300_pci_init_one, + remove: pc300_pci_remove_one, }; diff --git a/trunk/drivers/net/wd.c b/trunk/drivers/net/wd.c index a0326818ff2f..7f38012b9c92 100644 --- a/trunk/drivers/net/wd.c +++ b/trunk/drivers/net/wd.c @@ -433,7 +433,7 @@ wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_ memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); } else { /* Packet is in one chunk -- we can copy + cksum. */ - memcpy_fromio(skb->data, xfer_start, count); + eth_io_copy_and_sum(skb, xfer_start, count, 0); } /* Turn off 16 bit access so that reboot works. ISA brain-damage */ diff --git a/trunk/drivers/pcmcia/m32r_pcc.c b/trunk/drivers/pcmcia/m32r_pcc.c index 4dbef0762376..bbf025874d0c 100644 --- a/trunk/drivers/pcmcia/m32r_pcc.c +++ b/trunk/drivers/pcmcia/m32r_pcc.c @@ -722,7 +722,7 @@ static int __init init_m32r_pcc(void) /* Set up interrupt handler(s) */ for (i = 0 ; i < pcc_sockets ; i++) { - socket[i].socket.dev.parent = &pcc_device.dev; + socket[i].socket.dev.dev = &pcc_device.dev; socket[i].socket.ops = &pcc_operations; socket[i].socket.resource_ops = &pccard_static_ops; socket[i].socket.owner = THIS_MODULE; diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index 82f2ac87ccd4..94d3df62a5fa 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -305,7 +305,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, case RTC_IRQP_READ: if (ops->irq_set_freq) - err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); + err = put_user(rtc->irq_freq, (unsigned long *) arg); break; case RTC_IRQP_SET: diff --git a/trunk/drivers/rtc/rtc-pcf8563.c b/trunk/drivers/rtc/rtc-pcf8563.c index 038118bbfaea..4b72b8ef5d66 100644 --- a/trunk/drivers/rtc/rtc-pcf8563.c +++ b/trunk/drivers/rtc/rtc-pcf8563.c @@ -53,25 +53,6 @@ I2C_CLIENT_INSMOD; #define PCF8563_SC_LV 0x80 /* low voltage */ #define PCF8563_MO_C 0x80 /* century */ -struct pcf8563 { - struct i2c_client client; - /* - * The meaning of MO_C bit varies by the chip type. - * From PCF8563 datasheet: this bit is toggled when the years - * register overflows from 99 to 00 - * 0 indicates the century is 20xx - * 1 indicates the century is 19xx - * From RTC8564 datasheet: this bit indicates change of - * century. When the year digit data overflows from 99 to 00, - * this bit is set. By presetting it to 0 while still in the - * 20th century, it will be set in year 2000, ... - * There seems no reliable way to know how the system use this - * bit. So let's do it heuristically, assuming we are live in - * 1970...2069. - */ - int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ -}; - static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind); static int pcf8563_detach(struct i2c_client *client); @@ -81,7 +62,6 @@ static int pcf8563_detach(struct i2c_client *client); */ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) { - struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client); unsigned char buf[13] = { PCF8563_REG_ST1 }; struct i2c_msg msgs[] = { @@ -114,12 +94,8 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F); tm->tm_wday = buf[PCF8563_REG_DW] & 0x07; tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ - tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]); - if (tm->tm_year < 70) - tm->tm_year += 100; /* assume we are in 1970...2069 */ - /* detect the polarity heuristically. see note above. */ - pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ? - (tm->tm_year >= 100) : (tm->tm_year < 100); + tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]) + + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 0 : 100); dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " "mday=%d, mon=%d, year=%d, wday=%d\n", @@ -138,7 +114,6 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) { - struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client); int i, err; unsigned char buf[9]; @@ -160,7 +135,7 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) /* year and century */ buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100); - if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100)) + if (tm->tm_year < 100) buf[PCF8563_REG_MO] |= PCF8563_MO_C; buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; @@ -273,7 +248,6 @@ static struct i2c_driver pcf8563_driver = { static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) { - struct pcf8563 *pcf8563; struct i2c_client *client; struct rtc_device *rtc; @@ -286,12 +260,11 @@ static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) goto exit; } - if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) { + if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - client = &pcf8563->client; client->addr = address; client->driver = &pcf8563_driver; client->adapter = adapter; @@ -328,7 +301,7 @@ static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) i2c_detach_client(client); exit_kfree: - kfree(pcf8563); + kfree(client); exit: return err; @@ -336,7 +309,6 @@ static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) static int pcf8563_detach(struct i2c_client *client) { - struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client); int err; struct rtc_device *rtc = i2c_get_clientdata(client); @@ -346,7 +318,7 @@ static int pcf8563_detach(struct i2c_client *client) if ((err = i2c_detach_client(client))) return err; - kfree(pcf8563); + kfree(client); return 0; } diff --git a/trunk/drivers/s390/char/monreader.c b/trunk/drivers/s390/char/monreader.c index 3a1a958fb5f2..a138b1510093 100644 --- a/trunk/drivers/s390/char/monreader.c +++ b/trunk/drivers/s390/char/monreader.c @@ -3,7 +3,7 @@ * * Character device driver for reading z/VM *MONITOR service records. * - * Copyright 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH. * * Author: Gerald Schaefer */ @@ -22,7 +22,7 @@ #include #include #include -#include +#include "../net/iucv.h" //#define MON_DEBUG /* Debug messages on/off */ @@ -50,13 +50,14 @@ static char mon_dcss_name[9] = "MONDCSS\0"; struct mon_msg { u32 pos; u32 mca_offset; - struct iucv_message msg; + iucv_MessagePending local_eib; char msglim_reached; char replied_msglim; }; struct mon_private { - struct iucv_path *path; + u16 pathid; + iucv_handle_t iucv_handle; struct mon_msg *msg_array[MON_MSGLIM]; unsigned int write_index; unsigned int read_index; @@ -74,6 +75,8 @@ static unsigned long mon_dcss_end; static DECLARE_WAIT_QUEUE_HEAD(mon_read_wait_queue); static DECLARE_WAIT_QUEUE_HEAD(mon_conn_wait_queue); +static u8 iucv_host[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + static u8 user_data_connect[16] = { /* Version code, must be 0x01 for shared mode */ 0x01, @@ -97,7 +100,8 @@ static u8 user_data_sever[16] = { * Create the 8 bytes EBCDIC DCSS segment name from * an ASCII name, incl. padding */ -static inline void dcss_mkname(char *ascii_name, char *ebcdic_name) +static inline void +dcss_mkname(char *ascii_name, char *ebcdic_name) { int i; @@ -115,7 +119,8 @@ static inline void dcss_mkname(char *ascii_name, char *ebcdic_name) * print appropriate error message for segment_load()/segment_type() * return code */ -static void mon_segment_warn(int rc, char* seg_name) +static void +mon_segment_warn(int rc, char* seg_name) { switch (rc) { case -ENOENT: @@ -161,37 +166,44 @@ static void mon_segment_warn(int rc, char* seg_name) } } -static inline unsigned long mon_mca_start(struct mon_msg *monmsg) +static inline unsigned long +mon_mca_start(struct mon_msg *monmsg) { - return *(u32 *) &monmsg->msg.rmmsg; + return monmsg->local_eib.ln1msg1.iprmmsg1_u32; } -static inline unsigned long mon_mca_end(struct mon_msg *monmsg) +static inline unsigned long +mon_mca_end(struct mon_msg *monmsg) { - return *(u32 *) &monmsg->msg.rmmsg[4]; + return monmsg->local_eib.ln1msg2.ipbfln1f; } -static inline u8 mon_mca_type(struct mon_msg *monmsg, u8 index) +static inline u8 +mon_mca_type(struct mon_msg *monmsg, u8 index) { return *((u8 *) mon_mca_start(monmsg) + monmsg->mca_offset + index); } -static inline u32 mon_mca_size(struct mon_msg *monmsg) +static inline u32 +mon_mca_size(struct mon_msg *monmsg) { return mon_mca_end(monmsg) - mon_mca_start(monmsg) + 1; } -static inline u32 mon_rec_start(struct mon_msg *monmsg) +static inline u32 +mon_rec_start(struct mon_msg *monmsg) { return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 4)); } -static inline u32 mon_rec_end(struct mon_msg *monmsg) +static inline u32 +mon_rec_end(struct mon_msg *monmsg) { return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 8)); } -static inline int mon_check_mca(struct mon_msg *monmsg) +static inline int +mon_check_mca(struct mon_msg *monmsg) { if ((mon_rec_end(monmsg) <= mon_rec_start(monmsg)) || (mon_rec_start(monmsg) < mon_dcss_start) || @@ -209,17 +221,20 @@ static inline int mon_check_mca(struct mon_msg *monmsg) return 0; } -static inline int mon_send_reply(struct mon_msg *monmsg, - struct mon_private *monpriv) +static inline int +mon_send_reply(struct mon_msg *monmsg, struct mon_private *monpriv) { + u8 prmmsg[8]; int rc; P_DEBUG("read, REPLY: pathid = 0x%04X, msgid = 0x%08X, trgcls = " "0x%08X\n\n", - monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class); - - rc = iucv_message_reply(monpriv->path, &monmsg->msg, - IUCV_IPRMDATA, NULL, 0); + monmsg->local_eib.ippathid, monmsg->local_eib.ipmsgid, + monmsg->local_eib.iptrgcls); + rc = iucv_reply_prmmsg(monmsg->local_eib.ippathid, + monmsg->local_eib.ipmsgid, + monmsg->local_eib.iptrgcls, + 0, prmmsg); atomic_dec(&monpriv->msglim_count); if (likely(!monmsg->msglim_reached)) { monmsg->pos = 0; @@ -236,19 +251,10 @@ static inline int mon_send_reply(struct mon_msg *monmsg, return 0; } -static inline void mon_free_mem(struct mon_private *monpriv) -{ - int i; - - for (i = 0; i < MON_MSGLIM; i++) - if (monpriv->msg_array[i]) - kfree(monpriv->msg_array[i]); - kfree(monpriv); -} - -static inline struct mon_private *mon_alloc_mem(void) +static inline struct mon_private * +mon_alloc_mem(void) { - int i; + int i,j; struct mon_private *monpriv; monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); @@ -261,15 +267,16 @@ static inline struct mon_private *mon_alloc_mem(void) GFP_KERNEL); if (!monpriv->msg_array[i]) { P_ERROR("open, no memory for msg_array\n"); - mon_free_mem(monpriv); + for (j = 0; j < i; j++) + kfree(monpriv->msg_array[j]); return NULL; } } return monpriv; } -static inline void mon_read_debug(struct mon_msg *monmsg, - struct mon_private *monpriv) +static inline void +mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv) { #ifdef MON_DEBUG u8 msg_type[2], mca_type; @@ -277,7 +284,7 @@ static inline void mon_read_debug(struct mon_msg *monmsg, records_len = mon_rec_end(monmsg) - mon_rec_start(monmsg) + 1; - memcpy(msg_type, &monmsg->msg.class, 2); + memcpy(msg_type, &monmsg->local_eib.iptrgcls, 2); EBCASC(msg_type, 2); mca_type = mon_mca_type(monmsg, 0); EBCASC(&mca_type, 1); @@ -285,7 +292,8 @@ static inline void mon_read_debug(struct mon_msg *monmsg, P_DEBUG("read, mon_read_index = %i, mon_write_index = %i\n", monpriv->read_index, monpriv->write_index); P_DEBUG("read, pathid = 0x%04X, msgid = 0x%08X, trgcls = 0x%08X\n", - monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class); + monmsg->local_eib.ippathid, monmsg->local_eib.ipmsgid, + monmsg->local_eib.iptrgcls); P_DEBUG("read, msg_type = '%c%c', mca_type = '%c' / 0x%X / 0x%X\n", msg_type[0], msg_type[1], mca_type ? mca_type : 'X', mon_mca_type(monmsg, 1), mon_mca_type(monmsg, 2)); @@ -298,7 +306,8 @@ static inline void mon_read_debug(struct mon_msg *monmsg, #endif } -static inline void mon_next_mca(struct mon_msg *monmsg) +static inline void +mon_next_mca(struct mon_msg *monmsg) { if (likely((mon_mca_size(monmsg) - monmsg->mca_offset) == 12)) return; @@ -307,7 +316,8 @@ static inline void mon_next_mca(struct mon_msg *monmsg) monmsg->pos = 0; } -static inline struct mon_msg *mon_next_message(struct mon_private *monpriv) +static inline struct mon_msg * +mon_next_message(struct mon_private *monpriv) { struct mon_msg *monmsg; @@ -332,37 +342,39 @@ static inline struct mon_msg *mon_next_message(struct mon_private *monpriv) /****************************************************************************** * IUCV handler * *****************************************************************************/ -static void mon_iucv_path_complete(struct iucv_path *path, u8 ipuser[16]) +static void +mon_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data) { - struct mon_private *monpriv = path->private; + struct mon_private *monpriv = (struct mon_private *) pgm_data; P_DEBUG("IUCV connection completed\n"); P_DEBUG("IUCV ACCEPT (from *MONITOR): Version = 0x%02X, Event = " "0x%02X, Sample = 0x%02X\n", - ipuser[0], ipuser[1], ipuser[2]); + eib->ipuser[0], eib->ipuser[1], eib->ipuser[2]); atomic_set(&monpriv->iucv_connected, 1); wake_up(&mon_conn_wait_queue); } -static void mon_iucv_path_severed(struct iucv_path *path, u8 ipuser[16]) +static void +mon_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data) { - struct mon_private *monpriv = path->private; + struct mon_private *monpriv = (struct mon_private *) pgm_data; - P_ERROR("IUCV connection severed with rc = 0x%X\n", ipuser[0]); - iucv_path_sever(path, NULL); + P_ERROR("IUCV connection severed with rc = 0x%X\n", + (u8) eib->ipuser[0]); atomic_set(&monpriv->iucv_severed, 1); wake_up(&mon_conn_wait_queue); wake_up_interruptible(&mon_read_wait_queue); } -static void mon_iucv_message_pending(struct iucv_path *path, - struct iucv_message *msg) +static void +mon_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data) { - struct mon_private *monpriv = path->private; + struct mon_private *monpriv = (struct mon_private *) pgm_data; P_DEBUG("IUCV message pending\n"); - memcpy(&monpriv->msg_array[monpriv->write_index]->msg, - msg, sizeof(*msg)); + memcpy(&monpriv->msg_array[monpriv->write_index]->local_eib, eib, + sizeof(iucv_MessagePending)); if (atomic_inc_return(&monpriv->msglim_count) == MON_MSGLIM) { P_WARNING("IUCV message pending, message limit (%i) reached\n", MON_MSGLIM); @@ -373,45 +385,54 @@ static void mon_iucv_message_pending(struct iucv_path *path, wake_up_interruptible(&mon_read_wait_queue); } -static struct iucv_handler monreader_iucv_handler = { - .path_complete = mon_iucv_path_complete, - .path_severed = mon_iucv_path_severed, - .message_pending = mon_iucv_message_pending, +static iucv_interrupt_ops_t mon_iucvops = { + .ConnectionComplete = mon_iucv_ConnectionComplete, + .ConnectionSevered = mon_iucv_ConnectionSevered, + .MessagePending = mon_iucv_MessagePending, }; /****************************************************************************** * file operations * *****************************************************************************/ -static int mon_open(struct inode *inode, struct file *filp) +static int +mon_open(struct inode *inode, struct file *filp) { + int rc, i; struct mon_private *monpriv; - int rc; /* * only one user allowed */ - rc = -EBUSY; if (test_and_set_bit(MON_IN_USE, &mon_in_use)) - goto out; + return -EBUSY; - rc = -ENOMEM; monpriv = mon_alloc_mem(); if (!monpriv) - goto out_use; + return -ENOMEM; /* - * Connect to *MONITOR service + * Register with IUCV and connect to *MONITOR service */ - monpriv->path = iucv_path_alloc(MON_MSGLIM, IUCV_IPRMDATA, GFP_KERNEL); - if (!monpriv->path) - goto out_priv; - rc = iucv_path_connect(monpriv->path, &monreader_iucv_handler, - MON_SERVICE, NULL, user_data_connect, monpriv); + monpriv->iucv_handle = iucv_register_program("my_monreader ", + MON_SERVICE, + NULL, + &mon_iucvops, + monpriv); + if (!monpriv->iucv_handle) { + P_ERROR("failed to register with iucv driver\n"); + rc = -EIO; + goto out_error; + } + P_INFO("open, registered with IUCV\n"); + + rc = iucv_connect(&monpriv->pathid, MON_MSGLIM, user_data_connect, + MON_SERVICE, iucv_host, IPRMDATA, NULL, NULL, + monpriv->iucv_handle, NULL); if (rc) { P_ERROR("iucv connection to *MONITOR failed with " "IPUSER SEVER code = %i\n", rc); rc = -EIO; - goto out_path; + goto out_unregister; } /* * Wait for connection confirmation @@ -423,23 +444,24 @@ static int mon_open(struct inode *inode, struct file *filp) atomic_set(&monpriv->iucv_severed, 0); atomic_set(&monpriv->iucv_connected, 0); rc = -EIO; - goto out_path; + goto out_unregister; } P_INFO("open, established connection to *MONITOR service\n\n"); filp->private_data = monpriv; return nonseekable_open(inode, filp); -out_path: - kfree(monpriv->path); -out_priv: - mon_free_mem(monpriv); -out_use: +out_unregister: + iucv_unregister_program(monpriv->iucv_handle); +out_error: + for (i = 0; i < MON_MSGLIM; i++) + kfree(monpriv->msg_array[i]); + kfree(monpriv); clear_bit(MON_IN_USE, &mon_in_use); -out: return rc; } -static int mon_close(struct inode *inode, struct file *filp) +static int +mon_close(struct inode *inode, struct file *filp) { int rc, i; struct mon_private *monpriv = filp->private_data; @@ -447,12 +469,18 @@ static int mon_close(struct inode *inode, struct file *filp) /* * Close IUCV connection and unregister */ - rc = iucv_path_sever(monpriv->path, user_data_sever); + rc = iucv_sever(monpriv->pathid, user_data_sever); if (rc) P_ERROR("close, iucv_sever failed with rc = %i\n", rc); else P_INFO("close, terminated connection to *MONITOR service\n"); + rc = iucv_unregister_program(monpriv->iucv_handle); + if (rc) + P_ERROR("close, iucv_unregister failed with rc = %i\n", rc); + else + P_INFO("close, unregistered with IUCV\n"); + atomic_set(&monpriv->iucv_severed, 0); atomic_set(&monpriv->iucv_connected, 0); atomic_set(&monpriv->read_ready, 0); @@ -467,8 +495,8 @@ static int mon_close(struct inode *inode, struct file *filp) return 0; } -static ssize_t mon_read(struct file *filp, char __user *data, - size_t count, loff_t *ppos) +static ssize_t +mon_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) { struct mon_private *monpriv = filp->private_data; struct mon_msg *monmsg; @@ -535,7 +563,8 @@ static ssize_t mon_read(struct file *filp, char __user *data, return count; } -static unsigned int mon_poll(struct file *filp, struct poll_table_struct *p) +static unsigned int +mon_poll(struct file *filp, struct poll_table_struct *p) { struct mon_private *monpriv = filp->private_data; @@ -564,7 +593,8 @@ static struct miscdevice mon_dev = { /****************************************************************************** * module init/exit * *****************************************************************************/ -static int __init mon_init(void) +static int __init +mon_init(void) { int rc; @@ -573,34 +603,22 @@ static int __init mon_init(void) return -ENODEV; } - /* - * Register with IUCV and connect to *MONITOR service - */ - rc = iucv_register(&monreader_iucv_handler, 1); - if (rc) { - P_ERROR("failed to register with iucv driver\n"); - return rc; - } - P_INFO("open, registered with IUCV\n"); - rc = segment_type(mon_dcss_name); if (rc < 0) { mon_segment_warn(rc, mon_dcss_name); - goto out_iucv; + return rc; } if (rc != SEG_TYPE_SC) { P_ERROR("segment %s has unsupported type, should be SC\n", mon_dcss_name); - rc = -EINVAL; - goto out_iucv; + return -EINVAL; } rc = segment_load(mon_dcss_name, SEGMENT_SHARED, &mon_dcss_start, &mon_dcss_end); if (rc < 0) { mon_segment_warn(rc, mon_dcss_name); - rc = -EINVAL; - goto out_iucv; + return -EINVAL; } dcss_mkname(mon_dcss_name, &user_data_connect[8]); @@ -616,16 +634,14 @@ static int __init mon_init(void) out: segment_unload(mon_dcss_name); -out_iucv: - iucv_unregister(&monreader_iucv_handler, 1); return rc; } -static void __exit mon_exit(void) +static void __exit +mon_exit(void) { segment_unload(mon_dcss_name); WARN_ON(misc_deregister(&mon_dev) != 0); - iucv_unregister(&monreader_iucv_handler, 1); return; } diff --git a/trunk/drivers/s390/char/vmlogrdr.c b/trunk/drivers/s390/char/vmlogrdr.c index 8432a76b961e..4f894dc2373b 100644 --- a/trunk/drivers/s390/char/vmlogrdr.c +++ b/trunk/drivers/s390/char/vmlogrdr.c @@ -3,7 +3,7 @@ * character device driver for reading z/VM system service records * * - * Copyright 2004 IBM Corporation + * Copyright (C) 2004 IBM Corporation * character device driver for reading z/VM system service records, * Version 1.0 * Author(s): Xenia Tkatschow @@ -21,7 +21,7 @@ #include #include #include -#include +#include "../net/iucv.h" #include #include #include @@ -60,11 +60,12 @@ struct vmlogrdr_priv_t { char system_service[8]; char internal_name[8]; char recording_name[8]; - struct iucv_path *path; + u16 pathid; int connection_established; int iucv_path_severed; - struct iucv_message local_interrupt_buffer; + iucv_MessagePending local_interrupt_buffer; atomic_t receive_ready; + iucv_handle_t iucv_handle; int minor_num; char * buffer; char * current_position; @@ -96,19 +97,37 @@ static struct file_operations vmlogrdr_fops = { }; -static void vmlogrdr_iucv_path_complete(struct iucv_path *, u8 ipuser[16]); -static void vmlogrdr_iucv_path_severed(struct iucv_path *, u8 ipuser[16]); -static void vmlogrdr_iucv_message_pending(struct iucv_path *, - struct iucv_message *); +static u8 iucvMagic[16] = { + 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 +}; -static struct iucv_handler vmlogrdr_iucv_handler = { - .path_complete = vmlogrdr_iucv_path_complete, - .path_severed = vmlogrdr_iucv_path_severed, - .message_pending = vmlogrdr_iucv_message_pending, +static u8 mask[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +static u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + +static void +vmlogrdr_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data); +static void +vmlogrdr_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data); +static void +vmlogrdr_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data); + + +static iucv_interrupt_ops_t vmlogrdr_iucvops = { + .ConnectionComplete = vmlogrdr_iucv_ConnectionComplete, + .ConnectionSevered = vmlogrdr_iucv_ConnectionSevered, + .MessagePending = vmlogrdr_iucv_MessagePending, +}; + static DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue); static DECLARE_WAIT_QUEUE_HEAD(read_wait_queue); @@ -157,29 +176,28 @@ static struct cdev *vmlogrdr_cdev = NULL; static int recording_class_AB; -static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 ipuser[16]) +static void +vmlogrdr_iucv_ConnectionComplete (iucv_ConnectionComplete * eib, + void * pgm_data) { - struct vmlogrdr_priv_t * logptr = path->private; - + struct vmlogrdr_priv_t * logptr = pgm_data; spin_lock(&logptr->priv_lock); logptr->connection_established = 1; spin_unlock(&logptr->priv_lock); wake_up(&conn_wait_queue); + return; } -static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 ipuser[16]) +static void +vmlogrdr_iucv_ConnectionSevered (iucv_ConnectionSevered * eib, void * pgm_data) { - struct vmlogrdr_priv_t * logptr = path->private; - u8 reason = (u8) ipuser[8]; + u8 reason = (u8) eib->ipuser[8]; + struct vmlogrdr_priv_t * logptr = pgm_data; printk (KERN_ERR "vmlogrdr: connection severed with" " reason %i\n", reason); - iucv_path_sever(path, NULL); - kfree(path); - logptr->path = NULL; - spin_lock(&logptr->priv_lock); logptr->connection_established = 0; logptr->iucv_path_severed = 1; @@ -191,10 +209,10 @@ static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 ipuser[16]) } -static void vmlogrdr_iucv_message_pending(struct iucv_path *path, - struct iucv_message *msg) +static void +vmlogrdr_iucv_MessagePending (iucv_MessagePending * eib, void * pgm_data) { - struct vmlogrdr_priv_t * logptr = path->private; + struct vmlogrdr_priv_t * logptr = pgm_data; /* * This function is the bottom half so it should be quick. @@ -202,15 +220,15 @@ static void vmlogrdr_iucv_message_pending(struct iucv_path *path, * the usage count */ spin_lock(&logptr->priv_lock); - memcpy(&logptr->local_interrupt_buffer, msg, sizeof(*msg)); + memcpy(&(logptr->local_interrupt_buffer), eib, sizeof(*eib)); atomic_inc(&logptr->receive_ready); spin_unlock(&logptr->priv_lock); wake_up_interruptible(&read_wait_queue); } -static int vmlogrdr_get_recording_class_AB(void) -{ +static int +vmlogrdr_get_recording_class_AB(void) { char cp_command[]="QUERY COMMAND RECORDING "; char cp_response[80]; char *tail; @@ -240,9 +258,8 @@ static int vmlogrdr_get_recording_class_AB(void) } -static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, - int action, int purge) -{ +static int +vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) { char cp_command[80]; char cp_response[160]; @@ -300,7 +317,8 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, } -static int vmlogrdr_open (struct inode *inode, struct file *filp) +static int +vmlogrdr_open (struct inode *inode, struct file *filp) { int dev_num = 0; struct vmlogrdr_priv_t * logptr = NULL; @@ -310,7 +328,10 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) dev_num = iminor(inode); if (dev_num > MAXMINOR) return -ENODEV; + logptr = &sys_ser[dev_num]; + if (logptr == NULL) + return -ENODEV; /* * only allow for blocking reads to be open @@ -323,38 +344,52 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) if (logptr->dev_in_use) { spin_unlock_bh(&logptr->priv_lock); return -EBUSY; + } else { + logptr->dev_in_use = 1; + spin_unlock_bh(&logptr->priv_lock); } - logptr->dev_in_use = 1; - logptr->connection_established = 0; - logptr->iucv_path_severed = 0; + atomic_set(&logptr->receive_ready, 0); logptr->buffer_free = 1; - spin_unlock_bh(&logptr->priv_lock); /* set the file options */ filp->private_data = logptr; filp->f_op = &vmlogrdr_fops; /* start recording for this service*/ - if (logptr->autorecording) { + ret=0; + if (logptr->autorecording) ret = vmlogrdr_recording(logptr,1,logptr->autopurge); - if (ret) - printk (KERN_WARNING "vmlogrdr: failed to start " - "recording automatically\n"); + if (ret) + printk (KERN_WARNING "vmlogrdr: failed to start " + "recording automatically\n"); + + /* Register with iucv driver */ + logptr->iucv_handle = iucv_register_program(iucvMagic, + logptr->system_service, mask, &vmlogrdr_iucvops, + logptr); + + if (logptr->iucv_handle == NULL) { + printk (KERN_ERR "vmlogrdr: failed to register with" + "iucv driver\n"); + goto not_registered; } /* create connection to the system service */ - logptr->path = iucv_path_alloc(10, 0, GFP_KERNEL); - if (!logptr->path) - goto out_dev; - connect_rc = iucv_path_connect(logptr->path, &vmlogrdr_iucv_handler, - logptr->system_service, NULL, NULL, - logptr); + spin_lock_bh(&logptr->priv_lock); + logptr->connection_established = 0; + logptr->iucv_path_severed = 0; + spin_unlock_bh(&logptr->priv_lock); + + connect_rc = iucv_connect (&(logptr->pathid), 10, iucvMagic, + logptr->system_service, iucv_host, 0, + NULL, NULL, + logptr->iucv_handle, NULL); if (connect_rc) { printk (KERN_ERR "vmlogrdr: iucv connection to %s " "failed with rc %i \n", logptr->system_service, connect_rc); - goto out_path; + goto not_connected; } /* We've issued the connect and now we must wait for a @@ -363,28 +398,35 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) */ wait_event(conn_wait_queue, (logptr->connection_established) || (logptr->iucv_path_severed)); - if (logptr->iucv_path_severed) - goto out_record; + if (logptr->iucv_path_severed) { + goto not_connected; + } + return nonseekable_open(inode, filp); -out_record: +not_connected: + iucv_unregister_program(logptr->iucv_handle); + logptr->iucv_handle = NULL; +not_registered: if (logptr->autorecording) vmlogrdr_recording(logptr,0,logptr->autopurge); -out_path: - kfree(logptr->path); /* kfree(NULL) is ok. */ - logptr->path = NULL; -out_dev: logptr->dev_in_use = 0; return -EIO; + + } -static int vmlogrdr_release (struct inode *inode, struct file *filp) +static int +vmlogrdr_release (struct inode *inode, struct file *filp) { int ret; struct vmlogrdr_priv_t * logptr = filp->private_data; + iucv_unregister_program(logptr->iucv_handle); + logptr->iucv_handle = NULL; + if (logptr->autorecording) { ret = vmlogrdr_recording(logptr,0,logptr->autopurge); if (ret) @@ -397,8 +439,8 @@ static int vmlogrdr_release (struct inode *inode, struct file *filp) } -static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) -{ +static int +vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) { int rc, *temp; /* we need to keep track of two data sizes here: * The number of bytes we need to receive from iucv and @@ -419,7 +461,8 @@ static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) * We need to return the total length of the record * + size of FENCE in the first 4 bytes of the buffer. */ - iucv_data_count = priv->local_interrupt_buffer.length; + iucv_data_count = + priv->local_interrupt_buffer.ln1msg2.ipbfln1f; user_data_count = sizeof(int); temp = (int*)priv->buffer; *temp= iucv_data_count + sizeof(FENCE); @@ -431,10 +474,14 @@ static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) */ if (iucv_data_count > NET_BUFFER_SIZE) iucv_data_count = NET_BUFFER_SIZE; - rc = iucv_message_receive(priv->path, - &priv->local_interrupt_buffer, - 0, buffer, iucv_data_count, - &priv->residual_length); + rc = iucv_receive(priv->pathid, + priv->local_interrupt_buffer.ipmsgid, + priv->local_interrupt_buffer.iptrgcls, + buffer, + iucv_data_count, + NULL, + NULL, + &priv->residual_length); spin_unlock_bh(&priv->priv_lock); /* An rc of 5 indicates that the record was bigger then * the buffer, which is OK for us. A 9 indicates that the @@ -466,8 +513,8 @@ static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) } -static ssize_t vmlogrdr_read(struct file *filp, char __user *data, - size_t count, loff_t * ppos) +static ssize_t +vmlogrdr_read(struct file *filp, char __user *data, size_t count, loff_t * ppos) { int rc; struct vmlogrdr_priv_t * priv = filp->private_data; @@ -499,10 +546,8 @@ static ssize_t vmlogrdr_read(struct file *filp, char __user *data, return count; } -static ssize_t vmlogrdr_autopurge_store(struct device * dev, - struct device_attribute *attr, - const char * buf, size_t count) -{ +static ssize_t +vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) { struct vmlogrdr_priv_t *priv = dev->driver_data; ssize_t ret = count; @@ -520,10 +565,8 @@ static ssize_t vmlogrdr_autopurge_store(struct device * dev, } -static ssize_t vmlogrdr_autopurge_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ +static ssize_t +vmlogrdr_autopurge_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vmlogrdr_priv_t *priv = dev->driver_data; return sprintf(buf, "%u\n", priv->autopurge); } @@ -533,10 +576,8 @@ static DEVICE_ATTR(autopurge, 0644, vmlogrdr_autopurge_show, vmlogrdr_autopurge_store); -static ssize_t vmlogrdr_purge_store(struct device * dev, - struct device_attribute *attr, - const char * buf, size_t count) -{ +static ssize_t +vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) { char cp_command[80]; char cp_response[80]; @@ -576,10 +617,9 @@ static ssize_t vmlogrdr_purge_store(struct device * dev, static DEVICE_ATTR(purge, 0200, NULL, vmlogrdr_purge_store); -static ssize_t vmlogrdr_autorecording_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ +static ssize_t +vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) { struct vmlogrdr_priv_t *priv = dev->driver_data; ssize_t ret = count; @@ -597,10 +637,8 @@ static ssize_t vmlogrdr_autorecording_store(struct device *dev, } -static ssize_t vmlogrdr_autorecording_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ +static ssize_t +vmlogrdr_autorecording_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vmlogrdr_priv_t *priv = dev->driver_data; return sprintf(buf, "%u\n", priv->autorecording); } @@ -610,10 +648,9 @@ static DEVICE_ATTR(autorecording, 0644, vmlogrdr_autorecording_show, vmlogrdr_autorecording_store); -static ssize_t vmlogrdr_recording_store(struct device * dev, - struct device_attribute *attr, - const char * buf, size_t count) -{ +static ssize_t +vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) { + struct vmlogrdr_priv_t *priv = dev->driver_data; ssize_t ret; @@ -638,9 +675,8 @@ static ssize_t vmlogrdr_recording_store(struct device * dev, static DEVICE_ATTR(recording, 0200, NULL, vmlogrdr_recording_store); -static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver, - char *buf) -{ +static ssize_t +vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) { char cp_command[] = "QUERY RECORDING "; int len; @@ -673,63 +709,52 @@ static struct device_driver vmlogrdr_driver = { }; -static int vmlogrdr_register_driver(void) -{ +static int +vmlogrdr_register_driver(void) { int ret; - /* Register with iucv driver */ - ret = iucv_register(&vmlogrdr_iucv_handler, 1); - if (ret) { - printk (KERN_ERR "vmlogrdr: failed to register with" - "iucv driver\n"); - goto out; - } - ret = driver_register(&vmlogrdr_driver); if (ret) { printk(KERN_ERR "vmlogrdr: failed to register driver.\n"); - goto out_iucv; + return ret; } ret = driver_create_file(&vmlogrdr_driver, &driver_attr_recording_status); if (ret) { printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n"); - goto out_driver; + goto unregdriver; } vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr"); if (IS_ERR(vmlogrdr_class)) { printk(KERN_ERR "vmlogrdr: failed to create class.\n"); - ret = PTR_ERR(vmlogrdr_class); - vmlogrdr_class = NULL; - goto out_attr; + ret=PTR_ERR(vmlogrdr_class); + vmlogrdr_class=NULL; + goto unregattr; } return 0; -out_attr: +unregattr: driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); -out_driver: +unregdriver: driver_unregister(&vmlogrdr_driver); -out_iucv: - iucv_unregister(&vmlogrdr_iucv_handler, 1); -out: return ret; } -static void vmlogrdr_unregister_driver(void) -{ +static void +vmlogrdr_unregister_driver(void) { class_destroy(vmlogrdr_class); vmlogrdr_class = NULL; driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); driver_unregister(&vmlogrdr_driver); - iucv_unregister(&vmlogrdr_iucv_handler, 1); + return; } -static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) -{ +static int +vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) { struct device *dev; int ret; @@ -778,10 +803,9 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) } -static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv) -{ - class_device_destroy(vmlogrdr_class, - MKDEV(vmlogrdr_major, priv->minor_num)); +static int +vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) { + class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num)); if (priv->device != NULL) { sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group); device_unregister(priv->device); @@ -791,8 +815,8 @@ static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv) } -static int vmlogrdr_register_cdev(dev_t dev) -{ +static int +vmlogrdr_register_cdev(dev_t dev) { int rc = 0; vmlogrdr_cdev = cdev_alloc(); if (!vmlogrdr_cdev) { @@ -812,10 +836,9 @@ static int vmlogrdr_register_cdev(dev_t dev) } -static void vmlogrdr_cleanup(void) -{ +static void +vmlogrdr_cleanup(void) { int i; - if (vmlogrdr_cdev) { cdev_del(vmlogrdr_cdev); vmlogrdr_cdev=NULL; @@ -832,7 +855,8 @@ static void vmlogrdr_cleanup(void) } -static int vmlogrdr_init(void) +static int +vmlogrdr_init(void) { int rc; int i; @@ -882,7 +906,8 @@ static int vmlogrdr_init(void) } -static void vmlogrdr_exit(void) +static void +vmlogrdr_exit(void) { vmlogrdr_cleanup(); printk (KERN_INFO "vmlogrdr: driver unloaded\n"); diff --git a/trunk/drivers/s390/net/Kconfig b/trunk/drivers/s390/net/Kconfig index f98fa465df0a..52625153a4f0 100644 --- a/trunk/drivers/s390/net/Kconfig +++ b/trunk/drivers/s390/net/Kconfig @@ -22,6 +22,13 @@ config CTC available. This option is also available as a module which will be called ctc.ko. If you do not know what it is, it's safe to say "Y". +config IUCV + tristate "IUCV support (VM only)" + help + Select this option if you want to use inter-user communication + under VM or VIF. If unsure, say "Y" to enable a fast communication + link between VM guests. + config NETIUCV tristate "IUCV network device support (VM only)" depends on IUCV && NETDEVICES diff --git a/trunk/drivers/s390/net/Makefile b/trunk/drivers/s390/net/Makefile index bbe3ab2e93d9..4777e36a922f 100644 --- a/trunk/drivers/s390/net/Makefile +++ b/trunk/drivers/s390/net/Makefile @@ -4,6 +4,7 @@ ctc-objs := ctcmain.o ctcdbug.o +obj-$(CONFIG_IUCV) += iucv.o obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o obj-$(CONFIG_SMSGIUCV) += smsgiucv.o obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o diff --git a/trunk/drivers/s390/net/iucv.c b/trunk/drivers/s390/net/iucv.c new file mode 100644 index 000000000000..229aeb5fc399 --- /dev/null +++ b/trunk/drivers/s390/net/iucv.c @@ -0,0 +1,2540 @@ +/* + * IUCV network driver + * + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): + * Original source: + * Alan Altmark (Alan_Altmark@us.ibm.com) Sept. 2000 + * Xenia Tkatschow (xenia@us.ibm.com) + * 2Gb awareness and general cleanup: + * Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) + * + * Documentation used: + * The original source + * CP Programming Service, IBM document # SC24-5760 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* #define DEBUG */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iucv.h" +#include +#include +#include +#include +#include + +/* FLAGS: + * All flags are defined in the field IPFLAGS1 of each function + * and can be found in CP Programming Services. + * IPSRCCLS - Indicates you have specified a source class + * IPFGMCL - Indicates you have specified a target class + * IPFGPID - Indicates you have specified a pathid + * IPFGMID - Indicates you have specified a message ID + * IPANSLST - Indicates that you are using an address list for + * reply data + * IPBUFLST - Indicates that you are using an address list for + * message data + */ + +#define IPSRCCLS 0x01 +#define IPFGMCL 0x01 +#define IPFGPID 0x02 +#define IPFGMID 0x04 +#define IPANSLST 0x08 +#define IPBUFLST 0x40 + +static int +iucv_bus_match (struct device *dev, struct device_driver *drv) +{ + return 0; +} + +struct bus_type iucv_bus = { + .name = "iucv", + .match = iucv_bus_match, +}; + +struct device *iucv_root; + +/* General IUCV interrupt structure */ +typedef struct { + __u16 ippathid; + __u8 res1; + __u8 iptype; + __u32 res2; + __u8 ipvmid[8]; + __u8 res3[24]; +} iucv_GeneralInterrupt; + +static iucv_GeneralInterrupt *iucv_external_int_buffer = NULL; + +/* Spin Lock declaration */ + +static DEFINE_SPINLOCK(iucv_lock); + +static int messagesDisabled = 0; + +/***************INTERRUPT HANDLING ***************/ + +typedef struct { + struct list_head queue; + iucv_GeneralInterrupt data; +} iucv_irqdata; + +static struct list_head iucv_irq_queue; +static DEFINE_SPINLOCK(iucv_irq_queue_lock); + +/* + *Internal function prototypes + */ +static void iucv_tasklet_handler(unsigned long); +static void iucv_irq_handler(__u16); + +static DECLARE_TASKLET(iucv_tasklet,iucv_tasklet_handler,0); + +/************ FUNCTION ID'S ****************************/ + +#define ACCEPT 10 +#define CONNECT 11 +#define DECLARE_BUFFER 12 +#define PURGE 9 +#define QUERY 0 +#define QUIESCE 13 +#define RECEIVE 5 +#define REJECT 8 +#define REPLY 6 +#define RESUME 14 +#define RETRIEVE_BUFFER 2 +#define SEND 4 +#define SETMASK 16 +#define SEVER 15 + +/** + * Structure: handler + * members: list - list management. + * structure: id + * userid - 8 char array of machine identification + * user_data - 16 char array for user identification + * mask - 24 char array used to compare the 2 previous + * interrupt_table - vector of interrupt functions. + * pgm_data - ulong, application data that is passed + * to the interrupt handlers +*/ +typedef struct handler_t { + struct list_head list; + struct { + __u8 userid[8]; + __u8 user_data[16]; + __u8 mask[24]; + } id; + iucv_interrupt_ops_t *interrupt_table; + void *pgm_data; +} handler; + +/** + * iucv_handler_table: List of registered handlers. + */ +static struct list_head iucv_handler_table; + +/** + * iucv_pathid_table: an array of *handler pointing into + * iucv_handler_table for fast indexing by pathid; + */ +static handler **iucv_pathid_table; + +static unsigned long max_connections; + +/** + * iucv_cpuid: contains the logical cpu number of the cpu which + * has declared the iucv buffer by issuing DECLARE_BUFFER. + * If no cpu has done the initialization iucv_cpuid contains -1. + */ +static int iucv_cpuid = -1; +/** + * register_flag: is 0 when external interrupt has not been registered + */ +static int register_flag; + +/****************FIVE 40-BYTE PARAMETER STRUCTURES******************/ +/* Data struct 1: iparml_control + * Used for iucv_accept + * iucv_connect + * iucv_quiesce + * iucv_resume + * iucv_sever + * iucv_retrieve_buffer + * Data struct 2: iparml_dpl (data in parameter list) + * Used for iucv_send_prmmsg + * iucv_send2way_prmmsg + * iucv_send2way_prmmsg_array + * iucv_reply_prmmsg + * Data struct 3: iparml_db (data in a buffer) + * Used for iucv_receive + * iucv_receive_array + * iucv_reject + * iucv_reply + * iucv_reply_array + * iucv_send + * iucv_send_array + * iucv_send2way + * iucv_send2way_array + * iucv_declare_buffer + * Data struct 4: iparml_purge + * Used for iucv_purge + * iucv_query + * Data struct 5: iparml_set_mask + * Used for iucv_set_mask + */ + +typedef struct { + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u16 ipmsglim; + __u16 res1; + __u8 ipvmid[8]; + __u8 ipuser[16]; + __u8 iptarget[8]; +} iparml_control; + +typedef struct { + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u32 iptrgcls; + __u8 iprmmsg[8]; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 ipbfadr2; + __u32 ipbfln2f; + __u32 res; +} iparml_dpl; + +typedef struct { + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u32 iptrgcls; + __u32 ipbfadr1; + __u32 ipbfln1f; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 ipbfadr2; + __u32 ipbfln2f; + __u32 res; +} iparml_db; + +typedef struct { + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u8 ipaudit[3]; + __u8 res1[5]; + __u32 res2; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 res3[3]; +} iparml_purge; + +typedef struct { + __u8 ipmask; + __u8 res1[2]; + __u8 iprcode; + __u32 res2[9]; +} iparml_set_mask; + +typedef struct { + union { + iparml_control p_ctrl; + iparml_dpl p_dpl; + iparml_db p_db; + iparml_purge p_purge; + iparml_set_mask p_set_mask; + } param; + atomic_t in_use; + __u32 res; +} __attribute__ ((aligned(8))) iucv_param; +#define PARAM_POOL_SIZE (PAGE_SIZE / sizeof(iucv_param)) + +static iucv_param * iucv_param_pool; + +MODULE_AUTHOR("(C) 2001 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); +MODULE_DESCRIPTION("Linux for S/390 IUCV lowlevel driver"); +MODULE_LICENSE("GPL"); + +/* + * Debugging stuff + *******************************************************************************/ + + +#ifdef DEBUG +static int debuglevel = 0; + +module_param(debuglevel, int, 0); +MODULE_PARM_DESC(debuglevel, + "Specifies the debug level (0=off ... 3=all)"); + +static void +iucv_dumpit(char *title, void *buf, int len) +{ + int i; + __u8 *p = (__u8 *)buf; + + if (debuglevel < 3) + return; + + printk(KERN_DEBUG "%s\n", title); + printk(" "); + for (i = 0; i < len; i++) { + if (!(i % 16) && i != 0) + printk ("\n "); + else if (!(i % 4) && i != 0) + printk(" "); + printk("%02X", *p++); + } + if (len % 16) + printk ("\n"); + return; +} +#define iucv_debug(lvl, fmt, args...) \ +do { \ + if (debuglevel >= lvl) \ + printk(KERN_DEBUG "%s: " fmt "\n", __FUNCTION__ , ## args); \ +} while (0) + +#else + +#define iucv_debug(lvl, fmt, args...) do { } while (0) +#define iucv_dumpit(title, buf, len) do { } while (0) + +#endif + +/* + * Internal functions + *******************************************************************************/ + +/** + * print start banner + */ +static void +iucv_banner(void) +{ + printk(KERN_INFO "IUCV lowlevel driver initialized\n"); +} + +/** + * iucv_init - Initialization + * + * Allocates and initializes various data structures. + */ +static int +iucv_init(void) +{ + int ret; + + if (iucv_external_int_buffer) + return 0; + + if (!MACHINE_IS_VM) { + printk(KERN_ERR "IUCV: IUCV connection needs VM as base\n"); + return -EPROTONOSUPPORT; + } + + ret = bus_register(&iucv_bus); + if (ret) { + printk(KERN_ERR "IUCV: failed to register bus.\n"); + return ret; + } + + iucv_root = s390_root_dev_register("iucv"); + if (IS_ERR(iucv_root)) { + printk(KERN_ERR "IUCV: failed to register iucv root.\n"); + bus_unregister(&iucv_bus); + return PTR_ERR(iucv_root); + } + + /* Note: GFP_DMA used used to get memory below 2G */ + iucv_external_int_buffer = kzalloc(sizeof(iucv_GeneralInterrupt), + GFP_KERNEL|GFP_DMA); + if (!iucv_external_int_buffer) { + printk(KERN_WARNING + "%s: Could not allocate external interrupt buffer\n", + __FUNCTION__); + s390_root_dev_unregister(iucv_root); + bus_unregister(&iucv_bus); + return -ENOMEM; + } + + /* Initialize parameter pool */ + iucv_param_pool = kzalloc(sizeof(iucv_param) * PARAM_POOL_SIZE, + GFP_KERNEL|GFP_DMA); + if (!iucv_param_pool) { + printk(KERN_WARNING "%s: Could not allocate param pool\n", + __FUNCTION__); + kfree(iucv_external_int_buffer); + iucv_external_int_buffer = NULL; + s390_root_dev_unregister(iucv_root); + bus_unregister(&iucv_bus); + return -ENOMEM; + } + + /* Initialize irq queue */ + INIT_LIST_HEAD(&iucv_irq_queue); + + /* Initialize handler table */ + INIT_LIST_HEAD(&iucv_handler_table); + + iucv_banner(); + return 0; +} + +/** + * iucv_exit - De-Initialization + * + * Frees everything allocated from iucv_init. + */ +static int iucv_retrieve_buffer (void); + +static void +iucv_exit(void) +{ + iucv_retrieve_buffer(); + kfree(iucv_external_int_buffer); + iucv_external_int_buffer = NULL; + kfree(iucv_param_pool); + iucv_param_pool = NULL; + s390_root_dev_unregister(iucv_root); + bus_unregister(&iucv_bus); + printk(KERN_INFO "IUCV lowlevel driver unloaded\n"); +} + +/** + * grab_param: - Get a parameter buffer from the pre-allocated pool. + * + * This function searches for an unused element in the pre-allocated pool + * of parameter buffers. If one is found, it marks it "in use" and returns + * a pointer to it. The calling function is responsible for releasing it + * when it has finished its usage. + * + * Returns: A pointer to iucv_param. + */ +static __inline__ iucv_param * +grab_param(void) +{ + iucv_param *ptr; + static int hint = 0; + + ptr = iucv_param_pool + hint; + do { + ptr++; + if (ptr >= iucv_param_pool + PARAM_POOL_SIZE) + ptr = iucv_param_pool; + } while (atomic_cmpxchg(&ptr->in_use, 0, 1) != 0); + hint = ptr - iucv_param_pool; + + memset(&ptr->param, 0, sizeof(ptr->param)); + return ptr; +} + +/** + * release_param - Release a parameter buffer. + * @p: A pointer to a struct iucv_param, previously obtained by calling + * grab_param(). + * + * This function marks the specified parameter buffer "unused". + */ +static __inline__ void +release_param(void *p) +{ + atomic_set(&((iucv_param *)p)->in_use, 0); +} + +/** + * iucv_add_handler: - Add a new handler + * @new_handler: handle that is being entered into chain. + * + * Places new handle on iucv_handler_table, if identical handler is not + * found. + * + * Returns: 0 on success, !0 on failure (handler already in chain). + */ +static int +iucv_add_handler (handler *new) +{ + ulong flags; + + iucv_debug(1, "entering"); + iucv_dumpit("handler:", new, sizeof(handler)); + + spin_lock_irqsave (&iucv_lock, flags); + if (!list_empty(&iucv_handler_table)) { + struct list_head *lh; + + /** + * Search list for handler with identical id. If one + * is found, the new handler is _not_ added. + */ + list_for_each(lh, &iucv_handler_table) { + handler *h = list_entry(lh, handler, list); + if (!memcmp(&new->id, &h->id, sizeof(h->id))) { + iucv_debug(1, "ret 1"); + spin_unlock_irqrestore (&iucv_lock, flags); + return 1; + } + } + } + /** + * If we get here, no handler was found. + */ + INIT_LIST_HEAD(&new->list); + list_add(&new->list, &iucv_handler_table); + spin_unlock_irqrestore (&iucv_lock, flags); + + iucv_debug(1, "exiting"); + return 0; +} + +/** + * b2f0: + * @code: identifier of IUCV call to CP. + * @parm: pointer to 40 byte iparml area passed to CP + * + * Calls CP to execute IUCV commands. + * + * Returns: return code from CP's IUCV call + */ +static inline ulong b2f0(__u32 code, void *parm) +{ + register unsigned long reg0 asm ("0"); + register unsigned long reg1 asm ("1"); + iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param)); + + reg0 = code; + reg1 = virt_to_phys(parm); + asm volatile(".long 0xb2f01000" : : "d" (reg0), "a" (reg1)); + + iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param)); + + return (unsigned long)*((__u8 *)(parm + 3)); +} + +/* + * Name: iucv_add_pathid + * Purpose: Adds a path id to the system. + * Input: pathid - pathid that is going to be entered into system + * handle - address of handler that the pathid will be associated + * with. + * pgm_data - token passed in by application. + * Output: 0: successful addition of pathid + * - EINVAL - pathid entry is being used by another application + * - ENOMEM - storage allocation for a new pathid table failed +*/ +static int +__iucv_add_pathid(__u16 pathid, handler *handler) +{ + + iucv_debug(1, "entering"); + + iucv_debug(1, "handler is pointing to %p", handler); + + if (pathid > (max_connections - 1)) + return -EINVAL; + + if (iucv_pathid_table[pathid]) { + iucv_debug(1, "pathid entry is %p", iucv_pathid_table[pathid]); + printk(KERN_WARNING + "%s: Pathid being used, error.\n", __FUNCTION__); + return -EINVAL; + } + iucv_pathid_table[pathid] = handler; + + iucv_debug(1, "exiting"); + return 0; +} /* end of add_pathid function */ + +static int +iucv_add_pathid(__u16 pathid, handler *handler) +{ + ulong flags; + int rc; + + spin_lock_irqsave (&iucv_lock, flags); + rc = __iucv_add_pathid(pathid, handler); + spin_unlock_irqrestore (&iucv_lock, flags); + return rc; +} + +static void +iucv_remove_pathid(__u16 pathid) +{ + ulong flags; + + if (pathid > (max_connections - 1)) + return; + + spin_lock_irqsave (&iucv_lock, flags); + iucv_pathid_table[pathid] = NULL; + spin_unlock_irqrestore (&iucv_lock, flags); +} + +/** + * iucv_declare_buffer_cpuid + * Register at VM for subsequent IUCV operations. This is executed + * on the reserved CPU iucv_cpuid. Called from iucv_declare_buffer(). + */ +static void +iucv_declare_buffer_cpuid (void *result) +{ + iparml_db *parm; + + parm = (iparml_db *)grab_param(); + parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer); + if ((*((ulong *)result) = b2f0(DECLARE_BUFFER, parm)) == 1) + *((ulong *)result) = parm->iprcode; + release_param(parm); +} + +/** + * iucv_retrieve_buffer_cpuid: + * Unregister IUCV usage at VM. This is always executed on the same + * cpu that registered the buffer to VM. + * Called from iucv_retrieve_buffer(). + */ +static void +iucv_retrieve_buffer_cpuid (void *cpu) +{ + iparml_control *parm; + + parm = (iparml_control *)grab_param(); + b2f0(RETRIEVE_BUFFER, parm); + release_param(parm); +} + +/** + * Name: iucv_declare_buffer + * Purpose: Specifies the guests real address of an external + * interrupt. + * Input: void + * Output: iprcode - return code from b2f0 call + */ +static int +iucv_declare_buffer (void) +{ + unsigned long flags; + ulong b2f0_result; + + iucv_debug(1, "entering"); + b2f0_result = -ENODEV; + spin_lock_irqsave (&iucv_lock, flags); + if (iucv_cpuid == -1) { + /* Reserve any cpu for use by iucv. */ + iucv_cpuid = smp_get_cpu(CPU_MASK_ALL); + spin_unlock_irqrestore (&iucv_lock, flags); + smp_call_function_on(iucv_declare_buffer_cpuid, + &b2f0_result, 0, 1, iucv_cpuid); + if (b2f0_result) { + smp_put_cpu(iucv_cpuid); + iucv_cpuid = -1; + } + iucv_debug(1, "Address of EIB = %p", iucv_external_int_buffer); + } else { + spin_unlock_irqrestore (&iucv_lock, flags); + b2f0_result = 0; + } + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/** + * iucv_retrieve_buffer: + * + * Terminates all use of IUCV. + * Returns: return code from CP + */ +static int +iucv_retrieve_buffer (void) +{ + iucv_debug(1, "entering"); + if (iucv_cpuid != -1) { + smp_call_function_on(iucv_retrieve_buffer_cpuid, + NULL, 0, 1, iucv_cpuid); + /* Release the cpu reserved by iucv_declare_buffer. */ + smp_put_cpu(iucv_cpuid); + iucv_cpuid = -1; + } + iucv_debug(1, "exiting"); + return 0; +} + +/** + * iucv_remove_handler: + * @users_handler: handler to be removed + * + * Remove handler when application unregisters. + */ +static void +iucv_remove_handler(handler *handler) +{ + unsigned long flags; + + if ((!iucv_pathid_table) || (!handler)) + return; + + iucv_debug(1, "entering"); + + spin_lock_irqsave (&iucv_lock, flags); + list_del(&handler->list); + if (list_empty(&iucv_handler_table)) { + if (register_flag) { + unregister_external_interrupt(0x4000, iucv_irq_handler); + register_flag = 0; + } + } + spin_unlock_irqrestore (&iucv_lock, flags); + + iucv_debug(1, "exiting"); + return; +} + +/** + * iucv_register_program: + * @pgmname: user identification + * @userid: machine identification + * @pgmmask: Indicates which bits in the pgmname and userid combined will be + * used to determine who is given control. + * @ops: Address of interrupt handler table. + * @pgm_data: Application data to be passed to interrupt handlers. + * + * Registers an application with IUCV. + * Returns: + * The address of handler, or NULL on failure. + * NOTE on pgmmask: + * If pgmname, userid and pgmmask are provided, pgmmask is entered into the + * handler as is. + * If pgmmask is NULL, the internal mask is set to all 0xff's + * When userid is NULL, the first 8 bytes of the internal mask are forced + * to 0x00. + * If pgmmask and userid are NULL, the first 8 bytes of the internal mask + * are forced to 0x00 and the last 16 bytes to 0xff. + */ + +iucv_handle_t +iucv_register_program (__u8 pgmname[16], + __u8 userid[8], + __u8 pgmmask[24], + iucv_interrupt_ops_t * ops, void *pgm_data) +{ + ulong rc = 0; /* return code from function calls */ + handler *new_handler; + + iucv_debug(1, "entering"); + + if (ops == NULL) { + /* interrupt table is not defined */ + printk(KERN_WARNING "%s: Interrupt table is not defined, " + "exiting\n", __FUNCTION__); + return NULL; + } + if (!pgmname) { + printk(KERN_WARNING "%s: pgmname not provided\n", __FUNCTION__); + return NULL; + } + + /* Allocate handler entry */ + new_handler = kmalloc(sizeof(handler), GFP_ATOMIC); + if (new_handler == NULL) { + printk(KERN_WARNING "%s: storage allocation for new handler " + "failed.\n", __FUNCTION__); + return NULL; + } + + if (!iucv_pathid_table) { + if (iucv_init()) { + kfree(new_handler); + return NULL; + } + + max_connections = iucv_query_maxconn(); + iucv_pathid_table = kcalloc(max_connections, sizeof(handler *), + GFP_ATOMIC); + if (iucv_pathid_table == NULL) { + printk(KERN_WARNING "%s: iucv_pathid_table storage " + "allocation failed\n", __FUNCTION__); + kfree(new_handler); + return NULL; + } + } + memset(new_handler, 0, sizeof (handler)); + memcpy(new_handler->id.user_data, pgmname, + sizeof (new_handler->id.user_data)); + if (userid) { + memcpy (new_handler->id.userid, userid, + sizeof (new_handler->id.userid)); + ASCEBC (new_handler->id.userid, + sizeof (new_handler->id.userid)); + EBC_TOUPPER (new_handler->id.userid, + sizeof (new_handler->id.userid)); + + if (pgmmask) { + memcpy (new_handler->id.mask, pgmmask, + sizeof (new_handler->id.mask)); + } else { + memset (new_handler->id.mask, 0xFF, + sizeof (new_handler->id.mask)); + } + } else { + if (pgmmask) { + memcpy (new_handler->id.mask, pgmmask, + sizeof (new_handler->id.mask)); + } else { + memset (new_handler->id.mask, 0xFF, + sizeof (new_handler->id.mask)); + } + memset (new_handler->id.userid, 0x00, + sizeof (new_handler->id.userid)); + } + /* fill in the rest of handler */ + new_handler->pgm_data = pgm_data; + new_handler->interrupt_table = ops; + + /* + * Check if someone else is registered with same pgmname, userid + * and mask. If someone is already registered with same pgmname, + * userid and mask, registration will fail and NULL will be returned + * to the application. + * If identical handler not found, then handler is added to list. + */ + rc = iucv_add_handler(new_handler); + if (rc) { + printk(KERN_WARNING "%s: Someone already registered with same " + "pgmname, userid, pgmmask\n", __FUNCTION__); + kfree (new_handler); + return NULL; + } + + rc = iucv_declare_buffer(); + if (rc) { + char *err = "Unknown"; + iucv_remove_handler(new_handler); + kfree(new_handler); + switch(rc) { + case 0x03: + err = "Directory error"; + break; + case 0x0a: + err = "Invalid length"; + break; + case 0x13: + err = "Buffer already exists"; + break; + case 0x3e: + err = "Buffer overlap"; + break; + case 0x5c: + err = "Paging or storage error"; + break; + } + printk(KERN_WARNING "%s: iucv_declare_buffer " + "returned error 0x%02lx (%s)\n", __FUNCTION__, rc, err); + return NULL; + } + if (!register_flag) { + /* request the 0x4000 external interrupt */ + rc = register_external_interrupt (0x4000, iucv_irq_handler); + if (rc) { + iucv_remove_handler(new_handler); + kfree (new_handler); + printk(KERN_WARNING "%s: " + "register_external_interrupt returned %ld\n", + __FUNCTION__, rc); + return NULL; + + } + register_flag = 1; + } + iucv_debug(1, "exiting"); + return new_handler; +} /* end of register function */ + +/** + * iucv_unregister_program: + * @handle: address of handler + * + * Unregister application with IUCV. + * Returns: + * 0 on success, -EINVAL, if specified handle is invalid. + */ + +int +iucv_unregister_program (iucv_handle_t handle) +{ + handler *h = NULL; + struct list_head *lh; + int i; + ulong flags; + + iucv_debug(1, "entering"); + iucv_debug(1, "address of handler is %p", h); + + /* Checking if handle is valid */ + spin_lock_irqsave (&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + if ((handler *)handle == list_entry(lh, handler, list)) { + h = (handler *)handle; + break; + } + } + if (!h) { + spin_unlock_irqrestore (&iucv_lock, flags); + if (handle) + printk(KERN_WARNING + "%s: Handler not found in iucv_handler_table.\n", + __FUNCTION__); + else + printk(KERN_WARNING + "%s: NULL handle passed by application.\n", + __FUNCTION__); + return -EINVAL; + } + + /** + * First, walk thru iucv_pathid_table and sever any pathid which is + * still pointing to the handler to be removed. + */ + for (i = 0; i < max_connections; i++) + if (iucv_pathid_table[i] == h) { + spin_unlock_irqrestore (&iucv_lock, flags); + iucv_sever(i, h->id.user_data); + spin_lock_irqsave(&iucv_lock, flags); + } + spin_unlock_irqrestore (&iucv_lock, flags); + + iucv_remove_handler(h); + kfree(h); + + iucv_debug(1, "exiting"); + return 0; +} + +/** + * iucv_accept: + * @pathid: Path identification number + * @msglim_reqstd: The number of outstanding messages requested. + * @user_data: Data specified by the iucv_connect function. + * @flags1: Contains options for this path. + * - IPPRTY (0x20) Specifies if you want to send priority message. + * - IPRMDATA (0x80) Specifies whether your program can handle a message + * in the parameter list. + * - IPQUSCE (0x40) Specifies whether you want to quiesce the path being + * established. + * @handle: Address of handler. + * @pgm_data: Application data passed to interrupt handlers. + * @flags1_out: Pointer to an int. If not NULL, on return the options for + * the path are stored at the given location: + * - IPPRTY (0x20) Indicates you may send a priority message. + * @msglim: Pointer to an __u16. If not NULL, on return the maximum + * number of outstanding messages is stored at the given + * location. + * + * This function is issued after the user receives a Connection Pending external + * interrupt and now wishes to complete the IUCV communication path. + * Returns: + * return code from CP + */ +int +iucv_accept(__u16 pathid, __u16 msglim_reqstd, + __u8 user_data[16], int flags1, + iucv_handle_t handle, void *pgm_data, + int *flags1_out, __u16 * msglim) +{ + ulong b2f0_result = 0; + ulong flags; + struct list_head *lh; + handler *h = NULL; + iparml_control *parm; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + /* Checking if handle is valid */ + spin_lock_irqsave (&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + if ((handler *)handle == list_entry(lh, handler, list)) { + h = (handler *)handle; + break; + } + } + spin_unlock_irqrestore (&iucv_lock, flags); + + if (!h) { + if (handle) + printk(KERN_WARNING + "%s: Handler not found in iucv_handler_table.\n", + __FUNCTION__); + else + printk(KERN_WARNING + "%s: NULL handle passed by application.\n", + __FUNCTION__); + return -EINVAL; + } + + parm = (iparml_control *)grab_param(); + + parm->ippathid = pathid; + parm->ipmsglim = msglim_reqstd; + if (user_data) + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + + parm->ipflags1 = (__u8)flags1; + b2f0_result = b2f0(ACCEPT, parm); + + if (!b2f0_result) { + if (msglim) + *msglim = parm->ipmsglim; + if (pgm_data) + h->pgm_data = pgm_data; + if (flags1_out) + *flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0; + } + release_param(parm); + + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/** + * iucv_connect: + * @pathid: Path identification number + * @msglim_reqstd: Number of outstanding messages requested + * @user_data: 16-byte user data + * @userid: 8-byte of user identification + * @system_name: 8-byte identifying the system name + * @flags1: Specifies options for this path: + * - IPPRTY (0x20) Specifies if you want to send priority message. + * - IPRMDATA (0x80) Specifies whether your program can handle a message + * in the parameter list. + * - IPQUSCE (0x40) Specifies whether you want to quiesce the path being + * established. + * - IPLOCAL (0x01) Allows an application to force the partner to be on the + * local system. If local is specified then target class + * cannot be specified. + * @flags1_out: Pointer to an int. If not NULL, on return the options for + * the path are stored at the given location: + * - IPPRTY (0x20) Indicates you may send a priority message. + * @msglim: Pointer to an __u16. If not NULL, on return the maximum + * number of outstanding messages is stored at the given + * location. + * @handle: Address of handler. + * @pgm_data: Application data to be passed to interrupt handlers. + * + * This function establishes an IUCV path. Although the connect may complete + * successfully, you are not able to use the path until you receive an IUCV + * Connection Complete external interrupt. + * Returns: return code from CP, or one of the following + * - ENOMEM + * - return code from iucv_declare_buffer + * - EINVAL - invalid handle passed by application + * - EINVAL - pathid address is NULL + * - ENOMEM - pathid table storage allocation failed + * - return code from internal function add_pathid + */ +int +iucv_connect (__u16 *pathid, __u16 msglim_reqstd, + __u8 user_data[16], __u8 userid[8], + __u8 system_name[8], int flags1, + int *flags1_out, __u16 * msglim, + iucv_handle_t handle, void *pgm_data) +{ + iparml_control *parm; + iparml_control local_parm; + struct list_head *lh; + ulong b2f0_result = 0; + ulong flags; + int add_pathid_result = 0; + handler *h = NULL; + __u8 no_memory[16] = "NO MEMORY"; + + iucv_debug(1, "entering"); + + /* Checking if handle is valid */ + spin_lock_irqsave (&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + if ((handler *)handle == list_entry(lh, handler, list)) { + h = (handler *)handle; + break; + } + } + spin_unlock_irqrestore (&iucv_lock, flags); + + if (!h) { + if (handle) + printk(KERN_WARNING + "%s: Handler not found in iucv_handler_table.\n", + __FUNCTION__); + else + printk(KERN_WARNING + "%s: NULL handle passed by application.\n", + __FUNCTION__); + return -EINVAL; + } + + if (pathid == NULL) { + printk(KERN_WARNING "%s: NULL pathid pointer\n", + __FUNCTION__); + return -EINVAL; + } + + parm = (iparml_control *)grab_param(); + + parm->ipmsglim = msglim_reqstd; + + if (user_data) + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + + if (userid) { + memcpy(parm->ipvmid, userid, sizeof(parm->ipvmid)); + ASCEBC(parm->ipvmid, sizeof(parm->ipvmid)); + EBC_TOUPPER(parm->ipvmid, sizeof(parm->ipvmid)); + } + + if (system_name) { + memcpy(parm->iptarget, system_name, sizeof(parm->iptarget)); + ASCEBC(parm->iptarget, sizeof(parm->iptarget)); + EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget)); + } + + /* In order to establish an IUCV connection, the procedure is: + * + * b2f0(CONNECT) + * take the ippathid from the b2f0 call + * register the handler to the ippathid + * + * Unfortunately, the ConnectionEstablished message gets sent after the + * b2f0(CONNECT) call but before the register is handled. + * + * In order for this race condition to be eliminated, the IUCV Control + * Interrupts must be disabled for the above procedure. + * + * David Kennedy + */ + + /* Enable everything but IUCV Control messages */ + iucv_setmask(~(AllInterrupts)); + messagesDisabled = 1; + + spin_lock_irqsave (&iucv_lock, flags); + parm->ipflags1 = (__u8)flags1; + b2f0_result = b2f0(CONNECT, parm); + memcpy(&local_parm, parm, sizeof(local_parm)); + release_param(parm); + parm = &local_parm; + if (!b2f0_result) + add_pathid_result = __iucv_add_pathid(parm->ippathid, h); + spin_unlock_irqrestore (&iucv_lock, flags); + + if (b2f0_result) { + iucv_setmask(~0); + messagesDisabled = 0; + return b2f0_result; + } + + *pathid = parm->ippathid; + + /* Enable everything again */ + iucv_setmask(IUCVControlInterruptsFlag); + + if (msglim) + *msglim = parm->ipmsglim; + if (flags1_out) + *flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0; + + if (add_pathid_result) { + iucv_sever(*pathid, no_memory); + printk(KERN_WARNING "%s: add_pathid failed with rc =" + " %d\n", __FUNCTION__, add_pathid_result); + return(add_pathid_result); + } + + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/** + * iucv_purge: + * @pathid: Path identification number + * @msgid: Message ID of message to purge. + * @srccls: Message class of the message to purge. + * @audit: Pointer to an __u32. If not NULL, on return, information about + * asynchronous errors that may have affected the normal completion + * of this message ist stored at the given location. + * + * Cancels a message you have sent. + * Returns: return code from CP + */ +int +iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit) +{ + iparml_purge *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + parm = (iparml_purge *)grab_param(); + + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->ipsrccls = srccls; + parm->ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID); + b2f0_result = b2f0(PURGE, parm); + + if (!b2f0_result && audit) { + memcpy(audit, parm->ipaudit, sizeof(parm->ipaudit)); + /* parm->ipaudit has only 3 bytes */ + *audit >>= 8; + } + + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", b2f0_result); + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/** + * iucv_query_generic: + * @want_maxconn: Flag, describing which value is to be returned. + * + * Helper function for iucv_query_maxconn() and iucv_query_bufsize(). + * + * Returns: The buffersize, if want_maxconn is 0; the maximum number of + * connections, if want_maxconn is 1 or an error-code < 0 on failure. + */ +static int +iucv_query_generic(int want_maxconn) +{ + register unsigned long reg0 asm ("0"); + register unsigned long reg1 asm ("1"); + iparml_purge *parm = (iparml_purge *)grab_param(); + int bufsize, maxconn; + int ccode; + + /** + * Call b2f0 and store R0 (max buffer size), + * R1 (max connections) and CC. + */ + reg0 = QUERY; + reg1 = virt_to_phys(parm); + asm volatile( + " .long 0xb2f01000\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc"); + bufsize = reg0; + maxconn = reg1; + release_param(parm); + + if (ccode) + return -EPERM; + if (want_maxconn) + return maxconn; + return bufsize; +} + +/** + * iucv_query_maxconn: + * + * Determines the maximum number of connections thay may be established. + * + * Returns: Maximum number of connections that can be. + */ +ulong +iucv_query_maxconn(void) +{ + return iucv_query_generic(1); +} + +/** + * iucv_query_bufsize: + * + * Determines the size of the external interrupt buffer. + * + * Returns: Size of external interrupt buffer. + */ +ulong +iucv_query_bufsize (void) +{ + return iucv_query_generic(0); +} + +/** + * iucv_quiesce: + * @pathid: Path identification number + * @user_data: 16-byte user data + * + * Temporarily suspends incoming messages on an IUCV path. + * You can later reactivate the path by invoking the iucv_resume function. + * Returns: return code from CP + */ +int +iucv_quiesce (__u16 pathid, __u8 user_data[16]) +{ + iparml_control *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + parm = (iparml_control *)grab_param(); + + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + parm->ippathid = pathid; + + b2f0_result = b2f0(QUIESCE, parm); + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", b2f0_result); + iucv_debug(1, "exiting"); + + return b2f0_result; +} + +/** + * iucv_receive: + * @pathid: Path identification number. + * @buffer: Address of buffer to receive. Must be below 2G. + * @buflen: Length of buffer to receive. + * @msgid: Specifies the message ID. + * @trgcls: Specifies target class. + * @flags1_out: Receives options for path on return. + * - IPNORPY (0x10) Specifies whether a reply is required + * - IPPRTY (0x20) Specifies if you want to send priority message + * - IPRMDATA (0x80) Specifies the data is contained in the parameter list + * @residual_buffer: Receives the address of buffer updated by the number + * of bytes you have received on return. + * @residual_length: On return, receives one of the following values: + * - 0 If the receive buffer is the same length as + * the message. + * - Remaining bytes in buffer If the receive buffer is longer than the + * message. + * - Remaining bytes in message If the receive buffer is shorter than the + * message. + * + * This function receives messages that are being sent to you over established + * paths. + * Returns: return code from CP IUCV call; If the receive buffer is shorter + * than the message, always 5 + * -EINVAL - buffer address is pointing to NULL + */ +int +iucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls, + void *buffer, ulong buflen, + int *flags1_out, ulong * residual_buffer, ulong * residual_length) +{ + iparml_db *parm; + ulong b2f0_result; + int moved = 0; /* number of bytes moved from parmlist to buffer */ + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr1 = (__u32) (addr_t) buffer; + parm->ipbfln1f = (__u32) ((ulong) buflen); + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPFGPID | IPFGMID | IPFGMCL); + + b2f0_result = b2f0(RECEIVE, parm); + + if (!b2f0_result || b2f0_result == 5) { + if (flags1_out) { + iucv_debug(2, "*flags1_out = %d", *flags1_out); + *flags1_out = (parm->ipflags1 & (~0x07)); + iucv_debug(2, "*flags1_out = %d", *flags1_out); + } + + if (!(parm->ipflags1 & IPRMDATA)) { /*msg not in parmlist */ + if (residual_length) + *residual_length = parm->ipbfln1f; + + if (residual_buffer) + *residual_buffer = parm->ipbfadr1; + } else { + moved = min_t (unsigned long, buflen, 8); + + memcpy ((char *) buffer, + (char *) &parm->ipbfadr1, moved); + + if (buflen < 8) + b2f0_result = 5; + + if (residual_length) + *residual_length = abs (buflen - 8); + + if (residual_buffer) + *residual_buffer = (ulong) (buffer + moved); + } + } + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +/* + * Name: iucv_receive_array + * Purpose: This function receives messages that are being sent to you + * over established paths. + * Input: pathid - path identification number + * buffer - address of array of buffers + * buflen - total length of buffers + * msgid - specifies the message ID. + * trgcls - specifies target class + * Output: + * flags1_out: Options for path. + * IPNORPY - 0x10 specifies whether a reply is required + * IPPRTY - 0x20 specifies if you want to send priority message + * IPRMDATA - 0x80 specifies the data is contained in the parameter list + * residual_buffer - address points to the current list entry IUCV + * is working on. + * residual_length - + * Contains one of the following values, if the receive buffer is: + * The same length as the message, this field is zero. + * Longer than the message, this field contains the number of + * bytes remaining in the buffer. + * Shorter than the message, this field contains the residual + * count (that is, the number of bytes remaining in the + * message that does not fit into the buffer. In this case + * b2f0_result = 5. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL + */ +int +iucv_receive_array (__u16 pathid, + __u32 msgid, __u32 trgcls, + iucv_array_t * buffer, ulong buflen, + int *flags1_out, + ulong * residual_buffer, ulong * residual_length) +{ + iparml_db *parm; + ulong b2f0_result; + int i = 0, moved = 0, need_to_move = 8, dyn_len; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPBUFLST | IPFGPID | IPFGMID | IPFGMCL); + + b2f0_result = b2f0(RECEIVE, parm); + + if (!b2f0_result || b2f0_result == 5) { + + if (flags1_out) { + iucv_debug(2, "*flags1_out = %d", *flags1_out); + *flags1_out = (parm->ipflags1 & (~0x07)); + iucv_debug(2, "*flags1_out = %d", *flags1_out); + } + + if (!(parm->ipflags1 & IPRMDATA)) { /*msg not in parmlist */ + + if (residual_length) + *residual_length = parm->ipbfln1f; + + if (residual_buffer) + *residual_buffer = parm->ipbfadr1; + + } else { + /* copy msg from parmlist to users array. */ + + while ((moved < 8) && (moved < buflen)) { + dyn_len = + min_t (unsigned int, + (buffer + i)->length, need_to_move); + + memcpy ((char *)((ulong)((buffer + i)->address)), + ((char *) &parm->ipbfadr1) + moved, + dyn_len); + + moved += dyn_len; + need_to_move -= dyn_len; + + (buffer + i)->address = + (__u32) + ((ulong)(__u8 *) ((ulong)(buffer + i)->address) + + dyn_len); + + (buffer + i)->length -= dyn_len; + i++; + } + + if (need_to_move) /* buflen < 8 bytes */ + b2f0_result = 5; + + if (residual_length) + *residual_length = abs (buflen - 8); + + if (residual_buffer) { + if (!moved) + *residual_buffer = (ulong) buffer; + else + *residual_buffer = + (ulong) (buffer + (i - 1)); + } + + } + } + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +/** + * iucv_reject: + * @pathid: Path identification number. + * @msgid: Message ID of the message to reject. + * @trgcls: Target class of the message to reject. + * Returns: return code from CP + * + * Refuses a specified message. Between the time you are notified of a + * message and the time that you complete the message, the message may + * be rejected. + */ +int +iucv_reject (__u16 pathid, __u32 msgid, __u32 trgcls) +{ + iparml_db *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPFGMCL | IPFGMID | IPFGPID); + + b2f0_result = b2f0(REJECT, parm); + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", b2f0_result); + iucv_debug(1, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_reply + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Input: pathid - path identification number + * msgid - specifies the message ID. + * trgcls - specifies target class + * flags1 - option for path + * IPPRTY- 0x20 - specifies if you want to send priority message + * buffer - address of reply buffer + * buflen - length of reply buffer + * Output: ipbfadr2 - Address of buffer updated by the number + * of bytes you have moved. + * ipbfln2f - Contains one of the following values: + * If the answer buffer is the same length as the reply, this field + * contains zero. + * If the answer buffer is longer than the reply, this field contains + * the number of bytes remaining in the buffer. + * If the answer buffer is shorter than the reply, this field contains + * a residual count (that is, the number of bytes remianing in the + * reply that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL + */ +int +iucv_reply (__u16 pathid, + __u32 msgid, __u32 trgcls, + int flags1, + void *buffer, ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr2 = (__u32) ((ulong) buffer); + parm->ipbfln2f = (__u32) buflen; /* length of message */ + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (__u8) flags1; /* priority message */ + + b2f0_result = b2f0(REPLY, parm); + + if ((!b2f0_result) || (b2f0_result == 5)) { + if (ipbfadr2) + *ipbfadr2 = parm->ipbfadr2; + if (ipbfln2f) + *ipbfln2f = parm->ipbfln2f; + } + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_reply_array + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * The array identifies a list of addresses and lengths of + * discontiguous buffers that contains the reply data. + * Input: pathid - path identification number + * msgid - specifies the message ID. + * trgcls - specifies target class + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * buffer - address of array of reply buffers + * buflen - total length of reply buffers + * Output: ipbfadr2 - Address of buffer which IUCV is currently working on. + * ipbfln2f - Contains one of the following values: + * If the answer buffer is the same length as the reply, this field + * contains zero. + * If the answer buffer is longer than the reply, this field contains + * the number of bytes remaining in the buffer. + * If the answer buffer is shorter than the reply, this field contains + * a residual count (that is, the number of bytes remianing in the + * reply that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL +*/ +int +iucv_reply_array (__u16 pathid, + __u32 msgid, __u32 trgcls, + int flags1, + iucv_array_t * buffer, + ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr2 = (__u32) ((ulong) buffer); + parm->ipbfln2f = buflen; /* length of message */ + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPANSLST | flags1); + + b2f0_result = b2f0(REPLY, parm); + + if ((!b2f0_result) || (b2f0_result == 5)) { + + if (ipbfadr2) + *ipbfadr2 = parm->ipbfadr2; + if (ipbfln2f) + *ipbfln2f = parm->ipbfln2f; + } + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_reply_prmmsg + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Prmmsg signifies the data is moved into the + * parameter list. + * Input: pathid - path identification number + * msgid - specifies the message ID. + * trgcls - specifies target class + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * prmmsg - 8-bytes of data to be placed into the parameter + * list. + * Output: NA + * Return: b2f0_result - return code from CP +*/ +int +iucv_reply_prmmsg (__u16 pathid, + __u32 msgid, __u32 trgcls, int flags1, __u8 prmmsg[8]) +{ + iparml_dpl *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + memcpy(parm->iprmmsg, prmmsg, sizeof (parm->iprmmsg)); + parm->ipflags1 = (IPRMDATA | flags1); + + b2f0_result = b2f0(REPLY, parm); + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/** + * iucv_resume: + * @pathid: Path identification number + * @user_data: 16-byte of user data + * + * This function restores communication over a quiesced path. + * Returns: return code from CP + */ +int +iucv_resume (__u16 pathid, __u8 user_data[16]) +{ + iparml_control *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + parm = (iparml_control *)grab_param(); + + memcpy (parm->ipuser, user_data, sizeof (*user_data)); + parm->ippathid = pathid; + + b2f0_result = b2f0(RESUME, parm); + release_param(parm); + + iucv_debug(1, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send + * Purpose: sends messages + * Input: pathid - ushort, pathid + * msgid - ulong *, id of message returned to caller + * trgcls - ulong, target message class + * srccls - ulong, source message class + * msgtag - ulong, message tag + * flags1 - Contains options for this path. + * IPPRTY - Ox20 - specifies if you want to send a priority message. + * buffer - pointer to buffer + * buflen - ulong, length of buffer + * Output: b2f0_result - return code from b2f0 call + * msgid - returns message id + */ +int +iucv_send (__u16 pathid, __u32 * msgid, + __u32 trgcls, __u32 srccls, + __u32 msgtag, int flags1, void *buffer, ulong buflen) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPNORPY | flags1); /* one way priority message */ + + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag to be associated witht the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * buffer - address of array of send buffers + * buflen - total length of send buffers + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL + */ +int +iucv_send_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPNORPY | IPBUFLST | flags1); + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +/* + * Name: iucv_send_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag to be associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * prmmsg - 8-bytes of data to be placed into parameter list + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP +*/ +int +iucv_send_prmmsg (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, __u32 msgtag, int flags1, __u8 prmmsg[8]) +{ + iparml_dpl *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPRMDATA | IPNORPY | flags1); + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); + + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send2way + * Purpose: This function transmits data to another application. + * Data to be transmitted is in a buffer. The receiver + * of the send is expected to reply to the message and + * a buffer is provided into which IUCV moves the reply + * to this message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * buffer - address of send buffer + * buflen - length of send buffer + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer or ansbuf address is NULL + */ +int +iucv_send2way (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + int flags1, + void *buffer, ulong buflen, void *ansbuf, ulong anslen) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer || !ansbuf) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = flags1; /* priority message */ + + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send2way_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. The receiver of the send is expected to + * reply to the message and a buffer is provided into which + * IUCV moves the reply to this message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - spcifies a tag to be associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * buffer - address of array of send buffers + * buflen - total length of send buffers + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL + */ +int +iucv_send2way_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + int flags1, + iucv_array_t * buffer, + ulong buflen, iucv_array_t * ansbuf, ulong anslen) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer || !ansbuf) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPBUFLST | IPANSLST | flags1); + b2f0_result = b2f0(SEND, parm); + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +/* + * Name: iucv_send2way_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag to be associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * prmmsg - 8-bytes of data to be placed in parameter list + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL +*/ +int +iucv_send2way_prmmsg (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + ulong flags1, __u8 prmmsg[8], void *ansbuf, ulong anslen) +{ + iparml_dpl *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!ansbuf) + return -EINVAL; + + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipflags1 = (IPRMDATA | flags1); /* message in prmlist */ + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); + + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send2way_prmmsg_array + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. The contents of ansbuf is the address of the + * array of addresses and lengths of discontiguous buffers + * that contain the reply. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag to be associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * prmmsg - 8-bytes of data to be placed into the parameter list + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - ansbuf address is NULL + */ +int +iucv_send2way_prmmsg_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + int flags1, + __u8 prmmsg[8], + iucv_array_t * ansbuf, ulong anslen) +{ + iparml_dpl *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!ansbuf) + return -EINVAL; + + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipflags1 = (IPRMDATA | IPANSLST | flags1); + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); + b2f0_result = b2f0(SEND, parm); + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +void +iucv_setmask_cpuid (void *result) +{ + iparml_set_mask *parm; + + iucv_debug(1, "entering"); + parm = (iparml_set_mask *)grab_param(); + parm->ipmask = *((__u8*)result); + *((ulong *)result) = b2f0(SETMASK, parm); + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", *((ulong *)result)); + iucv_debug(1, "exiting"); +} + +/* + * Name: iucv_setmask + * Purpose: This function enables or disables the following IUCV + * external interruptions: Nonpriority and priority message + * interrupts, nonpriority and priority reply interrupts. + * Input: SetMaskFlag - options for interrupts + * 0x80 - Nonpriority_MessagePendingInterruptsFlag + * 0x40 - Priority_MessagePendingInterruptsFlag + * 0x20 - Nonpriority_MessageCompletionInterruptsFlag + * 0x10 - Priority_MessageCompletionInterruptsFlag + * 0x08 - IUCVControlInterruptsFlag + * Output: NA + * Return: b2f0_result - return code from CP +*/ +int +iucv_setmask (int SetMaskFlag) +{ + union { + ulong result; + __u8 param; + } u; + int cpu; + + u.param = SetMaskFlag; + cpu = get_cpu(); + smp_call_function_on(iucv_setmask_cpuid, &u, 0, 1, iucv_cpuid); + put_cpu(); + + return u.result; +} + +/** + * iucv_sever: + * @pathid: Path identification number + * @user_data: 16-byte of user data + * + * This function terminates an iucv path. + * Returns: return code from CP + */ +int +iucv_sever(__u16 pathid, __u8 user_data[16]) +{ + iparml_control *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + parm = (iparml_control *)grab_param(); + + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + parm->ippathid = pathid; + + b2f0_result = b2f0(SEVER, parm); + + if (!b2f0_result) + iucv_remove_pathid(pathid); + release_param(parm); + + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/* + * Interrupt Handlers + *******************************************************************************/ + +/** + * iucv_irq_handler: + * @regs: Current registers + * @code: irq code + * + * Handles external interrupts coming in from CP. + * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler(). + */ +static void +iucv_irq_handler(__u16 code) +{ + iucv_irqdata *irqdata; + + irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC); + if (!irqdata) { + printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); + return; + } + + memcpy(&irqdata->data, iucv_external_int_buffer, + sizeof(iucv_GeneralInterrupt)); + + spin_lock(&iucv_irq_queue_lock); + list_add_tail(&irqdata->queue, &iucv_irq_queue); + spin_unlock(&iucv_irq_queue_lock); + + tasklet_schedule(&iucv_tasklet); +} + +/** + * iucv_do_int: + * @int_buf: Pointer to copy of external interrupt buffer + * + * The workhorse for handling interrupts queued by iucv_irq_handler(). + * This function is called from the bottom half iucv_tasklet_handler(). + */ +static void +iucv_do_int(iucv_GeneralInterrupt * int_buf) +{ + handler *h = NULL; + struct list_head *lh; + ulong flags; + iucv_interrupt_ops_t *interrupt = NULL; /* interrupt addresses */ + __u8 temp_buff1[24], temp_buff2[24]; /* masked handler id. */ + int rc = 0, j = 0; + __u8 no_listener[16] = "NO LISTENER"; + + iucv_debug(2, "entering, pathid %d, type %02X", + int_buf->ippathid, int_buf->iptype); + iucv_dumpit("External Interrupt Buffer:", + int_buf, sizeof(iucv_GeneralInterrupt)); + + ASCEBC (no_listener, 16); + + if (int_buf->iptype != 01) { + if ((int_buf->ippathid) > (max_connections - 1)) { + printk(KERN_WARNING "%s: Got interrupt with pathid %d" + " > max_connections (%ld)\n", __FUNCTION__, + int_buf->ippathid, max_connections - 1); + } else { + h = iucv_pathid_table[int_buf->ippathid]; + interrupt = h->interrupt_table; + iucv_dumpit("Handler:", h, sizeof(handler)); + } + } + + /* end of if statement */ + switch (int_buf->iptype) { + case 0x01: /* connection pending */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + spin_lock_irqsave(&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + h = list_entry(lh, handler, list); + memcpy(temp_buff1, &(int_buf->ipvmid), 24); + memcpy(temp_buff2, &(h->id.userid), 24); + for (j = 0; j < 24; j++) { + temp_buff1[j] &= (h->id.mask)[j]; + temp_buff2[j] &= (h->id.mask)[j]; + } + + iucv_dumpit("temp_buff1:", + temp_buff1, sizeof(temp_buff1)); + iucv_dumpit("temp_buff2", + temp_buff2, sizeof(temp_buff2)); + + if (!memcmp (temp_buff1, temp_buff2, 24)) { + + iucv_debug(2, + "found a matching handler"); + break; + } else + h = NULL; + } + spin_unlock_irqrestore (&iucv_lock, flags); + if (h) { + /* ADD PATH TO PATHID TABLE */ + rc = iucv_add_pathid(int_buf->ippathid, h); + if (rc) { + iucv_sever (int_buf->ippathid, + no_listener); + iucv_debug(1, + "add_pathid failed, rc = %d", + rc); + } else { + interrupt = h->interrupt_table; + if (interrupt->ConnectionPending) { + EBCASC (int_buf->ipvmid, 8); + interrupt->ConnectionPending( + (iucv_ConnectionPending *)int_buf, + h->pgm_data); + } else + iucv_sever(int_buf->ippathid, + no_listener); + } + } else + iucv_sever(int_buf->ippathid, no_listener); + break; + + case 0x02: /*connection complete */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + if (h) { + if (interrupt->ConnectionComplete) + { + interrupt->ConnectionComplete( + (iucv_ConnectionComplete *)int_buf, + h->pgm_data); + } + else + iucv_debug(1, + "ConnectionComplete not called"); + } else + iucv_sever(int_buf->ippathid, no_listener); + break; + + case 0x03: /* connection severed */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + if (h) { + if (interrupt->ConnectionSevered) + interrupt->ConnectionSevered( + (iucv_ConnectionSevered *)int_buf, + h->pgm_data); + + else + iucv_sever (int_buf->ippathid, no_listener); + } else + iucv_sever(int_buf->ippathid, no_listener); + break; + + case 0x04: /* connection quiesced */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + if (h) { + if (interrupt->ConnectionQuiesced) + interrupt->ConnectionQuiesced( + (iucv_ConnectionQuiesced *)int_buf, + h->pgm_data); + else + iucv_debug(1, + "ConnectionQuiesced not called"); + } + break; + + case 0x05: /* connection resumed */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + if (h) { + if (interrupt->ConnectionResumed) + interrupt->ConnectionResumed( + (iucv_ConnectionResumed *)int_buf, + h->pgm_data); + else + iucv_debug(1, + "ConnectionResumed not called"); + } + break; + + case 0x06: /* priority message complete */ + case 0x07: /* nonpriority message complete */ + if (h) { + if (interrupt->MessageComplete) + interrupt->MessageComplete( + (iucv_MessageComplete *)int_buf, + h->pgm_data); + else + iucv_debug(2, + "MessageComplete not called"); + } + break; + + case 0x08: /* priority message pending */ + case 0x09: /* nonpriority message pending */ + if (h) { + if (interrupt->MessagePending) + interrupt->MessagePending( + (iucv_MessagePending *) int_buf, + h->pgm_data); + else + iucv_debug(2, + "MessagePending not called"); + } + break; + default: /* unknown iucv type */ + printk(KERN_WARNING "%s: unknown iucv interrupt\n", + __FUNCTION__); + break; + } /* end switch */ + + iucv_debug(2, "exiting pathid %d, type %02X", + int_buf->ippathid, int_buf->iptype); + + return; +} + +/** + * iucv_tasklet_handler: + * + * This function loops over the queue of irq buffers and runs iucv_do_int() + * on every queue element. + */ +static void +iucv_tasklet_handler(unsigned long ignored) +{ + struct list_head head; + struct list_head *next; + ulong flags; + + spin_lock_irqsave(&iucv_irq_queue_lock, flags); + list_add(&head, &iucv_irq_queue); + list_del_init(&iucv_irq_queue); + spin_unlock_irqrestore (&iucv_irq_queue_lock, flags); + + next = head.next; + while (next != &head) { + iucv_irqdata *p = list_entry(next, iucv_irqdata, queue); + + next = next->next; + iucv_do_int(&p->data); + kfree(p); + } + + return; +} + +subsys_initcall(iucv_init); +module_exit(iucv_exit); + +/** + * Export all public stuff + */ +EXPORT_SYMBOL (iucv_bus); +EXPORT_SYMBOL (iucv_root); +EXPORT_SYMBOL (iucv_accept); +EXPORT_SYMBOL (iucv_connect); +#if 0 +EXPORT_SYMBOL (iucv_purge); +EXPORT_SYMBOL (iucv_query_maxconn); +EXPORT_SYMBOL (iucv_query_bufsize); +EXPORT_SYMBOL (iucv_quiesce); +#endif +EXPORT_SYMBOL (iucv_receive); +#if 0 +EXPORT_SYMBOL (iucv_receive_array); +#endif +EXPORT_SYMBOL (iucv_reject); +#if 0 +EXPORT_SYMBOL (iucv_reply); +EXPORT_SYMBOL (iucv_reply_array); +EXPORT_SYMBOL (iucv_resume); +#endif +EXPORT_SYMBOL (iucv_reply_prmmsg); +EXPORT_SYMBOL (iucv_send); +EXPORT_SYMBOL (iucv_send2way); +EXPORT_SYMBOL (iucv_send2way_array); +EXPORT_SYMBOL (iucv_send2way_prmmsg); +EXPORT_SYMBOL (iucv_send2way_prmmsg_array); +#if 0 +EXPORT_SYMBOL (iucv_send_array); +EXPORT_SYMBOL (iucv_send_prmmsg); +EXPORT_SYMBOL (iucv_setmask); +#endif +EXPORT_SYMBOL (iucv_sever); +EXPORT_SYMBOL (iucv_register_program); +EXPORT_SYMBOL (iucv_unregister_program); diff --git a/trunk/drivers/s390/net/iucv.h b/trunk/drivers/s390/net/iucv.h new file mode 100644 index 000000000000..5b6b1b7241c9 --- /dev/null +++ b/trunk/drivers/s390/net/iucv.h @@ -0,0 +1,849 @@ +/* + * drivers/s390/net/iucv.h + * IUCV base support. + * + * S390 version + * Copyright (C) 2000 IBM Corporation + * Author(s):Alan Altmark (Alan_Altmark@us.ibm.com) + * Xenia Tkatschow (xenia@us.ibm.com) + * + * + * Functionality: + * To explore any of the IUCV functions, one must first register + * their program using iucv_register_program(). Once your program has + * successfully completed a register, it can exploit the other functions. + * For furthur reference on all IUCV functionality, refer to the + * CP Programming Services book, also available on the web + * thru www.ibm.com/s390/vm/pubs, manual # SC24-5760 + * + * Definition of Return Codes + * -All positive return codes including zero are reflected back + * from CP except for iucv_register_program. The definition of each + * return code can be found in CP Programming Services book. + * Also available on the web thru www.ibm.com/s390/vm/pubs, manual # SC24-5760 + * - Return Code of: + * (-EINVAL) Invalid value + * (-ENOMEM) storage allocation failed + * pgmask defined in iucv_register_program will be set depending on input + * paramters. + * + */ + +#include +#include + +/** + * Debug Facility stuff + */ +#define IUCV_DBF_SETUP_NAME "iucv_setup" +#define IUCV_DBF_SETUP_LEN 32 +#define IUCV_DBF_SETUP_PAGES 2 +#define IUCV_DBF_SETUP_NR_AREAS 1 +#define IUCV_DBF_SETUP_LEVEL 3 + +#define IUCV_DBF_DATA_NAME "iucv_data" +#define IUCV_DBF_DATA_LEN 128 +#define IUCV_DBF_DATA_PAGES 2 +#define IUCV_DBF_DATA_NR_AREAS 1 +#define IUCV_DBF_DATA_LEVEL 2 + +#define IUCV_DBF_TRACE_NAME "iucv_trace" +#define IUCV_DBF_TRACE_LEN 16 +#define IUCV_DBF_TRACE_PAGES 4 +#define IUCV_DBF_TRACE_NR_AREAS 1 +#define IUCV_DBF_TRACE_LEVEL 3 + +#define IUCV_DBF_TEXT(name,level,text) \ + do { \ + debug_text_event(iucv_dbf_##name,level,text); \ + } while (0) + +#define IUCV_DBF_HEX(name,level,addr,len) \ + do { \ + debug_event(iucv_dbf_##name,level,(void*)(addr),len); \ + } while (0) + +DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf); + +#define IUCV_DBF_TEXT_(name,level,text...) \ + do { \ + char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \ + sprintf(iucv_dbf_txt_buf, text); \ + debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \ + put_cpu_var(iucv_dbf_txt_buf); \ + } while (0) + +#define IUCV_DBF_SPRINTF(name,level,text...) \ + do { \ + debug_sprintf_event(iucv_dbf_trace, level, ##text ); \ + debug_sprintf_event(iucv_dbf_trace, level, text ); \ + } while (0) + +/** + * some more debug stuff + */ +#define IUCV_HEXDUMP16(importance,header,ptr) \ +PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ + "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ + *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \ + *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \ + *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \ + *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \ + *(((char*)ptr)+12),*(((char*)ptr)+13), \ + *(((char*)ptr)+14),*(((char*)ptr)+15)); \ +PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ + "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ + *(((char*)ptr)+16),*(((char*)ptr)+17), \ + *(((char*)ptr)+18),*(((char*)ptr)+19), \ + *(((char*)ptr)+20),*(((char*)ptr)+21), \ + *(((char*)ptr)+22),*(((char*)ptr)+23), \ + *(((char*)ptr)+24),*(((char*)ptr)+25), \ + *(((char*)ptr)+26),*(((char*)ptr)+27), \ + *(((char*)ptr)+28),*(((char*)ptr)+29), \ + *(((char*)ptr)+30),*(((char*)ptr)+31)); + +static inline void +iucv_hex_dump(unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + if (i && !(i % 16)) + printk("\n"); + printk("%02x ", *(buf + i)); + } + printk("\n"); +} +/** + * end of debug stuff + */ + +#define uchar unsigned char +#define ushort unsigned short +#define ulong unsigned long +#define iucv_handle_t void * + +/* flags1: + * All flags are defined in the field IPFLAGS1 of each function + * and can be found in CP Programming Services. + * IPLOCAL - Indicates the connect can only be satisfied on the + * local system + * IPPRTY - Indicates a priority message + * IPQUSCE - Indicates you do not want to receive messages on a + * path until an iucv_resume is issued + * IPRMDATA - Indicates that the message is in the parameter list + */ +#define IPLOCAL 0x01 +#define IPPRTY 0x20 +#define IPQUSCE 0x40 +#define IPRMDATA 0x80 + +/* flags1_out: + * All flags are defined in the output field of IPFLAGS1 for each function + * and can be found in CP Programming Services. + * IPNORPY - Specifies this is a one-way message and no reply is expected. + * IPPRTY - Indicates a priority message is permitted. Defined in flags1. + */ +#define IPNORPY 0x10 + +#define Nonpriority_MessagePendingInterruptsFlag 0x80 +#define Priority_MessagePendingInterruptsFlag 0x40 +#define Nonpriority_MessageCompletionInterruptsFlag 0x20 +#define Priority_MessageCompletionInterruptsFlag 0x10 +#define IUCVControlInterruptsFlag 0x08 +#define AllInterrupts 0xf8 +/* + * Mapping of external interrupt buffers should be used with the corresponding + * interrupt types. + * Names: iucv_ConnectionPending -> connection pending + * iucv_ConnectionComplete -> connection complete + * iucv_ConnectionSevered -> connection severed + * iucv_ConnectionQuiesced -> connection quiesced + * iucv_ConnectionResumed -> connection resumed + * iucv_MessagePending -> message pending + * iucv_MessageComplete -> message complete + */ +typedef struct { + u16 ippathid; + uchar ipflags1; + uchar iptype; + u16 ipmsglim; + u16 res1; + uchar ipvmid[8]; + uchar ipuser[16]; + u32 res3; + uchar ippollfg; + uchar res4[3]; +} iucv_ConnectionPending; + +typedef struct { + u16 ippathid; + uchar ipflags1; + uchar iptype; + u16 ipmsglim; + u16 res1; + uchar res2[8]; + uchar ipuser[16]; + u32 res3; + uchar ippollfg; + uchar res4[3]; +} iucv_ConnectionComplete; + +typedef struct { + u16 ippathid; + uchar res1; + uchar iptype; + u32 res2; + uchar res3[8]; + uchar ipuser[16]; + u32 res4; + uchar ippollfg; + uchar res5[3]; +} iucv_ConnectionSevered; + +typedef struct { + u16 ippathid; + uchar res1; + uchar iptype; + u32 res2; + uchar res3[8]; + uchar ipuser[16]; + u32 res4; + uchar ippollfg; + uchar res5[3]; +} iucv_ConnectionQuiesced; + +typedef struct { + u16 ippathid; + uchar res1; + uchar iptype; + u32 res2; + uchar res3[8]; + uchar ipuser[16]; + u32 res4; + uchar ippollfg; + uchar res5[3]; +} iucv_ConnectionResumed; + +typedef struct { + u16 ippathid; + uchar ipflags1; + uchar iptype; + u32 ipmsgid; + u32 iptrgcls; + union u2 { + u32 iprmmsg1_u32; + uchar iprmmsg1[4]; + } ln1msg1; + union u1 { + u32 ipbfln1f; + uchar iprmmsg2[4]; + } ln1msg2; + u32 res1[3]; + u32 ipbfln2f; + uchar ippollfg; + uchar res2[3]; +} iucv_MessagePending; + +typedef struct { + u16 ippathid; + uchar ipflags1; + uchar iptype; + u32 ipmsgid; + u32 ipaudit; + uchar iprmmsg[8]; + u32 ipsrccls; + u32 ipmsgtag; + u32 res; + u32 ipbfln2f; + uchar ippollfg; + uchar res2[3]; +} iucv_MessageComplete; + +/* + * iucv_interrupt_ops_t: Is a vector of functions that handle + * IUCV interrupts. + * Parameter list: + * eib - is a pointer to a 40-byte area described + * with one of the structures above. + * pgm_data - this data is strictly for the + * interrupt handler that is passed by + * the application. This may be an address + * or token. +*/ +typedef struct { + void (*ConnectionPending) (iucv_ConnectionPending * eib, + void *pgm_data); + void (*ConnectionComplete) (iucv_ConnectionComplete * eib, + void *pgm_data); + void (*ConnectionSevered) (iucv_ConnectionSevered * eib, + void *pgm_data); + void (*ConnectionQuiesced) (iucv_ConnectionQuiesced * eib, + void *pgm_data); + void (*ConnectionResumed) (iucv_ConnectionResumed * eib, + void *pgm_data); + void (*MessagePending) (iucv_MessagePending * eib, void *pgm_data); + void (*MessageComplete) (iucv_MessageComplete * eib, void *pgm_data); +} iucv_interrupt_ops_t; + +/* + *iucv_array_t : Defines buffer array. + * Inside the array may be 31- bit addresses and 31-bit lengths. +*/ +typedef struct { + u32 address; + u32 length; +} iucv_array_t __attribute__ ((aligned (8))); + +extern struct bus_type iucv_bus; +extern struct device *iucv_root; + +/* -prototypes- */ +/* + * Name: iucv_register_program + * Purpose: Registers an application with IUCV + * Input: prmname - user identification + * userid - machine identification + * pgmmask - indicates which bits in the prmname and userid combined will be + * used to determine who is given control + * ops - address of vector of interrupt handlers + * pgm_data- application data passed to interrupt handlers + * Output: NA + * Return: address of handler + * (0) - Error occurred, registration not completed. + * NOTE: Exact cause of failure will be recorded in syslog. +*/ +iucv_handle_t iucv_register_program (uchar pgmname[16], + uchar userid[8], + uchar pgmmask[24], + iucv_interrupt_ops_t * ops, + void *pgm_data); + +/* + * Name: iucv_unregister_program + * Purpose: Unregister application with IUCV + * Input: address of handler + * Output: NA + * Return: (0) - Normal return + * (-EINVAL) - Internal error, wild pointer +*/ +int iucv_unregister_program (iucv_handle_t handle); + +/* + * Name: iucv_accept + * Purpose: This function is issued after the user receives a Connection Pending external + * interrupt and now wishes to complete the IUCV communication path. + * Input: pathid - u16 , Path identification number + * msglim_reqstd - u16, The number of outstanding messages requested. + * user_data - uchar[16], Data specified by the iucv_connect function. + * flags1 - int, Contains options for this path. + * -IPPRTY - 0x20- Specifies if you want to send priority message. + * -IPRMDATA - 0x80, Specifies whether your program can handle a message + * in the parameter list. + * -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being + * established. + * handle - iucv_handle_t, Address of handler. + * pgm_data - void *, Application data passed to interrupt handlers. + * flags1_out - int * Contains information about the path + * - IPPRTY - 0x20, Indicates you may send priority messages. + * msglim - *u16, Number of outstanding messages. + * Output: return code from CP IUCV call. +*/ + +int iucv_accept (u16 pathid, + u16 msglim_reqstd, + uchar user_data[16], + int flags1, + iucv_handle_t handle, + void *pgm_data, int *flags1_out, u16 * msglim); + +/* + * Name: iucv_connect + * Purpose: This function establishes an IUCV path. Although the connect may complete + * successfully, you are not able to use the path until you receive an IUCV + * Connection Complete external interrupt. + * Input: pathid - u16 *, Path identification number + * msglim_reqstd - u16, Number of outstanding messages requested + * user_data - uchar[16], 16-byte user data + * userid - uchar[8], User identification + * system_name - uchar[8], 8-byte identifying the system name + * flags1 - int, Contains options for this path. + * -IPPRTY - 0x20, Specifies if you want to send priority message. + * -IPRMDATA - 0x80, Specifies whether your program can handle a message + * in the parameter list. + * -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being + * established. + * -IPLOCAL - 0X01, Allows an application to force the partner to be on + * the local system. If local is specified then target class cannot be + * specified. + * flags1_out - int * Contains information about the path + * - IPPRTY - 0x20, Indicates you may send priority messages. + * msglim - * u16, Number of outstanding messages + * handle - iucv_handle_t, Address of handler + * pgm_data - void *, Application data passed to interrupt handlers + * Output: return code from CP IUCV call + * rc - return code from iucv_declare_buffer + * -EINVAL - Invalid handle passed by application + * -EINVAL - Pathid address is NULL + * add_pathid_result - Return code from internal function add_pathid +*/ +int + iucv_connect (u16 * pathid, + u16 msglim_reqstd, + uchar user_data[16], + uchar userid[8], + uchar system_name[8], + int flags1, + int *flags1_out, + u16 * msglim, iucv_handle_t handle, void *pgm_data); + +/* + * Name: iucv_purge + * Purpose: This function cancels a message that you have sent. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID of the message to be purged. + * srccls - Specifies the source message class. + * Output: audit - Contains information about asynchronous error + * that may have affected the normal completion + * of this message. + * Return: Return code from CP IUCV call. +*/ +int iucv_purge (u16 pathid, u32 msgid, u32 srccls, __u32 *audit); +/* + * Name: iucv_query_maxconn + * Purpose: This function determines the maximum number of communication paths you + * may establish. + * Return: maxconn - ulong, Maximum number of connection the virtual machine may + * establish. +*/ +ulong iucv_query_maxconn (void); + +/* + * Name: iucv_query_bufsize + * Purpose: This function determines how large an external interrupt + * buffer IUCV requires to store information. + * Return: bufsize - ulong, Size of external interrupt buffer. + */ +ulong iucv_query_bufsize (void); + +/* + * Name: iucv_quiesce + * Purpose: This function temporarily suspends incoming messages on an + * IUCV path. You can later reactivate the path by invoking + * the iucv_resume function. + * Input: pathid - Path identification number + * user_data - 16-bytes of user data + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_quiesce (u16 pathid, uchar user_data[16]); + +/* + * Name: iucv_receive + * Purpose: This function receives messages that are being sent to you + * over established paths. Data will be returned in buffer for length of + * buflen. + * Input: + * pathid - Path identification number. + * buffer - Address of buffer to receive. + * buflen - Length of buffer to receive. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * Output: + * flags1_out: int *, Contains information about this path. + * IPNORPY - 0x10 Specifies this is a one-way message and no reply is + * expected. + * IPPRTY - 0x20 Specifies if you want to send priority message. + * IPRMDATA - 0x80 specifies the data is contained in the parameter list + * residual_buffer - address of buffer updated by the number + * of bytes you have received. + * residual_length - + * Contains one of the following values, if the receive buffer is: + * The same length as the message, this field is zero. + * Longer than the message, this field contains the number of + * bytes remaining in the buffer. + * Shorter than the message, this field contains the residual + * count (that is, the number of bytes remaining in the + * message that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: Return code from CP IUCV call. + * (-EINVAL) - buffer address is pointing to NULL +*/ +int iucv_receive (u16 pathid, + u32 msgid, + u32 trgcls, + void *buffer, + ulong buflen, + int *flags1_out, + ulong * residual_buffer, ulong * residual_length); + + /* + * Name: iucv_receive_array + * Purpose: This function receives messages that are being sent to you + * over established paths. Data will be returned in first buffer for + * length of first buffer. + * Input: pathid - Path identification number. + * msgid - specifies the message ID. + * trgcls - Specifies target class. + * buffer - Address of array of buffers. + * buflen - Total length of buffers. + * Output: + * flags1_out: int *, Contains information about this path. + * IPNORPY - 0x10 Specifies this is a one-way message and no reply is + * expected. + * IPPRTY - 0x20 Specifies if you want to send priority message. + * IPRMDATA - 0x80 specifies the data is contained in the parameter list + * residual_buffer - address points to the current list entry IUCV + * is working on. + * residual_length - + * Contains one of the following values, if the receive buffer is: + * The same length as the message, this field is zero. + * Longer than the message, this field contains the number of + * bytes remaining in the buffer. + * Shorter than the message, this field contains the residual + * count (that is, the number of bytes remaining in the + * message that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. + */ +int iucv_receive_array (u16 pathid, + u32 msgid, + u32 trgcls, + iucv_array_t * buffer, + ulong buflen, + int *flags1_out, + ulong * residual_buffer, ulong * residual_length); + +/* + * Name: iucv_reject + * Purpose: The reject function refuses a specified message. Between the + * time you are notified of a message and the time that you + * complete the message, the message may be rejected. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_reject (u16 pathid, u32 msgid, u32 trgcls); + +/* + * Name: iucv_reply + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * flags1 - Option for path. + * IPPRTY- 0x20, Specifies if you want to send priority message. + * buffer - Address of reply buffer. + * buflen - Length of reply buffer. + * Output: residual_buffer - Address of buffer updated by the number + * of bytes you have moved. + * residual_length - Contains one of the following values: + * If the answer buffer is the same length as the reply, this field + * contains zero. + * If the answer buffer is longer than the reply, this field contains + * the number of bytes remaining in the buffer. + * If the answer buffer is shorter than the reply, this field contains + * a residual count (that is, the number of bytes remianing in the + * reply that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_reply (u16 pathid, + u32 msgid, + u32 trgcls, + int flags1, + void *buffer, ulong buflen, ulong * residual_buffer, + ulong * residual_length); + +/* + * Name: iucv_reply_array + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * The array identifies a list of addresses and lengths of + * discontiguous buffers that contains the reply data. + * Input: pathid - Path identification number + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * flags1 - Option for path. + * IPPRTY- 0x20, Specifies if you want to send priority message. + * buffer - Address of array of reply buffers. + * buflen - Total length of reply buffers. + * Output: residual_buffer - Address of buffer which IUCV is currently working on. + * residual_length - Contains one of the following values: + * If the answer buffer is the same length as the reply, this field + * contains zero. + * If the answer buffer is longer than the reply, this field contains + * the number of bytes remaining in the buffer. + * If the answer buffer is shorter than the reply, this field contains + * a residual count (that is, the number of bytes remianing in the + * reply that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_reply_array (u16 pathid, + u32 msgid, + u32 trgcls, + int flags1, + iucv_array_t * buffer, + ulong buflen, ulong * residual_address, + ulong * residual_length); + +/* + * Name: iucv_reply_prmmsg + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Prmmsg signifies the data is moved into the + * parameter list. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * prmmsg - 8-bytes of data to be placed into the parameter. + * list. + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_reply_prmmsg (u16 pathid, + u32 msgid, u32 trgcls, int flags1, uchar prmmsg[8]); + +/* + * Name: iucv_resume + * Purpose: This function restores communications over a quiesced path + * Input: pathid - Path identification number. + * user_data - 16-bytes of user data. + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_resume (u16 pathid, uchar user_data[16]); + +/* + * Name: iucv_send + * Purpose: This function transmits data to another application. + * Data to be transmitted is in a buffer and this is a + * one-way message and the receiver will not reply to the + * message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * buffer - Address of send buffer. + * buflen - Length of send buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_send (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, u32 msgtag, int flags1, void *buffer, ulong buflen); + +/* + * Name: iucv_send_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated witht the message. + * flags1 - Option for path. + * IPPRTY- specifies if you want to send priority message. + * buffer - Address of array of send buffers. + * buflen - Total length of send buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_send_array (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + int flags1, iucv_array_t * buffer, ulong buflen); + +/* + * Name: iucv_send_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 specifies if you want to send priority message. + * prmmsg - 8-bytes of data to be placed into parameter list. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. +*/ +int iucv_send_prmmsg (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, u32 msgtag, int flags1, uchar prmmsg[8]); + +/* + * Name: iucv_send2way + * Purpose: This function transmits data to another application. + * Data to be transmitted is in a buffer. The receiver + * of the send is expected to reply to the message and + * a buffer is provided into which IUCV moves the reply + * to this message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * buffer - Address of send buffer. + * buflen - Length of send buffer. + * ansbuf - Address of buffer into which IUCV moves the reply of + * this message. + * anslen - Address of length of buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer or ansbuf address is NULL. +*/ +int iucv_send2way (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + int flags1, + void *buffer, ulong buflen, void *ansbuf, ulong anslen); + +/* + * Name: iucv_send2way_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. The receiver of the send is expected to + * reply to the message and a buffer is provided into which + * IUCV moves the reply to this message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * buffer - Sddress of array of send buffers. + * buflen - Total length of send buffers. + * ansbuf - Address of array of buffer into which IUCV moves the reply + * of this message. + * anslen - Address of length reply buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_send2way_array (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + int flags1, + iucv_array_t * buffer, + ulong buflen, iucv_array_t * ansbuf, ulong anslen); + +/* + * Name: iucv_send2way_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. + * Input: pathid - Rath identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * prmmsg - 8-bytes of data to be placed in parameter list. + * ansbuf - Address of buffer into which IUCV moves the reply of + * this message. + * anslen - Address of length of buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_send2way_prmmsg (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + ulong flags1, + uchar prmmsg[8], void *ansbuf, ulong anslen); + +/* + * Name: iucv_send2way_prmmsg_array + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. The contents of ansbuf is the address of the + * array of addresses and lengths of discontiguous buffers + * that contain the reply. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 specifies if you want to send priority message. + * prmmsg - 8-bytes of data to be placed into the parameter list. + * ansbuf - Address of array of buffer into which IUCV moves the reply + * of this message. + * anslen - Address of length of reply buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Ansbuf address is NULL. +*/ +int iucv_send2way_prmmsg_array (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + int flags1, + uchar prmmsg[8], + iucv_array_t * ansbuf, ulong anslen); + +/* + * Name: iucv_setmask + * Purpose: This function enables or disables the following IUCV + * external interruptions: Nonpriority and priority message + * interrupts, nonpriority and priority reply interrupts. + * Input: SetMaskFlag - options for interrupts + * 0x80 - Nonpriority_MessagePendingInterruptsFlag + * 0x40 - Priority_MessagePendingInterruptsFlag + * 0x20 - Nonpriority_MessageCompletionInterruptsFlag + * 0x10 - Priority_MessageCompletionInterruptsFlag + * 0x08 - IUCVControlInterruptsFlag + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_setmask (int SetMaskFlag); + +/* + * Name: iucv_sever + * Purpose: This function terminates an IUCV path. + * Input: pathid - Path identification number. + * user_data - 16-bytes of user data. + * Output: NA + * Return: Return code from CP IUCV call. + * (-EINVAL) - Interal error, wild pointer. +*/ +int iucv_sever (u16 pathid, uchar user_data[16]); diff --git a/trunk/drivers/s390/net/netiucv.c b/trunk/drivers/s390/net/netiucv.c index 6387b483f2bf..3346088f47e0 100644 --- a/trunk/drivers/s390/net/netiucv.c +++ b/trunk/drivers/s390/net/netiucv.c @@ -1,7 +1,7 @@ /* * IUCV network driver * - * Copyright 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) * * Sysfs integration and all bugs therein by Cornelia Huck @@ -58,94 +58,13 @@ #include #include -#include +#include "iucv.h" #include "fsm.h" MODULE_AUTHOR ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); -/** - * Debug Facility stuff - */ -#define IUCV_DBF_SETUP_NAME "iucv_setup" -#define IUCV_DBF_SETUP_LEN 32 -#define IUCV_DBF_SETUP_PAGES 2 -#define IUCV_DBF_SETUP_NR_AREAS 1 -#define IUCV_DBF_SETUP_LEVEL 3 - -#define IUCV_DBF_DATA_NAME "iucv_data" -#define IUCV_DBF_DATA_LEN 128 -#define IUCV_DBF_DATA_PAGES 2 -#define IUCV_DBF_DATA_NR_AREAS 1 -#define IUCV_DBF_DATA_LEVEL 2 - -#define IUCV_DBF_TRACE_NAME "iucv_trace" -#define IUCV_DBF_TRACE_LEN 16 -#define IUCV_DBF_TRACE_PAGES 4 -#define IUCV_DBF_TRACE_NR_AREAS 1 -#define IUCV_DBF_TRACE_LEVEL 3 - -#define IUCV_DBF_TEXT(name,level,text) \ - do { \ - debug_text_event(iucv_dbf_##name,level,text); \ - } while (0) - -#define IUCV_DBF_HEX(name,level,addr,len) \ - do { \ - debug_event(iucv_dbf_##name,level,(void*)(addr),len); \ - } while (0) - -DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf); - -#define IUCV_DBF_TEXT_(name,level,text...) \ - do { \ - char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \ - sprintf(iucv_dbf_txt_buf, text); \ - debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \ - put_cpu_var(iucv_dbf_txt_buf); \ - } while (0) - -#define IUCV_DBF_SPRINTF(name,level,text...) \ - do { \ - debug_sprintf_event(iucv_dbf_trace, level, ##text ); \ - debug_sprintf_event(iucv_dbf_trace, level, text ); \ - } while (0) - -/** - * some more debug stuff - */ -#define IUCV_HEXDUMP16(importance,header,ptr) \ -PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ - "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ - *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \ - *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \ - *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \ - *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \ - *(((char*)ptr)+12),*(((char*)ptr)+13), \ - *(((char*)ptr)+14),*(((char*)ptr)+15)); \ -PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ - "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ - *(((char*)ptr)+16),*(((char*)ptr)+17), \ - *(((char*)ptr)+18),*(((char*)ptr)+19), \ - *(((char*)ptr)+20),*(((char*)ptr)+21), \ - *(((char*)ptr)+22),*(((char*)ptr)+23), \ - *(((char*)ptr)+24),*(((char*)ptr)+25), \ - *(((char*)ptr)+26),*(((char*)ptr)+27), \ - *(((char*)ptr)+28),*(((char*)ptr)+29), \ - *(((char*)ptr)+30),*(((char*)ptr)+31)); - -static inline void iucv_hex_dump(unsigned char *buf, size_t len) -{ - size_t i; - - for (i = 0; i < len; i++) { - if (i && !(i % 16)) - printk("\n"); - printk("%02x ", *(buf + i)); - } - printk("\n"); -} #define PRINTK_HEADER " iucv: " /* for debugging */ @@ -154,25 +73,6 @@ static struct device_driver netiucv_driver = { .bus = &iucv_bus, }; -static int netiucv_callback_connreq(struct iucv_path *, - u8 ipvmid[8], u8 ipuser[16]); -static void netiucv_callback_connack(struct iucv_path *, u8 ipuser[16]); -static void netiucv_callback_connrej(struct iucv_path *, u8 ipuser[16]); -static void netiucv_callback_connsusp(struct iucv_path *, u8 ipuser[16]); -static void netiucv_callback_connres(struct iucv_path *, u8 ipuser[16]); -static void netiucv_callback_rx(struct iucv_path *, struct iucv_message *); -static void netiucv_callback_txdone(struct iucv_path *, struct iucv_message *); - -static struct iucv_handler netiucv_handler = { - .path_pending = netiucv_callback_connreq, - .path_complete = netiucv_callback_connack, - .path_severed = netiucv_callback_connrej, - .path_quiesced = netiucv_callback_connsusp, - .path_resumed = netiucv_callback_connres, - .message_pending = netiucv_callback_rx, - .message_complete = netiucv_callback_txdone -}; - /** * Per connection profiling data */ @@ -192,8 +92,9 @@ struct connection_profile { * Representation of one iucv connection */ struct iucv_connection { - struct list_head list; - struct iucv_path *path; + struct iucv_connection *next; + iucv_handle_t handle; + __u16 pathid; struct sk_buff *rx_buff; struct sk_buff *tx_buff; struct sk_buff_head collect_queue; @@ -211,9 +112,12 @@ struct iucv_connection { /** * Linked list of all connection structs. */ -static struct list_head iucv_connection_list = - LIST_HEAD_INIT(iucv_connection_list); -static rwlock_t iucv_connection_rwlock = RW_LOCK_UNLOCKED; +struct iucv_connection_struct { + struct iucv_connection *iucv_connections; + rwlock_t iucv_rwlock; +}; + +static struct iucv_connection_struct iucv_conns; /** * Representation of event-data for the @@ -238,11 +142,11 @@ struct netiucv_priv { /** * Link level header for a packet. */ -struct ll_header { - u16 next; -}; +typedef struct ll_header_t { + __u16 next; +} ll_header; -#define NETIUCV_HDRLEN (sizeof(struct ll_header)) +#define NETIUCV_HDRLEN (sizeof(ll_header)) #define NETIUCV_BUFSIZE_MAX 32768 #define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX #define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN) @@ -254,25 +158,35 @@ struct ll_header { * Compatibility macros for busy handling * of network devices. */ -static inline void netiucv_clear_busy(struct net_device *dev) +static __inline__ void netiucv_clear_busy(struct net_device *dev) { - struct netiucv_priv *priv = netdev_priv(dev); - clear_bit(0, &priv->tbusy); + clear_bit(0, &(((struct netiucv_priv *)dev->priv)->tbusy)); netif_wake_queue(dev); } -static inline int netiucv_test_and_set_busy(struct net_device *dev) +static __inline__ int netiucv_test_and_set_busy(struct net_device *dev) { - struct netiucv_priv *priv = netdev_priv(dev); netif_stop_queue(dev); - return test_and_set_bit(0, &priv->tbusy); + return test_and_set_bit(0, &((struct netiucv_priv *)dev->priv)->tbusy); } -static u8 iucvMagic[16] = { +static __u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static __u8 iucvMagic[16] = { 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }; +/** + * This mask means the 16-byte IUCV "magic" and the origin userid must + * match exactly as specified in order to give connection_pending() + * control. + */ +static __u8 netiucv_mask[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + /** * Convert an iucv userId to its printable * form (strip whitespace at end). @@ -281,7 +195,8 @@ static u8 iucvMagic[16] = { * * @returns The printable string (static data!!) */ -static inline char *netiucv_printname(char *name) +static __inline__ char * +netiucv_printname(char *name) { static char tmp[9]; char *p = tmp; @@ -464,7 +379,8 @@ static debug_info_t *iucv_dbf_trace = NULL; DEFINE_PER_CPU(char[256], iucv_dbf_txt_buf); -static void iucv_unregister_dbf_views(void) +static void +iucv_unregister_dbf_views(void) { if (iucv_dbf_setup) debug_unregister(iucv_dbf_setup); @@ -473,7 +389,8 @@ static void iucv_unregister_dbf_views(void) if (iucv_dbf_trace) debug_unregister(iucv_dbf_trace); } -static int iucv_register_dbf_views(void) +static int +iucv_register_dbf_views(void) { iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME, IUCV_DBF_SETUP_PAGES, @@ -505,111 +422,125 @@ static int iucv_register_dbf_views(void) return 0; } -/* +/** * Callback-wrappers, called from lowlevel iucv layer. - */ + *****************************************************************************/ -static void netiucv_callback_rx(struct iucv_path *path, - struct iucv_message *msg) +static void +netiucv_callback_rx(iucv_MessagePending *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; struct iucv_event ev; ev.conn = conn; - ev.data = msg; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_RX, &ev); } -static void netiucv_callback_txdone(struct iucv_path *path, - struct iucv_message *msg) +static void +netiucv_callback_txdone(iucv_MessageComplete *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; struct iucv_event ev; ev.conn = conn; - ev.data = msg; + ev.data = (void *)eib; fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev); } -static void netiucv_callback_connack(struct iucv_path *path, u8 ipuser[16]) +static void +netiucv_callback_connack(iucv_ConnectionComplete *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; + struct iucv_event ev; - fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, conn); + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev); } -static int netiucv_callback_connreq(struct iucv_path *path, - u8 ipvmid[8], u8 ipuser[16]) +static void +netiucv_callback_connreq(iucv_ConnectionPending *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; struct iucv_event ev; - int rc; - if (memcmp(iucvMagic, ipuser, sizeof(ipuser))) - /* ipuser must match iucvMagic. */ - return -EINVAL; - rc = -EINVAL; - read_lock_bh(&iucv_connection_rwlock); - list_for_each_entry(conn, &iucv_connection_list, list) { - if (strncmp(ipvmid, conn->userid, 8)) - continue; - /* Found a matching connection for this path. */ - conn->path = path; - ev.conn = conn; - ev.data = path; - fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev); - rc = 0; - } - read_unlock_bh(&iucv_connection_rwlock); - return rc; + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev); } -static void netiucv_callback_connrej(struct iucv_path *path, u8 ipuser[16]) +static void +netiucv_callback_connrej(iucv_ConnectionSevered *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; + struct iucv_event ev; - fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, conn); + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, &ev); } -static void netiucv_callback_connsusp(struct iucv_path *path, u8 ipuser[16]) +static void +netiucv_callback_connsusp(iucv_ConnectionQuiesced *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; + struct iucv_event ev; - fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, conn); + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, &ev); } -static void netiucv_callback_connres(struct iucv_path *path, u8 ipuser[16]) +static void +netiucv_callback_connres(iucv_ConnectionResumed *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; + struct iucv_event ev; - fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn); -} + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_RES, &ev); +} + +static iucv_interrupt_ops_t netiucv_ops = { + .ConnectionPending = netiucv_callback_connreq, + .ConnectionComplete = netiucv_callback_connack, + .ConnectionSevered = netiucv_callback_connrej, + .ConnectionQuiesced = netiucv_callback_connsusp, + .ConnectionResumed = netiucv_callback_connres, + .MessagePending = netiucv_callback_rx, + .MessageComplete = netiucv_callback_txdone +}; /** * Dummy NOP action for all statemachines */ -static void fsm_action_nop(fsm_instance *fi, int event, void *arg) +static void +fsm_action_nop(fsm_instance *fi, int event, void *arg) { } -/* +/** * Actions of the connection statemachine - */ + *****************************************************************************/ /** - * netiucv_unpack_skb - * @conn: The connection where this skb has been received. - * @pskb: The received skb. + * Helper function for conn_action_rx() + * Unpack a just received skb and hand it over to + * upper layers. * - * Unpack a just received skb and hand it over to upper layers. - * Helper function for conn_action_rx. + * @param conn The connection where this skb has been received. + * @param pskb The received skb. */ -static void netiucv_unpack_skb(struct iucv_connection *conn, - struct sk_buff *pskb) +//static __inline__ void +static void +netiucv_unpack_skb(struct iucv_connection *conn, struct sk_buff *pskb) { struct net_device *dev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(dev); - u16 offset = 0; + struct netiucv_priv *privptr = dev->priv; + __u16 offset = 0; skb_put(pskb, NETIUCV_HDRLEN); pskb->dev = dev; @@ -618,7 +549,7 @@ static void netiucv_unpack_skb(struct iucv_connection *conn, while (1) { struct sk_buff *skb; - struct ll_header *header = (struct ll_header *) pskb->data; + ll_header *header = (ll_header *)pskb->data; if (!header->next) break; @@ -664,37 +595,40 @@ static void netiucv_unpack_skb(struct iucv_connection *conn, } } -static void conn_action_rx(fsm_instance *fi, int event, void *arg) +static void +conn_action_rx(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; + struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; - struct iucv_message *msg = ev->data; - struct netiucv_priv *privptr = netdev_priv(conn->netdev); + iucv_MessagePending *eib = (iucv_MessagePending *)ev->data; + struct netiucv_priv *privptr =(struct netiucv_priv *)conn->netdev->priv; + + __u32 msglen = eib->ln1msg2.ipbfln1f; int rc; IUCV_DBF_TEXT(trace, 4, __FUNCTION__); if (!conn->netdev) { - iucv_message_reject(conn->path, msg); + /* FRITZ: How to tell iucv LL to drop the msg? */ PRINT_WARN("Received data for unlinked connection\n"); IUCV_DBF_TEXT(data, 2, - "Received data for unlinked connection\n"); + "Received data for unlinked connection\n"); return; } - if (msg->length > conn->max_buffsize) { - iucv_message_reject(conn->path, msg); + if (msglen > conn->max_buffsize) { + /* FRITZ: How to tell iucv LL to drop the msg? */ privptr->stats.rx_dropped++; PRINT_WARN("msglen %d > max_buffsize %d\n", - msg->length, conn->max_buffsize); + msglen, conn->max_buffsize); IUCV_DBF_TEXT_(data, 2, "msglen %d > max_buffsize %d\n", - msg->length, conn->max_buffsize); + msglen, conn->max_buffsize); return; } conn->rx_buff->data = conn->rx_buff->tail = conn->rx_buff->head; conn->rx_buff->len = 0; - rc = iucv_message_receive(conn->path, msg, 0, conn->rx_buff->data, - msg->length, NULL); - if (rc || msg->length < 5) { + rc = iucv_receive(conn->pathid, eib->ipmsgid, eib->iptrgcls, + conn->rx_buff->data, msglen, NULL, NULL, NULL); + if (rc || msglen < 5) { privptr->stats.rx_errors++; PRINT_WARN("iucv_receive returned %08x\n", rc); IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_receive\n", rc); @@ -703,26 +637,26 @@ static void conn_action_rx(fsm_instance *fi, int event, void *arg) netiucv_unpack_skb(conn, conn->rx_buff); } -static void conn_action_txdone(fsm_instance *fi, int event, void *arg) +static void +conn_action_txdone(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; + struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; - struct iucv_message *msg = ev->data; - struct iucv_message txmsg; + iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data; struct netiucv_priv *privptr = NULL; - u32 single_flag = msg->tag; - u32 txbytes = 0; - u32 txpackets = 0; - u32 stat_maxcq = 0; + /* Shut up, gcc! skb is always below 2G. */ + __u32 single_flag = eib->ipmsgtag; + __u32 txbytes = 0; + __u32 txpackets = 0; + __u32 stat_maxcq = 0; struct sk_buff *skb; unsigned long saveflags; - struct ll_header header; - int rc; + ll_header header; IUCV_DBF_TEXT(trace, 4, __FUNCTION__); - if (conn && conn->netdev) - privptr = netdev_priv(conn->netdev); + if (conn && conn->netdev && conn->netdev->priv) + privptr = (struct netiucv_priv *)conn->netdev->priv; conn->prof.tx_pending--; if (single_flag) { if ((skb = skb_dequeue(&conn->commit_queue))) { @@ -754,55 +688,56 @@ static void conn_action_txdone(fsm_instance *fi, int event, void *arg) conn->prof.maxmulti = conn->collect_len; conn->collect_len = 0; spin_unlock_irqrestore(&conn->collect_lock, saveflags); - if (conn->tx_buff->len == 0) { - fsm_newstate(fi, CONN_STATE_IDLE); - return; - } + if (conn->tx_buff->len) { + int rc; + + header.next = 0; + memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, + NETIUCV_HDRLEN); - header.next = 0; - memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN); - conn->prof.send_stamp = xtime; - txmsg.class = 0; - txmsg.tag = 0; - rc = iucv_message_send(conn->path, &txmsg, 0, 0, + conn->prof.send_stamp = xtime; + rc = iucv_send(conn->pathid, NULL, 0, 0, 0, 0, conn->tx_buff->data, conn->tx_buff->len); - conn->prof.doios_multi++; - conn->prof.txlen += conn->tx_buff->len; - conn->prof.tx_pending++; - if (conn->prof.tx_pending > conn->prof.tx_max_pending) - conn->prof.tx_max_pending = conn->prof.tx_pending; - if (rc) { - conn->prof.tx_pending--; - fsm_newstate(fi, CONN_STATE_IDLE); - if (privptr) - privptr->stats.tx_errors += txpackets; - PRINT_WARN("iucv_send returned %08x\n", rc); - IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc); - } else { - if (privptr) { - privptr->stats.tx_packets += txpackets; - privptr->stats.tx_bytes += txbytes; + conn->prof.doios_multi++; + conn->prof.txlen += conn->tx_buff->len; + conn->prof.tx_pending++; + if (conn->prof.tx_pending > conn->prof.tx_max_pending) + conn->prof.tx_max_pending = conn->prof.tx_pending; + if (rc) { + conn->prof.tx_pending--; + fsm_newstate(fi, CONN_STATE_IDLE); + if (privptr) + privptr->stats.tx_errors += txpackets; + PRINT_WARN("iucv_send returned %08x\n", rc); + IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc); + } else { + if (privptr) { + privptr->stats.tx_packets += txpackets; + privptr->stats.tx_bytes += txbytes; + } + if (stat_maxcq > conn->prof.maxcqueue) + conn->prof.maxcqueue = stat_maxcq; } - if (stat_maxcq > conn->prof.maxcqueue) - conn->prof.maxcqueue = stat_maxcq; - } + } else + fsm_newstate(fi, CONN_STATE_IDLE); } -static void conn_action_connaccept(fsm_instance *fi, int event, void *arg) +static void +conn_action_connaccept(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; + struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; - struct iucv_path *path = ev->data; + iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data; struct net_device *netdev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(netdev); + struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; int rc; + __u16 msglimit; + __u8 udata[16]; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - conn->path = path; - path->msglim = NETIUCV_QUEUELEN_DEFAULT; - path->flags = 0; - rc = iucv_path_accept(path, &netiucv_handler, NULL, conn); + rc = iucv_accept(eib->ippathid, NETIUCV_QUEUELEN_DEFAULT, udata, 0, + conn->handle, conn, NULL, &msglimit); if (rc) { PRINT_WARN("%s: IUCV accept failed with error %d\n", netdev->name, rc); @@ -810,126 +745,183 @@ static void conn_action_connaccept(fsm_instance *fi, int event, void *arg) return; } fsm_newstate(fi, CONN_STATE_IDLE); - netdev->tx_queue_len = conn->path->msglim; + conn->pathid = eib->ippathid; + netdev->tx_queue_len = msglimit; fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev); } -static void conn_action_connreject(fsm_instance *fi, int event, void *arg) +static void +conn_action_connreject(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; - struct iucv_path *path = ev->data; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; + struct net_device *netdev = conn->netdev; + iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data; + __u8 udata[16]; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - iucv_path_sever(path, NULL); + + iucv_sever(eib->ippathid, udata); + if (eib->ippathid != conn->pathid) { + PRINT_INFO("%s: IR Connection Pending; " + "pathid %d does not match original pathid %d\n", + netdev->name, eib->ippathid, conn->pathid); + IUCV_DBF_TEXT_(data, 2, + "connreject: IR pathid %d, conn. pathid %d\n", + eib->ippathid, conn->pathid); + iucv_sever(conn->pathid, udata); + } } -static void conn_action_connack(fsm_instance *fi, int event, void *arg) +static void +conn_action_connack(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; + iucv_ConnectionComplete *eib = (iucv_ConnectionComplete *)ev->data; struct net_device *netdev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(netdev); + struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); + fsm_deltimer(&conn->timer); fsm_newstate(fi, CONN_STATE_IDLE); - netdev->tx_queue_len = conn->path->msglim; + if (eib->ippathid != conn->pathid) { + PRINT_INFO("%s: IR Connection Complete; " + "pathid %d does not match original pathid %d\n", + netdev->name, eib->ippathid, conn->pathid); + IUCV_DBF_TEXT_(data, 2, + "connack: IR pathid %d, conn. pathid %d\n", + eib->ippathid, conn->pathid); + conn->pathid = eib->ippathid; + } + netdev->tx_queue_len = eib->ipmsglim; fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev); } -static void conn_action_conntimsev(fsm_instance *fi, int event, void *arg) +static void +conn_action_conntimsev(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_connection *conn = (struct iucv_connection *)arg; + __u8 udata[16]; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); + fsm_deltimer(&conn->timer); - iucv_path_sever(conn->path, NULL); + iucv_sever(conn->pathid, udata); fsm_newstate(fi, CONN_STATE_STARTWAIT); } -static void conn_action_connsever(fsm_instance *fi, int event, void *arg) +static void +conn_action_connsever(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; struct net_device *netdev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(netdev); + struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; + __u8 udata[16]; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); fsm_deltimer(&conn->timer); - iucv_path_sever(conn->path, NULL); + iucv_sever(conn->pathid, udata); PRINT_INFO("%s: Remote dropped connection\n", netdev->name); IUCV_DBF_TEXT(data, 2, - "conn_action_connsever: Remote dropped connection\n"); + "conn_action_connsever: Remote dropped connection\n"); fsm_newstate(fi, CONN_STATE_STARTWAIT); fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); } -static void conn_action_start(fsm_instance *fi, int event, void *arg) +static void +conn_action_start(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; + __u16 msglimit; int rc; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - fsm_newstate(fi, CONN_STATE_STARTWAIT); + if (!conn->handle) { + IUCV_DBF_TEXT(trace, 5, "calling iucv_register_program\n"); + conn->handle = + iucv_register_program(iucvMagic, conn->userid, + netiucv_mask, + &netiucv_ops, conn); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + if (!conn->handle) { + fsm_newstate(fi, CONN_STATE_REGERR); + conn->handle = NULL; + IUCV_DBF_TEXT(setup, 2, + "NULL from iucv_register_program\n"); + return; + } + + PRINT_DEBUG("%s('%s'): registered successfully\n", + conn->netdev->name, conn->userid); + } + PRINT_DEBUG("%s('%s'): connecting ...\n", - conn->netdev->name, conn->userid); + conn->netdev->name, conn->userid); - /* - * We must set the state before calling iucv_connect because the - * callback handler could be called at any point after the connection - * request is sent - */ + /* We must set the state before calling iucv_connect because the callback + * handler could be called at any point after the connection request is + * sent */ fsm_newstate(fi, CONN_STATE_SETUPWAIT); - conn->path = iucv_path_alloc(NETIUCV_QUEUELEN_DEFAULT, 0, GFP_KERNEL); - rc = iucv_path_connect(conn->path, &netiucv_handler, conn->userid, - NULL, iucvMagic, conn); + rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic, + conn->userid, iucv_host, 0, NULL, &msglimit, + conn->handle, conn); switch (rc) { - case 0: - conn->netdev->tx_queue_len = conn->path->msglim; - fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, - CONN_EVENT_TIMER, conn); - return; - case 11: - PRINT_INFO("%s: User %s is currently not available.\n", - conn->netdev->name, - netiucv_printname(conn->userid)); - fsm_newstate(fi, CONN_STATE_STARTWAIT); - break; - case 12: - PRINT_INFO("%s: User %s is currently not ready.\n", - conn->netdev->name, - netiucv_printname(conn->userid)); - fsm_newstate(fi, CONN_STATE_STARTWAIT); - break; - case 13: - PRINT_WARN("%s: Too many IUCV connections.\n", - conn->netdev->name); - fsm_newstate(fi, CONN_STATE_CONNERR); - break; - case 14: - PRINT_WARN("%s: User %s has too many IUCV connections.\n", - conn->netdev->name, - netiucv_printname(conn->userid)); - fsm_newstate(fi, CONN_STATE_CONNERR); - break; - case 15: - PRINT_WARN("%s: No IUCV authorization in CP directory.\n", - conn->netdev->name); - fsm_newstate(fi, CONN_STATE_CONNERR); - break; - default: - PRINT_WARN("%s: iucv_connect returned error %d\n", - conn->netdev->name, rc); - fsm_newstate(fi, CONN_STATE_CONNERR); - break; + case 0: + conn->netdev->tx_queue_len = msglimit; + fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, + CONN_EVENT_TIMER, conn); + return; + case 11: + PRINT_INFO("%s: User %s is currently not available.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + return; + case 12: + PRINT_INFO("%s: User %s is currently not ready.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + return; + case 13: + PRINT_WARN("%s: Too many IUCV connections.\n", + conn->netdev->name); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + case 14: + PRINT_WARN( + "%s: User %s has too many IUCV connections.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + case 15: + PRINT_WARN( + "%s: No IUCV authorization in CP directory.\n", + conn->netdev->name); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + default: + PRINT_WARN("%s: iucv_connect returned error %d\n", + conn->netdev->name, rc); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; } IUCV_DBF_TEXT_(setup, 5, "iucv_connect rc is %d\n", rc); - kfree(conn->path); - conn->path = NULL; + IUCV_DBF_TEXT(trace, 5, "calling iucv_unregister_program\n"); + iucv_unregister_program(conn->handle); + conn->handle = NULL; } -static void netiucv_purge_skb_queue(struct sk_buff_head *q) +static void +netiucv_purge_skb_queue(struct sk_buff_head *q) { struct sk_buff *skb; @@ -939,34 +931,36 @@ static void netiucv_purge_skb_queue(struct sk_buff_head *q) } } -static void conn_action_stop(fsm_instance *fi, int event, void *arg) +static void +conn_action_stop(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; + struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; struct net_device *netdev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(netdev); + struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); fsm_deltimer(&conn->timer); fsm_newstate(fi, CONN_STATE_STOPPED); netiucv_purge_skb_queue(&conn->collect_queue); - if (conn->path) { - IUCV_DBF_TEXT(trace, 5, "calling iucv_path_sever\n"); - iucv_path_sever(conn->path, iucvMagic); - kfree(conn->path); - conn->path = NULL; - } + if (conn->handle) + IUCV_DBF_TEXT(trace, 5, "calling iucv_unregister_program\n"); + iucv_unregister_program(conn->handle); + conn->handle = NULL; netiucv_purge_skb_queue(&conn->commit_queue); fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); } -static void conn_action_inval(fsm_instance *fi, int event, void *arg) +static void +conn_action_inval(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; struct net_device *netdev = conn->netdev; - PRINT_WARN("%s: Cannot connect without username\n", netdev->name); + PRINT_WARN("%s: Cannot connect without username\n", + netdev->name); IUCV_DBF_TEXT(data, 2, "conn_action_inval called\n"); } @@ -1005,27 +999,29 @@ static const fsm_node conn_fsm[] = { static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); -/* +/** * Actions for interface - statemachine. - */ + *****************************************************************************/ /** - * dev_action_start - * @fi: An instance of an interface statemachine. - * @event: The event, just happened. - * @arg: Generic pointer, casted from struct net_device * upon call. - * * Startup connection by sending CONN_EVENT_START to it. + * + * @param fi An instance of an interface statemachine. + * @param event The event, just happened. + * @param arg Generic pointer, casted from struct net_device * upon call. */ -static void dev_action_start(fsm_instance *fi, int event, void *arg) +static void +dev_action_start(fsm_instance *fi, int event, void *arg) { - struct net_device *dev = arg; - struct netiucv_priv *privptr = netdev_priv(dev); + struct net_device *dev = (struct net_device *)arg; + struct netiucv_priv *privptr = dev->priv; + struct iucv_event ev; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); + ev.conn = privptr->conn; fsm_newstate(fi, DEV_STATE_STARTWAIT); - fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn); + fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev); } /** @@ -1038,8 +1034,8 @@ static void dev_action_start(fsm_instance *fi, int event, void *arg) static void dev_action_stop(fsm_instance *fi, int event, void *arg) { - struct net_device *dev = arg; - struct netiucv_priv *privptr = netdev_priv(dev); + struct net_device *dev = (struct net_device *)arg; + struct netiucv_priv *privptr = dev->priv; struct iucv_event ev; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); @@ -1061,8 +1057,8 @@ dev_action_stop(fsm_instance *fi, int event, void *arg) static void dev_action_connup(fsm_instance *fi, int event, void *arg) { - struct net_device *dev = arg; - struct netiucv_priv *privptr = netdev_priv(dev); + struct net_device *dev = (struct net_device *)arg; + struct netiucv_priv *privptr = dev->priv; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); @@ -1135,13 +1131,11 @@ static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node); * * @return 0 on success, -ERRNO on failure. (Never fails.) */ -static int netiucv_transmit_skb(struct iucv_connection *conn, - struct sk_buff *skb) -{ - struct iucv_message msg; +static int +netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) { unsigned long saveflags; - struct ll_header header; - int rc; + ll_header header; + int rc = 0; if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) { int l = skb->len + NETIUCV_HDRLEN; @@ -1151,12 +1145,11 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, (conn->max_buffsize - NETIUCV_HDRLEN)) { rc = -EBUSY; IUCV_DBF_TEXT(data, 2, - "EBUSY from netiucv_transmit_skb\n"); + "EBUSY from netiucv_transmit_skb\n"); } else { atomic_inc(&skb->users); skb_queue_tail(&conn->collect_queue, skb); conn->collect_len += l; - rc = 0; } spin_unlock_irqrestore(&conn->collect_lock, saveflags); } else { @@ -1195,10 +1188,9 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, fsm_newstate(conn->fsm, CONN_STATE_TX); conn->prof.send_stamp = xtime; - msg.tag = 1; - msg.class = 0; - rc = iucv_message_send(conn->path, &msg, 0, 0, - nskb->data, nskb->len); + rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */, + 0, nskb->data, nskb->len); + /* Shut up, gcc! nskb is always below 2G. */ conn->prof.doios_single++; conn->prof.txlen += skb->len; conn->prof.tx_pending++; @@ -1208,7 +1200,7 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, struct netiucv_priv *privptr; fsm_newstate(conn->fsm, CONN_STATE_IDLE); conn->prof.tx_pending--; - privptr = netdev_priv(conn->netdev); + privptr = (struct netiucv_priv *)conn->netdev->priv; if (privptr) privptr->stats.tx_errors++; if (copied) @@ -1234,9 +1226,9 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, return rc; } -/* +/** * Interface API for upper network layers - */ + *****************************************************************************/ /** * Open an interface. @@ -1246,11 +1238,9 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, * * @return 0 on success, -ERRNO on failure. (Never fails.) */ -static int netiucv_open(struct net_device *dev) -{ - struct netiucv_priv *priv = netdev_priv(dev); - - fsm_event(priv->fsm, DEV_EVENT_START, dev); +static int +netiucv_open(struct net_device *dev) { + fsm_event(((struct netiucv_priv *)dev->priv)->fsm, DEV_EVENT_START,dev); return 0; } @@ -1262,11 +1252,9 @@ static int netiucv_open(struct net_device *dev) * * @return 0 on success, -ERRNO on failure. (Never fails.) */ -static int netiucv_close(struct net_device *dev) -{ - struct netiucv_priv *priv = netdev_priv(dev); - - fsm_event(priv->fsm, DEV_EVENT_STOP, dev); +static int +netiucv_close(struct net_device *dev) { + fsm_event(((struct netiucv_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev); return 0; } @@ -1283,8 +1271,8 @@ static int netiucv_close(struct net_device *dev) */ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) { - struct netiucv_priv *privptr = netdev_priv(dev); - int rc; + int rc = 0; + struct netiucv_priv *privptr = dev->priv; IUCV_DBF_TEXT(trace, 4, __FUNCTION__); /** @@ -1324,41 +1312,40 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) return -EBUSY; } dev->trans_start = jiffies; - rc = netiucv_transmit_skb(privptr->conn, skb) != 0; + if (netiucv_transmit_skb(privptr->conn, skb)) + rc = 1; netiucv_clear_busy(dev); return rc; } /** - * netiucv_stats - * @dev: Pointer to interface struct. - * * Returns interface statistics of a device. * - * Returns pointer to stats struct of this interface. + * @param dev Pointer to interface struct. + * + * @return Pointer to stats struct of this interface. */ -static struct net_device_stats *netiucv_stats (struct net_device * dev) +static struct net_device_stats * +netiucv_stats (struct net_device * dev) { - struct netiucv_priv *priv = netdev_priv(dev); - IUCV_DBF_TEXT(trace, 5, __FUNCTION__); - return &priv->stats; + return &((struct netiucv_priv *)dev->priv)->stats; } /** - * netiucv_change_mtu - * @dev: Pointer to interface struct. - * @new_mtu: The new MTU to use for this interface. - * * Sets MTU of an interface. * - * Returns 0 on success, -EINVAL if MTU is out of valid range. + * @param dev Pointer to interface struct. + * @param new_mtu The new MTU to use for this interface. + * + * @return 0 on success, -EINVAL if MTU is out of valid range. * (valid range is 576 .. NETIUCV_MTU_MAX). */ -static int netiucv_change_mtu(struct net_device * dev, int new_mtu) +static int +netiucv_change_mtu (struct net_device * dev, int new_mtu) { IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - if (new_mtu < 576 || new_mtu > NETIUCV_MTU_MAX) { + if ((new_mtu < 576) || (new_mtu > NETIUCV_MTU_MAX)) { IUCV_DBF_TEXT(setup, 2, "given MTU out of valid range\n"); return -EINVAL; } @@ -1366,12 +1353,12 @@ static int netiucv_change_mtu(struct net_device * dev, int new_mtu) return 0; } -/* +/** * attributes in sysfs - */ + *****************************************************************************/ -static ssize_t user_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +user_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1379,8 +1366,8 @@ static ssize_t user_show(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid)); } -static ssize_t user_write(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +user_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; struct net_device *ndev = priv->conn->netdev; @@ -1388,70 +1375,80 @@ static ssize_t user_write(struct device *dev, struct device_attribute *attr, char *tmp; char username[9]; int i; - struct iucv_connection *cp; + struct iucv_connection **clist = &iucv_conns.iucv_connections; + unsigned long flags; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - if (count > 9) { - PRINT_WARN("netiucv: username too long (%d)!\n", (int) count); + if (count>9) { + PRINT_WARN("netiucv: username too long (%d)!\n", (int)count); IUCV_DBF_TEXT_(setup, 2, - "%d is length of username\n", (int) count); + "%d is length of username\n", (int)count); return -EINVAL; } tmp = strsep((char **) &buf, "\n"); - for (i = 0, p = tmp; i < 8 && *p; i++, p++) { - if (isalnum(*p) || (*p == '$')) { + for (i=0, p=tmp; i<8 && *p; i++, p++) { + if (isalnum(*p) || (*p == '$')) username[i]= toupper(*p); - continue; - } - if (*p == '\n') { + else if (*p == '\n') { /* trailing lf, grr */ break; + } else { + PRINT_WARN("netiucv: Invalid char %c in username!\n", + *p); + IUCV_DBF_TEXT_(setup, 2, + "username: invalid character %c\n", + *p); + return -EINVAL; } - PRINT_WARN("netiucv: Invalid char %c in username!\n", *p); - IUCV_DBF_TEXT_(setup, 2, - "username: invalid character %c\n", *p); - return -EINVAL; } - while (i < 8) + while (i<8) username[i++] = ' '; username[8] = '\0'; - if (memcmp(username, priv->conn->userid, 9) && - (ndev->flags & (IFF_UP | IFF_RUNNING))) { - /* username changed while the interface is active. */ - PRINT_WARN("netiucv: device %s active, connected to %s\n", - dev->bus_id, priv->conn->userid); - PRINT_WARN("netiucv: user cannot be updated\n"); - IUCV_DBF_TEXT(setup, 2, "user_write: device active\n"); - return -EBUSY; - } - read_lock_bh(&iucv_connection_rwlock); - list_for_each_entry(cp, &iucv_connection_list, list) { - if (!strncmp(username, cp->userid, 9) && cp->netdev != ndev) { - read_unlock_bh(&iucv_connection_rwlock); - PRINT_WARN("netiucv: Connection to %s already " - "exists\n", username); - return -EEXIST; + if (memcmp(username, priv->conn->userid, 9)) { + /* username changed */ + if (ndev->flags & (IFF_UP | IFF_RUNNING)) { + PRINT_WARN( + "netiucv: device %s active, connected to %s\n", + dev->bus_id, priv->conn->userid); + PRINT_WARN("netiucv: user cannot be updated\n"); + IUCV_DBF_TEXT(setup, 2, "user_write: device active\n"); + return -EBUSY; } } - read_unlock_bh(&iucv_connection_rwlock); + read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + while (*clist) { + if (!strncmp(username, (*clist)->userid, 9) || + ((*clist)->netdev != ndev)) + break; + clist = &((*clist)->next); + } + read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); + if (*clist) { + PRINT_WARN("netiucv: Connection to %s already exists\n", + username); + return -EEXIST; + } memcpy(priv->conn->userid, username, 9); + return count; + } static DEVICE_ATTR(user, 0644, user_show, user_write); -static ssize_t buffer_show (struct device *dev, struct device_attribute *attr, - char *buf) -{ struct netiucv_priv *priv = dev->driver_data; +static ssize_t +buffer_show (struct device *dev, struct device_attribute *attr, char *buf) +{ + struct netiucv_priv *priv = dev->driver_data; IUCV_DBF_TEXT(trace, 5, __FUNCTION__); return sprintf(buf, "%d\n", priv->conn->max_buffsize); } -static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +buffer_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; struct net_device *ndev = priv->conn->netdev; @@ -1505,8 +1502,8 @@ static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write); -static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +dev_fsm_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1516,8 +1513,8 @@ static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL); -static ssize_t conn_fsm_show (struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t +conn_fsm_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1527,8 +1524,8 @@ static ssize_t conn_fsm_show (struct device *dev, static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL); -static ssize_t maxmulti_show (struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t +maxmulti_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1536,9 +1533,8 @@ static ssize_t maxmulti_show (struct device *dev, return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti); } -static ssize_t maxmulti_write (struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +maxmulti_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1549,8 +1545,8 @@ static ssize_t maxmulti_write (struct device *dev, static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write); -static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +maxcq_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1558,8 +1554,8 @@ static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue); } -static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +maxcq_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1570,8 +1566,8 @@ static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write); -static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +sdoio_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1579,8 +1575,8 @@ static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.doios_single); } -static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +sdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1591,8 +1587,8 @@ static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write); -static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +mdoio_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1600,8 +1596,8 @@ static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi); } -static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +mdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1612,8 +1608,8 @@ static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write); -static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +txlen_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1621,8 +1617,8 @@ static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.txlen); } -static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +txlen_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1633,8 +1629,8 @@ static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write); -static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +txtime_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1642,8 +1638,8 @@ static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.tx_time); } -static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +txtime_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1654,8 +1650,8 @@ static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write); -static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +txpend_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1663,8 +1659,8 @@ static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending); } -static ssize_t txpend_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +txpend_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1675,8 +1671,8 @@ static ssize_t txpend_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write); -static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +txmpnd_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1684,8 +1680,8 @@ static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending); } -static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +txmpnd_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1725,7 +1721,8 @@ static struct attribute_group netiucv_stat_attr_group = { .attrs = netiucv_stat_attrs, }; -static inline int netiucv_add_files(struct device *dev) +static inline int +netiucv_add_files(struct device *dev) { int ret; @@ -1739,16 +1736,18 @@ static inline int netiucv_add_files(struct device *dev) return ret; } -static inline void netiucv_remove_files(struct device *dev) +static inline void +netiucv_remove_files(struct device *dev) { IUCV_DBF_TEXT(trace, 3, __FUNCTION__); sysfs_remove_group(&dev->kobj, &netiucv_stat_attr_group); sysfs_remove_group(&dev->kobj, &netiucv_attr_group); } -static int netiucv_register_device(struct net_device *ndev) +static int +netiucv_register_device(struct net_device *ndev) { - struct netiucv_priv *priv = netdev_priv(ndev); + struct netiucv_priv *priv = ndev->priv; struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); int ret; @@ -1787,7 +1786,8 @@ static int netiucv_register_device(struct net_device *ndev) return ret; } -static void netiucv_unregister_device(struct device *dev) +static void +netiucv_unregister_device(struct device *dev) { IUCV_DBF_TEXT(trace, 3, __FUNCTION__); netiucv_remove_files(dev); @@ -1798,89 +1798,107 @@ static void netiucv_unregister_device(struct device *dev) * Allocate and initialize a new connection structure. * Add it to the list of netiucv connections; */ -static struct iucv_connection *netiucv_new_connection(struct net_device *dev, - char *username) -{ - struct iucv_connection *conn; +static struct iucv_connection * +netiucv_new_connection(struct net_device *dev, char *username) +{ + unsigned long flags; + struct iucv_connection **clist = &iucv_conns.iucv_connections; + struct iucv_connection *conn = + kzalloc(sizeof(struct iucv_connection), GFP_KERNEL); + + if (conn) { + skb_queue_head_init(&conn->collect_queue); + skb_queue_head_init(&conn->commit_queue); + spin_lock_init(&conn->collect_lock); + conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; + conn->netdev = dev; + + conn->rx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, + GFP_KERNEL | GFP_DMA); + if (!conn->rx_buff) { + kfree(conn); + return NULL; + } + conn->tx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, + GFP_KERNEL | GFP_DMA); + if (!conn->tx_buff) { + kfree_skb(conn->rx_buff); + kfree(conn); + return NULL; + } + conn->fsm = init_fsm("netiucvconn", conn_state_names, + conn_event_names, NR_CONN_STATES, + NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN, + GFP_KERNEL); + if (!conn->fsm) { + kfree_skb(conn->tx_buff); + kfree_skb(conn->rx_buff); + kfree(conn); + return NULL; + } + fsm_settimer(conn->fsm, &conn->timer); + fsm_newstate(conn->fsm, CONN_STATE_INVALID); - conn = kzalloc(sizeof(*conn), GFP_KERNEL); - if (!conn) - goto out; - skb_queue_head_init(&conn->collect_queue); - skb_queue_head_init(&conn->commit_queue); - spin_lock_init(&conn->collect_lock); - conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; - conn->netdev = dev; - - conn->rx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA); - if (!conn->rx_buff) - goto out_conn; - conn->tx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA); - if (!conn->tx_buff) - goto out_rx; - conn->fsm = init_fsm("netiucvconn", conn_state_names, - conn_event_names, NR_CONN_STATES, - NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN, - GFP_KERNEL); - if (!conn->fsm) - goto out_tx; - - fsm_settimer(conn->fsm, &conn->timer); - fsm_newstate(conn->fsm, CONN_STATE_INVALID); - - if (username) { - memcpy(conn->userid, username, 9); - fsm_newstate(conn->fsm, CONN_STATE_STOPPED); - } + if (username) { + memcpy(conn->userid, username, 9); + fsm_newstate(conn->fsm, CONN_STATE_STOPPED); + } - write_lock_bh(&iucv_connection_rwlock); - list_add_tail(&conn->list, &iucv_connection_list); - write_unlock_bh(&iucv_connection_rwlock); + write_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + conn->next = *clist; + *clist = conn; + write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); + } return conn; - -out_tx: - kfree_skb(conn->tx_buff); -out_rx: - kfree_skb(conn->rx_buff); -out_conn: - kfree(conn); -out: - return NULL; } /** * Release a connection structure and remove it from the * list of netiucv connections. */ -static void netiucv_remove_connection(struct iucv_connection *conn) +static void +netiucv_remove_connection(struct iucv_connection *conn) { + struct iucv_connection **clist = &iucv_conns.iucv_connections; + unsigned long flags; + IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - write_lock_bh(&iucv_connection_rwlock); - list_del_init(&conn->list); - write_unlock_bh(&iucv_connection_rwlock); - if (conn->path) { - iucv_path_sever(conn->path, iucvMagic); - kfree(conn->path); - conn->path = NULL; + if (conn == NULL) + return; + write_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + while (*clist) { + if (*clist == conn) { + *clist = conn->next; + write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); + if (conn->handle) { + iucv_unregister_program(conn->handle); + conn->handle = NULL; + } + fsm_deltimer(&conn->timer); + kfree_fsm(conn->fsm); + kfree_skb(conn->rx_buff); + kfree_skb(conn->tx_buff); + return; + } + clist = &((*clist)->next); } - fsm_deltimer(&conn->timer); - kfree_fsm(conn->fsm); - kfree_skb(conn->rx_buff); - kfree_skb(conn->tx_buff); + write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); } /** * Release everything of a net device. */ -static void netiucv_free_netdevice(struct net_device *dev) +static void +netiucv_free_netdevice(struct net_device *dev) { - struct netiucv_priv *privptr = netdev_priv(dev); + struct netiucv_priv *privptr; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); if (!dev) return; + privptr = (struct netiucv_priv *)dev->priv; if (privptr) { if (privptr->conn) netiucv_remove_connection(privptr->conn); @@ -1895,8 +1913,11 @@ static void netiucv_free_netdevice(struct net_device *dev) /** * Initialize a net device. (Called from kernel in alloc_netdev()) */ -static void netiucv_setup_netdevice(struct net_device *dev) +static void +netiucv_setup_netdevice(struct net_device *dev) { + memset(dev->priv, 0, sizeof(struct netiucv_priv)); + dev->mtu = NETIUCV_MTU_DEFAULT; dev->hard_start_xmit = netiucv_tx; dev->open = netiucv_open; @@ -1915,7 +1936,8 @@ static void netiucv_setup_netdevice(struct net_device *dev) /** * Allocate and initialize everything of a net device. */ -static struct net_device *netiucv_init_netdevice(char *username) +static struct net_device * +netiucv_init_netdevice(char *username) { struct netiucv_priv *privptr; struct net_device *dev; @@ -1924,40 +1946,40 @@ static struct net_device *netiucv_init_netdevice(char *username) netiucv_setup_netdevice); if (!dev) return NULL; - if (dev_alloc_name(dev, dev->name) < 0) - goto out_netdev; + if (dev_alloc_name(dev, dev->name) < 0) { + free_netdev(dev); + return NULL; + } - privptr = netdev_priv(dev); + privptr = (struct netiucv_priv *)dev->priv; privptr->fsm = init_fsm("netiucvdev", dev_state_names, dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, dev_fsm, DEV_FSM_LEN, GFP_KERNEL); - if (!privptr->fsm) - goto out_netdev; - + if (!privptr->fsm) { + free_netdev(dev); + return NULL; + } privptr->conn = netiucv_new_connection(dev, username); if (!privptr->conn) { + kfree_fsm(privptr->fsm); + free_netdev(dev); IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n"); - goto out_fsm; + return NULL; } fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); - return dev; -out_fsm: - kfree_fsm(privptr->fsm); -out_netdev: - free_netdev(dev); - return NULL; + return dev; } -static ssize_t conn_write(struct device_driver *drv, - const char *buf, size_t count) +static ssize_t +conn_write(struct device_driver *drv, const char *buf, size_t count) { - const char *p; + char *p; char username[9]; - int i, rc; + int i, ret; struct net_device *dev; - struct netiucv_priv *priv; - struct iucv_connection *cp; + struct iucv_connection **clist = &iucv_conns.iucv_connections; + unsigned long flags; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); if (count>9) { @@ -1966,82 +1988,83 @@ static ssize_t conn_write(struct device_driver *drv, return -EINVAL; } - for (i = 0, p = buf; i < 8 && *p; i++, p++) { - if (isalnum(*p) || *p == '$') { - username[i] = toupper(*p); - continue; - } - if (*p == '\n') + for (i=0, p=(char *)buf; i<8 && *p; i++, p++) { + if (isalnum(*p) || (*p == '$')) + username[i]= toupper(*p); + else if (*p == '\n') { /* trailing lf, grr */ break; - PRINT_WARN("netiucv: Invalid character in username!\n"); - IUCV_DBF_TEXT_(setup, 2, - "conn_write: invalid character %c\n", *p); - return -EINVAL; + } else { + PRINT_WARN("netiucv: Invalid character in username!\n"); + IUCV_DBF_TEXT_(setup, 2, + "conn_write: invalid character %c\n", *p); + return -EINVAL; + } } - while (i < 8) + while (i<8) username[i++] = ' '; username[8] = '\0'; - read_lock_bh(&iucv_connection_rwlock); - list_for_each_entry(cp, &iucv_connection_list, list) { - if (!strncmp(username, cp->userid, 9)) { - read_unlock_bh(&iucv_connection_rwlock); - PRINT_WARN("netiucv: Connection to %s already " - "exists\n", username); - return -EEXIST; - } + read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + while (*clist) { + if (!strncmp(username, (*clist)->userid, 9)) + break; + clist = &((*clist)->next); + } + read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); + if (*clist) { + PRINT_WARN("netiucv: Connection to %s already exists\n", + username); + return -EEXIST; } - read_unlock_bh(&iucv_connection_rwlock); - dev = netiucv_init_netdevice(username); if (!dev) { - PRINT_WARN("netiucv: Could not allocate network device " - "structure for user '%s'\n", - netiucv_printname(username)); + PRINT_WARN( + "netiucv: Could not allocate network device structure " + "for user '%s'\n", netiucv_printname(username)); IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n"); return -ENODEV; } - rc = netiucv_register_device(dev); - if (rc) { + if ((ret = netiucv_register_device(dev))) { IUCV_DBF_TEXT_(setup, 2, - "ret %d from netiucv_register_device\n", rc); + "ret %d from netiucv_register_device\n", ret); goto out_free_ndev; } /* sysfs magic */ - priv = netdev_priv(dev); - SET_NETDEV_DEV(dev, priv->dev); + SET_NETDEV_DEV(dev, + (struct device*)((struct netiucv_priv*)dev->priv)->dev); - rc = register_netdev(dev); - if (rc) - goto out_unreg; + if ((ret = register_netdev(dev))) { + netiucv_unregister_device((struct device*) + ((struct netiucv_priv*)dev->priv)->dev); + goto out_free_ndev; + } PRINT_INFO("%s: '%s'\n", dev->name, netiucv_printname(username)); return count; -out_unreg: - netiucv_unregister_device(priv->dev); out_free_ndev: PRINT_WARN("netiucv: Could not register '%s'\n", dev->name); IUCV_DBF_TEXT(setup, 2, "conn_write: could not register\n"); netiucv_free_netdevice(dev); - return rc; + return ret; } static DRIVER_ATTR(connection, 0200, NULL, conn_write); -static ssize_t remove_write (struct device_driver *drv, - const char *buf, size_t count) +static ssize_t +remove_write (struct device_driver *drv, const char *buf, size_t count) { - struct iucv_connection *cp; + struct iucv_connection **clist = &iucv_conns.iucv_connections; + unsigned long flags; struct net_device *ndev; struct netiucv_priv *priv; struct device *dev; char name[IFNAMSIZ]; - const char *p; + char *p; int i; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); @@ -2049,27 +2072,33 @@ static ssize_t remove_write (struct device_driver *drv, if (count >= IFNAMSIZ) count = IFNAMSIZ - 1;; - for (i = 0, p = buf; i < count && *p; i++, p++) { - if (*p == '\n' || *p == ' ') + for (i=0, p=(char *)buf; inetdev; - priv = netdev_priv(ndev); + read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + while (*clist) { + ndev = (*clist)->netdev; + priv = (struct netiucv_priv*)ndev->priv; dev = priv->dev; - if (strncmp(name, ndev->name, count)) - continue; - read_unlock_bh(&iucv_connection_rwlock); + + if (strncmp(name, ndev->name, count)) { + clist = &((*clist)->next); + continue; + } + read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); if (ndev->flags & (IFF_UP | IFF_RUNNING)) { - PRINT_WARN("netiucv: net device %s active with peer " - "%s\n", ndev->name, priv->conn->userid); + PRINT_WARN( + "netiucv: net device %s active with peer %s\n", + ndev->name, priv->conn->userid); PRINT_WARN("netiucv: %s cannot be removed\n", - ndev->name); + ndev->name); IUCV_DBF_TEXT(data, 2, "remove_write: still active\n"); return -EBUSY; } @@ -2077,7 +2106,7 @@ static ssize_t remove_write (struct device_driver *drv, netiucv_unregister_device(dev); return count; } - read_unlock_bh(&iucv_connection_rwlock); + read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); PRINT_WARN("netiucv: net device %s unknown\n", name); IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n"); return -EINVAL; @@ -2085,86 +2114,67 @@ static ssize_t remove_write (struct device_driver *drv, static DRIVER_ATTR(remove, 0200, NULL, remove_write); -static struct attribute * netiucv_drv_attrs[] = { - &driver_attr_connection.attr, - &driver_attr_remove.attr, - NULL, -}; - -static struct attribute_group netiucv_drv_attr_group = { - .attrs = netiucv_drv_attrs, -}; - -static void netiucv_banner(void) +static void +netiucv_banner(void) { PRINT_INFO("NETIUCV driver initialized\n"); } -static void __exit netiucv_exit(void) +static void __exit +netiucv_exit(void) { - struct iucv_connection *cp; - struct net_device *ndev; - struct netiucv_priv *priv; - struct device *dev; - IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - while (!list_empty(&iucv_connection_list)) { - cp = list_entry(iucv_connection_list.next, - struct iucv_connection, list); - list_del(&cp->list); - ndev = cp->netdev; - priv = netdev_priv(ndev); - dev = priv->dev; + while (iucv_conns.iucv_connections) { + struct net_device *ndev = iucv_conns.iucv_connections->netdev; + struct netiucv_priv *priv = (struct netiucv_priv*)ndev->priv; + struct device *dev = priv->dev; unregister_netdev(ndev); netiucv_unregister_device(dev); } - sysfs_remove_group(&netiucv_driver.kobj, &netiucv_drv_attr_group); + driver_remove_file(&netiucv_driver, &driver_attr_connection); + driver_remove_file(&netiucv_driver, &driver_attr_remove); driver_unregister(&netiucv_driver); - iucv_unregister(&netiucv_handler, 1); iucv_unregister_dbf_views(); PRINT_INFO("NETIUCV driver unloaded\n"); return; } -static int __init netiucv_init(void) +static int __init +netiucv_init(void) { - int rc; + int ret; - rc = iucv_register_dbf_views(); - if (rc) - goto out; - rc = iucv_register(&netiucv_handler, 1); - if (rc) - goto out_dbf; + ret = iucv_register_dbf_views(); + if (ret) { + PRINT_WARN("netiucv_init failed, " + "iucv_register_dbf_views rc = %d\n", ret); + return ret; + } IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - rc = driver_register(&netiucv_driver); - if (rc) { + ret = driver_register(&netiucv_driver); + if (ret) { PRINT_ERR("NETIUCV: failed to register driver.\n"); - IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc); - goto out_iucv; + IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", ret); + iucv_unregister_dbf_views(); + return ret; } - rc = sysfs_create_group(&netiucv_driver.kobj, &netiucv_drv_attr_group); - if (rc) { - PRINT_ERR("NETIUCV: failed to add driver attributes.\n"); - IUCV_DBF_TEXT_(setup, 2, - "ret %d - netiucv_drv_attr_group\n", rc); - goto out_driver; + /* Add entry for specifying connections. */ + ret = driver_create_file(&netiucv_driver, &driver_attr_connection); + if (!ret) { + ret = driver_create_file(&netiucv_driver, &driver_attr_remove); + netiucv_banner(); + rwlock_init(&iucv_conns.iucv_rwlock); + } else { + PRINT_ERR("NETIUCV: failed to add driver attribute.\n"); + IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_create_file\n", ret); + driver_unregister(&netiucv_driver); + iucv_unregister_dbf_views(); } - netiucv_banner(); - return rc; - -out_driver: - driver_unregister(&netiucv_driver); -out_iucv: - iucv_unregister(&netiucv_handler, 1); -out_dbf: - iucv_unregister_dbf_views(); -out: - return rc; + return ret; } module_init(netiucv_init); diff --git a/trunk/drivers/s390/net/smsgiucv.c b/trunk/drivers/s390/net/smsgiucv.c index 3ccca5871fdf..b8179c27ceb6 100644 --- a/trunk/drivers/s390/net/smsgiucv.c +++ b/trunk/drivers/s390/net/smsgiucv.c @@ -1,7 +1,7 @@ /* * IUCV special message driver * - * Copyright 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) * * This program is free software; you can redistribute it and/or modify @@ -23,10 +23,10 @@ #include #include #include -#include #include #include -#include "smsgiucv.h" + +#include "iucv.h" struct smsg_callback { struct list_head list; @@ -39,46 +39,38 @@ MODULE_AUTHOR ("(C) 2003 IBM Corporation by Martin Schwidefsky (schwidefsky@de.ibm.com)"); MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver"); -static struct iucv_path *smsg_path; - +static iucv_handle_t smsg_handle; +static unsigned short smsg_pathid; static DEFINE_SPINLOCK(smsg_list_lock); static struct list_head smsg_list = LIST_HEAD_INIT(smsg_list); -static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); -static void smsg_message_pending(struct iucv_path *, struct iucv_message *); - -static struct iucv_handler smsg_handler = { - .path_pending = smsg_path_pending, - .message_pending = smsg_message_pending, -}; - -static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8], - u8 ipuser[16]) +static void +smsg_connection_complete(iucv_ConnectionComplete *eib, void *pgm_data) { - if (strncmp(ipvmid, "*MSG ", sizeof(ipvmid)) != 0) - return -EINVAL; - /* Path pending from *MSG. */ - return iucv_path_accept(path, &smsg_handler, "SMSGIUCV ", NULL); } -static void smsg_message_pending(struct iucv_path *path, - struct iucv_message *msg) + +static void +smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) { struct smsg_callback *cb; - unsigned char *buffer; + unsigned char *msg; unsigned char sender[9]; + unsigned short len; int rc, i; - buffer = kmalloc(msg->length + 1, GFP_ATOMIC | GFP_DMA); - if (!buffer) { - iucv_message_reject(path, msg); + len = eib->ln1msg2.ipbfln1f; + msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); + if (!msg) { + iucv_reject(eib->ippathid, eib->ipmsgid, eib->iptrgcls); return; } - rc = iucv_message_receive(path, msg, 0, buffer, msg->length, NULL); + rc = iucv_receive(eib->ippathid, eib->ipmsgid, eib->iptrgcls, + msg, len, NULL, NULL, NULL); if (rc == 0) { - buffer[msg->length] = 0; - EBCASC(buffer, msg->length); - memcpy(sender, buffer, 8); + msg[len] = 0; + EBCASC(msg, len); + memcpy(sender, msg, 8); sender[8] = 0; /* Remove trailing whitespace from the sender name. */ for (i = 7; i >= 0; i--) { @@ -88,17 +80,27 @@ static void smsg_message_pending(struct iucv_path *path, } spin_lock(&smsg_list_lock); list_for_each_entry(cb, &smsg_list, list) - if (strncmp(buffer + 8, cb->prefix, cb->len) == 0) { - cb->callback(sender, buffer + 8); + if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { + cb->callback(sender, msg + 8); break; } spin_unlock(&smsg_list_lock); } - kfree(buffer); + kfree(msg); } -int smsg_register_callback(char *prefix, - void (*callback)(char *from, char *str)) +static iucv_interrupt_ops_t smsg_ops = { + .ConnectionComplete = smsg_connection_complete, + .MessagePending = smsg_message_pending, +}; + +static struct device_driver smsg_driver = { + .name = "SMSGIUCV", + .bus = &iucv_bus, +}; + +int +smsg_register_callback(char *prefix, void (*callback)(char *from, char *str)) { struct smsg_callback *cb; @@ -108,18 +110,18 @@ int smsg_register_callback(char *prefix, cb->prefix = prefix; cb->len = strlen(prefix); cb->callback = callback; - spin_lock_bh(&smsg_list_lock); + spin_lock(&smsg_list_lock); list_add_tail(&cb->list, &smsg_list); - spin_unlock_bh(&smsg_list_lock); + spin_unlock(&smsg_list_lock); return 0; } -void smsg_unregister_callback(char *prefix, - void (*callback)(char *from, char *str)) +void +smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str)) { struct smsg_callback *cb, *tmp; - spin_lock_bh(&smsg_list_lock); + spin_lock(&smsg_list_lock); cb = NULL; list_for_each_entry(tmp, &smsg_list, list) if (tmp->callback == callback && @@ -128,58 +130,55 @@ void smsg_unregister_callback(char *prefix, list_del(&cb->list); break; } - spin_unlock_bh(&smsg_list_lock); + spin_unlock(&smsg_list_lock); kfree(cb); } -static struct device_driver smsg_driver = { - .name = "SMSGIUCV", - .bus = &iucv_bus, -}; - -static void __exit smsg_exit(void) +static void __exit +smsg_exit(void) { - cpcmd("SET SMSG IUCV", NULL, 0, NULL); - iucv_unregister(&smsg_handler, 1); - driver_unregister(&smsg_driver); + if (smsg_handle > 0) { + cpcmd("SET SMSG OFF", NULL, 0, NULL); + iucv_sever(smsg_pathid, NULL); + iucv_unregister_program(smsg_handle); + driver_unregister(&smsg_driver); + } + return; } -static int __init smsg_init(void) +static int __init +smsg_init(void) { + static unsigned char pgmmask[24] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; int rc; rc = driver_register(&smsg_driver); - if (rc != 0) - goto out; - rc = iucv_register(&smsg_handler, 1); - if (rc) { - printk(KERN_ERR "SMSGIUCV: failed to register to iucv"); - rc = -EIO; /* better errno ? */ - goto out_driver; + if (rc != 0) { + printk(KERN_ERR "SMSGIUCV: failed to register driver.\n"); + return rc; } - smsg_path = iucv_path_alloc(255, 0, GFP_KERNEL); - if (!smsg_path) { - rc = -ENOMEM; - goto out_register; + smsg_handle = iucv_register_program("SMSGIUCV ", "*MSG ", + pgmmask, &smsg_ops, NULL); + if (!smsg_handle) { + printk(KERN_ERR "SMSGIUCV: failed to register to iucv"); + driver_unregister(&smsg_driver); + return -EIO; /* better errno ? */ } - rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", - NULL, NULL, NULL); + rc = iucv_connect (&smsg_pathid, 255, NULL, "*MSG ", NULL, 0, + NULL, NULL, smsg_handle, NULL); if (rc) { printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG"); - rc = -EIO; /* better errno ? */ - goto out_free; + iucv_unregister_program(smsg_handle); + driver_unregister(&smsg_driver); + smsg_handle = NULL; + return -EIO; } cpcmd("SET SMSG IUCV", NULL, 0, NULL); return 0; - -out_free: - iucv_path_free(smsg_path); -out_register: - iucv_unregister(&smsg_handler, 1); -out_driver: - driver_unregister(&smsg_driver); -out: - return rc; } module_init(smsg_init); diff --git a/trunk/drivers/scsi/NCR53C9x.c b/trunk/drivers/scsi/NCR53C9x.c index 8b5334c56f0a..3c912ee29da0 100644 --- a/trunk/drivers/scsi/NCR53C9x.c +++ b/trunk/drivers/scsi/NCR53C9x.c @@ -528,16 +528,12 @@ void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) /* Allocate structure and insert basic data such as SCSI chip frequency * data and a pointer to the device */ -struct NCR_ESP* esp_allocate(struct scsi_host_template *tpnt, void *esp_dev, - int hotplug) +struct NCR_ESP* esp_allocate(struct scsi_host_template *tpnt, void *esp_dev) { struct NCR_ESP *esp, *elink; struct Scsi_Host *esp_host; - if (hotplug) - esp_host = scsi_host_alloc(tpnt, sizeof(struct NCR_ESP)); - else - esp_host = scsi_register(tpnt, sizeof(struct NCR_ESP)); + esp_host = scsi_register(tpnt, sizeof(struct NCR_ESP)); if(!esp_host) panic("Cannot register ESP SCSI host"); esp = (struct NCR_ESP *) esp_host->hostdata; diff --git a/trunk/drivers/scsi/NCR53C9x.h b/trunk/drivers/scsi/NCR53C9x.h index d85cb73a9f69..521e3f842cfd 100644 --- a/trunk/drivers/scsi/NCR53C9x.h +++ b/trunk/drivers/scsi/NCR53C9x.h @@ -652,7 +652,7 @@ extern int nesps, esps_in_use, esps_running; /* External functions */ extern void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs); -extern struct NCR_ESP *esp_allocate(struct scsi_host_template *, void *, int); +extern struct NCR_ESP *esp_allocate(struct scsi_host_template *, void *); extern void esp_deallocate(struct NCR_ESP *); extern void esp_release(void); extern void esp_initialize(struct NCR_ESP *); diff --git a/trunk/drivers/scsi/blz1230.c b/trunk/drivers/scsi/blz1230.c index 23f7c24ab809..329a8f297b31 100644 --- a/trunk/drivers/scsi/blz1230.c +++ b/trunk/drivers/scsi/blz1230.c @@ -121,8 +121,7 @@ int __init blz1230_esp_detect(struct scsi_host_template *tpnt) */ address = ZTWO_VADDR(board); eregs = (struct ESP_regs *)(address + REAL_BLZ1230_ESP_ADDR); - esp = esp_allocate(tpnt, (void *)board + REAL_BLZ1230_ESP_ADDR, - 0); + esp = esp_allocate(tpnt, (void *)board+REAL_BLZ1230_ESP_ADDR); esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); udelay(5); diff --git a/trunk/drivers/scsi/blz2060.c b/trunk/drivers/scsi/blz2060.c index b6203ec00961..b6c137b97350 100644 --- a/trunk/drivers/scsi/blz2060.c +++ b/trunk/drivers/scsi/blz2060.c @@ -100,7 +100,7 @@ int __init blz2060_esp_detect(struct scsi_host_template *tpnt) unsigned long board = z->resource.start; if (request_mem_region(board+BLZ2060_ESP_ADDR, sizeof(struct ESP_regs), "NCR53C9x")) { - esp = esp_allocate(tpnt, (void *)board + BLZ2060_ESP_ADDR, 0); + esp = esp_allocate(tpnt, (void *)board+BLZ2060_ESP_ADDR); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; diff --git a/trunk/drivers/scsi/cyberstorm.c b/trunk/drivers/scsi/cyberstorm.c index c6b98a42e89d..7c7cfb54e897 100644 --- a/trunk/drivers/scsi/cyberstorm.c +++ b/trunk/drivers/scsi/cyberstorm.c @@ -126,7 +126,7 @@ int __init cyber_esp_detect(struct scsi_host_template *tpnt) sizeof(struct ESP_regs)); return 0; } - esp = esp_allocate(tpnt, (void *)board + CYBER_ESP_ADDR, 0); + esp = esp_allocate(tpnt, (void *)board+CYBER_ESP_ADDR); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; diff --git a/trunk/drivers/scsi/cyberstormII.c b/trunk/drivers/scsi/cyberstormII.c index e336e853e66f..d88cb9cf091e 100644 --- a/trunk/drivers/scsi/cyberstormII.c +++ b/trunk/drivers/scsi/cyberstormII.c @@ -98,7 +98,7 @@ int __init cyberII_esp_detect(struct scsi_host_template *tpnt) address = (unsigned long)ZTWO_VADDR(board); eregs = (struct ESP_regs *)(address + CYBERII_ESP_ADDR); - esp = esp_allocate(tpnt, (void *)board + CYBERII_ESP_ADDR, 0); + esp = esp_allocate(tpnt, (void *)board+CYBERII_ESP_ADDR); esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); udelay(5); diff --git a/trunk/drivers/scsi/dec_esp.c b/trunk/drivers/scsi/dec_esp.c index d42ad663ffee..c29ccbc44693 100644 --- a/trunk/drivers/scsi/dec_esp.c +++ b/trunk/drivers/scsi/dec_esp.c @@ -18,7 +18,7 @@ * 20001005 - Initialization fixes for 2.4.0-test9 * Florian Lohoff * - * Copyright (C) 2002, 2003, 2005, 2006 Maciej W. Rozycki + * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki */ #include @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -43,6 +42,7 @@ #include #include #include +#include #define DEC_SCSI_SREG 0 #define DEC_SCSI_DMAREG 0x40000 @@ -98,33 +98,51 @@ static irqreturn_t scsi_dma_merr_int(int, void *); static irqreturn_t scsi_dma_err_int(int, void *); static irqreturn_t scsi_dma_int(int, void *); -static struct scsi_host_template dec_esp_template = { - .module = THIS_MODULE, +static int dec_esp_detect(struct scsi_host_template * tpnt); + +static int dec_esp_release(struct Scsi_Host *shost) +{ + if (shost->irq) + free_irq(shost->irq, NULL); + if (shost->io_port && shost->n_io_port) + release_region(shost->io_port, shost->n_io_port); + scsi_unregister(shost); + return 0; +} + +static struct scsi_host_template driver_template = { + .proc_name = "dec_esp", + .proc_info = esp_proc_info, .name = "NCR53C94", + .detect = dec_esp_detect, + .slave_alloc = esp_slave_alloc, + .slave_destroy = esp_slave_destroy, + .release = dec_esp_release, .info = esp_info, .queuecommand = esp_queue, .eh_abort_handler = esp_abort, .eh_bus_reset_handler = esp_reset, - .slave_alloc = esp_slave_alloc, - .slave_destroy = esp_slave_destroy, - .proc_info = esp_proc_info, - .proc_name = "dec_esp", .can_queue = 7, + .this_id = 7, .sg_tablesize = SG_ALL, .cmd_per_lun = 1, .use_clustering = DISABLE_CLUSTERING, }; -static struct NCR_ESP *dec_esp_platform; + +#include "scsi_module.c" /***************************************************************** Detection */ -static int dec_esp_platform_probe(void) +static int dec_esp_detect(struct scsi_host_template * tpnt) { struct NCR_ESP *esp; - int err = 0; + struct ConfigDev *esp_dev; + int slot; + unsigned long mem_start; if (IOASIC) { - esp = esp_allocate(&dec_esp_template, NULL, 1); + esp_dev = 0; + esp = esp_allocate(tpnt, (void *) esp_dev); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; @@ -182,175 +200,112 @@ static int dec_esp_platform_probe(void) /* Check for differential SCSI-bus */ esp->diff = 0; - err = request_irq(esp->irq, esp_intr, IRQF_DISABLED, - "ncr53c94", esp->ehost); - if (err) - goto err_alloc; - err = request_irq(dec_interrupt[DEC_IRQ_ASC_MERR], - scsi_dma_merr_int, IRQF_DISABLED, - "ncr53c94 error", esp->ehost); - if (err) - goto err_irq; - err = request_irq(dec_interrupt[DEC_IRQ_ASC_ERR], - scsi_dma_err_int, IRQF_DISABLED, - "ncr53c94 overrun", esp->ehost); - if (err) - goto err_irq_merr; - err = request_irq(dec_interrupt[DEC_IRQ_ASC_DMA], scsi_dma_int, - IRQF_DISABLED, "ncr53c94 dma", esp->ehost); - if (err) - goto err_irq_err; - esp_initialize(esp); - err = scsi_add_host(esp->ehost, NULL); - if (err) { - printk(KERN_ERR "ESP: Unable to register adapter\n"); - goto err_irq_dma; - } - - scsi_scan_host(esp->ehost); + if (request_irq(esp->irq, esp_intr, IRQF_DISABLED, + "ncr53c94", esp->ehost)) + goto err_dealloc; + if (request_irq(dec_interrupt[DEC_IRQ_ASC_MERR], + scsi_dma_merr_int, IRQF_DISABLED, + "ncr53c94 error", esp->ehost)) + goto err_free_irq; + if (request_irq(dec_interrupt[DEC_IRQ_ASC_ERR], + scsi_dma_err_int, IRQF_DISABLED, + "ncr53c94 overrun", esp->ehost)) + goto err_free_irq_merr; + if (request_irq(dec_interrupt[DEC_IRQ_ASC_DMA], + scsi_dma_int, IRQF_DISABLED, + "ncr53c94 dma", esp->ehost)) + goto err_free_irq_err; - dec_esp_platform = esp; } - return 0; - -err_irq_dma: - free_irq(dec_interrupt[DEC_IRQ_ASC_DMA], esp->ehost); -err_irq_err: - free_irq(dec_interrupt[DEC_IRQ_ASC_ERR], esp->ehost); -err_irq_merr: - free_irq(dec_interrupt[DEC_IRQ_ASC_MERR], esp->ehost); -err_irq: - free_irq(esp->irq, esp->ehost); -err_alloc: - esp_deallocate(esp); - scsi_host_put(esp->ehost); - return err; -} - -static int __init dec_esp_probe(struct device *dev) -{ - struct NCR_ESP *esp; - resource_size_t start, len; - int err; - - esp = esp_allocate(&dec_esp_template, NULL, 1); - - dev_set_drvdata(dev, esp); - - start = to_tc_dev(dev)->resource.start; - len = to_tc_dev(dev)->resource.end - start + 1; - - if (!request_mem_region(start, len, dev->bus_id)) { - printk(KERN_ERR "%s: Unable to reserve MMIO resource\n", - dev->bus_id); - err = -EBUSY; - goto err_alloc; - } - - /* Store base addr into esp struct. */ - esp->slot = start; - - esp->dregs = 0; - esp->eregs = (void *)CKSEG1ADDR(start + DEC_SCSI_SREG); - esp->do_pio_cmds = 1; - - /* Set the command buffer. */ - esp->esp_command = (volatile unsigned char *)pmaz_cmd_buffer; - - /* Get virtual dma address for command buffer. */ - esp->esp_command_dvma = virt_to_phys(pmaz_cmd_buffer); - - esp->cfreq = tc_get_speed(to_tc_dev(dev)->bus); - - esp->irq = to_tc_dev(dev)->interrupt; - - /* Required functions. */ - esp->dma_bytes_sent = &dma_bytes_sent; - esp->dma_can_transfer = &dma_can_transfer; - esp->dma_dump_state = &dma_dump_state; - esp->dma_init_read = &pmaz_dma_init_read; - esp->dma_init_write = &pmaz_dma_init_write; - esp->dma_ints_off = &pmaz_dma_ints_off; - esp->dma_ints_on = &pmaz_dma_ints_on; - esp->dma_irq_p = &dma_irq_p; - esp->dma_ports_p = &dma_ports_p; - esp->dma_setup = &pmaz_dma_setup; - - /* Optional functions. */ - esp->dma_barrier = 0; - esp->dma_drain = &pmaz_dma_drain; - esp->dma_invalidate = 0; - esp->dma_irq_entry = 0; - esp->dma_irq_exit = 0; - esp->dma_poll = 0; - esp->dma_reset = 0; - esp->dma_led_off = 0; - esp->dma_led_on = 0; - - esp->dma_mmu_get_scsi_one = pmaz_dma_mmu_get_scsi_one; - esp->dma_mmu_get_scsi_sgl = 0; - esp->dma_mmu_release_scsi_one = 0; - esp->dma_mmu_release_scsi_sgl = 0; - esp->dma_advance_sg = 0; - - err = request_irq(esp->irq, esp_intr, IRQF_DISABLED, "PMAZ_AA", - esp->ehost); - if (err) { - printk(KERN_ERR "%s: Unable to get IRQ %d\n", - dev->bus_id, esp->irq); - goto err_resource; + if (TURBOCHANNEL) { + while ((slot = search_tc_card("PMAZ-AA")) >= 0) { + claim_tc_card(slot); + + esp_dev = 0; + esp = esp_allocate(tpnt, (void *) esp_dev); + + mem_start = get_tc_base_addr(slot); + + /* Store base addr into esp struct */ + esp->slot = CPHYSADDR(mem_start); + + esp->dregs = 0; + esp->eregs = (void *)CKSEG1ADDR(mem_start + + DEC_SCSI_SREG); + esp->do_pio_cmds = 1; + + /* Set the command buffer */ + esp->esp_command = (volatile unsigned char *) pmaz_cmd_buffer; + + /* get virtual dma address for command buffer */ + esp->esp_command_dvma = virt_to_phys(pmaz_cmd_buffer); + + esp->cfreq = get_tc_speed(); + + esp->irq = get_tc_irq_nr(slot); + + /* Required functions */ + esp->dma_bytes_sent = &dma_bytes_sent; + esp->dma_can_transfer = &dma_can_transfer; + esp->dma_dump_state = &dma_dump_state; + esp->dma_init_read = &pmaz_dma_init_read; + esp->dma_init_write = &pmaz_dma_init_write; + esp->dma_ints_off = &pmaz_dma_ints_off; + esp->dma_ints_on = &pmaz_dma_ints_on; + esp->dma_irq_p = &dma_irq_p; + esp->dma_ports_p = &dma_ports_p; + esp->dma_setup = &pmaz_dma_setup; + + /* Optional functions */ + esp->dma_barrier = 0; + esp->dma_drain = &pmaz_dma_drain; + esp->dma_invalidate = 0; + esp->dma_irq_entry = 0; + esp->dma_irq_exit = 0; + esp->dma_poll = 0; + esp->dma_reset = 0; + esp->dma_led_off = 0; + esp->dma_led_on = 0; + + esp->dma_mmu_get_scsi_one = pmaz_dma_mmu_get_scsi_one; + esp->dma_mmu_get_scsi_sgl = 0; + esp->dma_mmu_release_scsi_one = 0; + esp->dma_mmu_release_scsi_sgl = 0; + esp->dma_advance_sg = 0; + + if (request_irq(esp->irq, esp_intr, IRQF_DISABLED, + "PMAZ_AA", esp->ehost)) { + esp_deallocate(esp); + release_tc_card(slot); + continue; + } + esp->scsi_id = 7; + esp->diff = 0; + esp_initialize(esp); + } } - esp->scsi_id = 7; - esp->diff = 0; - esp_initialize(esp); - - err = scsi_add_host(esp->ehost, dev); - if (err) { - printk(KERN_ERR "%s: Unable to register adapter\n", - dev->bus_id); - goto err_irq; + if(nesps) { + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); + esps_running = esps_in_use; + return esps_in_use; } - - scsi_scan_host(esp->ehost); - return 0; -err_irq: - free_irq(esp->irq, esp->ehost); - -err_resource: - release_mem_region(start, len); - -err_alloc: +err_free_irq_err: + free_irq(dec_interrupt[DEC_IRQ_ASC_ERR], scsi_dma_err_int); +err_free_irq_merr: + free_irq(dec_interrupt[DEC_IRQ_ASC_MERR], scsi_dma_merr_int); +err_free_irq: + free_irq(esp->irq, esp_intr); +err_dealloc: esp_deallocate(esp); - scsi_host_put(esp->ehost); - return err; -} - -static void __exit dec_esp_platform_remove(void) -{ - struct NCR_ESP *esp = dec_esp_platform; - - free_irq(esp->irq, esp->ehost); - esp_deallocate(esp); - scsi_host_put(esp->ehost); - dec_esp_platform = NULL; -} - -static void __exit dec_esp_remove(struct device *dev) -{ - struct NCR_ESP *esp = dev_get_drvdata(dev); - - free_irq(esp->irq, esp->ehost); - esp_deallocate(esp); - scsi_host_put(esp->ehost); + return 0; } - /************************************************************* DMA Functions */ static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id) { @@ -621,67 +576,3 @@ static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp { sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer); } - - -#ifdef CONFIG_TC -static int __init dec_esp_tc_probe(struct device *dev); -static int __exit dec_esp_tc_remove(struct device *dev); - -static const struct tc_device_id dec_esp_tc_table[] = { - { "DEC ", "PMAZ-AA " }, - { } -}; -MODULE_DEVICE_TABLE(tc, dec_esp_tc_table); - -static struct tc_driver dec_esp_tc_driver = { - .id_table = dec_esp_tc_table, - .driver = { - .name = "dec_esp", - .bus = &tc_bus_type, - .probe = dec_esp_tc_probe, - .remove = __exit_p(dec_esp_tc_remove), - }, -}; - -static int __init dec_esp_tc_probe(struct device *dev) -{ - int status = dec_esp_probe(dev); - if (!status) - get_device(dev); - return status; -} - -static int __exit dec_esp_tc_remove(struct device *dev) -{ - put_device(dev); - dec_esp_remove(dev); - return 0; -} -#endif - -static int __init dec_esp_init(void) -{ - int status; - - status = tc_register_driver(&dec_esp_tc_driver); - if (!status) - dec_esp_platform_probe(); - - if (nesps) { - pr_info("ESP: Total of %d ESP hosts found, " - "%d actually in use.\n", nesps, esps_in_use); - esps_running = esps_in_use; - } - - return status; -} - -static void __exit dec_esp_exit(void) -{ - dec_esp_platform_remove(); - tc_unregister_driver(&dec_esp_tc_driver); -} - - -module_init(dec_esp_init); -module_exit(dec_esp_exit); diff --git a/trunk/drivers/scsi/fastlane.c b/trunk/drivers/scsi/fastlane.c index 4266a2139b5f..2a1c5c22b9e0 100644 --- a/trunk/drivers/scsi/fastlane.c +++ b/trunk/drivers/scsi/fastlane.c @@ -142,7 +142,7 @@ int __init fastlane_esp_detect(struct scsi_host_template *tpnt) if (board < 0x1000000) { goto err_release; } - esp = esp_allocate(tpnt, (void *)board + FASTLANE_ESP_ADDR, 0); + esp = esp_allocate(tpnt, (void *)board+FASTLANE_ESP_ADDR); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index 8f55e1431433..437684084377 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -1375,7 +1375,7 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) } BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE); - if (mtask->hdr->itt == RESERVED_ITT) { + if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) { struct iscsi_session *session = conn->session; spin_lock_bh(&session->lock); diff --git a/trunk/drivers/scsi/jazz_esp.c b/trunk/drivers/scsi/jazz_esp.c index 19dd4b962e18..bfac4441d89f 100644 --- a/trunk/drivers/scsi/jazz_esp.c +++ b/trunk/drivers/scsi/jazz_esp.c @@ -75,7 +75,7 @@ static int jazz_esp_detect(struct scsi_host_template *tpnt) */ if (1) { esp_dev = NULL; - esp = esp_allocate(tpnt, esp_dev, 0); + esp = esp_allocate(tpnt, (void *) esp_dev); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 7c75771c77ff..d37048c96eab 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -113,7 +113,8 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) hdr->opcode = ISCSI_OP_SCSI_CMD; hdr->flags = ISCSI_ATTR_SIMPLE; int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); - hdr->itt = build_itt(ctask->itt, conn->id, session->age); + hdr->itt = ctask->itt | (conn->id << ISCSI_CID_SHIFT) | + (session->age << ISCSI_AGE_SHIFT); hdr->data_length = cpu_to_be32(sc->request_bufflen); hdr->cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++; @@ -269,7 +270,7 @@ static int iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto out; } - senselen = be16_to_cpu(*(__be16 *)data); + senselen = be16_to_cpu(*(uint16_t *)data); if (datalen < senselen) goto invalid_datalen; @@ -337,7 +338,7 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, if (ntoh24(reject->dlength) >= sizeof(struct iscsi_hdr)) { memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr)); - itt = get_itt(rejected_pdu.itt); + itt = rejected_pdu.itt & ISCSI_ITT_MASK; printk(KERN_ERR "itt 0x%x had pdu (op 0x%x) rejected " "due to DataDigest error.\n", itt, rejected_pdu.opcode); @@ -366,10 +367,10 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, struct iscsi_mgmt_task *mtask; uint32_t itt; - if (hdr->itt != RESERVED_ITT) - itt = get_itt(hdr->itt); + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) + itt = hdr->itt & ISCSI_ITT_MASK; else - itt = ~0U; + itt = hdr->itt; if (itt < session->cmds_max) { ctask = session->cmds[itt]; @@ -439,7 +440,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, iscsi_tmf_rsp(conn, hdr); break; case ISCSI_OP_NOOP_IN: - if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || datalen) { + if (hdr->ttt != ISCSI_RESERVED_TAG || datalen) { rc = ISCSI_ERR_PROTO; break; } @@ -456,7 +457,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, rc = ISCSI_ERR_BAD_OPCODE; break; } - } else if (itt == ~0U) { + } else if (itt == ISCSI_RESERVED_TAG) { rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)hdr); if (rc) @@ -469,7 +470,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, break; } - if (hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) + if (hdr->ttt == ISCSI_RESERVED_TAG) break; if (iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0)) @@ -515,24 +516,24 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr, struct iscsi_cmd_task *ctask; uint32_t itt; - if (hdr->itt != RESERVED_ITT) { - if (((__force u32)hdr->itt & ISCSI_AGE_MASK) != + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + if ((hdr->itt & ISCSI_AGE_MASK) != (session->age << ISCSI_AGE_SHIFT)) { printk(KERN_ERR "iscsi: received itt %x expected " - "session age (%x)\n", (__force u32)hdr->itt, + "session age (%x)\n", hdr->itt, session->age & ISCSI_AGE_MASK); return ISCSI_ERR_BAD_ITT; } - if (((__force u32)hdr->itt & ISCSI_CID_MASK) != + if ((hdr->itt & ISCSI_CID_MASK) != (conn->id << ISCSI_CID_SHIFT)) { printk(KERN_ERR "iscsi: received itt %x, expected " - "CID (%x)\n", (__force u32)hdr->itt, conn->id); + "CID (%x)\n", hdr->itt, conn->id); return ISCSI_ERR_BAD_ITT; } - itt = get_itt(hdr->itt); + itt = hdr->itt & ISCSI_ITT_MASK; } else - itt = ~0U; + itt = hdr->itt; if (itt < session->cmds_max) { ctask = session->cmds[itt]; @@ -895,8 +896,9 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, /* * pre-format CmdSN for outgoing PDU. */ - if (hdr->itt != RESERVED_ITT) { - hdr->itt = build_itt(mtask->itt, conn->id, session->age); + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + hdr->itt = mtask->itt | (conn->id << ISCSI_CID_SHIFT) | + (session->age << ISCSI_AGE_SHIFT); nop->cmdsn = cpu_to_be32(session->cmdsn); if (conn->c_stage == ISCSI_CONN_STARTED && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) @@ -1062,7 +1064,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, spin_lock_bh(&session->lock); ctask->mtask = (struct iscsi_mgmt_task *) - session->mgmt_cmds[get_itt(hdr->itt) - + session->mgmt_cmds[(hdr->itt & ISCSI_ITT_MASK) - ISCSI_MGMT_ITT_OFFSET]; if (conn->tmabort_state == TMABORT_INITIAL) { diff --git a/trunk/drivers/scsi/mac_esp.c b/trunk/drivers/scsi/mac_esp.c index bcb49021b7e2..3586fac9be9a 100644 --- a/trunk/drivers/scsi/mac_esp.c +++ b/trunk/drivers/scsi/mac_esp.c @@ -351,7 +351,7 @@ int mac_esp_detect(struct scsi_host_template * tpnt) for (chipnum = 0; chipnum < chipspresent; chipnum ++) { struct NCR_ESP * esp; - esp = esp_allocate(tpnt, NULL, 0); + esp = esp_allocate(tpnt, (void *) NULL); esp->eregs = (struct ESP_regs *) get_base(chipnum); esp->dma_irq_p = &esp_dafb_dma_irq_p; diff --git a/trunk/drivers/scsi/mca_53c9x.c b/trunk/drivers/scsi/mca_53c9x.c index d693d0f21395..998a8bbc1a4b 100644 --- a/trunk/drivers/scsi/mca_53c9x.c +++ b/trunk/drivers/scsi/mca_53c9x.c @@ -122,7 +122,7 @@ static int mca_esp_detect(struct scsi_host_template *tpnt) if ((slot = mca_find_adapter(*id_to_check, 0)) != MCA_NOTFOUND) { - esp = esp_allocate(tpnt, NULL, 0); + esp = esp_allocate(tpnt, (void *) NULL); pos[0] = mca_read_stored_pos(slot, 2); pos[1] = mca_read_stored_pos(slot, 3); diff --git a/trunk/drivers/scsi/oktagon_esp.c b/trunk/drivers/scsi/oktagon_esp.c index 26a6d55faf3e..c116a6ae3c54 100644 --- a/trunk/drivers/scsi/oktagon_esp.c +++ b/trunk/drivers/scsi/oktagon_esp.c @@ -133,7 +133,7 @@ int oktagon_esp_detect(struct scsi_host_template *tpnt) eregs = (struct ESP_regs *)(address + OKTAGON_ESP_ADDR); /* This line was 5 lines lower */ - esp = esp_allocate(tpnt, (void *)board + OKTAGON_ESP_ADDR, 0); + esp = esp_allocate(tpnt, (void *)board+OKTAGON_ESP_ADDR); /* we have to shift the registers only one bit for oktagon */ esp->shift = 1; diff --git a/trunk/drivers/scsi/osst.c b/trunk/drivers/scsi/osst.c index bd6bbf61adb8..7d2311067903 100644 --- a/trunk/drivers/scsi/osst.c +++ b/trunk/drivers/scsi/osst.c @@ -521,10 +521,10 @@ static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_ break; default: ; /* probably FILL */ } - aux->filemark_cnt = htonl(STp->filemark_cnt); - aux->phys_fm = htonl(0xffffffff); - aux->last_mark_ppos = htonl(STp->last_mark_ppos); - aux->last_mark_lbn = htonl(STp->last_mark_lbn); + aux->filemark_cnt = ntohl(STp->filemark_cnt); + aux->phys_fm = ntohl(0xffffffff); + aux->last_mark_ppos = ntohl(STp->last_mark_ppos); + aux->last_mark_lbn = ntohl(STp->last_mark_lbn); } /* diff --git a/trunk/drivers/scsi/osst.h b/trunk/drivers/scsi/osst.h index 2cc7b5a1606a..1e426f5d0ed8 100644 --- a/trunk/drivers/scsi/osst.h +++ b/trunk/drivers/scsi/osst.h @@ -288,11 +288,11 @@ typedef struct { #else #error "Please fix " #endif - __be16 max_speed; /* Maximum speed supported in KBps */ + u16 max_speed; /* Maximum speed supported in KBps */ u8 reserved10, reserved11; - __be16 ctl; /* Continuous Transfer Limit in blocks */ - __be16 speed; /* Current Speed, in KBps */ - __be16 buffer_size; /* Buffer Size, in 512 bytes */ + u16 ctl; /* Continuous Transfer Limit in blocks */ + u16 speed; /* Current Speed, in KBps */ + u16 buffer_size; /* Buffer Size, in 512 bytes */ u8 reserved18, reserved19; } osst_capabilities_page_t; @@ -352,8 +352,8 @@ typedef struct { u8 reserved2; u8 density; u8 reserved3,reserved4; - __be16 segtrk; - __be16 trks; + u16 segtrk; + u16 trks; u8 reserved5,reserved6,reserved7,reserved8,reserved9,reserved10; } osst_tape_paramtr_page_t; @@ -369,18 +369,18 @@ typedef struct { typedef struct os_partition_s { __u8 partition_num; __u8 par_desc_ver; - __be16 wrt_pass_cntr; - __be32 first_frame_ppos; - __be32 last_frame_ppos; - __be32 eod_frame_ppos; + __u16 wrt_pass_cntr; + __u32 first_frame_ppos; + __u32 last_frame_ppos; + __u32 eod_frame_ppos; } os_partition_t; /* * DAT entry */ typedef struct os_dat_entry_s { - __be32 blk_sz; - __be16 blk_cnt; + __u32 blk_sz; + __u16 blk_cnt; __u8 flags; __u8 reserved; } os_dat_entry_t; @@ -412,23 +412,23 @@ typedef struct os_dat_s { * AUX */ typedef struct os_aux_s { - __be32 format_id; /* hardware compability AUX is based on */ + __u32 format_id; /* hardware compability AUX is based on */ char application_sig[4]; /* driver used to write this media */ - __be32 hdwr; /* reserved */ - __be32 update_frame_cntr; /* for configuration frame */ + __u32 hdwr; /* reserved */ + __u32 update_frame_cntr; /* for configuration frame */ __u8 frame_type; __u8 frame_type_reserved; __u8 reserved_18_19[2]; os_partition_t partition; __u8 reserved_36_43[8]; - __be32 frame_seq_num; - __be32 logical_blk_num_high; - __be32 logical_blk_num; + __u32 frame_seq_num; + __u32 logical_blk_num_high; + __u32 logical_blk_num; os_dat_t dat; __u8 reserved188_191[4]; - __be32 filemark_cnt; - __be32 phys_fm; - __be32 last_mark_ppos; + __u32 filemark_cnt; + __u32 phys_fm; + __u32 last_mark_ppos; __u8 reserved204_223[20]; /* @@ -436,8 +436,8 @@ typedef struct os_aux_s { * * Linux specific fields: */ - __be32 next_mark_ppos; /* when known, points to next marker */ - __be32 last_mark_lbn; /* storing log_blk_num of last mark is extends ADR spec */ + __u32 next_mark_ppos; /* when known, points to next marker */ + __u32 last_mark_lbn; /* storing log_blk_num of last mark is extends ADR spec */ __u8 linux_specific[24]; __u8 reserved_256_511[256]; @@ -450,19 +450,19 @@ typedef struct os_fm_tab_s { __u8 reserved_1; __u8 fm_tab_ent_sz; __u8 reserved_3; - __be16 fm_tab_ent_cnt; + __u16 fm_tab_ent_cnt; __u8 reserved6_15[10]; - __be32 fm_tab_ent[OS_FM_TAB_MAX]; + __u32 fm_tab_ent[OS_FM_TAB_MAX]; } os_fm_tab_t; typedef struct os_ext_trk_ey_s { __u8 et_part_num; __u8 fmt; - __be16 fm_tab_off; + __u16 fm_tab_off; __u8 reserved4_7[4]; - __be32 last_hlb_hi; - __be32 last_hlb; - __be32 last_pp; + __u32 last_hlb_hi; + __u32 last_hlb; + __u32 last_pp; __u8 reserved20_31[12]; } os_ext_trk_ey_t; @@ -479,17 +479,17 @@ typedef struct os_header_s { char ident_str[8]; __u8 major_rev; __u8 minor_rev; - __be16 ext_trk_tb_off; + __u16 ext_trk_tb_off; __u8 reserved12_15[4]; __u8 pt_par_num; __u8 pt_reserved1_3[3]; os_partition_t partition[16]; - __be32 cfg_col_width; - __be32 dat_col_width; - __be32 qfa_col_width; + __u32 cfg_col_width; + __u32 dat_col_width; + __u32 qfa_col_width; __u8 cartridge[16]; __u8 reserved304_511[208]; - __be32 old_filemark_list[16680/4]; /* in ADR 1.4 __u8 track_table[16680] */ + __u32 old_filemark_list[16680/4]; /* in ADR 1.4 __u8 track_table[16680] */ os_ext_trk_tb_t ext_track_tb; __u8 reserved17272_17735[464]; os_fm_tab_t dat_fm_tab; diff --git a/trunk/drivers/scsi/sun3x_esp.c b/trunk/drivers/scsi/sun3x_esp.c index 80fb3f88af2e..6b60536ac92b 100644 --- a/trunk/drivers/scsi/sun3x_esp.c +++ b/trunk/drivers/scsi/sun3x_esp.c @@ -53,7 +53,7 @@ int sun3x_esp_detect(struct scsi_host_template *tpnt) struct ConfigDev *esp_dev; esp_dev = 0; - esp = esp_allocate(tpnt, esp_dev, 0); + esp = esp_allocate(tpnt, (void *) esp_dev); /* Do command transfer with DMA */ esp->do_pio_cmds = 0; diff --git a/trunk/drivers/serial/uartlite.c b/trunk/drivers/serial/uartlite.c index f5051cf1a0c8..db8607e3d531 100644 --- a/trunk/drivers/serial/uartlite.c +++ b/trunk/drivers/serial/uartlite.c @@ -256,7 +256,7 @@ static void ulite_release_port(struct uart_port *port) { release_mem_region(port->mapbase, ULITE_REGION); iounmap(port->membase); - port->membase = NULL; + port->membase = 0; } static int ulite_request_port(struct uart_port *port) @@ -438,7 +438,7 @@ static int __devinit ulite_probe(struct platform_device *pdev) port->iotype = UPIO_MEM; port->iobase = 1; /* mark port in use */ port->mapbase = res->start; - port->membase = NULL; + port->membase = 0; port->ops = &ulite_ops; port->irq = res2->start; port->flags = UPF_BOOT_AUTOCONF; @@ -462,7 +462,7 @@ static int ulite_remove(struct platform_device *pdev) uart_remove_one_port(&ulite_uart_driver, port); /* mark port as free */ - port->membase = NULL; + port->membase = 0; return 0; } diff --git a/trunk/drivers/tc/Makefile b/trunk/drivers/tc/Makefile index 967342692211..83b5bd75ce26 100644 --- a/trunk/drivers/tc/Makefile +++ b/trunk/drivers/tc/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-$(CONFIG_TC) += tc.o tc-driver.o +obj-$(CONFIG_TC) += tc.o obj-$(CONFIG_ZS) += zs.o obj-$(CONFIG_VT) += lk201.o lk201-map.o lk201-remap.o diff --git a/trunk/drivers/tc/tc-driver.c b/trunk/drivers/tc/tc-driver.c deleted file mode 100644 index 16b5bae63c74..000000000000 --- a/trunk/drivers/tc/tc-driver.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * TURBOchannel driver services. - * - * Copyright (c) 2005 James Simmons - * Copyright (c) 2006 Maciej W. Rozycki - * - * Loosely based on drivers/dio/dio-driver.c and - * drivers/pci/pci-driver.c. - * - * This file is subject to the terms and conditions of the GNU - * General Public License. See the file "COPYING" in the main - * directory of this archive for more details. - */ - -#include -#include -#include - -/** - * tc_register_driver - register a new TC driver - * @drv: the driver structure to register - * - * Adds the driver structure to the list of registered drivers - * Returns a negative value on error, otherwise 0. - * If no error occurred, the driver remains registered even if - * no device was claimed during registration. - */ -int tc_register_driver(struct tc_driver *tdrv) -{ - return driver_register(&tdrv->driver); -} -EXPORT_SYMBOL(tc_register_driver); - -/** - * tc_unregister_driver - unregister a TC driver - * @drv: the driver structure to unregister - * - * Deletes the driver structure from the list of registered TC drivers, - * gives it a chance to clean up by calling its remove() function for - * each device it was responsible for, and marks those devices as - * driverless. - */ -void tc_unregister_driver(struct tc_driver *tdrv) -{ - driver_unregister(&tdrv->driver); -} -EXPORT_SYMBOL(tc_unregister_driver); - -/** - * tc_match_device - tell if a TC device structure has a matching - * TC device ID structure - * @tdrv: the TC driver to earch for matching TC device ID strings - * @tdev: the TC device structure to match against - * - * Used by a driver to check whether a TC device present in the - * system is in its list of supported devices. Returns the matching - * tc_device_id structure or %NULL if there is no match. - */ -const struct tc_device_id *tc_match_device(struct tc_driver *tdrv, - struct tc_dev *tdev) -{ - const struct tc_device_id *id = tdrv->id_table; - - if (id) { - while (id->name[0] || id->vendor[0]) { - if (strcmp(tdev->name, id->name) == 0 && - strcmp(tdev->vendor, id->vendor) == 0) - return id; - id++; - } - } - return NULL; -} -EXPORT_SYMBOL(tc_match_device); - -/** - * tc_bus_match - Tell if a device structure has a matching - * TC device ID structure - * @dev: the device structure to match against - * @drv: the device driver to search for matching TC device ID strings - * - * Used by a driver to check whether a TC device present in the - * system is in its list of supported devices. Returns 1 if there - * is a match or 0 otherwise. - */ -static int tc_bus_match(struct device *dev, struct device_driver *drv) -{ - struct tc_dev *tdev = to_tc_dev(dev); - struct tc_driver *tdrv = to_tc_driver(drv); - const struct tc_device_id *id; - - id = tc_match_device(tdrv, tdev); - if (id) - return 1; - - return 0; -} - -struct bus_type tc_bus_type = { - .name = "tc", - .match = tc_bus_match, -}; -EXPORT_SYMBOL(tc_bus_type); - -static int __init tc_driver_init(void) -{ - return bus_register(&tc_bus_type); -} - -postcore_initcall(tc_driver_init); diff --git a/trunk/drivers/tc/tc.c b/trunk/drivers/tc/tc.c index f77f62a4b325..4a51e56f85b6 100644 --- a/trunk/drivers/tc/tc.c +++ b/trunk/drivers/tc/tc.c @@ -1,193 +1,254 @@ /* - * TURBOchannel bus services. + * tc-init: We assume the TURBOchannel to be up and running so + * just probe for Modules and fill in the global data structure + * tc_bus. * - * Copyright (c) Harald Koerfgen, 1998 - * Copyright (c) 2001, 2003, 2005, 2006 Maciej W. Rozycki - * Copyright (c) 2005 James Simmons + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * This file is subject to the terms and conditions of the GNU - * General Public License. See the file "COPYING" in the main - * directory of this archive for more details. + * Copyright (c) Harald Koerfgen, 1998 + * Copyright (c) 2001, 2003, 2005 Maciej W. Rozycki */ -#include -#include #include -#include #include -#include #include #include -#include #include +#include +#include #include +#include -static struct tc_bus tc_bus = { - .name = "TURBOchannel", -}; +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +slot_info tc_bus[MAX_SLOT]; +static int num_tcslots; +static tcinfo *info; /* - * Probing for TURBOchannel modules. + * Interface to the world. Read comment in include/asm-mips/tc.h. */ -static void __init tc_bus_add_devices(struct tc_bus *tbus) + +int search_tc_card(const char *name) +{ + int slot; + slot_info *sip; + + for (slot = 0; slot < num_tcslots; slot++) { + sip = &tc_bus[slot]; + if ((sip->flags & FREE) && + (strncmp(sip->name, name, strlen(name)) == 0)) { + return slot; + } + } + + return -ENODEV; +} + +void claim_tc_card(int slot) +{ + if (tc_bus[slot].flags & IN_USE) { + printk("claim_tc_card: attempting to claim a card already in use\n"); + return; + } + tc_bus[slot].flags &= ~FREE; + tc_bus[slot].flags |= IN_USE; +} + +void release_tc_card(int slot) { - resource_size_t slotsize = tbus->info.slot_size << 20; - resource_size_t extslotsize = tbus->ext_slot_size; - resource_size_t slotaddr; - resource_size_t extslotaddr; - resource_size_t devsize; - void __iomem *module; - struct tc_dev *tdev; + if (tc_bus[slot].flags & FREE) { + printk("release_tc_card: " + "attempting to release a card already free\n"); + return; + } + tc_bus[slot].flags &= ~IN_USE; + tc_bus[slot].flags |= FREE; +} + +unsigned long get_tc_base_addr(int slot) +{ + return tc_bus[slot].base_addr; +} + +unsigned long get_tc_irq_nr(int slot) +{ + return tc_bus[slot].interrupt; +} + +unsigned long get_tc_speed(void) +{ + return 100000 * (10000 / (unsigned long)info->clk_period); +} + +/* + * Probing for TURBOchannel modules + */ +static void __init tc_probe(unsigned long startaddr, unsigned long size, + int slots) +{ + unsigned long slotaddr; int i, slot, err; - u8 pattern[4]; long offset; + u8 pattern[4]; + volatile u8 *module; - for (slot = 0; slot < tbus->num_tcslots; slot++) { - slotaddr = tbus->slot_base + slot * slotsize; - extslotaddr = tbus->ext_slot_base + slot * extslotsize; - module = ioremap_nocache(slotaddr, slotsize); + for (slot = 0; slot < slots; slot++) { + slotaddr = startaddr + slot * size; + module = ioremap_nocache(slotaddr, size); BUG_ON(!module); - offset = TC_OLDCARD; + offset = OLDCARD; err = 0; - err |= tc_preadb(pattern + 0, module + offset + TC_PATTERN0); - err |= tc_preadb(pattern + 1, module + offset + TC_PATTERN1); - err |= tc_preadb(pattern + 2, module + offset + TC_PATTERN2); - err |= tc_preadb(pattern + 3, module + offset + TC_PATTERN3); - if (err) - goto out_err; + err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0); + err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1); + err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2); + err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3); + if (err) { + iounmap(module); + continue; + } if (pattern[0] != 0x55 || pattern[1] != 0x00 || pattern[2] != 0xaa || pattern[3] != 0xff) { - offset = TC_NEWCARD; + offset = NEWCARD; err = 0; - err |= tc_preadb(pattern + 0, - module + offset + TC_PATTERN0); - err |= tc_preadb(pattern + 1, - module + offset + TC_PATTERN1); - err |= tc_preadb(pattern + 2, - module + offset + TC_PATTERN2); - err |= tc_preadb(pattern + 3, - module + offset + TC_PATTERN3); - if (err) - goto out_err; + err |= get_dbe(pattern[0], module + TC_PATTERN0); + err |= get_dbe(pattern[1], module + TC_PATTERN1); + err |= get_dbe(pattern[2], module + TC_PATTERN2); + err |= get_dbe(pattern[3], module + TC_PATTERN3); + if (err) { + iounmap(module); + continue; + } } if (pattern[0] != 0x55 || pattern[1] != 0x00 || - pattern[2] != 0xaa || pattern[3] != 0xff) - goto out_err; - - /* Found a board, allocate it an entry in the list */ - tdev = kzalloc(sizeof(*tdev), GFP_KERNEL); - if (!tdev) { - printk(KERN_ERR "tc%x: unable to allocate tc_dev\n", - slot); - goto out_err; + pattern[2] != 0xaa || pattern[3] != 0xff) { + iounmap(module); + continue; } - sprintf(tdev->dev.bus_id, "tc%x", slot); - tdev->bus = tbus; - tdev->dev.parent = &tbus->dev; - tdev->dev.bus = &tc_bus_type; - tdev->slot = slot; + tc_bus[slot].base_addr = slotaddr; for (i = 0; i < 8; i++) { - tdev->firmware[i] = - readb(module + offset + TC_FIRM_VER + 4 * i); - tdev->vendor[i] = - readb(module + offset + TC_VENDOR + 4 * i); - tdev->name[i] = - readb(module + offset + TC_MODULE + 4 * i); + tc_bus[slot].firmware[i] = + module[TC_FIRM_VER + offset + 4 * i]; + tc_bus[slot].vendor[i] = + module[TC_VENDOR + offset + 4 * i]; + tc_bus[slot].name[i] = + module[TC_MODULE + offset + 4 * i]; } - tdev->firmware[8] = 0; - tdev->vendor[8] = 0; - tdev->name[8] = 0; - - pr_info("%s: %s %s %s\n", tdev->dev.bus_id, tdev->vendor, - tdev->name, tdev->firmware); - - devsize = readb(module + offset + TC_SLOT_SIZE); - devsize <<= 22; - if (devsize <= slotsize) { - tdev->resource.start = slotaddr; - tdev->resource.end = slotaddr + devsize - 1; - } else if (devsize <= extslotsize) { - tdev->resource.start = extslotaddr; - tdev->resource.end = extslotaddr + devsize - 1; - } else { - printk(KERN_ERR "%s: Cannot provide slot space " - "(%dMiB required, up to %dMiB supported)\n", - tdev->dev.bus_id, devsize >> 20, - max(slotsize, extslotsize) >> 20); - kfree(tdev); - goto out_err; + tc_bus[slot].firmware[8] = 0; + tc_bus[slot].vendor[8] = 0; + tc_bus[slot].name[8] = 0; + /* + * Looks unneccesary, but we may change + * TC? in the future + */ + switch (slot) { + case 0: + tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0]; + break; + case 1: + tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1]; + break; + case 2: + tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2]; + break; + /* + * Yuck! DS5000/200 onboard devices + */ + case 5: + tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5]; + break; + case 6: + tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6]; + break; + default: + tc_bus[slot].interrupt = -1; + break; } - tdev->resource.name = tdev->name; - tdev->resource.flags = IORESOURCE_MEM; - - tc_device_get_irq(tdev); - device_register(&tdev->dev); - list_add_tail(&tdev->node, &tbus->devices); - -out_err: iounmap(module); } } /* - * The main entry. + * the main entry */ static int __init tc_init(void) { - /* Initialize the TURBOchannel bus */ - if (tc_bus_get_info(&tc_bus)) + int tc_clock; + int i; + unsigned long slot0addr; + unsigned long slot_size; + + if (!TURBOCHANNEL) return 0; - INIT_LIST_HEAD(&tc_bus.devices); - strcpy(tc_bus.dev.bus_id, "tc"); - device_register(&tc_bus.dev); - - if (tc_bus.info.slot_size) { - unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000; - - pr_info("tc: TURBOchannel rev. %d at %d.%d MHz " - "(with%s parity)\n", tc_bus.info.revision, - tc_clock / 10, tc_clock % 10, - tc_bus.info.parity ? "" : "out"); - - tc_bus.resource[0].start = tc_bus.slot_base; - tc_bus.resource[0].end = tc_bus.slot_base + - (tc_bus.info.slot_size << 20) * - tc_bus.num_tcslots - 1; - tc_bus.resource[0].name = tc_bus.name; - tc_bus.resource[0].flags = IORESOURCE_MEM; - if (request_resource(&iomem_resource, - &tc_bus.resource[0]) < 0) { - printk(KERN_ERR "tc: Cannot reserve resource\n"); - return 0; - } - if (tc_bus.ext_slot_size) { - tc_bus.resource[1].start = tc_bus.ext_slot_base; - tc_bus.resource[1].end = tc_bus.ext_slot_base + - tc_bus.ext_slot_size * - tc_bus.num_tcslots - 1; - tc_bus.resource[1].name = tc_bus.name; - tc_bus.resource[1].flags = IORESOURCE_MEM; - if (request_resource(&iomem_resource, - &tc_bus.resource[1]) < 0) { - printk(KERN_ERR - "tc: Cannot reserve resource\n"); - release_resource(&tc_bus.resource[0]); - return 0; - } - } + for (i = 0; i < MAX_SLOT; i++) { + tc_bus[i].base_addr = 0; + tc_bus[i].name[0] = 0; + tc_bus[i].vendor[0] = 0; + tc_bus[i].firmware[0] = 0; + tc_bus[i].interrupt = -1; + tc_bus[i].flags = FREE; + } - tc_bus_add_devices(&tc_bus); + info = rex_gettcinfo(); + slot0addr = CPHYSADDR((long)rex_slot_address(0)); + + switch (mips_machtype) { + case MACH_DS5000_200: + num_tcslots = 7; + break; + case MACH_DS5000_1XX: + case MACH_DS5000_2X0: + case MACH_DS5900: + num_tcslots = 3; + break; + case MACH_DS5000_XX: + default: + num_tcslots = 2; + break; + } + + tc_clock = 10000 / info->clk_period; + + if (info->slot_size && slot0addr) { + pr_info("TURBOchannel rev. %d at %d.%d MHz (with%s parity)\n", + info->revision, tc_clock / 10, tc_clock % 10, + info->parity ? "" : "out"); + + slot_size = info->slot_size << 20; + + tc_probe(slot0addr, slot_size, num_tcslots); + + for (i = 0; i < num_tcslots; i++) { + if (!tc_bus[i].base_addr) + continue; + pr_info(" slot %d: %s %s %s\n", i, tc_bus[i].vendor, + tc_bus[i].name, tc_bus[i].firmware); + } } return 0; } subsys_initcall(tc_init); + +EXPORT_SYMBOL(search_tc_card); +EXPORT_SYMBOL(claim_tc_card); +EXPORT_SYMBOL(release_tc_card); +EXPORT_SYMBOL(get_tc_base_addr); +EXPORT_SYMBOL(get_tc_irq_nr); +EXPORT_SYMBOL(get_tc_speed); diff --git a/trunk/drivers/usb/host/ehci-ps3.c b/trunk/drivers/usb/host/ehci-ps3.c index 4d781a2a9807..371f194a9d39 100644 --- a/trunk/drivers/usb/host/ehci-ps3.c +++ b/trunk/drivers/usb/host/ehci-ps3.c @@ -104,7 +104,7 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, __LINE__, dev->m_region->lpar_addr); - result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); + result = ps3_alloc_io_irq(dev->interrupt_id, &virq); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index 46fa57a520d0..ec0da0343be4 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -677,10 +677,10 @@ static inline unsigned int ehci_readl (const struct ehci_hcd *ehci, { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO return ehci_big_endian_mmio(ehci) ? - readl_be(regs) : - readl(regs); + readl_be((__force u32 *)regs) : + readl((__force u32 *)regs); #else - return readl(regs); + return readl((__force u32 *)regs); #endif } @@ -689,10 +689,10 @@ static inline void ehci_writel (const struct ehci_hcd *ehci, { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ehci_big_endian_mmio(ehci) ? - writel_be(val, regs) : - writel(val, regs); + writel_be(val, (__force u32 *)regs) : + writel(val, (__force u32 *)regs); #else - writel(val, regs); + writel(val, (__force u32 *)regs); #endif } diff --git a/trunk/drivers/usb/host/ohci-ps3.c b/trunk/drivers/usb/host/ohci-ps3.c index 62283a3926de..69d948b4a701 100644 --- a/trunk/drivers/usb/host/ohci-ps3.c +++ b/trunk/drivers/usb/host/ohci-ps3.c @@ -107,7 +107,7 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, __LINE__, dev->m_region->lpar_addr); - result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); + result = ps3_alloc_io_irq(dev->interrupt_id, &virq); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", diff --git a/trunk/drivers/usb/host/ohci.h b/trunk/drivers/usb/host/ohci.h index c2b5ecfe5e9f..0dafcda37291 100644 --- a/trunk/drivers/usb/host/ohci.h +++ b/trunk/drivers/usb/host/ohci.h @@ -507,10 +507,10 @@ static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, { #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO return big_endian_mmio(ohci) ? - readl_be (regs) : - readl (regs); + readl_be ((__force u32 *)regs) : + readl ((__force u32 *)regs); #else - return readl (regs); + return readl ((__force u32 *)regs); #endif } @@ -519,10 +519,10 @@ static inline void _ohci_writel (const struct ohci_hcd *ohci, { #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO big_endian_mmio(ohci) ? - writel_be (val, regs) : - writel (val, regs); + writel_be (val, (__force u32 *)regs) : + writel (val, (__force u32 *)regs); #else - writel (val, regs); + writel (val, (__force u32 *)regs); #endif } diff --git a/trunk/drivers/usb/net/gl620a.c b/trunk/drivers/usb/net/gl620a.c index 31e5fe363fdc..a6f0f4d934df 100644 --- a/trunk/drivers/usb/net/gl620a.c +++ b/trunk/drivers/usb/net/gl620a.c @@ -70,12 +70,12 @@ (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4) struct gl_packet { - __le32 packet_length; + u32 packet_length; char packet_data [1]; }; struct gl_header { - __le32 packet_count; + u32 packet_count; struct gl_packet packets; }; @@ -85,14 +85,15 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) struct gl_packet *packet; struct sk_buff *gl_skb; u32 size; - u32 count; header = (struct gl_header *) skb->data; // get the packet count of the received skb - count = le32_to_cpu(header->packet_count); - if (count > GL_MAX_TRANSMIT_PACKETS) { - dbg("genelink: invalid received packet count %u", count); + le32_to_cpus(&header->packet_count); + if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS) + || (header->packet_count < 0)) { + dbg("genelink: invalid received packet count %d", + header->packet_count); return 0; } @@ -102,7 +103,7 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) // decrement the length for the packet count size 4 bytes skb_pull(skb, 4); - while (count > 1) { + while (header->packet_count > 1) { // get the packet length size = le32_to_cpu(packet->packet_length); @@ -123,8 +124,9 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) } // advance to the next packet - packet = (struct gl_packet *)&packet->packet_data[size]; - count--; + packet = (struct gl_packet *) + &packet->packet_data [size]; + header->packet_count--; // shift the data pointer to the next gl_packet skb_pull(skb, size + 4); @@ -147,8 +149,8 @@ genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) int length = skb->len; int headroom = skb_headroom(skb); int tailroom = skb_tailroom(skb); - __le32 *packet_count; - __le32 *packet_len; + u32 *packet_count; + u32 *packet_len; // FIXME: magic numbers, bleech padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1; @@ -170,7 +172,7 @@ genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) } // attach the packet count to the header - packet_count = (__le32 *) skb_push(skb, (4 + 4*1)); + packet_count = (u32 *) skb_push(skb, (4 + 4*1)); packet_len = packet_count + 1; *packet_count = cpu_to_le32(1); diff --git a/trunk/drivers/usb/serial/cp2101.c b/trunk/drivers/usb/serial/cp2101.c index 3ec24870bca9..06b4fffc189c 100644 --- a/trunk/drivers/usb/serial/cp2101.c +++ b/trunk/drivers/usb/serial/cp2101.c @@ -170,13 +170,13 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - __le32 *buf; + u32 *buf; int result, i, length; /* Number of integers required to contain the array */ length = (((size - 1) | 3) + 1)/4; - buf = kcalloc(length, sizeof(__le32), GFP_KERNEL); + buf = kcalloc(length, sizeof(u32), GFP_KERNEL); if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); return -ENOMEM; @@ -216,13 +216,13 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - __le32 *buf; + u32 *buf; int result, i, length; /* Number of integers required to contain the array */ length = (((size - 1) | 3) + 1)/4; - buf = kmalloc(length * sizeof(__le32), GFP_KERNEL); + buf = kmalloc(length * sizeof(u32), GFP_KERNEL); if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 45fe65d8d7a0..4e83f01e894e 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -1444,8 +1444,8 @@ config FB_PMAG_AA used mainly in the MIPS-based DECstation series. config FB_PMAG_BA - tristate "PMAG-BA TURBOchannel framebuffer support" - depends on FB && TC + bool "PMAG-BA TURBOchannel framebuffer support" + depends on (FB = y) && TC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -1454,8 +1454,8 @@ config FB_PMAG_BA used mainly in the MIPS-based DECstation series. config FB_PMAGB_B - tristate "PMAGB-B TURBOchannel framebuffer support" - depends on TC + bool "PMAGB-B TURBOchannel framebuffer support" + depends on (FB = y) && TC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/trunk/drivers/video/pmag-ba-fb.c b/trunk/drivers/video/pmag-ba-fb.c index 264d37243fad..f5361cd8ccce 100644 --- a/trunk/drivers/video/pmag-ba-fb.c +++ b/trunk/drivers/video/pmag-ba-fb.c @@ -15,8 +15,7 @@ * Michael Engel , * Karsten Merker and * Harald Koerfgen. - * Copyright (c) 2005, 2006 Maciej W. Rozycki - * Copyright (c) 2005 James Simmons + * Copyright (c) 2005 Maciej W. Rozycki * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this @@ -29,21 +28,26 @@ #include #include #include -#include #include #include #include +#include + #include