From 3b0ef6a8838064a87508589d5d738f941158c6d2 Mon Sep 17 00:00:00 2001 From: Giuliano Pochini Date: Sun, 15 Mar 2009 21:33:34 +0100 Subject: [PATCH] --- yaml --- r: 132973 b: refs/heads/master c: 9f5d790d1b0af8e3705df12fd5d49a1df2a45c47 h: refs/heads/master i: 132971: b85a7b22c5846ac8abf953af468b0bca401c3c12 v: v3 --- [refs] | 2 +- trunk/CREDITS | 2 +- trunk/Documentation/DocBook/Makefile | 3 +- trunk/Documentation/filesystems/ext2.txt | 5 +- trunk/Documentation/filesystems/proc.txt | 7 - trunk/Documentation/logo.gif | Bin 0 -> 16335 bytes trunk/Documentation/logo.svg | 2911 ----------- trunk/Documentation/logo.txt | 15 +- .../sound/alsa/ALSA-Configuration.txt | 34 +- .../alsa}/DocBook/alsa-driver-api.tmpl | 17 +- .../alsa}/DocBook/writing-an-alsa-driver.tmpl | 52 +- trunk/Documentation/sound/alsa/soc/dapm.txt | 3 - trunk/MAINTAINERS | 15 +- trunk/Makefile | 10 +- trunk/arch/arm/kernel/entry-common.S | 4 - trunk/arch/arm/kernel/fiq.c | 4 +- .../arm/mach-ep93xx/include/mach/platform.h | 2 - trunk/arch/arm/mach-mx1/devices.c | 2 - trunk/arch/arm/mach-mx1/mx1ads.c | 1 - trunk/arch/arm/mach-omap2/board-omap3beagle.c | 4 +- trunk/arch/arm/mach-orion5x/common.c | 7 - trunk/arch/arm/mach-pxa/e740.c | 5 - trunk/arch/arm/mach-pxa/e750.c | 5 - trunk/arch/arm/mach-pxa/h5000.c | 7 - .../arm/mach-pxa/include/mach/eseries-gpio.h | 15 - .../arch/arm/mach-pxa/include/mach/regs-ssp.h | 7 +- trunk/arch/arm/mach-pxa/spitz.c | 6 - trunk/arch/arm/mach-s3c2410/dma.c | 2 +- .../include/mach}/audio.h | 0 trunk/arch/arm/mach-s3c2412/dma.c | 4 +- trunk/arch/arm/mach-s3c2440/dma.c | 2 +- trunk/arch/arm/mach-s3c2443/dma.c | 2 +- trunk/arch/arm/mach-s3c6410/mach-smdk6410.c | 4 +- trunk/arch/arm/mm/copypage-feroceon.c | 2 +- trunk/arch/arm/mm/copypage-v3.c | 2 +- trunk/arch/arm/mm/copypage-v4mc.c | 2 +- trunk/arch/arm/mm/copypage-v4wb.c | 2 +- trunk/arch/arm/mm/copypage-v4wt.c | 2 +- trunk/arch/arm/mm/copypage-xsc3.c | 2 +- trunk/arch/arm/mm/copypage-xscale.c | 2 +- trunk/arch/arm/mm/dma-mapping.c | 20 +- trunk/arch/arm/mm/init.c | 2 +- trunk/arch/arm/mm/mmap.c | 2 +- trunk/arch/arm/plat-omap/Makefile | 3 +- trunk/arch/arm/plat-omap/common.c | 14 +- .../arch/arm/plat-omap/include/mach/common.h | 2 +- trunk/arch/arm/plat-omap/include/mach/pm.h | 2 +- trunk/arch/arm/plat-s3c64xx/clock.c | 2 +- trunk/arch/arm/plat-s3c64xx/gpiolib.c | 2 +- .../arch/arm/plat-s3c64xx/include/plat/irqs.h | 2 +- trunk/arch/arm/plat-s3c64xx/irq-eint.c | 15 +- trunk/arch/arm/plat-s3c64xx/irq.c | 2 +- trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c | 24 +- trunk/arch/arm/tools/mach-types | 136 +- trunk/arch/m68k/include/asm/param.h | 25 +- trunk/arch/m68k/include/asm/param_mm.h | 22 + trunk/arch/m68k/include/asm/param_no.h | 22 + trunk/arch/m68k/include/asm/ptrace.h | 88 +- trunk/arch/m68k/include/asm/ptrace_mm.h | 80 + trunk/arch/m68k/include/asm/ptrace_no.h | 87 + trunk/arch/m68k/include/asm/setup.h | 377 +- trunk/arch/m68k/include/asm/setup_mm.h | 376 ++ trunk/arch/m68k/include/asm/setup_no.h | 10 + trunk/arch/m68k/include/asm/sigcontext.h | 25 +- trunk/arch/m68k/include/asm/sigcontext_mm.h | 19 + trunk/arch/m68k/include/asm/sigcontext_no.h | 17 + trunk/arch/m68k/include/asm/siginfo.h | 98 +- trunk/arch/m68k/include/asm/siginfo_mm.h | 92 + trunk/arch/m68k/include/asm/siginfo_no.h | 6 + trunk/arch/m68k/include/asm/signal.h | 216 +- trunk/arch/m68k/include/asm/signal_mm.h | 206 + trunk/arch/m68k/include/asm/signal_no.h | 159 + trunk/arch/m68k/include/asm/swab.h | 30 +- trunk/arch/m68k/include/asm/swab_mm.h | 16 + trunk/arch/m68k/include/asm/swab_no.h | 24 + trunk/arch/m68k/include/asm/unistd.h | 377 +- trunk/arch/m68k/include/asm/unistd_mm.h | 372 ++ trunk/arch/m68k/include/asm/unistd_no.h | 372 ++ trunk/arch/mips/Kconfig | 26 +- trunk/arch/mips/Makefile | 2 +- .../{markeins_defconfig => emma2rh_defconfig} | 10 +- trunk/arch/mips/emma/Kconfig | 29 + trunk/arch/mips/emma/markeins/platform.c | 39 +- trunk/arch/mips/include/asm/seccomp.h | 4 + trunk/arch/mips/include/asm/thread_info.h | 6 - trunk/arch/parisc/configs/712_defconfig | 429 +- trunk/arch/parisc/configs/a500_defconfig | 490 +- trunk/arch/parisc/configs/b180_defconfig | 433 +- trunk/arch/parisc/configs/c3000_defconfig | 575 +-- trunk/arch/parisc/configs/default_defconfig | 585 +-- trunk/arch/parisc/hpux/fs.c | 1 + trunk/arch/parisc/include/asm/assembly.h | 11 +- trunk/arch/parisc/include/asm/io.h | 51 +- trunk/arch/parisc/include/asm/irq.h | 2 +- trunk/arch/parisc/include/asm/uaccess.h | 1 - trunk/arch/parisc/kernel/cache.c | 5 +- trunk/arch/parisc/kernel/entry.S | 6 +- trunk/arch/parisc/kernel/firmware.c | 12 +- trunk/arch/parisc/kernel/irq.c | 18 +- trunk/arch/parisc/kernel/pci-dma.c | 22 +- trunk/arch/parisc/mm/init.c | 6 +- trunk/arch/powerpc/configs/ps3_defconfig | 250 +- trunk/arch/powerpc/include/asm/cputable.h | 4 +- trunk/arch/powerpc/kernel/head_32.S | 15 +- trunk/arch/powerpc/platforms/ps3/Kconfig | 7 - trunk/arch/s390/include/asm/mman.h | 5 - trunk/arch/s390/include/asm/processor.h | 5 +- trunk/arch/s390/include/asm/topology.h | 2 - trunk/arch/s390/kernel/mcount.S | 6 +- trunk/arch/s390/lib/div64.c | 2 +- trunk/arch/s390/lib/uaccess_pt.c | 18 + trunk/arch/s390/mm/mmap.c | 48 +- trunk/arch/s390/mm/pgtable.c | 2 - trunk/arch/sparc/include/asm/pil.h | 1 - trunk/arch/sparc/kernel/kgdb_64.c | 2 +- trunk/arch/sparc/kernel/pci_common.c | 2 +- trunk/arch/sparc/kernel/ttable.S | 7 +- trunk/arch/sparc/mm/ultra.S | 24 +- trunk/arch/x86/kernel/kprobes.c | 3 - trunk/arch/x86/kernel/tsc.c | 110 +- trunk/drivers/acpi/bus.c | 9 +- trunk/drivers/acpi/numa.c | 2 +- trunk/drivers/acpi/osl.c | 50 + trunk/drivers/acpi/sleep.c | 16 - trunk/drivers/ata/ata_piix.c | 37 - trunk/drivers/ata/libata-sff.c | 6 +- trunk/drivers/ata/sata_mv.c | 3 +- trunk/drivers/block/Makefile | 1 - trunk/drivers/block/ps3vram.c | 865 ---- trunk/drivers/block/xsysace.c | 22 - trunk/drivers/char/agp/parisc-agp.c | 23 +- trunk/drivers/dca/dca-sysfs.c | 21 - trunk/drivers/hid/usbhid/hiddev.c | 4 +- trunk/drivers/ide/ide-atapi.c | 12 - trunk/drivers/ide/ide-dma.c | 12 +- trunk/drivers/ide/ide-floppy.c | 6 +- trunk/drivers/isdn/gigaset/bas-gigaset.c | 16 +- trunk/drivers/md/dm-crypt.c | 43 +- trunk/drivers/md/dm-io.c | 2 - trunk/drivers/md/dm-ioctl.c | 7 +- trunk/drivers/md/dm.c | 32 +- trunk/drivers/media/dvb/bt8xx/dst.c | 2 +- .../drivers/media/dvb/dvb-core/dvb_frontend.c | 7 +- .../media/dvb/frontends/stb0899_algo.c | 14 +- .../drivers/media/dvb/frontends/stb0899_drv.c | 2 +- .../media/dvb/frontends/stb0899_priv.h | 12 +- trunk/drivers/media/dvb/frontends/stb6100.c | 4 +- trunk/drivers/media/dvb/frontends/zl10353.c | 2 +- trunk/drivers/media/dvb/frontends/zl10353.h | 3 - trunk/drivers/media/video/cx88/cx88-alsa.c | 7 +- .../drivers/media/video/em28xx/em28xx-audio.c | 7 +- .../media/video/gspca/m5602/m5602_s5k4aa.c | 6 +- .../media/video/saa7134/saa7134-alsa.c | 8 +- .../drivers/media/video/saa7134/saa7134-dvb.c | 1 - trunk/drivers/media/video/tvaudio.c | 2 +- trunk/drivers/media/video/zoran/Kconfig | 1 - trunk/drivers/mtd/devices/Kconfig | 7 + trunk/drivers/mtd/devices/Makefile | 1 + trunk/drivers/mtd/devices/ps3vram.c | 768 +++ trunk/drivers/net/Kconfig | 13 - trunk/drivers/net/Makefile | 2 - trunk/drivers/net/benet/Kconfig | 7 - trunk/drivers/net/benet/Makefile | 7 - trunk/drivers/net/benet/be.h | 328 -- trunk/drivers/net/benet/be_cmds.c | 861 ---- trunk/drivers/net/benet/be_cmds.h | 688 --- trunk/drivers/net/benet/be_ethtool.c | 362 -- trunk/drivers/net/benet/be_hw.h | 211 - trunk/drivers/net/benet/be_main.c | 1911 ------- trunk/drivers/net/bnx2.c | 12 +- trunk/drivers/net/bnx2x.h | 2 +- trunk/drivers/net/bnx2x_init.h | 4 + trunk/drivers/net/bnx2x_main.c | 21 +- trunk/drivers/net/bonding/bond_main.c | 25 +- trunk/drivers/net/dm9000.c | 6 +- trunk/drivers/net/dnet.c | 994 ---- trunk/drivers/net/dnet.h | 225 - trunk/drivers/net/ibm_newemac/core.c | 3 - trunk/drivers/net/igb/igb_main.c | 26 +- trunk/drivers/net/ixgbe/ixgbe_main.c | 1 - trunk/drivers/net/mv643xx_eth.c | 10 +- trunk/drivers/net/netxen/netxen_nic.h | 1 + trunk/drivers/net/netxen/netxen_nic_hw.c | 22 + trunk/drivers/net/netxen/netxen_nic_main.c | 3 + trunk/drivers/net/qlge/qlge.h | 1 - trunk/drivers/net/qlge/qlge_main.c | 57 +- trunk/drivers/net/r8169.c | 122 +- trunk/drivers/net/sh_eth.c | 20 +- trunk/drivers/net/sh_eth.h | 4 +- trunk/drivers/net/smsc911x.c | 4 - trunk/drivers/net/sungem.c | 9 +- trunk/drivers/net/tulip/tulip_core.c | 45 +- trunk/drivers/net/ucc_geth.c | 34 +- trunk/drivers/net/ucc_geth.h | 3 +- trunk/drivers/net/via-velocity.c | 15 +- trunk/drivers/net/virtio_net.c | 3 - trunk/drivers/net/wireless/ath9k/ath9k.h | 4 +- trunk/drivers/net/wireless/ath9k/core.h | 33 - trunk/drivers/net/wireless/ath9k/hw.c | 22 +- trunk/drivers/net/wireless/ath9k/main.c | 1 - trunk/drivers/net/wireless/zd1211rw/zd_mac.c | 8 +- trunk/drivers/parisc/dino.c | 13 +- trunk/drivers/parisc/gsc.c | 39 +- trunk/drivers/parisc/iosapic.c | 16 +- trunk/drivers/parisc/lba_pci.c | 4 +- trunk/drivers/parisc/sba_iommu.c | 63 +- trunk/drivers/platform/x86/Kconfig | 14 +- trunk/drivers/platform/x86/acer-wmi.c | 2 +- trunk/drivers/platform/x86/asus-laptop.c | 5 +- trunk/drivers/platform/x86/eeepc-laptop.c | 6 +- trunk/drivers/platform/x86/thinkpad_acpi.c | 8 +- trunk/drivers/platform/x86/wmi.c | 2 +- trunk/drivers/sbus/char/openprom.c | 1 - trunk/drivers/scsi/fcoe/fc_transport_fcoe.c | 91 +- trunk/drivers/scsi/fcoe/fcoe_sw.c | 56 +- trunk/drivers/scsi/fcoe/libfcoe.c | 318 +- trunk/drivers/scsi/lasi700.c | 2 +- trunk/drivers/scsi/libfc/fc_disc.c | 63 +- trunk/drivers/scsi/libfc/fc_exch.c | 32 +- trunk/drivers/scsi/libfc/fc_fcp.c | 56 +- trunk/drivers/scsi/libfc/fc_lport.c | 173 +- trunk/drivers/scsi/libfc/fc_rport.c | 197 +- trunk/drivers/scsi/qla2xxx/qla_attr.c | 9 +- trunk/drivers/scsi/qla2xxx/qla_init.c | 19 +- trunk/drivers/scsi/qla2xxx/qla_mbx.c | 3 +- trunk/drivers/scsi/qla2xxx/qla_mid.c | 10 +- trunk/drivers/scsi/qla2xxx/qla_os.c | 6 +- trunk/drivers/scsi/qla2xxx/qla_version.h | 2 +- trunk/drivers/scsi/sd.c | 26 +- trunk/drivers/scsi/zalon.c | 2 +- trunk/drivers/staging/Kconfig | 2 + trunk/drivers/staging/Makefile | 1 + trunk/drivers/staging/benet/Kconfig | 7 + trunk/drivers/staging/benet/MAINTAINERS | 6 + trunk/drivers/staging/benet/Makefile | 14 + trunk/drivers/staging/benet/TODO | 6 + trunk/drivers/staging/benet/asyncmesg.h | 82 + trunk/drivers/staging/benet/be_cm.h | 134 + trunk/drivers/staging/benet/be_common.h | 53 + trunk/drivers/staging/benet/be_ethtool.c | 348 ++ trunk/drivers/staging/benet/be_init.c | 1382 +++++ trunk/drivers/staging/benet/be_int.c | 863 ++++ trunk/drivers/staging/benet/be_netif.c | 705 +++ trunk/drivers/staging/benet/benet.h | 429 ++ trunk/drivers/staging/benet/bestatus.h | 103 + trunk/drivers/staging/benet/cev.h | 243 + trunk/drivers/staging/benet/cq.c | 211 + trunk/drivers/staging/benet/descriptors.h | 71 + trunk/drivers/staging/benet/doorbells.h | 179 + trunk/drivers/staging/benet/ep.h | 66 + trunk/drivers/staging/benet/eq.c | 299 ++ trunk/drivers/staging/benet/eth.c | 1273 +++++ trunk/drivers/staging/benet/etx_context.h | 55 + trunk/drivers/staging/benet/funcobj.c | 565 +++ trunk/drivers/staging/benet/fwcmd_common.h | 222 + .../drivers/staging/benet/fwcmd_common_bmap.h | 717 +++ trunk/drivers/staging/benet/fwcmd_eth_bmap.h | 280 ++ trunk/drivers/staging/benet/fwcmd_hdr_bmap.h | 54 + trunk/drivers/staging/benet/fwcmd_mcc.h | 94 + trunk/drivers/staging/benet/fwcmd_opcodes.h | 244 + .../drivers/staging/benet/fwcmd_types_bmap.h | 29 + trunk/drivers/staging/benet/host_struct.h | 182 + trunk/drivers/staging/benet/hwlib.h | 830 +++ trunk/drivers/staging/benet/mpu.c | 1364 +++++ trunk/drivers/staging/benet/mpu.h | 74 + trunk/drivers/staging/benet/mpu_context.h | 46 + trunk/drivers/staging/benet/pcicfg.h | 825 +++ trunk/drivers/staging/benet/post_codes.h | 111 + trunk/drivers/staging/benet/regmap.h | 68 + trunk/drivers/staging/go7007/snd-go7007.c | 7 +- trunk/drivers/usb/atm/cxacru.c | 3 +- trunk/drivers/usb/class/usbtmc.c | 4 +- trunk/drivers/usb/core/devio.c | 12 +- trunk/drivers/usb/gadget/gmidi.c | 7 +- trunk/drivers/usb/host/ehci-q.c | 3 +- trunk/drivers/usb/host/ehci-sched.c | 10 +- trunk/drivers/usb/image/mdc800.c | 1 - trunk/drivers/usb/misc/adutux.c | 6 +- trunk/drivers/usb/misc/vstusb.c | 1 - trunk/drivers/usb/serial/cp2101.c | 1 - trunk/drivers/usb/serial/ftdi_sio.c | 5 - trunk/drivers/usb/serial/ftdi_sio.h | 20 - trunk/drivers/usb/serial/option.c | 14 +- trunk/drivers/usb/storage/unusual_devs.h | 16 +- trunk/drivers/usb/wusbcore/wa-xfer.c | 4 +- trunk/drivers/video/aty/radeon_pm.c | 24 - .../drivers/video/logo/logo_linux_clut224.ppm | 4428 ++++++----------- trunk/drivers/video/logo/logo_linux_vga16.ppm | 4339 ++++++---------- trunk/fs/aio.c | 42 +- trunk/fs/bio-integrity.c | 5 +- trunk/fs/bio.c | 6 +- trunk/fs/btrfs/ctree.h | 9 - trunk/fs/btrfs/extent-tree.c | 45 +- trunk/fs/btrfs/volumes.c | 8 - trunk/fs/buffer.c | 23 +- trunk/fs/ecryptfs/crypto.c | 51 +- trunk/fs/ecryptfs/ecryptfs_kernel.h | 4 +- trunk/fs/ecryptfs/inode.c | 32 +- trunk/fs/ecryptfs/keystore.c | 3 +- trunk/fs/ecryptfs/main.c | 5 +- trunk/fs/ext4/extents.c | 6 +- trunk/fs/ext4/ialloc.c | 4 +- trunk/fs/ext4/mballoc.c | 13 +- trunk/fs/lockd/clntlock.c | 51 +- trunk/fs/minix/inode.c | 2 +- trunk/fs/nfs/client.c | 73 +- trunk/fs/nfs/dir.c | 8 +- trunk/fs/nfs/nfs3acl.c | 27 +- trunk/fs/nfs/nfs3xdr.c | 34 +- trunk/fs/nfs/nfs4namespace.c | 15 +- trunk/fs/nfsd/nfs4xdr.c | 1 - trunk/fs/ocfs2/alloc.c | 3 +- trunk/fs/ocfs2/aops.c | 7 +- trunk/fs/ocfs2/namei.c | 3 +- trunk/fs/ocfs2/ocfs2_fs.h | 6 + trunk/fs/ocfs2/xattr.c | 30 +- trunk/fs/proc/base.c | 16 +- trunk/fs/ramfs/file-nommu.c | 4 - trunk/fs/ufs/super.c | 2 +- .../asm-arm/plat-s3c24xx}/regs-iis.h | 0 .../asm-arm/plat-s3c24xx}/regs-s3c2412-iis.h | 7 +- trunk/include/linux/bio.h | 4 +- trunk/include/linux/capability.h | 6 +- trunk/include/linux/compiler-gcc.h | 10 +- trunk/include/linux/dca.h | 20 - trunk/include/linux/ide.h | 1 - trunk/include/linux/input.h | 1 - trunk/include/linux/lockd/lockd.h | 8 - trunk/include/linux/mfd/wm8350/audio.h | 1 - trunk/include/linux/mfd/wm8400-audio.h | 1 - trunk/include/linux/nfs_xdr.h | 2 - trunk/include/linux/nfsacl.h | 3 - .../include/net/netfilter/nf_conntrack_core.h | 3 +- trunk/include/scsi/fc/fc_fcoe.h | 4 + trunk/include/scsi/fc/fc_fs.h | 5 - trunk/include/scsi/libfc.h | 138 +- trunk/include/scsi/libfcoe.h | 9 +- trunk/include/sound/ad1816a.h | 2 - trunk/include/sound/asound.h | 185 +- trunk/include/sound/atmel-abdac.h | 23 - trunk/include/sound/atmel-ac97c.h | 40 - trunk/include/sound/control.h | 52 +- trunk/include/sound/core.h | 36 +- trunk/include/sound/hwdep.h | 38 +- trunk/include/sound/jack.h | 5 - trunk/include/sound/pcm.h | 3 +- trunk/include/sound/pxa2xx-lib.h | 15 - trunk/include/sound/rawmidi.h | 1 + trunk/include/sound/sfnt_info.h | 14 +- trunk/include/sound/soc-dai.h | 2 +- trunk/include/sound/soc-dapm.h | 31 +- trunk/include/sound/soc.h | 69 +- trunk/include/sound/uda1341.h | 126 + trunk/include/sound/version.h | 2 +- trunk/include/sound/wss.h | 1 - trunk/kernel/module.c | 26 +- trunk/kernel/signal.c | 8 - trunk/mm/vmscan.c | 2 +- trunk/net/core/dev.c | 7 +- trunk/net/ipv4/ip_fragment.c | 3 +- trunk/net/ipv6/af_inet6.c | 3 - trunk/net/ipv6/netfilter/nf_conntrack_reasm.c | 8 +- trunk/net/ipv6/reassembly.c | 7 +- trunk/net/ipv6/sit.c | 2 +- trunk/net/mac80211/tx.c | 2 - trunk/net/netfilter/nf_conntrack_core.c | 2 +- trunk/net/netfilter/nf_conntrack_netlink.c | 1 - trunk/net/netfilter/nf_conntrack_proto_tcp.c | 4 +- trunk/net/sctp/endpointola.c | 3 +- trunk/net/sunrpc/sched.c | 33 +- trunk/net/sunrpc/xprt.c | 2 +- trunk/net/sunrpc/xprtsock.c | 23 +- trunk/net/wireless/Kconfig | 10 - trunk/net/wireless/lib80211_crypt_ccmp.c | 2 - trunk/net/wireless/lib80211_crypt_tkip.c | 4 - trunk/net/wireless/nl80211.c | 11 - trunk/net/xfrm/xfrm_state.c | 90 +- trunk/scripts/kconfig/conf.c | 16 +- trunk/scripts/kconfig/confdata.c | 51 +- trunk/sound/Kconfig | 2 - trunk/sound/Makefile | 2 +- trunk/sound/aoa/aoa-gpio.h | 2 - trunk/sound/aoa/core/alsa.c | 7 +- trunk/sound/aoa/core/gpio-feature.c | 17 +- trunk/sound/aoa/fabrics/layout.c | 81 +- trunk/sound/aoa/soundbus/i2sbus/core.c | 22 +- trunk/sound/arm/Kconfig | 11 + trunk/sound/arm/Makefile | 3 + trunk/sound/arm/aaci.c | 7 +- trunk/sound/arm/pxa2xx-ac97-lib.c | 71 +- trunk/sound/arm/pxa2xx-ac97.c | 7 +- trunk/sound/arm/sa11xx-uda1341.c | 983 ++++ trunk/sound/atmel/Kconfig | 19 - trunk/sound/atmel/Makefile | 5 - trunk/sound/atmel/abdac.c | 602 --- trunk/sound/atmel/ac97c.c | 932 ---- trunk/sound/atmel/ac97c.h | 71 - trunk/sound/core/hwdep.c | 9 +- trunk/sound/core/init.c | 89 +- trunk/sound/core/jack.c | 45 +- trunk/sound/core/misc.c | 10 +- trunk/sound/core/oss/mixer_oss.c | 3 - trunk/sound/core/oss/pcm_oss.c | 53 +- trunk/sound/core/oss/pcm_plugin.h | 4 +- trunk/sound/core/pcm.c | 3 +- trunk/sound/core/pcm_lib.c | 155 +- trunk/sound/core/pcm_native.c | 6 +- trunk/sound/core/pcm_timer.c | 6 + trunk/sound/core/rawmidi.c | 379 +- trunk/sound/core/seq/oss/seq_oss_device.h | 2 +- trunk/sound/core/seq/seq_prioq.c | 3 +- trunk/sound/core/sgbuf.c | 7 +- trunk/sound/core/vmaster.c | 62 +- trunk/sound/drivers/dummy.c | 8 +- trunk/sound/drivers/ml403-ac97cr.c | 6 +- trunk/sound/drivers/mpu401/mpu401.c | 6 +- trunk/sound/drivers/mtpav.c | 18 +- trunk/sound/drivers/mts64.c | 8 +- trunk/sound/drivers/opl3/opl3_lib.c | 2 +- trunk/sound/drivers/opl3/opl3_midi.c | 30 +- trunk/sound/drivers/opl3/opl3_oss.c | 8 +- trunk/sound/drivers/opl3/opl3_synth.c | 2 +- trunk/sound/drivers/pcsp/pcsp.c | 8 +- trunk/sound/drivers/portman2x4.c | 6 +- trunk/sound/drivers/serial-u16550.c | 24 +- trunk/sound/drivers/virmidi.c | 12 +- trunk/sound/drivers/vx/vx_core.c | 3 +- trunk/sound/drivers/vx/vx_hwdep.c | 12 + trunk/sound/drivers/vx/vx_uer.c | 2 +- trunk/sound/i2c/Makefile | 2 + trunk/sound/i2c/l3/Makefile | 8 + trunk/sound/i2c/l3/uda1341.c | 935 ++++ trunk/sound/isa/Kconfig | 25 +- trunk/sound/isa/ad1816a/ad1816a.c | 21 +- trunk/sound/isa/ad1816a/ad1816a_lib.c | 11 +- trunk/sound/isa/ad1848/ad1848.c | 6 +- trunk/sound/isa/adlib.c | 6 +- trunk/sound/isa/als100.c | 7 +- trunk/sound/isa/azt2320.c | 7 +- trunk/sound/isa/cmi8330.c | 94 +- trunk/sound/isa/cs423x/Makefile | 8 +- trunk/sound/isa/cs423x/cs4231.c | 6 +- trunk/sound/isa/cs423x/cs4232.c | 2 + trunk/sound/isa/cs423x/cs4236.c | 185 +- trunk/sound/isa/cs423x/cs4236_lib.c | 45 +- trunk/sound/isa/dt019x.c | 7 +- trunk/sound/isa/es1688/es1688.c | 29 +- trunk/sound/isa/es1688/es1688_lib.c | 23 +- trunk/sound/isa/es18xx.c | 24 +- trunk/sound/isa/gus/gus_dma.c | 27 +- trunk/sound/isa/gus/gus_irq.c | 6 +- trunk/sound/isa/gus/gus_pcm.c | 26 +- trunk/sound/isa/gus/gus_uart.c | 10 +- trunk/sound/isa/gus/gusclassic.c | 6 +- trunk/sound/isa/gus/gusextreme.c | 6 +- trunk/sound/isa/gus/gusmax.c | 8 +- trunk/sound/isa/gus/interwave.c | 42 +- trunk/sound/isa/opl3sa2.c | 59 +- trunk/sound/isa/opti9xx/miro.c | 7 +- trunk/sound/isa/opti9xx/opti92x-ad1848.c | 65 +- trunk/sound/isa/sb/es968.c | 7 +- trunk/sound/isa/sb/sb16.c | 28 +- trunk/sound/isa/sb/sb8.c | 8 +- trunk/sound/isa/sc6000.c | 10 +- trunk/sound/isa/sgalaxy.c | 6 +- trunk/sound/isa/sscape.c | 16 +- trunk/sound/isa/wavefront/wavefront.c | 30 +- trunk/sound/isa/wavefront/wavefront_synth.c | 2 +- trunk/sound/isa/wss/wss_lib.c | 79 +- trunk/sound/mips/au1x00.c | 9 +- trunk/sound/mips/hal2.c | 6 +- trunk/sound/mips/sgio2audio.c | 6 +- trunk/sound/parisc/harmony.c | 6 +- trunk/sound/pci/ac97/ac97_codec.c | 6 +- trunk/sound/pci/ad1889.c | 6 +- trunk/sound/pci/ak4531_codec.c | 3 +- trunk/sound/pci/ali5451/ali5451.c | 10 +- trunk/sound/pci/als300.c | 8 +- trunk/sound/pci/als4000.c | 9 +- trunk/sound/pci/atiixp.c | 6 +- trunk/sound/pci/atiixp_modem.c | 6 +- trunk/sound/pci/au88x0/au88x0.c | 6 +- trunk/sound/pci/au88x0/au88x0_a3d.c | 7 +- trunk/sound/pci/au88x0/au88x0_core.c | 21 +- trunk/sound/pci/au88x0/au88x0_synth.c | 39 +- trunk/sound/pci/aw2/aw2-alsa.c | 6 +- trunk/sound/pci/azt3328.c | 14 +- trunk/sound/pci/bt87x.c | 6 +- trunk/sound/pci/ca0106/ca0106_main.c | 105 +- trunk/sound/pci/cmipci.c | 6 +- trunk/sound/pci/cs4281.c | 12 +- trunk/sound/pci/cs46xx/cs46xx.c | 6 +- trunk/sound/pci/cs46xx/cs46xx_lib.c | 6 +- trunk/sound/pci/cs46xx/cs46xx_lib.h | 6 +- trunk/sound/pci/cs5530.c | 6 +- trunk/sound/pci/cs5535audio/cs5535audio.c | 8 +- trunk/sound/pci/echoaudio/echo3g_dsp.c | 2 +- trunk/sound/pci/echoaudio/echoaudio.c | 23 +- trunk/sound/pci/echoaudio/echoaudio_3g.c | 3 +- trunk/sound/pci/echoaudio/echoaudio_dsp.c | 6 +- trunk/sound/pci/echoaudio/gina20_dsp.c | 4 +- trunk/sound/pci/echoaudio/layla20_dsp.c | 4 +- trunk/sound/pci/echoaudio/mia_dsp.c | 4 +- trunk/sound/pci/echoaudio/midi.c | 4 +- trunk/sound/pci/emu10k1/emu10k1.c | 6 +- trunk/sound/pci/emu10k1/emu10k1x.c | 6 +- trunk/sound/pci/ens1370.c | 9 +- trunk/sound/pci/es1938.c | 29 +- trunk/sound/pci/es1968.c | 6 +- trunk/sound/pci/fm801.c | 6 +- trunk/sound/pci/hda/hda_intel.c | 45 +- trunk/sound/pci/ice1712/ice1712.c | 6 +- trunk/sound/pci/ice1712/ice1724.c | 6 +- trunk/sound/pci/intel8x0.c | 6 +- trunk/sound/pci/intel8x0m.c | 6 +- trunk/sound/pci/korg1212/korg1212.c | 6 +- trunk/sound/pci/maestro3.c | 6 +- trunk/sound/pci/mixart/mixart.c | 7 +- trunk/sound/pci/mixart/mixart_hwdep.c | 58 +- trunk/sound/pci/nm256/nm256.c | 6 +- trunk/sound/pci/oxygen/oxygen_lib.c | 8 +- trunk/sound/pci/pcxhr/pcxhr.c | 6 +- trunk/sound/pci/pcxhr/pcxhr_hwdep.c | 12 + trunk/sound/pci/riptide/riptide.c | 6 +- trunk/sound/pci/rme32.c | 7 +- trunk/sound/pci/rme96.c | 7 +- trunk/sound/pci/rme9652/hdsp.c | 15 +- trunk/sound/pci/rme9652/hdspm.c | 17 +- trunk/sound/pci/rme9652/rme9652.c | 8 +- trunk/sound/pci/sis7019.c | 5 +- trunk/sound/pci/sonicvibes.c | 115 +- trunk/sound/pci/trident/trident.c | 6 +- trunk/sound/pci/trident/trident_main.c | 57 +- trunk/sound/pci/via82xx.c | 29 +- trunk/sound/pci/via82xx_modem.c | 11 +- trunk/sound/pci/vx222/vx222.c | 6 +- trunk/sound/pci/vx222/vx222_ops.c | 8 +- trunk/sound/pci/ymfpci/ymfpci.c | 6 +- trunk/sound/pci/ymfpci/ymfpci_main.c | 14 +- trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c | 19 +- trunk/sound/pcmcia/pdaudiocf/pdaudiocf_core.c | 23 +- trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c | 4 +- trunk/sound/pcmcia/vx/vxpocket.c | 32 +- trunk/sound/ppc/powermac.c | 6 +- trunk/sound/ppc/snd_ps3.c | 6 +- trunk/sound/sh/aica.c | 8 +- trunk/sound/soc/Kconfig | 1 - trunk/sound/soc/Makefile | 2 +- trunk/sound/soc/atmel/atmel-pcm.c | 2 +- trunk/sound/soc/atmel/atmel_ssc_dai.c | 33 +- trunk/sound/soc/atmel/playpaq_wm8510.c | 24 +- trunk/sound/soc/atmel/sam9g20_wm8731.c | 124 +- trunk/sound/soc/au1x/dbdma2.c | 2 +- trunk/sound/soc/au1x/psc-ac97.c | 10 +- trunk/sound/soc/au1x/psc-i2s.c | 12 +- trunk/sound/soc/blackfin/bf5xx-ac97-pcm.c | 2 +- trunk/sound/soc/blackfin/bf5xx-ac97.c | 94 +- trunk/sound/soc/blackfin/bf5xx-ad73311.c | 4 +- trunk/sound/soc/blackfin/bf5xx-i2s-pcm.c | 2 +- trunk/sound/soc/blackfin/bf5xx-i2s.c | 14 +- trunk/sound/soc/blackfin/bf5xx-sport.c | 104 +- trunk/sound/soc/codecs/Kconfig | 23 +- trunk/sound/soc/codecs/Makefile | 7 - trunk/sound/soc/codecs/ac97.c | 29 +- trunk/sound/soc/codecs/ad1980.c | 33 +- trunk/sound/soc/codecs/ad73311.c | 8 +- trunk/sound/soc/codecs/ad73311.h | 2 +- trunk/sound/soc/codecs/ak4104.c | 365 -- trunk/sound/soc/codecs/ak4104.h | 7 - trunk/sound/soc/codecs/ak4535.c | 46 +- trunk/sound/soc/codecs/cs4270.c | 667 ++- trunk/sound/soc/codecs/pcm3008.c | 12 +- trunk/sound/soc/codecs/ssm2602.c | 58 +- trunk/sound/soc/codecs/tlv320aic23.c | 57 +- trunk/sound/soc/codecs/tlv320aic26.c | 29 +- trunk/sound/soc/codecs/tlv320aic3x.c | 161 +- trunk/sound/soc/codecs/twl4030.c | 524 +- trunk/sound/soc/codecs/twl4030.h | 15 - trunk/sound/soc/codecs/uda134x.c | 84 +- trunk/sound/soc/codecs/uda1380.c | 241 +- trunk/sound/soc/codecs/wm8350.c | 166 +- trunk/sound/soc/codecs/wm8350.h | 8 - trunk/sound/soc/codecs/wm8400.c | 1582 ------ trunk/sound/soc/codecs/wm8400.h | 62 - trunk/sound/soc/codecs/wm8510.c | 55 +- trunk/sound/soc/codecs/wm8580.c | 381 +- trunk/sound/soc/codecs/wm8580.h | 5 + trunk/sound/soc/codecs/wm8728.c | 50 +- trunk/sound/soc/codecs/wm8731.c | 432 +- trunk/sound/soc/codecs/wm8731.h | 6 + trunk/sound/soc/codecs/wm8750.c | 48 +- trunk/sound/soc/codecs/wm8753.c | 542 +- trunk/sound/soc/codecs/wm8753.h | 6 + trunk/sound/soc/codecs/wm8900.c | 51 +- trunk/sound/soc/codecs/wm8903.c | 60 +- trunk/sound/soc/codecs/wm8971.c | 46 +- trunk/sound/soc/codecs/wm8990.c | 54 +- trunk/sound/soc/codecs/wm9705.c | 415 -- trunk/sound/soc/codecs/wm9705.h | 14 - trunk/sound/soc/codecs/wm9712.c | 57 +- trunk/sound/soc/codecs/wm9713.c | 96 +- trunk/sound/soc/davinci/Kconfig | 2 +- trunk/sound/soc/davinci/davinci-evm.c | 3 +- trunk/sound/soc/davinci/davinci-i2s.c | 14 +- trunk/sound/soc/davinci/davinci-pcm.c | 2 +- trunk/sound/soc/davinci/davinci-sffsdr.c | 43 +- trunk/sound/soc/fsl/Kconfig | 17 +- trunk/sound/soc/fsl/Makefile | 7 +- trunk/sound/soc/fsl/fsl_dma.c | 181 +- trunk/sound/soc/fsl/fsl_ssi.c | 98 +- trunk/sound/soc/fsl/fsl_ssi.h | 2 - trunk/sound/soc/fsl/mpc5200_psc_i2s.c | 20 +- trunk/sound/soc/fsl/mpc8610_hpcd.c | 5 - trunk/sound/soc/omap/Kconfig | 14 +- trunk/sound/soc/omap/Makefile | 2 - trunk/sound/soc/omap/n810.c | 47 +- trunk/sound/soc/omap/omap-mcbsp.c | 20 +- trunk/sound/soc/omap/omap-pcm.c | 2 +- trunk/sound/soc/omap/omap3pandora.c | 49 +- trunk/sound/soc/omap/osk5912.c | 12 +- trunk/sound/soc/omap/sdp3430.c | 115 - trunk/sound/soc/pxa/Kconfig | 27 - trunk/sound/soc/pxa/Makefile | 6 - trunk/sound/soc/pxa/corgi.c | 58 +- trunk/sound/soc/pxa/e740_wm9705.c | 211 - trunk/sound/soc/pxa/e750_wm9705.c | 187 - trunk/sound/soc/pxa/e800_wm9712.c | 115 +- trunk/sound/soc/pxa/mioa701_wm9713.c | 250 - trunk/sound/soc/pxa/palm27x.c | 15 +- trunk/sound/soc/pxa/poodle.c | 56 +- trunk/sound/soc/pxa/pxa-ssp.c | 150 +- trunk/sound/soc/pxa/pxa2xx-ac97.c | 59 +- trunk/sound/soc/pxa/pxa2xx-i2s.c | 54 +- trunk/sound/soc/pxa/spitz.c | 14 +- trunk/sound/soc/pxa/tosa.c | 14 +- trunk/sound/soc/pxa/zylonite.c | 132 +- trunk/sound/soc/s3c24xx/Kconfig | 29 +- trunk/sound/soc/s3c24xx/Makefile | 6 - trunk/sound/soc/s3c24xx/jive_wm8750.c | 201 - trunk/sound/soc/s3c24xx/neo1973_wm8753.c | 67 +- trunk/sound/soc/s3c24xx/s3c-i2s-v2.c | 638 --- trunk/sound/soc/s3c24xx/s3c-i2s-v2.h | 90 - trunk/sound/soc/s3c24xx/s3c2412-i2s.c | 622 ++- trunk/sound/soc/s3c24xx/s3c2412-i2s.h | 17 +- trunk/sound/soc/s3c24xx/s3c2443-ac97.c | 20 +- trunk/sound/soc/s3c24xx/s3c24xx-i2s.c | 71 +- trunk/sound/soc/s3c24xx/s3c24xx-pcm.c | 49 +- trunk/sound/soc/s3c24xx/s3c24xx_uda134x.c | 2 +- trunk/sound/soc/s3c24xx/s3c64xx-i2s.c | 222 - trunk/sound/soc/s3c24xx/s3c64xx-i2s.h | 31 - trunk/sound/soc/sh/hac.c | 12 +- trunk/sound/soc/sh/ssi.c | 30 +- trunk/sound/soc/soc-core.c | 181 +- trunk/sound/soc/soc-dapm.c | 390 +- trunk/sound/soc/soc-jack.c | 267 - trunk/sound/sparc/amd7930.c | 12 +- trunk/sound/sparc/cs4231.c | 9 +- trunk/sound/sparc/dbri.c | 8 +- trunk/sound/spi/at73c213.c | 7 +- trunk/sound/synth/emux/emux_hwdep.c | 21 + trunk/sound/synth/emux/emux_oss.c | 2 +- trunk/sound/synth/emux/emux_seq.c | 16 +- trunk/sound/synth/emux/emux_synth.c | 6 +- trunk/sound/synth/emux/soundfont.c | 28 +- trunk/sound/usb/caiaq/caiaq-device.c | 22 +- trunk/sound/usb/usbaudio.c | 6 +- trunk/sound/usb/usbmixer.c | 22 +- trunk/sound/usb/usx2y/us122l.c | 59 +- trunk/sound/usb/usx2y/usX2Yhwdep.c | 15 + trunk/sound/usb/usx2y/usbusx2y.c | 56 +- trunk/sound/usb/usx2y/usx2yhwdeppcm.h | 2 - 671 files changed, 28038 insertions(+), 32981 deletions(-) create mode 100644 trunk/Documentation/logo.gif delete mode 100644 trunk/Documentation/logo.svg rename trunk/Documentation/{ => sound/alsa}/DocBook/alsa-driver-api.tmpl (87%) rename trunk/Documentation/{ => sound/alsa}/DocBook/writing-an-alsa-driver.tmpl (99%) rename trunk/arch/arm/{plat-s3c/include/plat => mach-s3c2410/include/mach}/audio.h (100%) create mode 100644 trunk/arch/m68k/include/asm/param_mm.h create mode 100644 trunk/arch/m68k/include/asm/param_no.h create mode 100644 trunk/arch/m68k/include/asm/ptrace_mm.h create mode 100644 trunk/arch/m68k/include/asm/ptrace_no.h create mode 100644 trunk/arch/m68k/include/asm/setup_mm.h create mode 100644 trunk/arch/m68k/include/asm/setup_no.h create mode 100644 trunk/arch/m68k/include/asm/sigcontext_mm.h create mode 100644 trunk/arch/m68k/include/asm/sigcontext_no.h create mode 100644 trunk/arch/m68k/include/asm/siginfo_mm.h create mode 100644 trunk/arch/m68k/include/asm/siginfo_no.h create mode 100644 trunk/arch/m68k/include/asm/signal_mm.h create mode 100644 trunk/arch/m68k/include/asm/signal_no.h create mode 100644 trunk/arch/m68k/include/asm/swab_mm.h create mode 100644 trunk/arch/m68k/include/asm/swab_no.h create mode 100644 trunk/arch/m68k/include/asm/unistd_mm.h create mode 100644 trunk/arch/m68k/include/asm/unistd_no.h rename trunk/arch/mips/configs/{markeins_defconfig => emma2rh_defconfig} (99%) create mode 100644 trunk/arch/mips/emma/Kconfig delete mode 100644 trunk/drivers/block/ps3vram.c create mode 100644 trunk/drivers/mtd/devices/ps3vram.c delete mode 100644 trunk/drivers/net/benet/Kconfig delete mode 100644 trunk/drivers/net/benet/Makefile delete mode 100644 trunk/drivers/net/benet/be.h delete mode 100644 trunk/drivers/net/benet/be_cmds.c delete mode 100644 trunk/drivers/net/benet/be_cmds.h delete mode 100644 trunk/drivers/net/benet/be_ethtool.c delete mode 100644 trunk/drivers/net/benet/be_hw.h delete mode 100644 trunk/drivers/net/benet/be_main.c delete mode 100644 trunk/drivers/net/dnet.c delete mode 100644 trunk/drivers/net/dnet.h create mode 100644 trunk/drivers/staging/benet/Kconfig create mode 100644 trunk/drivers/staging/benet/MAINTAINERS create mode 100644 trunk/drivers/staging/benet/Makefile create mode 100644 trunk/drivers/staging/benet/TODO create mode 100644 trunk/drivers/staging/benet/asyncmesg.h create mode 100644 trunk/drivers/staging/benet/be_cm.h create mode 100644 trunk/drivers/staging/benet/be_common.h create mode 100644 trunk/drivers/staging/benet/be_ethtool.c create mode 100644 trunk/drivers/staging/benet/be_init.c create mode 100644 trunk/drivers/staging/benet/be_int.c create mode 100644 trunk/drivers/staging/benet/be_netif.c create mode 100644 trunk/drivers/staging/benet/benet.h create mode 100644 trunk/drivers/staging/benet/bestatus.h create mode 100644 trunk/drivers/staging/benet/cev.h create mode 100644 trunk/drivers/staging/benet/cq.c create mode 100644 trunk/drivers/staging/benet/descriptors.h create mode 100644 trunk/drivers/staging/benet/doorbells.h create mode 100644 trunk/drivers/staging/benet/ep.h create mode 100644 trunk/drivers/staging/benet/eq.c create mode 100644 trunk/drivers/staging/benet/eth.c create mode 100644 trunk/drivers/staging/benet/etx_context.h create mode 100644 trunk/drivers/staging/benet/funcobj.c create mode 100644 trunk/drivers/staging/benet/fwcmd_common.h create mode 100644 trunk/drivers/staging/benet/fwcmd_common_bmap.h create mode 100644 trunk/drivers/staging/benet/fwcmd_eth_bmap.h create mode 100644 trunk/drivers/staging/benet/fwcmd_hdr_bmap.h create mode 100644 trunk/drivers/staging/benet/fwcmd_mcc.h create mode 100644 trunk/drivers/staging/benet/fwcmd_opcodes.h create mode 100644 trunk/drivers/staging/benet/fwcmd_types_bmap.h create mode 100644 trunk/drivers/staging/benet/host_struct.h create mode 100644 trunk/drivers/staging/benet/hwlib.h create mode 100644 trunk/drivers/staging/benet/mpu.c create mode 100644 trunk/drivers/staging/benet/mpu.h create mode 100644 trunk/drivers/staging/benet/mpu_context.h create mode 100644 trunk/drivers/staging/benet/pcicfg.h create mode 100644 trunk/drivers/staging/benet/post_codes.h create mode 100644 trunk/drivers/staging/benet/regmap.h rename trunk/{arch/arm/plat-s3c24xx/include/plat => include/asm-arm/plat-s3c24xx}/regs-iis.h (100%) rename trunk/{arch/arm/plat-s3c/include/plat => include/asm-arm/plat-s3c24xx}/regs-s3c2412-iis.h (93%) delete mode 100644 trunk/include/sound/atmel-abdac.h delete mode 100644 trunk/include/sound/atmel-ac97c.h create mode 100644 trunk/include/sound/uda1341.h create mode 100644 trunk/sound/arm/sa11xx-uda1341.c delete mode 100644 trunk/sound/atmel/Kconfig delete mode 100644 trunk/sound/atmel/Makefile delete mode 100644 trunk/sound/atmel/abdac.c delete mode 100644 trunk/sound/atmel/ac97c.c delete mode 100644 trunk/sound/atmel/ac97c.h create mode 100644 trunk/sound/i2c/l3/Makefile create mode 100644 trunk/sound/i2c/l3/uda1341.c create mode 100644 trunk/sound/isa/cs423x/cs4232.c delete mode 100644 trunk/sound/soc/codecs/ak4104.c delete mode 100644 trunk/sound/soc/codecs/ak4104.h delete mode 100644 trunk/sound/soc/codecs/wm8400.c delete mode 100644 trunk/sound/soc/codecs/wm8400.h delete mode 100644 trunk/sound/soc/codecs/wm9705.c delete mode 100644 trunk/sound/soc/codecs/wm9705.h delete mode 100644 trunk/sound/soc/pxa/e740_wm9705.c delete mode 100644 trunk/sound/soc/pxa/e750_wm9705.c delete mode 100644 trunk/sound/soc/pxa/mioa701_wm9713.c delete mode 100644 trunk/sound/soc/s3c24xx/jive_wm8750.c delete mode 100644 trunk/sound/soc/s3c24xx/s3c-i2s-v2.c delete mode 100644 trunk/sound/soc/s3c24xx/s3c-i2s-v2.h delete mode 100644 trunk/sound/soc/s3c24xx/s3c64xx-i2s.c delete mode 100644 trunk/sound/soc/s3c24xx/s3c64xx-i2s.h delete mode 100644 trunk/sound/soc/soc-jack.c diff --git a/[refs] b/[refs] index 5903a6725b7f..9d700d17a243 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ae02cde7e9bc7bb4cb48b1798479889f043ba2ae +refs/heads/master: 9f5d790d1b0af8e3705df12fd5d49a1df2a45c47 diff --git a/trunk/CREDITS b/trunk/CREDITS index e8b7d36611e5..5e0736722afd 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -3738,7 +3738,7 @@ S: 93149 Nittenau S: Germany N: Gertjan van Wingerde -E: gwingerde@gmail.com +E: gwingerde@home.nl D: Ralink rt2x00 WLAN driver D: Minix V2 file-system D: Misc fixes diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index a3a83d38f96f..1462ed86d40a 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -12,8 +12,7 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ - mac80211.xml debugobjects.xml sh.xml regulator.xml \ - alsa-driver-api.xml writing-an-alsa-driver.xml + mac80211.xml debugobjects.xml sh.xml regulator.xml ### # The build process is as follows (targets): diff --git a/trunk/Documentation/filesystems/ext2.txt b/trunk/Documentation/filesystems/ext2.txt index e055acb6b2d4..23448551cabe 100644 --- a/trunk/Documentation/filesystems/ext2.txt +++ b/trunk/Documentation/filesystems/ext2.txt @@ -376,8 +376,7 @@ Implementations for: Windows 95/98/NT/2000 http://www.chrysocome.net/explore2fs Windows 95 (*) http://www.yipton.net/content.html#FSDEXT2 DOS client (*) ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/ -OS/2 (+) ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/ +OS/2 (*) ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/ RISC OS client http://www.esw-heim.tu-clausthal.de/~marco/smorbrod/IscaFS/ -(*) no longer actively developed/supported (as of Apr 2001) -(+) no longer actively developed/supported (as of Mar 2009) +(*) no longer actively developed/supported (as of Mar 2009) diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index 830bad7cce0f..a87be42f8211 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -1478,13 +1478,6 @@ of problems on the network like duplicate address or bad checksums. Normally, this should be enabled, but if the problem persists the messages can be disabled. -netdev_budget -------------- - -Maximum number of packets taken from all interfaces in one polling cycle (NAPI -poll). In one polling cycle interfaces which are registered to polling are -probed in a round-robin manner. The limit of packets in one such probe can be -set per-device via sysfs class/net//weight . netdev_max_backlog ------------------ diff --git a/trunk/Documentation/logo.gif b/trunk/Documentation/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..2eae75fecfb965f49065c680063a40c594736ee5 GIT binary patch literal 16335 zcmWk!c|6nqAOGyI4Ks7kJ-l`WUeEXOc)wiTT?l)^KpU)?Kn0W7l>r?R9$-;{Xg37E2u;Ex=Bm-OAYf|}zr`akX;6OC zziDV440N&@Ef~N~vViF5XjZBchXLg>(9HZKS`fkw4=fE}t7+D5cm&xKx-m&wVWY`p zay0`QO$5l~ATAA!#XysSpez<^jswt0Kr{(2n8dJHOd1J+MMIfP=Ej&C5f2R_0AwOS zB>_P}L4rvFg+gIcfH@9=U0cne0*oMFg@C&CLlW5ok1evItGo0f;&XCbKr5jOUmAGl5uYL6?#L(IoK85R+v9 z0s#~SL9tluWD$Z*1rPv~P5I|81eHSO^ZC&vs6enHSXpCJ|8cZNAP}9^Ns~-~NWi)2 zK<8KhK?gd?L=do0E|J ztP*;%3^B)r(rD!ZHkwI=3RWf!a8L#bx;2StDub>J0B&w14u>P)ASNeQ1YE=x8!^d3 z=;#prouC{lqO+-*UkzR1B6vLBWUX0g5_F4&5OC029CRo1ADB4+0JgXYfk3d)!T^BO zf1`g*ZAT(0ItuIRzK?`W2|J06j!KLI)P6xh0I&lX{96M2Unl@#2ly+jh1@rm-`;hN_;6Sd;xq?up^NOFDk{Lwk2c_FlznG?%+Sy7TG= zB4TwW=h5Av+eEo_r2~mT7t`&MUVwX(?obV>%EOt!WsN?--;JHUF8v^|1Tx55@@S6l zH{Jj8zGh5w-J8O=#UtnTK1pzR8bmKv7eY>kKBs+JICcMOG1mSO=IdWYj>+pbFL#sc zQAckoS|uNOrM@}Ruzas5=ZEI*z5Hi{`tpp1@-ovmL+s)#S;K3I6$IPFs$>nfhIhpc z=|9W&yRgbHyY{zSGm5tvV>CJ6Q)O47=Sj_|^*I!&Ljr6%^|8nsj9 zPq%(dSuEbOS}hkPod`hTXSSFJ@|Vg z@7cwr{m(E zCO_4Wf3dwC7xAlFruIUIHKG~L~ z$YLRSO5};`PTNPspiGJtfI!hoI zpK_|sFj09EG${FVCcA@{BF5sfop-&D2c`2Qd?u1!r^RiK7@VmN%Kq@aG~H2oc3B^9q*b*S1w8iu~4lK$e=EZ9FW69r7L+M zN)zo|7OxL=mF#(|7P?P~4BN7u6Mp8AW9o8z{mPP7_79 zF^&1XnN;Ym^fk9P$kjl0cd;?v{=8#LB_@v}{;{_}*ef+WP_G?XTQIm&wR%1@gK@F6A^MCW5mH7xB z5uAw&rnO02lhW3vhUeR2uRE<{+)duL2|uEQC^h3<4wC7axBe{g$RxN%qXZ&6AFixj zc{K+OE-B(v=HX!Zcna51iJysi!tLe0|EB#5ExLUsxbwnpQ&cs&6Z6aE!3)fHiLJRV z2|7{3Y6&H(-Jgvsp!Vk+9MzWD35KI`sqmfmC`5jA@vbi$ibBpAXcnT&tdK<{Z(&nT z5mezNr=2iK-)<4^F|7V;xTvzLpCVDf*!BH{c8U5C^&m#io_ZGX$R4$nzXRDa7YV|s zNvSFed3RiaoaOz~4%MIX`H`3gly*^iHN0*?;u=X0%QaFrwF%#qkUM&vZIb$5^gV6! zUim037t@43u|32T&zSARfH0OLhN;(m@4%z`=J$98u(I*oYHW)B%v}jO4bwH|9-#z* z>0cz^t^RyKN$;)Ym=9c)+3v84eMgA?V92}Yhw=NIw})ghuy1psWxM{vf7Ph z#`#0dmTku*&>BL@aff6%JCgPBCOX-lWIz5`s zdCs#3e&TTSB|F-W5_K)6=uI@Bg`cNGSwuijhb{7qEgC_YllZQjoAjUk!Ohte&0m-A zD6%8-a#|c!u`aIC1|V@Y)}r$2q$A@~1I%+ET{&}32$$uMOC9@JC+8*X-b|jrI~{%c ztH?o-<8$#$8K`rcoGBmF0H?0mg9->-p-Kwv3~Lc#jL(v`RFZmBBHOd4+t__&`=X2& zP8OpB-Vv$)nymq-cdpQ~%P(UuLIyTU_XIi>_iw)}8*3f*K zp7cE|?(h~^T1O|*rl|JfUN{yQ(n*$?cqL*P7zP#WcaUB{ij#12LdIon_!fiiovG*#~J1)o-0ckow~CvFabE2?_A^IyTS zK)D8?2Midt-d;$W>8M%;Ghst0A0f=&;3}qlmkblgk(-mZGbXnDvIc9i7ZzO!?bZmZ z#FC%c(=E(yy#qil(hVZ?VrTb2|FML;EMB??~^|P5h9Q_{t8dO za$|j?pd}L6FX)n}Y|BBiTU5ANPi;0T=!sQUK-h6;3*9J*Y1h6s$J_5u zCAN#QV5~X%LC#P8aL~CG*M&6o(pI7VxeT)dD(iJuZ){$jfG+Ibso2U}KL4}jw)Jq2 z*G_{R4crEITCS`6la~*b_a>wn@Bd1VS6WoiL0HTQ{g-$$4!j0Oqn>D=xClS5fj(Ut zcs@2T>4+=n2nodCp8vdzmI*_CTNYL3gD+E%quJnbGKzadd~v_{_2h&h;@O#$vq#|P zi55x1LFY@3Ci@hDP-H-EH(lCIB7&LHiWXB903&G7R-pI?8j72Rs+Bw2l${2roPbi3 zqqR>jE}u|z;UTSn%&Pd-^sJnBvAQlK#_fBvk2(M(zB>?QflxsuTg$zF_s)Cut&@p zLv53de{@&4j{@xDY32p0KTz|bLq9#GTA85)vmaHw|P zF*(rws~0{nPrYo;^O?(&BW8cxLL%JGuknud>Yx^AqTi@u7+o>>qSM1$r+@PA z5KD3`h1g4QDMH;e&cR;j@ zg0%TqhUqPsnMD2~NG=I9&fs;gOkI(wfFPMdNn~VX5iml`s0*ax<$zE=B8fv2;T?6s zqO`~&>P(o}4i`SfEW`Y|ISNNGDOs+>Ynlx=>`H_z!$e=Yqj43GeOQn+SwsyBbkVM2 zlM_PmAUlC*Cn7hsJGPsK>}CoL=pY{oL|zjwzUxg~m;!%$B5Wa$wA;{#lJe7RyY*QY zt)V6~P$XiE6-ALnjEQ1j*cb2?;R+P6HvSU&9#oDE2a~~;G*BR4xO5KGLo554U0k$P zRt_LkDbR=&pw$nx98-~avLYD0SEHihv%4g94t9?Zi^PJ|xv2d#(FfY$O>#ma0#RGn zOR`u%jRxGIh#cU;9v8vx&*eX4Ua|_l=wAf70EqapMWz@K%WBd0Bt4n?)kl|vcf9nJ z6)h!)s~qp~ky&W46&8GhC{`vwIgp_qOtEQVeAgZ55EH707l#r7Yqsz~K2TP~JaJv@ z{{2fzR3uFRzknAqM2qnSh+#j}7Ny!fwxZ<>JX231w7DX5m&8C3l0_3=G8I2YMr2_@ z2hjJk@Zz&rU{(PAE&zuMz?x){504>|XyM#B#BkC52iL{Q$@Non$xHzptsvGWK=3ae z9PZfjRUjG0e<0g;n0r9urMtwW!0KGCNIVxt{UGX17TTH+6UG9s1mIVE-01TD~B9{ z*e;mbe$RbuV5+9y53MIjlJzCD6c3mCp|IRq04;p<_c7gOSXs!$sMAk8pCgBvPtcat zI6PD81LVOxzo#|MpNbJRm%r9Cs?SwqkG!cE#_xNS5*6$z*{>c}v2jEZmB3XRo z^Srprv@=sgQ5sRy^EYtoQ#w!oLXVXYPJn1l7isf*mQxc{eiCJU z%7V|s-^C0|&c>PAazDt^epVe{L}do`fRAb|YO%9^8hy4IAW`^eq*i>b?jI}t8rT1@ zwnz3~d-s4lAJVA#z_FJGdHS3sIU{nF@;sj1!FeMR(b7>&Dsi8&{CcXZ2q*I0%q8G~ zsNs8=vp!uK65@O-Tbam?^*PiI0RTs0+v54K{@CWMf!ZuC4B&%s09ft!lU9v~Tu2Wo z-YLMUE6zuow4JGWqBbiDrRii>@WAmRsiuFmD_|OVkBlhv1mj2$M`l-z)x*n5J*3db zv%h5|FL5;`T7Lt=mH58z2T(oJmh})JtboTx_V@omv^)}0SA2NJ;5n#Tw308%L3S-O zMe((=IrF{7CI{Neol=z?v@^teiT&McobMXX)yz0dYdc8kt2e2=-CcgMCi2yIx(Qu` zfg8a6=3Gz|XU5m2oqcf3y1ADIf9W_hZz^1gcDZWc`krfXN=bfx=KN@QBFKhcqICEf z)(#LIx)|3!e0Jy6B??Na?$yuG;s3BA`BHM%hliNj@^!uvy?F26Z1GX7NTK4$Hw`;x z`Lpmw#YUaYFePE5UfS~4Ms@*)uEb+wqBeG}FZd;YtTwHOTliyMVh3+{ ziriF+EA!R5u}k8{%{qo9hoW9L4PRn9ezCmtK{#pD!^{whL>1`HoKH|BEe#jr+Sgw50?8{zAo zU11Z$H)NDqf+?AE52`+ocOk7y3Z~D!5Fa;H%$C(_lC(`d<|Je|{aDGNXm<2j!E}h= zmE+S8?&pcGJJ>h)gDw*xGl8Pk4rVj`hAx-*H(Jjf{x1~u-={H~gO6R6iPO%*vvqG? zD8Ic^BSoONKQrV*lir=KoB2FD`@H1}rbbGx>D_xJkqY$G%!_wdYn?kK-kopX2ex$@ zWxhkSzPrdAsx9y{u}5sozCCL*ud*Y)O!5}|eP_}zs(OAwrBLMW=XbHyQW>PTIx35- zI#K<>1w(166tpRzDZ7qjgG9#A`od1Am6+dxPBfefL zO(2A)x$c}WT8=WDw?zpbZvEh3D*cHIC6G|hxNoK2E-R@F6y0(=D<*tppZXz3X(bBb zM#Pe8!d&8^!S=O}N-{2QF5~nZrK`E1*{YQ*GqY#KR%t4WHa1S})&m^|!=5i*S5mkc z35NUB5EB0I-RwPC(w}6+R*P@0RWe^I+fF@H`PkRG_T>CK9B#Nzd0_Cx-1>sF7mYxb za+o;(`Kr>u6Qj?M&%f(mUn@5JytR)Ak>)Inc9LgTe;0w<7d|r?dCsqC**fsPIVGVSRPuCPDa~5e6)H_VM6NI+kP+Nna``s zDz@Smce+O6zPVMo%k`kIrd`0_usg6XM zl)2CT)wB7wQ@w8&t?fRimTxwvzS<}dDFGwVRYo&ixn~n)^4S|PhrfR|TqW)NSii*& zRBEmBcj|ER)WvFEn^%i?$a#_|bBji}Q6(x=|Gld9N2d3Bhv&C%hZ-gKZDApSl7XYRj`Nh;fc)*JuPUYJzuZ2K{QdG9%5nvj@^QyFRAAxrGLO$I_DsGQ*C z<~-nS|9qg?Idkw^ zq-(UNn|Z_At{WEbZLdCyOuo4aF?4cCfWES{B1DID7s!jgT8Pwfdw$07@ZfXtk^YyL zY}0m>MGQ`a*?Y+tCzl`Cbg0N*=ZWP8|5$sTx@Yu-uD_Y?@Gn~3$*3P@tK(e-zePm` z_Fd`3#MouGraXE_{Yp&hM&wIttXESNDdE{Z-{-|I-cGSLLk><3&%PADcUs@Is6-=n z**0#%`)&2aQ_%eu24ADdumYNs-jc1C{;+L%OR~oDAn`iR%J;|bA=HlB33b9K)Bx{P zopxOlIhmMgf$8=C+}Bz+Q&p>JV`x*?8wQDH!!<>s$CS_Y5jD=_o8&ClG$i~GdJ;h zaI~ix(xN`zOjbM9m(<|?1ldSc{c3EuM6mx-8bNohiP8RN1q!e8$( z*S2@^X)vM~zR^~B)bxEY@Ll5r^Fp`&xYx7g9?}MP@wxFa17{zm;ka)bI~W}&KDRuY zTS!VgJL7b%P;a9;}UZpl+t1LUkE1 zcGMbPZ%FspHJg#p6PLD7mp<}b%dJ&IEE9%eE3JN(rbbM<=4A+j2CG)0y^KUDSy@$Jf~PIaANH`U=C&fS-n zaE`>}Ah|zK!pkMky7;X(v)koAxg!9c2A0kpTf6iWT3<-ll^_MXxUhv+d-t;RgRhxK zv`gJ`B6@MJK(#TlE?km&wyEUst{_LnEAVW6s1hQ3K@|&iPJcA@7Mw$ntRNd{p8ynq z6kZ3u>5Ce-O!!)cPM2;LPUrF?^)U8In|NOWKJ{6;S39P2wzwhxKb;|ijUs15FK?54 ztgF&VNhy;LUkd$|P-$B%#|7Oi$3v++r99~_?dE#x{SNA)vs*o<%uWZU9C83hcLy}xy=?HzFObHR8j?~mUL{%MOYg`Sx?^a!G39vZ zrN;~0<`dl`_RSSXcK_$27B#YR{9LH!f$KPg#n#+4c4@D%{>SGQCI3=$AZj$rR5UOn zO!QWMwT*Jqi_8PN44S39wI0blwSLwnwvZp`5RfuRu58-@wqx@c*TW& zZ|K5CqE5b!6KZOuXFj?Ig?R;6>sq;1sF#pYccQ~2zy{s+pmlMj12jX0(j0()*8eodt+kLC+n9M#&42mOIRZ{gEbp@z@wJJP;OZRn*>DhJXJE?e9-^r--Kw=~)!9h*cg%B1TL&Az&xm;(4 z|8_62^kj)=-3QxH^O@1>BPath7#_aCS+dQLD(BR~j1=DhO|Mnle8EEr2W& z_2C*M8SfPmI$qHhGJ7*jHQXW;)#RO}CQciQySM{PIx46hsXr5!AAHVfE~cKfo>SG) zq5zxZfeK;x&@h1UqsXN&@9Tzn=pw+9d)B0kKNh!lfx%Hnt#7TJ706F}9;3cEiV`5P z)7ASA>1r#W@M$%m@Tu^pFVtEMEIG(xc0#rNH{I*s2OmH+^O^iCl{N%1KUj*yX&>J1 zbu0%j1A85tLj{7$PsoE3Z)DXQbbR)-x2Ox11e3}cL}|paXon{UhCyzbRUNxR{{kJr z0IMhJvs#pf)TGMlIK1HK-lO22=AO|4h?Kv_sR*< z%bFj!0|FbF`*y!5bhrxzh*7i@N&Mc`(Q|M;Tn^KJvU~03X(gfkp^M}MS{sgO+J8pw zep;|sk-8_;S(4#^r+>Nlu_!fXYwS0 z@rWe|Ue!8)xlykk!&G>ucFXc*jeVLWQCi)1(wWdcj0g-=ju+qJc05uO)2sf=4Hz^@ zN?H5VFFCs++y0sS5Uh6n^p2Ox`G?u`n)+DhqcrFm?~KeoW}yo+_1&L@>&BHnIUfGc zzJUl9X@oR;B!PskG@B*8UOzPch4cMLP>0FLmb38kmAn4EATM@{wIke=Yeyu2 zJysxcRlEyLuEY6Z!97MA}L97byab=@H6szZnCtrs8*=$wS%}be+ z{cMtG@cjgs*62=-$~3rUZ(GSE{J0Jf&4%kS8&D5gE3IH&L9oMAu!O)?yaepXfPreW zU812;q^wQLr#fzF$zO#I)3Rh4uxzXLIEtM#3;t8&nN`U1{!jRd=LQOVIJN9Ke-0%* z>8J;7-&hW1&v}EYA zGVFj1jcTxinNx7-ORW}DML%Q6+4g=*nrNBBDR#SLM(cGtbaf@yxZDtu-gZXN86T7t zJ=yApg-CE|$0X5YB8*`DFoN6_m|=g8n7#VQAf&w1)*2jL25vk{h{1N^O1r=(>-%@E zzjTRrl6Yj0#7G115Ix+*oUdXoIxp6~<(07tWuUhGjoD|oyf_Xlp))g?nS~7k3*+g^ z9Qu6+SOh6un~@bbml21DP>I=Pwb?k{V;t4>^o-=0HQ>yQ^X6y|V$Std$itlemM4BM zR`s7!$U>%DPIPeAfBjcii*iL`~D?rSHRM%@?I9lOemv z=>b8#5j2Q29+F?1o!kUJ$O$Q`w4 zY2GV8;~;BVMzupCQq31(=6gM3wTM?A)V8n1?Ie*NTa*<~6(UhGb^=(L538ZO_+SZQ zmbrB9aUv`^2<*YkIuMlUT-LIi1%sHupQrYa_ohLtP>$3z+ciKE$V37{q_Q+|MwU2w z01jj%jdA0Mpagt2>rF%W#?#7tI~7s$-WFPhb;l@|9$Q&>uiE2Q6>!}Qp1^_?48Q__ z%zx!1;~PS;RIoW73dN)={(;F6VRBnABpwDQLt?Scu>zsy)XWGzFP7+e^4}&w>FHnX zS)itAYym_f$XEcDW`gy2fESP<^J36+tVb#UEnZvU*3ojPdE~X4ye4J_EjD<{YRbdoXSeCjY|EVT>0?9sXfDyt`i!M6od|F_-+L(f&_+ zT$Ff%HTGuT` zwQ%!H*ZepqaEQNEN6^7jqhHzz(L8x=*hjt%yi%*iDlR^LPB#J+kl#QUel$;h-U)Vob+DB%4 zosJGJi}EFKvcidhqoFW&s+TQh+~@t2xLdk7H?#BHU=)xcTodrLb~5zjfD_WBnFecg zoJ8PJ^$D#==1<(6QQk-FY^zeE<06u6b*x`Hso$5KqV=mp;(&%?ZAbK%;Q75Cm9>GSZ5r z@YjAS;j!zXYSPKwfdpzg_i|Q5+0^gU%=Tk%KRrJ5sq5|9_@U2Ebn}9`?ePY*qAesO zPqz%55fJp_@+2ek@LfYUFGZINp-q$L4*q>L$<*gr=cS3d+3GR;UxLA~*rCBtdvV_D z2r2|#zmpZtce9)G3u8@PcRsLo?5*fTcy&$afx0aFfHxm1IUh<)MX*C(ZF02%3uY)J z0pry@wi|VMae8{PscSx|iu0v*@$oC`-Z5xWQJWsJAUrHXef`#}q@h(TD0&MTN(wwh zgB)c<5@_LVo9V*0g0DXgA6;4!ewEekKRxW^SrPhV5^S!d9A@gWSV;5+IzF`uA1|a}(%Hj22q09Z(5p5yPZ{5YY8N!?C@I&c{ ztOf3SzZkc-b=6Y|A3lgr@P_|{YgX5FA-%13TvZ%%2amaDzwr5e&PrLa6K7{Ov%l%@spkr^5qX-9K^v30Em_jD z5?I1YL5W8Wj((c@4}6AjW;mfJ`Y5mOL2Fjt+gNU9`h)$Wb4~pzM$4RurX2+>TU1kR zB_~5hsE>>rD%N5b%HTH{%AR}@Vaqi7<>c=OK zJ{|rL_jr>XJQ3%azF%^EIJldmBRKq2YVD$AeJXxs-F;>6KB2B3LgGR00ZhKT`5~{% zR$04WfBX>(KN?h42R8;nxgT%$4*tMICPhj-UpetKpa2?2+>LY~+|_l#gCPwl{VKc=iJ4G(7| z!c|}GtD}V6?46JN!ZC`meiQb%YuC3>1hFg)$qeZ190y5K0~Jd_ zKYkFO8+j|jr?|F9x>g84w(vazx;Y~Q;S3?o?R)p4>h_jtM%WhvF%^Cgupeq1ov5?OuncbA#sZ^~U~_+Ea7C_c?Q-(Q!HwnwB> z(d!eSEHgSF_LBaq&7WxGQ}Z;ZGWS@KdlrERdD(SWKj7b<)L7?izFRbCk}K zI19r*EADSE+~k{xF?$g$5#ogRzmIO}P1GKElK6RNb@RdN)bO5Zy*48!+~LB?7rv*~ z${xjz4-7v(`cvB{11^5VU|K>wGZR&#ImZ0@{&2Rk35*|XsxwrGyZh(b{gNn~!dx56 z=IG($4%Iexww^&{Ot0H_W3s$ruh07?fee)KjagDUUgVVT>z}PYP0smxe${FJAZ0`< zX;juvuDdRGa#(b>f{IN zaEa~DsWH-_t$@4XUQ;sTfv(tdE{EMP1ui~bJH{0j0WiIW@T&)ZgWRja=VkoW9b`?i zifwQ2o~n$UcCYr^>)9p+_{TYMdo`~*ZE2Q;d^WA1sADOJ-M6b7c=}WElvj%5WhOVz zBIKJCBHV4VB8!Qeoxw#JvqICiRMZ};linA&jHqhgyDMpd6X}cePJO?r?FhLZC{_7I z2&3YZop>PJX4@bNW*MkO^@NU8OKR1UOZLoLAfxSJyB`o5J+rZWG6!wknI~Vfd=xU5 zybGeHr*qBc<%4oiLP3}mIU(~B_ZrX3k}|a%i^&|b*zTn`yMs$>o(8*~`W4>03=5&( ztNiYHWi?XZuGp~p=1tk7k|+^S1jeCYN1bD^c*Sh+)o$h6zYX^U9W@i`E-Ljk_n$5< zGgmy8ms#ka+f1|eaISu*J{{@oB<$RlD`mH5uD?PdN%{1JR>X~aBfW7>X|E}XPKpQD ztjq$7w)WmZSZ?H{o6s{1NY8@pdKYxJKTGS+*3YUZ7=4B$~-USO{MCUGRW*YMlv!=8mg znPmg+JMc$MVvCPQ^X^=?Ja}Kg{l0^=7D*ei$0ZVMlU^2kN9SU06xsJ4xZg4|v)lLi zlhPuqsm0}+3kO{jXt#@>*I$s6G8Wru92yk%XgEB2Xs?oaQBn0LFH=2_uT0?%BD7=Aa0RL%yj?yr zrdz{c^hS80Yu)XE0d1vU*DKaeSp9jGfLoQALYw%hzv^_;$!;G7u6F5u#gf$iyEfHC z&{S=8bG1CORry^SiU=ijppVho;Zd3nySmcO+K|(Y`Lvv<77fM0`Ow{I0r#~|FX!OF zv+Mh>Jj-7*JYc@d`J#)jVl9 z!b5nZz`JWfS&KgA<|;d!{3Il2xjg9R^Hc4O46t-9T}H&W z$K+5$t~PI8#FQ3wyw85`1+i?nB-zoh&R<-|IDV+o@*T{jcQ^}pm7{8+KC=uEtXH!F}<-bvUqf0 zW$lin)gPOqPLA7oGCoVVBPz$e*TAze+fJ%nVz-LSQkLgyiWpS|f@ZRW6wgqE{1`%# zc3mEO%CKX+r!5V1(j=M!SVS z&=?}8|E#=0?0KReF6p6_d8dH~aXYczbc|6-mJFe53$*lip6c>JTX@E( zfl%ZcS<0CTRw$_w`JfXYHmvR)w(E}XjHGC;uUBadry?STmE9x%{`SS1ul@h^)(jsi z+gm--;EL6)4*u*oOc(Zy+RVfmpE&2fSLN^QLaVw0hvkgJ0WgUfY+`P5p3`vLoi*!LQ4>uc?&$;rQL}LVY>xh>K;F%r;sOOpDSW;vwAzy0Zm) z2r;7gF=+68SVwgdPs`GHTxZ~lezet_YnW+gtdu*v;;#F?xG&x|Q#&R_bY$h1UC)Nw zY@SjyWOS2?^!%W|W;#tj<3`EayYcSw_wIwTVGq7RVuGA;xp){jC}_?F-hg5>q)EcU zp0|2pmJ9RAquc;n&beJhYmU4#wSG2+9B9w!0lVU;4vzb)ZYw9-Z(mkhhRZv47A<>T z6`Z)C;hTJK^wQ@PUx&2Fms#$rPL;IRU-T3#wtomIj^VSESLRj< z-)?ZsAc5Km*33u4MTIkx3GAbLS3hzkEYZmguh(VDshLw(!$OHIn!ML!HO55i(`8Bm zukF2M{E&zf#>YCzzJeN%c~&fD(*ND>BaRYFSeS&_&ew^H<*53&bj?VFT*vt?5h<;! zmO_16=R@8d8rlB#yyHjJ;vj(AGfYozirAbu5A0n1N{d>#AkUn8`RVD~^qN-}$KOtW zeEXs4W+;=$x$JpYxh%OQkJiOVkrq1ixjdcTKJNqG*d(fk+7BPRjqu{>?x2bC8-RSI z1JSwTz08}GS-Bjh%PD3SJ+pfjl=ItUj$?wA;l6{EwoBJKSg~&Xojq)}q^e_06uCD2 z-`{uo0ugDg@mLuq=sZHSc;<=lYs+!RbpbqC$y?np#Ahs>^`h&Ob2@t40T}3+=yQPe_(~Mle@=fzvXut$nrL;fpF3p^Tr zi6rrbi;DVwQNpTX)V>(rmY?v_1==lC?5#?<1lbCCc?Y>B2b^^qdgS)r#ziZabnola z+Jja9y;_vIb@0a6+iX?`@5G?JbAMxbUJV){H<7NlK7JwwYt)o(+YXlX5n2iAQr!{SMiu{Q$~rhQN{sq}vp#Y}YW=XU^84($ z;o@E~x`AYX`Lyjq#Jzh*tk%MDY><2gQJlar+D%SC;QHv21l)uXJVf<^9WIe>vcy-4Fe zx@;|Xqd@bnf-c>E z*RIVzB9}o_T#J2Z6fbd^hGEbl@eT;YgWR{(UCmkm<{ zomXEnOwyOffC)UJ6qbg;)96OB9a*!r{)hwhG$mfUq_loZvt!8MgP%3%8w8Dqj3Iru zwEsYBR(kDvV`)aVbhQi`W1@CkwisevtK??T)eP=J#Wl$4Ymzz|)9yxYMv9zple%-v zjNA?<+}^(pj%?mJqHjPqkftN!(_}Y5i+k?93^mNj%{(T_6^U+BD{9lkwLe#n6^?W8g}}Xzjf3l#3p-`l5KMlX5s#ju;=n$C3^&k`>jG}vS@Wu2 zENZQST~{zl1*qM1Mn}Lk&Fy_2G_eh$JVSpIG!vA%-oB~_V$fyXfT3pz>NDV$ZHL9~ zYd!t#RAo z5jZygzD8eSTwLyPeN0;5G*K#=4iNwtC*87~%wIq5(|2)E*p+z~2Q4N2G2btdm3l^m zcB`F40W5D>FZH1@uKj$U17d)4S6QQ!ZaO6@aSSn4sz8-HMyU=cRh$aVg$IY z8Z{sJ0;5O($3YJPu%9YS>5ItAd-N*+$nzdjsb0ol#mLKe3|2R~qoly88MQTZ@C6Gi zwyU|RN*XlC4;9iB(lP9gj&}U2@7g|vd)-G2A`?F~_{M&@6)mwRr&At z>DR%~HLghQ1A`?kp>z|Bahzdvje2#&Bd^4k)o_*g1Vlba64`;h@NKQ!0UO#T!)QYq zB(4rV>{<`kvbNV>{CYm&u9`u$@eiU@K3(GMHG0~va)p(pH2`d8FMY{ge+jg+QCKIV zu_Sa@U`TSrEwyc_q>1H&c9ohKAAV$q)`Eu8A)MoiP&T{oVebC5*D!(FS_2aLP&My? z<0?&;Y?@Pf{0AKbj<%N$T#~kObTlY}a$K-u+*j~nv zOdV31926ae2{Z_oEtWy_Rt1ybkHw(J1>qZS!Mj}FY%tC@IgPZTJnzX)5}oU7W!UyA z#FGIbbQ#1~%zw*?IUuOc<9(m*)2@8;y4a@0qaO%qQrh4;$Bnjme*Y)47`41p)^D`j z^0+eCUErq2Vr3itKh>T0(wx84VQ3%>((%{yDTk_0x}}Yw8eGfSB^AmM9!bpV6c zg`gqZM$N~(wf!!cLqb7Nb_dqlKzxH9sv$t>qzFU7yQEW2ulYPv-<912+d58@^GU;qFB literal 0 HcmV?d00001 diff --git a/trunk/Documentation/logo.svg b/trunk/Documentation/logo.svg deleted file mode 100644 index cb9e4851d8c3..000000000000 --- a/trunk/Documentation/logo.svg +++ /dev/null @@ -1,2911 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Documentation/logo.txt b/trunk/Documentation/logo.txt index a2e62445e28e..296f0f7f67eb 100644 --- a/trunk/Documentation/logo.txt +++ b/trunk/Documentation/logo.txt @@ -1,4 +1,13 @@ -Tux is taking a three month sabbatical to work as a barber, so Tuz is -standing in. He's taken pains to ensure you'll hardly notice. +This is the full-colour version of the currently unofficial Linux logo +("currently unofficial" just means that there has been no paperwork and +that I have not really announced it yet). It was created by Larry Ewing, +and is freely usable as long as you acknowledge Larry as the original +artist. + +Note that there are black-and-white versions of this available that +scale down to smaller sizes and are better for letterheads or whatever +you want to use it for: for the full range of logos take a look at +Larry's web-page: + + http://www.isc.tamu.edu/~lewing/linux/ -Image by Andrew McGown and Josh Bush. Image is licensed CC BY-SA. diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 57fe4f3ca2c0..841a9365d5fd 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -346,9 +346,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. sbirq - IRQ # for CMI8330 chip (SB16) sbdma8 - 8bit DMA # for CMI8330 chip (SB16) sbdma16 - 16bit DMA # for CMI8330 chip (SB16) - fmport - (optional) OPL3 I/O port - mpuport - (optional) MPU401 I/O port - mpuirq - (optional) MPU401 irq # This module supports multiple cards and autoprobe. @@ -391,11 +388,34 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. + Module snd-cs4232 + ----------------- + + Module for sound cards based on CS4232/CS4232A ISA chips. + + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + + port - port # for CS4232 chip (PnP setup - 0x534) + cport - control port # for CS4232 chip (PnP setup - 0x120,0x210,0xf00) + mpu_port - port # for MPU-401 UART (PnP setup - 0x300), -1 = disable + fm_port - FM port # for CS4232 chip (PnP setup - 0x388), -1 = disable + irq - IRQ # for CS4232 chip (5,7,9,11,12,15) + mpu_irq - IRQ # for MPU-401 UART (9,11,12,15) + dma1 - first DMA # for CS4232 chip (0,1,3) + dma2 - second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable + + This module supports multiple cards. This module does not support autoprobe + (if ISA PnP is not used) thus main port must be specified!!! Other ports are + optional. + + The power-management is supported. + Module snd-cs4236 ----------------- - Module for sound cards based on CS4232/CS4232A, - CS4235/CS4236/CS4236B/CS4237B/ + Module for sound cards based on CS4235/CS4236/CS4236B/CS4237B/ CS4238B/CS4239 ISA chips. isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) @@ -417,9 +437,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. - This module is aliased as snd-cs4232 since it provides the old - snd-cs4232 functionality, too. - Module snd-cs4281 ----------------- @@ -589,7 +606,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for ESS AudioDrive ES-1688 and ES-688 sound cards. port - port # for ES-1688 chip (0x220,0x240,0x260) - fm_port - port # for OPL3 (option; share the same port as default) mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default) irq - IRQ # for ES-1688 chip (5,7,9,10) mpu_irq - IRQ # for MPU-401 port (5,7,9,10) diff --git a/trunk/Documentation/DocBook/alsa-driver-api.tmpl b/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl similarity index 87% rename from trunk/Documentation/DocBook/alsa-driver-api.tmpl rename to trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl index 0230a96f0564..9d644f7e241e 100644 --- a/trunk/Documentation/DocBook/alsa-driver-api.tmpl +++ b/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl @@ -1,11 +1,11 @@ - - + + + + - The ALSA Driver API @@ -35,8 +35,6 @@ - - Management of Cards and Devices Card Management !Esound/core/init.c @@ -73,10 +71,6 @@ !Esound/pci/ac97/ac97_codec.c !Esound/pci/ac97/ac97_pcm.c - Virtual Master Control API -!Esound/core/vmaster.c -!Iinclude/sound/control.h - MIDI API Raw MIDI API @@ -94,9 +88,6 @@ Miscellaneous Functions Hardware-Dependent Devices API !Esound/core/hwdep.c - - Jack Abstraction Layer API -!Esound/core/jack.c ISA DMA Helpers !Esound/core/isadma.c diff --git a/trunk/Documentation/DocBook/writing-an-alsa-driver.tmpl b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl similarity index 99% rename from trunk/Documentation/DocBook/writing-an-alsa-driver.tmpl rename to trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index 46b08fef3744..87a7c07ab658 100644 --- a/trunk/Documentation/DocBook/writing-an-alsa-driver.tmpl +++ b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -1,11 +1,11 @@ - - + + + + - Writing an ALSA Driver @@ -492,9 +492,9 @@ } /* (2) */ - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; /* (3) */ err = snd_mychip_create(card, pci, &chip); @@ -590,9 +590,8 @@ @@ -810,28 +809,26 @@ As mentioned above, to create a card instance, call - snd_card_create(). + snd_card_new(). - The function takes five arguments, the card-index number, the + The function takes four arguments, the card-index number, the id string, the module pointer (usually THIS_MODULE), - the size of extra-data space, and the pointer to return the - card instance. The extra_size argument is used to + and the size of extra-data space. The last argument is used to allocate card->private_data for the chip-specific data. Note that these data - are allocated by snd_card_create(). + are allocated by snd_card_new(). @@ -918,16 +915,15 @@
- 1. Allocating via <function>snd_card_create()</function>. + 1. Allocating via <function>snd_card_new()</function>. As mentioned above, you can pass the extra-data-length - to the 4th argument of snd_card_create(), i.e. + to the 4th argument of snd_card_new(), i.e. @@ -956,8 +952,8 @@ After allocating a card instance via - snd_card_create() (with - 0 on the 4th arg), call + snd_card_new() (with + NULL on the 4th arg), call kzalloc(). @@ -965,7 +961,7 @@ @@ -5754,9 +5750,8 @@ struct _snd_pcm_runtime { .... struct snd_card *card; struct mychip *chip; - int err; .... - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); + card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL); .... chip = kzalloc(sizeof(*chip), GFP_KERNEL); .... @@ -5768,7 +5763,7 @@ struct _snd_pcm_runtime { When you created the chip data with - snd_card_create(), it's anyway accessible + snd_card_new(), it's anyway accessible via private_data field. @@ -5780,10 +5775,9 @@ struct _snd_pcm_runtime { .... struct snd_card *card; struct mychip *chip; - int err; .... - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct mychip), &card); + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct mychip)); .... chip = card->private_data; .... diff --git a/trunk/Documentation/sound/alsa/soc/dapm.txt b/trunk/Documentation/sound/alsa/soc/dapm.txt index 9e6763264a2e..46f9684d0b29 100644 --- a/trunk/Documentation/sound/alsa/soc/dapm.txt +++ b/trunk/Documentation/sound/alsa/soc/dapm.txt @@ -116,9 +116,6 @@ 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)), -If you dont want the mixer elements prefixed with the name of the mixer widget, -you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same -as for SND_SOC_DAPM_MIXER. 2.3 Platform/Machine domain Widgets ----------------------------------- diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 5d460c9d1c2c..61aeb5aae244 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3350,8 +3350,10 @@ S: Maintained PARISC ARCHITECTURE P: Kyle McMartin M: kyle@mcmartin.ca -P: Helge Deller -M: deller@gmx.de +P: Matthew Wilcox +M: matthew@wil.cx +P: Grant Grundler +M: grundler@parisc-linux.org L: linux-parisc@vger.kernel.org W: http://www.parisc-linux.org/ T: git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git @@ -3876,15 +3878,6 @@ L: linux-ide@vger.kernel.org T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git S: Supported -SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER -P: Sathya Perla -M: sathyap@serverengines.com -P: Subbu Seetharaman -M: subbus@serverengines.com -L: netdev@vger.kernel.org -W: http://www.serverengines.com -S: Supported - SFC NETWORK DRIVER P: Steve Hodgson P: Ben Hutchings diff --git a/trunk/Makefile b/trunk/Makefile index 1ab3ebfc9091..2e2f4a4324af 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,8 +1,8 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 29 -EXTRAVERSION = -NAME = Temporary Tasmanian Devil +EXTRAVERSION = -rc8 +NAME = Erotic Pickled Herring # *DOCUMENTATION* # To see a list of typical targets execute "make help" @@ -566,12 +566,6 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) # disable pointer signed / unsigned warnings in gcc 4.0 KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,) -# disable invalid "can't wrap" optimzations for signed / pointers -KBUILD_CFLAGS += $(call cc-option,-fwrapv) - -# revert to pre-gcc-4.4 behaviour of .eh_frame -KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) - # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments # But warn user when we do so warn-assign = \ diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index 159d0416f270..49a6ba926c2b 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -111,7 +111,6 @@ ENTRY(mcount) .globl mcount_call mcount_call: bl ftrace_stub - ldr lr, [fp, #-4] @ restore lr ldmia sp!, {r0-r3, pc} ENTRY(ftrace_caller) @@ -123,7 +122,6 @@ ENTRY(ftrace_caller) .globl ftrace_call ftrace_call: bl ftrace_stub - ldr lr, [fp, #-4] @ restore lr ldmia sp!, {r0-r3, pc} #else @@ -135,7 +133,6 @@ ENTRY(mcount) adr r0, ftrace_stub cmp r0, r2 bne trace - ldr lr, [fp, #-4] @ restore lr ldmia sp!, {r0-r3, pc} trace: @@ -144,7 +141,6 @@ trace: sub r0, r0, #MCOUNT_INSN_SIZE mov lr, pc mov pc, r2 - mov lr, r1 @ restore lr ldmia sp!, {r0-r3, pc} #endif /* CONFIG_DYNAMIC_FTRACE */ diff --git a/trunk/arch/arm/kernel/fiq.c b/trunk/arch/arm/kernel/fiq.c index 6ff7919613d7..36f81d967979 100644 --- a/trunk/arch/arm/kernel/fiq.c +++ b/trunk/arch/arm/kernel/fiq.c @@ -88,7 +88,7 @@ void set_fiq_handler(void *start, unsigned int length) * disable irqs for the duration. Note - these functions are almost * entirely coded in assembly. */ -void __naked set_fiq_regs(struct pt_regs *regs) +void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs) { register unsigned long tmp; asm volatile ( @@ -106,7 +106,7 @@ void __naked set_fiq_regs(struct pt_regs *regs) : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); } -void __naked get_fiq_regs(struct pt_regs *regs) +void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs) { register unsigned long tmp; asm volatile ( diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/platform.h b/trunk/arch/arm/mach-ep93xx/include/mach/platform.h index 05f0f4f2f3ce..88f7e88f152f 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/platform.h @@ -4,8 +4,6 @@ #ifndef __ASSEMBLY__ -struct i2c_board_info; - struct ep93xx_eth_data { unsigned char dev_addr[6]; diff --git a/trunk/arch/arm/mach-mx1/devices.c b/trunk/arch/arm/mach-mx1/devices.c index a95644193f3f..686d8d2dbb24 100644 --- a/trunk/arch/arm/mach-mx1/devices.c +++ b/trunk/arch/arm/mach-mx1/devices.c @@ -23,8 +23,6 @@ #include #include #include - -#include #include static struct resource imx_csi_resources[] = { diff --git a/trunk/arch/arm/mach-mx1/mx1ads.c b/trunk/arch/arm/mach-mx1/mx1ads.c index 3200cf60e384..2e4b185fe4a9 100644 --- a/trunk/arch/arm/mach-mx1/mx1ads.c +++ b/trunk/arch/arm/mach-mx1/mx1ads.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-omap2/board-omap3beagle.c b/trunk/arch/arm/mach-omap2/board-omap3beagle.c index e39cd2c46cfa..38c88fbe658d 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3beagle.c +++ b/trunk/arch/arm/mach-omap2/board-omap3beagle.c @@ -178,9 +178,7 @@ static int __init omap3_beagle_i2c_init(void) #ifdef CONFIG_I2C2_OMAP_BEAGLE omap_register_i2c_bus(2, 400, NULL, 0); #endif - /* Bus 3 is attached to the DVI port where devices like the pico DLP - * projector don't work reliably with 400kHz */ - omap_register_i2c_bus(3, 100, NULL, 0); + omap_register_i2c_bus(3, 400, NULL, 0); return 0; } diff --git a/trunk/arch/arm/mach-orion5x/common.c b/trunk/arch/arm/mach-orion5x/common.c index 8a0e49d84256..0a623379789f 100644 --- a/trunk/arch/arm/mach-orion5x/common.c +++ b/trunk/arch/arm/mach-orion5x/common.c @@ -431,10 +431,6 @@ void __init orion5x_uart1_init(void) /***************************************************************************** * XOR engine ****************************************************************************/ -struct mv_xor_platform_shared_data orion5x_xor_shared_data = { - .dram = &orion5x_mbus_dram_info, -}; - static struct resource orion5x_xor_shared_resources[] = { { .name = "xor low", @@ -452,9 +448,6 @@ static struct resource orion5x_xor_shared_resources[] = { static struct platform_device orion5x_xor_shared = { .name = MV_XOR_SHARED_NAME, .id = 0, - .dev = { - .platform_data = &orion5x_xor_shared_data, - }, .num_resources = ARRAY_SIZE(orion5x_xor_shared_resources), .resource = orion5x_xor_shared_resources, }; diff --git a/trunk/arch/arm/mach-pxa/e740.c b/trunk/arch/arm/mach-pxa/e740.c index a6fff782e7a8..6d48e00f4f0b 100644 --- a/trunk/arch/arm/mach-pxa/e740.c +++ b/trunk/arch/arm/mach-pxa/e740.c @@ -135,11 +135,6 @@ static unsigned long e740_pin_config[] __initdata = { /* IrDA */ GPIO38_GPIO | MFP_LPM_DRIVE_HIGH, - /* Audio power control */ - GPIO16_GPIO, /* AC97 codec AVDD2 supply (analogue power) */ - GPIO40_GPIO, /* Mic amp power */ - GPIO41_GPIO, /* Headphone amp power */ - /* PC Card */ GPIO8_GPIO, /* CD0 */ GPIO44_GPIO, /* CD1 */ diff --git a/trunk/arch/arm/mach-pxa/e750.c b/trunk/arch/arm/mach-pxa/e750.c index 665066fd280e..be1ab8edb973 100644 --- a/trunk/arch/arm/mach-pxa/e750.c +++ b/trunk/arch/arm/mach-pxa/e750.c @@ -133,11 +133,6 @@ static unsigned long e750_pin_config[] __initdata = { /* IrDA */ GPIO38_GPIO | MFP_LPM_DRIVE_HIGH, - /* Audio power control */ - GPIO4_GPIO, /* Headphone amp power */ - GPIO7_GPIO, /* Speaker amp power */ - GPIO37_GPIO, /* Headphone detect */ - /* PC Card */ GPIO8_GPIO, /* CD0 */ GPIO44_GPIO, /* CD1 */ diff --git a/trunk/arch/arm/mach-pxa/h5000.c b/trunk/arch/arm/mach-pxa/h5000.c index 295ec413d804..da6e4422c0f3 100644 --- a/trunk/arch/arm/mach-pxa/h5000.c +++ b/trunk/arch/arm/mach-pxa/h5000.c @@ -153,13 +153,6 @@ static unsigned long h5000_pin_config[] __initdata = { GPIO23_SSP1_SCLK, GPIO25_SSP1_TXD, GPIO26_SSP1_RXD, - - /* I2S */ - GPIO28_I2S_BITCLK_OUT, - GPIO29_I2S_SDATA_IN, - GPIO30_I2S_SDATA_OUT, - GPIO31_I2S_SYNC, - GPIO32_I2S_SYSCLK, }; /* diff --git a/trunk/arch/arm/mach-pxa/include/mach/eseries-gpio.h b/trunk/arch/arm/mach-pxa/include/mach/eseries-gpio.h index f3e5509820d7..efbd2aa9ecec 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/eseries-gpio.h +++ b/trunk/arch/arm/mach-pxa/include/mach/eseries-gpio.h @@ -45,21 +45,6 @@ /* e7xx IrDA power control */ #define GPIO_E7XX_IR_OFF 38 -/* e740 audio control GPIOs */ -#define GPIO_E740_WM9705_nAVDD2 16 -#define GPIO_E740_MIC_ON 40 -#define GPIO_E740_AMP_ON 41 - -/* e750 audio control GPIOs */ -#define GPIO_E750_HP_AMP_OFF 4 -#define GPIO_E750_SPK_AMP_OFF 7 -#define GPIO_E750_HP_DETECT 37 - -/* e800 audio control GPIOs */ -#define GPIO_E800_HP_DETECT 81 -#define GPIO_E800_HP_AMP_OFF 82 -#define GPIO_E800_SPK_AMP_ON 83 - /* ASIC related GPIOs */ #define GPIO_ESERIES_TMIO_IRQ 5 #define GPIO_ESERIES_TMIO_PCLR 19 diff --git a/trunk/arch/arm/mach-pxa/include/mach/regs-ssp.h b/trunk/arch/arm/mach-pxa/include/mach/regs-ssp.h index 018f6d65b57b..cf31986f6f05 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/regs-ssp.h +++ b/trunk/arch/arm/mach-pxa/include/mach/regs-ssp.h @@ -50,7 +50,7 @@ #define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */ #define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */ #define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ -#define SSCR0_ACS (1 << 30) /* Audio clock select */ +#define SSCR0_ADC (1 << 30) /* Audio clock select */ #define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ #endif @@ -109,11 +109,6 @@ #define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ #define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ -#if defined(CONFIG_PXA3xx) -#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */ -#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */ -#endif - #define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ #define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ #define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ diff --git a/trunk/arch/arm/mach-pxa/spitz.c b/trunk/arch/arm/mach-pxa/spitz.c index 0d62d311d41a..6d447c9ce8ab 100644 --- a/trunk/arch/arm/mach-pxa/spitz.c +++ b/trunk/arch/arm/mach-pxa/spitz.c @@ -105,12 +105,6 @@ static unsigned long spitz_pin_config[] __initdata = { GPIO57_nIOIS16, GPIO104_PSKTSEL, - /* I2S */ - GPIO28_I2S_BITCLK_OUT, - GPIO29_I2S_SDATA_IN, - GPIO30_I2S_SDATA_OUT, - GPIO31_I2S_SYNC, - /* MMC */ GPIO32_MMC_CLK, GPIO112_MMC_CMD, diff --git a/trunk/arch/arm/mach-s3c2410/dma.c b/trunk/arch/arm/mach-s3c2410/dma.c index 440c014e24b3..552b4c778fdc 100644 --- a/trunk/arch/arm/mach-s3c2410/dma.c +++ b/trunk/arch/arm/mach-s3c2410/dma.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = { diff --git a/trunk/arch/arm/plat-s3c/include/plat/audio.h b/trunk/arch/arm/mach-s3c2410/include/mach/audio.h similarity index 100% rename from trunk/arch/arm/plat-s3c/include/plat/audio.h rename to trunk/arch/arm/mach-s3c2410/include/mach/audio.h diff --git a/trunk/arch/arm/mach-s3c2412/dma.c b/trunk/arch/arm/mach-s3c2412/dma.c index 9e3478506c6f..919856c9433f 100644 --- a/trunk/arch/arm/mach-s3c2412/dma.c +++ b/trunk/arch/arm/mach-s3c2412/dma.c @@ -29,8 +29,8 @@ #include #include #include -#include -#include +#include +#include #include #define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID } diff --git a/trunk/arch/arm/mach-s3c2440/dma.c b/trunk/arch/arm/mach-s3c2440/dma.c index 69b6cf34df47..5b5ee0b8f4e0 100644 --- a/trunk/arch/arm/mach-s3c2440/dma.c +++ b/trunk/arch/arm/mach-s3c2440/dma.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = { diff --git a/trunk/arch/arm/mach-s3c2443/dma.c b/trunk/arch/arm/mach-s3c2443/dma.c index 8430e5829186..2a58a4d5aa5a 100644 --- a/trunk/arch/arm/mach-s3c2443/dma.c +++ b/trunk/arch/arm/mach-s3c2443/dma.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #define MAP(x) { \ diff --git a/trunk/arch/arm/mach-s3c6410/mach-smdk6410.c b/trunk/arch/arm/mach-s3c6410/mach-smdk6410.c index 25f7935576f8..3c4d47145c83 100644 --- a/trunk/arch/arm/mach-s3c6410/mach-smdk6410.c +++ b/trunk/arch/arm/mach-s3c6410/mach-smdk6410.c @@ -129,7 +129,7 @@ static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = { .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, }; -static struct map_desc smdk6410_iodesc[] = {}; +struct map_desc smdk6410_iodesc[] = {}; static struct platform_device *smdk6410_devices[] __initdata = { #ifdef CONFIG_SMDK6410_SD_CH0 @@ -146,7 +146,7 @@ static struct platform_device *smdk6410_devices[] __initdata = { static struct i2c_board_info i2c_devs0[] __initdata = { { I2C_BOARD_INFO("24c08", 0x50), }, - { I2C_BOARD_INFO("wm8580", 0x1b), }, + { I2C_BOARD_INFO("WM8580", 0X1b), }, }; static struct i2c_board_info i2c_devs1[] __initdata = { diff --git a/trunk/arch/arm/mm/copypage-feroceon.c b/trunk/arch/arm/mm/copypage-feroceon.c index 70997d5bee2d..c3ba6a94da0c 100644 --- a/trunk/arch/arm/mm/copypage-feroceon.c +++ b/trunk/arch/arm/mm/copypage-feroceon.c @@ -13,7 +13,7 @@ #include #include -static void __naked +static void __attribute__((naked)) feroceon_copy_user_page(void *kto, const void *kfrom) { asm("\ diff --git a/trunk/arch/arm/mm/copypage-v3.c b/trunk/arch/arm/mm/copypage-v3.c index de9c06854ad7..70ed96c8af8e 100644 --- a/trunk/arch/arm/mm/copypage-v3.c +++ b/trunk/arch/arm/mm/copypage-v3.c @@ -15,7 +15,7 @@ * * FIXME: do we need to handle cache stuff... */ -static void __naked +static void __attribute__((naked)) v3_copy_user_page(void *kto, const void *kfrom) { asm("\n\ diff --git a/trunk/arch/arm/mm/copypage-v4mc.c b/trunk/arch/arm/mm/copypage-v4mc.c index 7370a7142b04..1601698b9800 100644 --- a/trunk/arch/arm/mm/copypage-v4mc.c +++ b/trunk/arch/arm/mm/copypage-v4mc.c @@ -44,7 +44,7 @@ static DEFINE_SPINLOCK(minicache_lock); * instruction. If your processor does not supply this, you have to write your * own copy_user_highpage that does the right thing. */ -static void __naked +static void __attribute__((naked)) mc_copy_user_page(void *from, void *to) { asm volatile( diff --git a/trunk/arch/arm/mm/copypage-v4wb.c b/trunk/arch/arm/mm/copypage-v4wb.c index 9ab098414227..3ec93dab7656 100644 --- a/trunk/arch/arm/mm/copypage-v4wb.c +++ b/trunk/arch/arm/mm/copypage-v4wb.c @@ -22,7 +22,7 @@ * instruction. If your processor does not supply this, you have to write your * own copy_user_highpage that does the right thing. */ -static void __naked +static void __attribute__((naked)) v4wb_copy_user_page(void *kto, const void *kfrom) { asm("\ diff --git a/trunk/arch/arm/mm/copypage-v4wt.c b/trunk/arch/arm/mm/copypage-v4wt.c index 300efafd6643..0f1188efae45 100644 --- a/trunk/arch/arm/mm/copypage-v4wt.c +++ b/trunk/arch/arm/mm/copypage-v4wt.c @@ -20,7 +20,7 @@ * dirty data in the cache. However, we do have to ensure that * subsequent reads are up to date. */ -static void __naked +static void __attribute__((naked)) v4wt_copy_user_page(void *kto, const void *kfrom) { asm("\ diff --git a/trunk/arch/arm/mm/copypage-xsc3.c b/trunk/arch/arm/mm/copypage-xsc3.c index bc4525f5ab23..39a994542cad 100644 --- a/trunk/arch/arm/mm/copypage-xsc3.c +++ b/trunk/arch/arm/mm/copypage-xsc3.c @@ -29,7 +29,7 @@ * if we eventually end up using our copied page. * */ -static void __naked +static void __attribute__((naked)) xsc3_mc_copy_user_page(void *kto, const void *kfrom) { asm("\ diff --git a/trunk/arch/arm/mm/copypage-xscale.c b/trunk/arch/arm/mm/copypage-xscale.c index 76824d3e966a..d18f2397ee2d 100644 --- a/trunk/arch/arm/mm/copypage-xscale.c +++ b/trunk/arch/arm/mm/copypage-xscale.c @@ -42,7 +42,7 @@ static DEFINE_SPINLOCK(minicache_lock); * Dcache aliasing issue. The writes will be forwarded to the write buffer, * and merged as appropriate. */ -static void __naked +static void __attribute__((naked)) mc_copy_user_page(void *from, void *to) { /* diff --git a/trunk/arch/arm/mm/dma-mapping.c b/trunk/arch/arm/mm/dma-mapping.c index f1ef5613ccd4..310e479309ef 100644 --- a/trunk/arch/arm/mm/dma-mapping.c +++ b/trunk/arch/arm/mm/dma-mapping.c @@ -490,30 +490,26 @@ core_initcall(consistent_init); */ void dma_cache_maint(const void *start, size_t size, int direction) { - void (*inner_op)(const void *, const void *); - void (*outer_op)(unsigned long, unsigned long); + const void *end = start + size; - BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(start + size - 1)); + BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end - 1)); switch (direction) { case DMA_FROM_DEVICE: /* invalidate only */ - inner_op = dmac_inv_range; - outer_op = outer_inv_range; + dmac_inv_range(start, end); + outer_inv_range(__pa(start), __pa(end)); break; case DMA_TO_DEVICE: /* writeback only */ - inner_op = dmac_clean_range; - outer_op = outer_clean_range; + dmac_clean_range(start, end); + outer_clean_range(__pa(start), __pa(end)); break; case DMA_BIDIRECTIONAL: /* writeback and invalidate */ - inner_op = dmac_flush_range; - outer_op = outer_flush_range; + dmac_flush_range(start, end); + outer_flush_range(__pa(start), __pa(end)); break; default: BUG(); } - - inner_op(start, start + size); - outer_op(__pa(start), __pa(start) + size); } EXPORT_SYMBOL(dma_cache_maint); diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 80fd3b69ae1f..34df4d9d03a6 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -382,7 +382,7 @@ void __init bootmem_init(void) for_each_node(node) bootmem_free_node(node, mi); - high_memory = __va((memend_pfn << PAGE_SHIFT) - 1) + 1; + high_memory = __va(memend_pfn << PAGE_SHIFT); /* * This doesn't seem to be used by the Linux memory manager any diff --git a/trunk/arch/arm/mm/mmap.c b/trunk/arch/arm/mm/mmap.c index f7457fea6de8..5358fcc7f61e 100644 --- a/trunk/arch/arm/mm/mmap.c +++ b/trunk/arch/arm/mm/mmap.c @@ -124,7 +124,7 @@ int valid_phys_addr_range(unsigned long addr, size_t size) { if (addr < PHYS_OFFSET) return 0; - if (addr + size >= __pa(high_memory - 1)) + if (addr + size > __pa(high_memory)) return 0; return 1; diff --git a/trunk/arch/arm/plat-omap/Makefile b/trunk/arch/arm/plat-omap/Makefile index 04a100cfb8e5..deaff58878a2 100644 --- a/trunk/arch/arm/plat-omap/Makefile +++ b/trunk/arch/arm/plat-omap/Makefile @@ -18,8 +18,7 @@ obj-$(CONFIG_CPU_FREQ) += cpu-omap.o obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o -i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o -obj-y += $(i2c-omap-m) $(i2c-omap-y) +obj-$(CONFIG_I2C_OMAP) += i2c.o # OMAP mailbox framework obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o diff --git a/trunk/arch/arm/plat-omap/common.c b/trunk/arch/arm/plat-omap/common.c index 6825fbb5a056..0843b8882f93 100644 --- a/trunk/arch/arm/plat-omap/common.c +++ b/trunk/arch/arm/plat-omap/common.c @@ -199,17 +199,21 @@ static struct clocksource clocksource_32k = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +/* + * Rounds down to nearest nsec. + */ +unsigned long long omap_32k_ticks_to_nsecs(unsigned long ticks_32k) +{ + return cyc2ns(&clocksource_32k, ticks_32k); +} + /* * Returns current time from boot in nsecs. It's OK for this to wrap * around for now, as it's just a relative time stamp. */ unsigned long long sched_clock(void) { - unsigned long long ret; - - ret = (unsigned long long)omap_32k_read(); - ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift; - return ret; + return omap_32k_ticks_to_nsecs(omap_32k_read()); } static int __init omap_init_clocksource_32k(void) diff --git a/trunk/arch/arm/plat-omap/include/mach/common.h b/trunk/arch/arm/plat-omap/include/mach/common.h index e746ec7e785e..ef70e2b0f054 100644 --- a/trunk/arch/arm/plat-omap/include/mach/common.h +++ b/trunk/arch/arm/plat-omap/include/mach/common.h @@ -35,7 +35,7 @@ extern void omap_map_common_io(void); extern struct sys_timer omap_timer; extern void omap_serial_init(void); extern void omap_serial_enable_clocks(int enable); -#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) +#ifdef CONFIG_I2C_OMAP extern int omap_register_i2c_bus(int bus_id, u32 clkrate, struct i2c_board_info const *info, unsigned len); diff --git a/trunk/arch/arm/plat-omap/include/mach/pm.h b/trunk/arch/arm/plat-omap/include/mach/pm.h index 37e2f0f38b46..2a9c27ad4c37 100644 --- a/trunk/arch/arm/plat-omap/include/mach/pm.h +++ b/trunk/arch/arm/plat-omap/include/mach/pm.h @@ -108,7 +108,7 @@ !defined(CONFIG_ARCH_OMAP15XX) && \ !defined(CONFIG_ARCH_OMAP16XX) && \ !defined(CONFIG_ARCH_OMAP24XX) -#warning "Power management for this processor not implemented yet" +#error "Power management for this processor not implemented yet" #endif #ifndef __ASSEMBLER__ diff --git a/trunk/arch/arm/plat-s3c64xx/clock.c b/trunk/arch/arm/plat-s3c64xx/clock.c index ad1b9682c9c3..136c982c68e1 100644 --- a/trunk/arch/arm/plat-s3c64xx/clock.c +++ b/trunk/arch/arm/plat-s3c64xx/clock.c @@ -248,7 +248,7 @@ static struct clk *clks[] __initdata = { &clk_48m, }; -void __init s3c64xx_register_clocks(void) +void s3c64xx_register_clocks(void) { struct clk *clkp; int ret; diff --git a/trunk/arch/arm/plat-s3c64xx/gpiolib.c b/trunk/arch/arm/plat-s3c64xx/gpiolib.c index ee9188add8fb..cc62941d7b5c 100644 --- a/trunk/arch/arm/plat-s3c64xx/gpiolib.c +++ b/trunk/arch/arm/plat-s3c64xx/gpiolib.c @@ -417,4 +417,4 @@ static __init int s3c64xx_gpiolib_init(void) return 0; } -core_initcall(s3c64xx_gpiolib_init); +arch_initcall(s3c64xx_gpiolib_init); diff --git a/trunk/arch/arm/plat-s3c64xx/include/plat/irqs.h b/trunk/arch/arm/plat-s3c64xx/include/plat/irqs.h index f865bf4d709e..2846f550b727 100644 --- a/trunk/arch/arm/plat-s3c64xx/include/plat/irqs.h +++ b/trunk/arch/arm/plat-s3c64xx/include/plat/irqs.h @@ -117,7 +117,7 @@ #define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12) #define IRQ_NFC S3C64XX_IRQ_VIC1(13) #define IRQ_CFCON S3C64XX_IRQ_VIC1(14) -#define IRQ_USBH S3C64XX_IRQ_VIC1(15) +#define IRQ_UHOST S3C64XX_IRQ_VIC1(15) #define IRQ_SPI0 S3C64XX_IRQ_VIC1(16) #define IRQ_SPI1 S3C64XX_IRQ_VIC1(17) #define IRQ_IIC S3C64XX_IRQ_VIC1(18) diff --git a/trunk/arch/arm/plat-s3c64xx/irq-eint.c b/trunk/arch/arm/plat-s3c64xx/irq-eint.c index cf524826c93a..ebb305ce7689 100644 --- a/trunk/arch/arm/plat-s3c64xx/irq-eint.c +++ b/trunk/arch/arm/plat-s3c64xx/irq-eint.c @@ -14,15 +14,12 @@ #include #include -#include #include #include #include #include -#include -#include #include #include @@ -77,7 +74,6 @@ static void s3c_irq_eint_maskack(unsigned int irq) static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) { int offs = eint_offset(irq); - int pin; int shift; u32 ctrl, mask; u32 newvalue = 0; @@ -129,15 +125,6 @@ static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) ctrl |= newvalue << shift; __raw_writel(ctrl, reg); - /* set the GPIO pin appropriately */ - - if (offs < 23) - pin = S3C64XX_GPN(offs); - else - pin = S3C64XX_GPM(offs - 23); - - s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(2)); - return 0; } @@ -194,7 +181,7 @@ static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc) s3c_irq_demux_eint(20, 27); } -static int __init s3c64xx_init_irq_eint(void) +int __init s3c64xx_init_irq_eint(void) { int irq; diff --git a/trunk/arch/arm/plat-s3c64xx/irq.c b/trunk/arch/arm/plat-s3c64xx/irq.c index f22edf7c2d2d..a94f1d5e819d 100644 --- a/trunk/arch/arm/plat-s3c64xx/irq.c +++ b/trunk/arch/arm/plat-s3c64xx/irq.c @@ -207,7 +207,7 @@ static struct irq_chip s3c_irq_uart = { static void __init s3c64xx_uart_irq(struct uart_irq *uirq) { - void __iomem *reg_base = uirq->regs; + void *reg_base = uirq->regs; unsigned int irq; int offs; diff --git a/trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c b/trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c index 05b17528041e..8d9a0cada668 100644 --- a/trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c +++ b/trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c @@ -36,7 +36,7 @@ * ext_xtal_mux for want of an actual name from the manual. */ -static struct clk clk_ext_xtal_mux = { +struct clk clk_ext_xtal_mux = { .name = "ext_xtal", .id = -1, }; @@ -63,7 +63,7 @@ struct clksrc_clk { void __iomem *reg_divider; }; -static struct clk clk_fout_apll = { +struct clk clk_fout_apll = { .name = "fout_apll", .id = -1, }; @@ -78,7 +78,7 @@ static struct clk_sources clk_src_apll = { .nr_sources = ARRAY_SIZE(clk_src_apll_list), }; -static struct clksrc_clk clk_mout_apll = { +struct clksrc_clk clk_mout_apll = { .clk = { .name = "mout_apll", .id = -1, @@ -88,7 +88,7 @@ static struct clksrc_clk clk_mout_apll = { .sources = &clk_src_apll, }; -static struct clk clk_fout_epll = { +struct clk clk_fout_epll = { .name = "fout_epll", .id = -1, }; @@ -103,7 +103,7 @@ static struct clk_sources clk_src_epll = { .nr_sources = ARRAY_SIZE(clk_src_epll_list), }; -static struct clksrc_clk clk_mout_epll = { +struct clksrc_clk clk_mout_epll = { .clk = { .name = "mout_epll", .id = -1, @@ -123,7 +123,7 @@ static struct clk_sources clk_src_mpll = { .nr_sources = ARRAY_SIZE(clk_src_mpll_list), }; -static struct clksrc_clk clk_mout_mpll = { +struct clksrc_clk clk_mout_mpll = { .clk = { .name = "mout_mpll", .id = -1, @@ -145,7 +145,7 @@ static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk) return rate; } -static struct clk clk_dout_mpll = { +struct clk clk_dout_mpll = { .name = "dout_mpll", .id = -1, .parent = &clk_mout_mpll.clk, @@ -189,10 +189,10 @@ static struct clk_sources clkset_uart = { }; static struct clk *clkset_uhost_list[] = { - &clk_48m, &clk_mout_epll.clk, &clk_dout_mpll, &clk_fin_epll, + &clk_48m, }; static struct clk_sources clkset_uhost = { @@ -239,12 +239,10 @@ static int s3c64xx_setrate_clksrc(struct clk *clk, unsigned long rate) rate = clk_round_rate(clk, rate); div = clk_get_rate(clk->parent) / rate; - if (div > 16) - return -EINVAL; val = __raw_readl(reg); - val &= ~(0xf << sclk->shift); - val |= (div - 1) << sclk->shift; + val &= ~sclk->mask; + val |= (rate - 1) << sclk->shift; __raw_writel(val, reg); return 0; @@ -353,7 +351,7 @@ static struct clksrc_clk clk_mmc2 = { static struct clksrc_clk clk_usbhost = { .clk = { - .name = "usb-bus-host", + .name = "usb-host-bus", .id = -1, .ctrlbit = S3C_CLKCON_SCLK_UHOST, .enable = s3c64xx_sclk_ctrl, diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index b4211d8b2ac7..fd23c0e9e698 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Thu Mar 12 18:01:45 2009 +# Last update: Sun Nov 30 16:39:36 2008 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -1811,7 +1811,7 @@ pilz_pmi5 MACH_PILZ_PMI5 PILZ_PMI5 1820 jade MACH_JADE JADE 1821 ks8695_softplc MACH_KS8695_SOFTPLC KS8695_SOFTPLC 1822 gprisc3 MACH_GPRISC3 GPRISC3 1823 -stamp9g20 MACH_STAMP9G20 STAMP9G20 1824 +stamp9260 MACH_STAMP9260 STAMP9260 1824 smdk6430 MACH_SMDK6430 SMDK6430 1825 smdkc100 MACH_SMDKC100 SMDKC100 1826 tavorevb MACH_TAVOREVB TAVOREVB 1827 @@ -1993,134 +1993,4 @@ spark MACH_SPARK SPARK 2002 benzina MACH_BENZINA BENZINA 2003 blaze MACH_BLAZE BLAZE 2004 linkstation_ls_hgl MACH_LINKSTATION_LS_HGL LINKSTATION_LS_HGL 2005 -htckovsky MACH_HTCVENUS HTCVENUS 2006 -sony_prs505 MACH_SONY_PRS505 SONY_PRS505 2007 -hanlin_v3 MACH_HANLIN_V3 HANLIN_V3 2008 -sapphira MACH_SAPPHIRA SAPPHIRA 2009 -dack_sda_01 MACH_DACK_SDA_01 DACK_SDA_01 2010 -armbox MACH_ARMBOX ARMBOX 2011 -harris_rvp MACH_HARRIS_RVP HARRIS_RVP 2012 -ribaldo MACH_RIBALDO RIBALDO 2013 -agora MACH_AGORA AGORA 2014 -omap3_mini MACH_OMAP3_MINI OMAP3_MINI 2015 -a9sam6432_b MACH_A9SAM6432_B A9SAM6432_B 2016 -usg2410 MACH_USG2410 USG2410 2017 -pc72052_i10_revb MACH_PC72052_I10_REVB PC72052_I10_REVB 2018 -mx35_exm32 MACH_MX35_EXM32 MX35_EXM32 2019 -topas910 MACH_TOPAS910 TOPAS910 2020 -hyena MACH_HYENA HYENA 2021 -pospax MACH_POSPAX POSPAX 2022 -hdl_gx MACH_HDL_GX HDL_GX 2023 -ctera_4bay MACH_CTERA_4BAY CTERA_4BAY 2024 -ctera_plug_c MACH_CTERA_PLUG_C CTERA_PLUG_C 2025 -crwea_plug_i MACH_CRWEA_PLUG_I CRWEA_PLUG_I 2026 -egauge2 MACH_EGAUGE2 EGAUGE2 2027 -didj MACH_DIDJ DIDJ 2028 -m_s3c2443 MACH_MEISTER MEISTER 2029 -htcblackstone MACH_HTCBLACKSTONE HTCBLACKSTONE 2030 -cpuat9g20 MACH_CPUAT9G20 CPUAT9G20 2031 -smdk6440 MACH_SMDK6440 SMDK6440 2032 -omap_35xx_mvp MACH_OMAP_35XX_MVP OMAP_35XX_MVP 2033 -ctera_plug_i MACH_CTERA_PLUG_I CTERA_PLUG_I 2034 -pvg610_100 MACH_PVG610 PVG610 2035 -hprw6815 MACH_HPRW6815 HPRW6815 2036 -omap3_oswald MACH_OMAP3_OSWALD OMAP3_OSWALD 2037 -nas4220b MACH_NAS4220B NAS4220B 2038 -htcraphael_cdma MACH_HTCRAPHAEL_CDMA HTCRAPHAEL_CDMA 2039 -htcdiamond_cdma MACH_HTCDIAMOND_CDMA HTCDIAMOND_CDMA 2040 -scaler MACH_SCALER SCALER 2041 -zylonite2 MACH_ZYLONITE2 ZYLONITE2 2042 -aspenite MACH_ASPENITE ASPENITE 2043 -teton MACH_TETON TETON 2044 -ttc_dkb MACH_TTC_DKB TTC_DKB 2045 -bishop2 MACH_BISHOP2 BISHOP2 2046 -ippv5 MACH_IPPV5 IPPV5 2047 -farm926 MACH_FARM926 FARM926 2048 -mmccpu MACH_MMCCPU MMCCPU 2049 -sgmsfl MACH_SGMSFL SGMSFL 2050 -tt8000 MACH_TT8000 TT8000 2051 -zrn4300lp MACH_ZRN4300LP ZRN4300LP 2052 -mptc MACH_MPTC MPTC 2053 -h6051 MACH_H6051 H6051 2054 -pvg610_101 MACH_PVG610_101 PVG610_101 2055 -stamp9261_pc_evb MACH_STAMP9261_PC_EVB STAMP9261_PC_EVB 2056 -pelco_odysseus MACH_PELCO_ODYSSEUS PELCO_ODYSSEUS 2057 -tny_a9260 MACH_TNY_A9260 TNY_A9260 2058 -tny_a9g20 MACH_TNY_A9G20 TNY_A9G20 2059 -aesop_mp2530f MACH_AESOP_MP2530F AESOP_MP2530F 2060 -dx900 MACH_DX900 DX900 2061 -cpodc2 MACH_CPODC2 CPODC2 2062 -tilt_8925 MACH_TILT_8925 TILT_8925 2063 -davinci_dm357_evm MACH_DAVINCI_DM357_EVM DAVINCI_DM357_EVM 2064 -swordfish MACH_SWORDFISH SWORDFISH 2065 -corvus MACH_CORVUS CORVUS 2066 -taurus MACH_TAURUS TAURUS 2067 -axm MACH_AXM AXM 2068 -axc MACH_AXC AXC 2069 -baby MACH_BABY BABY 2070 -mp200 MACH_MP200 MP200 2071 -pcm043 MACH_PCM043 PCM043 2072 -hanlin_v3c MACH_HANLIN_V3C HANLIN_V3C 2073 -kbk9g20 MACH_KBK9G20 KBK9G20 2074 -adsturbog5 MACH_ADSTURBOG5 ADSTURBOG5 2075 -avenger_lite1 MACH_AVENGER_LITE1 AVENGER_LITE1 2076 -suc82x MACH_SUC SUC 2077 -at91sam7s256 MACH_AT91SAM7S256 AT91SAM7S256 2078 -mendoza MACH_MENDOZA MENDOZA 2079 -kira MACH_KIRA KIRA 2080 -mx1hbm MACH_MX1HBM MX1HBM 2081 -quatro43xx MACH_QUATRO43XX QUATRO43XX 2082 -quatro4230 MACH_QUATRO4230 QUATRO4230 2083 -nsb400 MACH_NSB400 NSB400 2084 -drp255 MACH_DRP255 DRP255 2085 -thoth MACH_THOTH THOTH 2086 -firestone MACH_FIRESTONE FIRESTONE 2087 -asusp750 MACH_ASUSP750 ASUSP750 2088 -ctera_dl MACH_CTERA_DL CTERA_DL 2089 -socr MACH_SOCR SOCR 2090 -htcoxygen MACH_HTCOXYGEN HTCOXYGEN 2091 -heroc MACH_HEROC HEROC 2092 -zeno6800 MACH_ZENO6800 ZENO6800 2093 -sc2mcs MACH_SC2MCS SC2MCS 2094 -gene100 MACH_GENE100 GENE100 2095 -as353x MACH_AS353X AS353X 2096 -sheevaplug MACH_SHEEVAPLUG SHEEVAPLUG 2097 -at91sam9g20 MACH_AT91SAM9G20 AT91SAM9G20 2098 -mv88f6192gtw_fe MACH_MV88F6192GTW_FE MV88F6192GTW_FE 2099 -cc9200 MACH_CC9200 CC9200 2100 -sm9200 MACH_SM9200 SM9200 2101 -tp9200 MACH_TP9200 TP9200 2102 -snapperdv MACH_SNAPPERDV SNAPPERDV 2103 -avengers_lite MACH_AVENGERS_LITE AVENGERS_LITE 2104 -avengers_lite1 MACH_AVENGERS_LITE1 AVENGERS_LITE1 2105 -omap3axon MACH_OMAP3AXON OMAP3AXON 2106 -ma8xx MACH_MA8XX MA8XX 2107 -mp201ek MACH_MP201EK MP201EK 2108 -davinci_tux MACH_DAVINCI_TUX DAVINCI_TUX 2109 -mpa1600 MACH_MPA1600 MPA1600 2110 -pelco_troy MACH_PELCO_TROY PELCO_TROY 2111 -nsb667 MACH_NSB667 NSB667 2112 -rovers5_4mpix MACH_ROVERS5_4MPIX ROVERS5_4MPIX 2113 -twocom MACH_TWOCOM TWOCOM 2114 -ubisys_p9_rcu3r2 MACH_UBISYS_P9_RCU3R2 UBISYS_P9_RCU3R2 2115 -hero_espresso MACH_HERO_ESPRESSO HERO_ESPRESSO 2116 -afeusb MACH_AFEUSB AFEUSB 2117 -t830 MACH_T830 T830 2118 -spd8020_cc MACH_SPD8020_CC SPD8020_CC 2119 -om_3d7k MACH_OM_3D7K OM_3D7K 2120 -picocom2 MACH_PICOCOM2 PICOCOM2 2121 -uwg4mx27 MACH_UWG4MX27 UWG4MX27 2122 -uwg4mx31 MACH_UWG4MX31 UWG4MX31 2123 -cherry MACH_CHERRY CHERRY 2124 -mx51_babbage MACH_MX51_BABBAGE MX51_BABBAGE 2125 -s3c2440turkiye MACH_S3C2440TURKIYE S3C2440TURKIYE 2126 -tx37 MACH_TX37 TX37 2127 -sbc2800_9g20 MACH_SBC2800_9G20 SBC2800_9G20 2128 -benzglb MACH_BENZGLB BENZGLB 2129 -benztd MACH_BENZTD BENZTD 2130 -cartesio_plus MACH_CARTESIO_PLUS CARTESIO_PLUS 2131 -solrad_g20 MACH_SOLRAD_G20 SOLRAD_G20 2132 -mx27wallace MACH_MX27WALLACE MX27WALLACE 2133 -fmzwebmodul MACH_FMZWEBMODUL FMZWEBMODUL 2134 -rd78x00_masa MACH_RD78X00_MASA RD78X00_MASA 2135 -smallogger MACH_SMALLOGGER SMALLOGGER 2136 +htcvenus MACH_HTCVENUS HTCVENUS 2006 diff --git a/trunk/arch/m68k/include/asm/param.h b/trunk/arch/m68k/include/asm/param.h index 85c41b75aa78..40d1112a4588 100644 --- a/trunk/arch/m68k/include/asm/param.h +++ b/trunk/arch/m68k/include/asm/param.h @@ -1,26 +1,5 @@ -#ifndef _M68K_PARAM_H -#define _M68K_PARAM_H - -#ifdef __KERNEL__ -# define HZ CONFIG_HZ /* Internal kernel timer frequency */ -# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ -# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#endif - -#ifndef HZ -#define HZ 100 -#endif - #ifdef __uClinux__ -#define EXEC_PAGESIZE 4096 +#include "param_no.h" #else -#define EXEC_PAGESIZE 8192 -#endif - -#ifndef NOGROUP -#define NOGROUP (-1) +#include "param_mm.h" #endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#endif /* _M68K_PARAM_H */ diff --git a/trunk/arch/m68k/include/asm/param_mm.h b/trunk/arch/m68k/include/asm/param_mm.h new file mode 100644 index 000000000000..536a27888358 --- /dev/null +++ b/trunk/arch/m68k/include/asm/param_mm.h @@ -0,0 +1,22 @@ +#ifndef _M68K_PARAM_H +#define _M68K_PARAM_H + +#ifdef __KERNEL__ +# define HZ CONFIG_HZ /* Internal kernel timer frequency */ +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 8192 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _M68K_PARAM_H */ diff --git a/trunk/arch/m68k/include/asm/param_no.h b/trunk/arch/m68k/include/asm/param_no.h new file mode 100644 index 000000000000..6044397adb64 --- /dev/null +++ b/trunk/arch/m68k/include/asm/param_no.h @@ -0,0 +1,22 @@ +#ifndef _M68KNOMMU_PARAM_H +#define _M68KNOMMU_PARAM_H + +#ifdef __KERNEL__ +#define HZ CONFIG_HZ +#define USER_HZ HZ +#define CLOCKS_PER_SEC (USER_HZ) +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _M68KNOMMU_PARAM_H */ diff --git a/trunk/arch/m68k/include/asm/ptrace.h b/trunk/arch/m68k/include/asm/ptrace.h index 8c9194b98548..e83cd2f66101 100644 --- a/trunk/arch/m68k/include/asm/ptrace.h +++ b/trunk/arch/m68k/include/asm/ptrace.h @@ -1,87 +1,5 @@ -#ifndef _M68K_PTRACE_H -#define _M68K_PTRACE_H - -#define PT_D1 0 -#define PT_D2 1 -#define PT_D3 2 -#define PT_D4 3 -#define PT_D5 4 -#define PT_D6 5 -#define PT_D7 6 -#define PT_A0 7 -#define PT_A1 8 -#define PT_A2 9 -#define PT_A3 10 -#define PT_A4 11 -#define PT_A5 12 -#define PT_A6 13 -#define PT_D0 14 -#define PT_USP 15 -#define PT_ORIG_D0 16 -#define PT_SR 17 -#define PT_PC 18 - -#ifndef __ASSEMBLY__ - -/* this struct defines the way the registers are stored on the - stack during a system call. */ - -struct pt_regs { - long d1; - long d2; - long d3; - long d4; - long d5; - long a0; - long a1; - long a2; - long d0; - long orig_d0; - long stkadj; -#ifdef CONFIG_COLDFIRE - unsigned format : 4; /* frame format specifier */ - unsigned vector : 12; /* vector offset */ - unsigned short sr; - unsigned long pc; +#ifdef __uClinux__ +#include "ptrace_no.h" #else - unsigned short sr; - unsigned long pc; - unsigned format : 4; /* frame format specifier */ - unsigned vector : 12; /* vector offset */ +#include "ptrace_mm.h" #endif -}; - -/* - * This is the extended stack used by signal handlers and the context - * switcher: it's pushed after the normal "struct pt_regs". - */ -struct switch_stack { - unsigned long d6; - unsigned long d7; - unsigned long a3; - unsigned long a4; - unsigned long a5; - unsigned long a6; - unsigned long retpc; -}; - -/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ -#define PTRACE_GETREGS 12 -#define PTRACE_SETREGS 13 -#define PTRACE_GETFPREGS 14 -#define PTRACE_SETFPREGS 15 - -#ifdef __KERNEL__ - -#ifndef PS_S -#define PS_S (0x2000) -#define PS_M (0x1000) -#endif - -#define user_mode(regs) (!((regs)->sr & PS_S)) -#define instruction_pointer(regs) ((regs)->pc) -#define profile_pc(regs) instruction_pointer(regs) -extern void show_regs(struct pt_regs *); -#endif /* __KERNEL__ */ -#endif /* __ASSEMBLY__ */ -#endif /* _M68K_PTRACE_H */ diff --git a/trunk/arch/m68k/include/asm/ptrace_mm.h b/trunk/arch/m68k/include/asm/ptrace_mm.h new file mode 100644 index 000000000000..57e763d79bf4 --- /dev/null +++ b/trunk/arch/m68k/include/asm/ptrace_mm.h @@ -0,0 +1,80 @@ +#ifndef _M68K_PTRACE_H +#define _M68K_PTRACE_H + +#define PT_D1 0 +#define PT_D2 1 +#define PT_D3 2 +#define PT_D4 3 +#define PT_D5 4 +#define PT_D6 5 +#define PT_D7 6 +#define PT_A0 7 +#define PT_A1 8 +#define PT_A2 9 +#define PT_A3 10 +#define PT_A4 11 +#define PT_A5 12 +#define PT_A6 13 +#define PT_D0 14 +#define PT_USP 15 +#define PT_ORIG_D0 16 +#define PT_SR 17 +#define PT_PC 18 + +#ifndef __ASSEMBLY__ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long d1; + long d2; + long d3; + long d4; + long d5; + long a0; + long a1; + long a2; + long d0; + long orig_d0; + long stkadj; + unsigned short sr; + unsigned long pc; + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ +}; + +/* + * This is the extended stack used by signal handlers and the context + * switcher: it's pushed after the normal "struct pt_regs". + */ +struct switch_stack { + unsigned long d6; + unsigned long d7; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long retpc; +}; + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 + +#ifdef __KERNEL__ + +#ifndef PS_S +#define PS_S (0x2000) +#define PS_M (0x1000) +#endif + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) +extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _M68K_PTRACE_H */ diff --git a/trunk/arch/m68k/include/asm/ptrace_no.h b/trunk/arch/m68k/include/asm/ptrace_no.h new file mode 100644 index 000000000000..8c9194b98548 --- /dev/null +++ b/trunk/arch/m68k/include/asm/ptrace_no.h @@ -0,0 +1,87 @@ +#ifndef _M68K_PTRACE_H +#define _M68K_PTRACE_H + +#define PT_D1 0 +#define PT_D2 1 +#define PT_D3 2 +#define PT_D4 3 +#define PT_D5 4 +#define PT_D6 5 +#define PT_D7 6 +#define PT_A0 7 +#define PT_A1 8 +#define PT_A2 9 +#define PT_A3 10 +#define PT_A4 11 +#define PT_A5 12 +#define PT_A6 13 +#define PT_D0 14 +#define PT_USP 15 +#define PT_ORIG_D0 16 +#define PT_SR 17 +#define PT_PC 18 + +#ifndef __ASSEMBLY__ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long d1; + long d2; + long d3; + long d4; + long d5; + long a0; + long a1; + long a2; + long d0; + long orig_d0; + long stkadj; +#ifdef CONFIG_COLDFIRE + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ + unsigned short sr; + unsigned long pc; +#else + unsigned short sr; + unsigned long pc; + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ +#endif +}; + +/* + * This is the extended stack used by signal handlers and the context + * switcher: it's pushed after the normal "struct pt_regs". + */ +struct switch_stack { + unsigned long d6; + unsigned long d7; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long retpc; +}; + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 + +#ifdef __KERNEL__ + +#ifndef PS_S +#define PS_S (0x2000) +#define PS_M (0x1000) +#endif + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) +extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _M68K_PTRACE_H */ diff --git a/trunk/arch/m68k/include/asm/setup.h b/trunk/arch/m68k/include/asm/setup.h index 4dfb3952b375..842f86f75ccd 100644 --- a/trunk/arch/m68k/include/asm/setup.h +++ b/trunk/arch/m68k/include/asm/setup.h @@ -1,376 +1,5 @@ -/* -** asm/setup.h -- Definition of the Linux/m68k setup information -** -** Copyright 1992 by Greg Harp -** -** 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. -** -** Created 09/29/92 by Greg Harp -** -** 5/2/94 Roman Hodek: -** Added bi_atari part of the machine dependent union bi_un; for now it -** contains just a model field to distinguish between TT and Falcon. -** 26/7/96 Roman Zippel: -** Renamed to setup.h; added some useful macros to allow gcc some -** optimizations if possible. -** 5/10/96 Geert Uytterhoeven: -** Redesign of the boot information structure; moved boot information -** structure to bootinfo.h -*/ - -#ifndef _M68K_SETUP_H -#define _M68K_SETUP_H - - - - /* - * Linux/m68k Architectures - */ - -#define MACH_AMIGA 1 -#define MACH_ATARI 2 -#define MACH_MAC 3 -#define MACH_APOLLO 4 -#define MACH_SUN3 5 -#define MACH_MVME147 6 -#define MACH_MVME16x 7 -#define MACH_BVME6000 8 -#define MACH_HP300 9 -#define MACH_Q40 10 -#define MACH_SUN3X 11 - -#define COMMAND_LINE_SIZE 256 - -#ifdef __KERNEL__ - -#define CL_SIZE COMMAND_LINE_SIZE - -#ifndef __ASSEMBLY__ -extern unsigned long m68k_machtype; -#endif /* !__ASSEMBLY__ */ - -#if !defined(CONFIG_AMIGA) -# define MACH_IS_AMIGA (0) -#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ - || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA) +#ifdef __uClinux__ +#include "setup_no.h" #else -# define MACH_AMIGA_ONLY -# define MACH_IS_AMIGA (1) -# define MACH_TYPE (MACH_AMIGA) +#include "setup_mm.h" #endif - -#if !defined(CONFIG_ATARI) -# define MACH_IS_ATARI (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ - || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI) -#else -# define MACH_ATARI_ONLY -# define MACH_IS_ATARI (1) -# define MACH_TYPE (MACH_ATARI) -#endif - -#if !defined(CONFIG_MAC) -# define MACH_IS_MAC (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \ - || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_MAC (m68k_machtype == MACH_MAC) -#else -# define MACH_MAC_ONLY -# define MACH_IS_MAC (1) -# define MACH_TYPE (MACH_MAC) -#endif - -#if defined(CONFIG_SUN3) -#define MACH_IS_SUN3 (1) -#define MACH_SUN3_ONLY (1) -#define MACH_TYPE (MACH_SUN3) -#else -#define MACH_IS_SUN3 (0) -#endif - -#if !defined (CONFIG_APOLLO) -# define MACH_IS_APOLLO (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO) -#else -# define MACH_APOLLO_ONLY -# define MACH_IS_APOLLO (1) -# define MACH_TYPE (MACH_APOLLO) -#endif - -#if !defined (CONFIG_MVME147) -# define MACH_IS_MVME147 (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x) -# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147) -#else -# define MACH_MVME147_ONLY -# define MACH_IS_MVME147 (1) -# define MACH_TYPE (MACH_MVME147) -#endif - -#if !defined (CONFIG_MVME16x) -# define MACH_IS_MVME16x (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x) -#else -# define MACH_MVME16x_ONLY -# define MACH_IS_MVME16x (1) -# define MACH_TYPE (MACH_MVME16x) -#endif - -#if !defined (CONFIG_BVME6000) -# define MACH_IS_BVME6000 (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000) -#else -# define MACH_BVME6000_ONLY -# define MACH_IS_BVME6000 (1) -# define MACH_TYPE (MACH_BVME6000) -#endif - -#if !defined (CONFIG_HP300) -# define MACH_IS_HP300 (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ - || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_HP300 (m68k_machtype == MACH_HP300) -#else -# define MACH_HP300_ONLY -# define MACH_IS_HP300 (1) -# define MACH_TYPE (MACH_HP300) -#endif - -#if !defined (CONFIG_Q40) -# define MACH_IS_Q40 (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ - || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_Q40 (m68k_machtype == MACH_Q40) -#else -# define MACH_Q40_ONLY -# define MACH_IS_Q40 (1) -# define MACH_TYPE (MACH_Q40) -#endif - -#if !defined (CONFIG_SUN3X) -# define MACH_IS_SUN3X (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ - || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ - || defined(CONFIG_Q40) || defined(CONFIG_MVME147) -# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X) -#else -# define CONFIG_SUN3X_ONLY -# define MACH_IS_SUN3X (1) -# define MACH_TYPE (MACH_SUN3X) -#endif - -#ifndef MACH_TYPE -# define MACH_TYPE (m68k_machtype) -#endif - -#endif /* __KERNEL__ */ - - - /* - * CPU, FPU and MMU types - * - * Note: we may rely on the following equalities: - * - * CPU_68020 == MMU_68851 - * CPU_68030 == MMU_68030 - * CPU_68040 == FPU_68040 == MMU_68040 - * CPU_68060 == FPU_68060 == MMU_68060 - */ - -#define CPUB_68020 0 -#define CPUB_68030 1 -#define CPUB_68040 2 -#define CPUB_68060 3 - -#define CPU_68020 (1< + +/* We have a bigger command line buffer. */ +#undef COMMAND_LINE_SIZE + +#endif /* __KERNEL__ */ + +#define COMMAND_LINE_SIZE 512 diff --git a/trunk/arch/m68k/include/asm/sigcontext.h b/trunk/arch/m68k/include/asm/sigcontext.h index 523db2a51cf3..bff6d40345a9 100644 --- a/trunk/arch/m68k/include/asm/sigcontext.h +++ b/trunk/arch/m68k/include/asm/sigcontext.h @@ -1,24 +1,5 @@ -#ifndef _ASM_M68k_SIGCONTEXT_H -#define _ASM_M68k_SIGCONTEXT_H - -struct sigcontext { - unsigned long sc_mask; /* old sigmask */ - unsigned long sc_usp; /* old user stack pointer */ - unsigned long sc_d0; - unsigned long sc_d1; - unsigned long sc_a0; - unsigned long sc_a1; #ifdef __uClinux__ - unsigned long sc_a5; -#endif - unsigned short sc_sr; - unsigned long sc_pc; - unsigned short sc_formatvec; -#ifndef __uClinux__ - unsigned long sc_fpregs[2*3]; /* room for two fp registers */ - unsigned long sc_fpcntl[3]; - unsigned char sc_fpstate[216]; -#endif -}; - +#include "sigcontext_no.h" +#else +#include "sigcontext_mm.h" #endif diff --git a/trunk/arch/m68k/include/asm/sigcontext_mm.h b/trunk/arch/m68k/include/asm/sigcontext_mm.h new file mode 100644 index 000000000000..64fbe34cf26f --- /dev/null +++ b/trunk/arch/m68k/include/asm/sigcontext_mm.h @@ -0,0 +1,19 @@ +#ifndef _ASM_M68k_SIGCONTEXT_H +#define _ASM_M68k_SIGCONTEXT_H + +struct sigcontext { + unsigned long sc_mask; /* old sigmask */ + unsigned long sc_usp; /* old user stack pointer */ + unsigned long sc_d0; + unsigned long sc_d1; + unsigned long sc_a0; + unsigned long sc_a1; + unsigned short sc_sr; + unsigned long sc_pc; + unsigned short sc_formatvec; + unsigned long sc_fpregs[2*3]; /* room for two fp registers */ + unsigned long sc_fpcntl[3]; + unsigned char sc_fpstate[216]; +}; + +#endif diff --git a/trunk/arch/m68k/include/asm/sigcontext_no.h b/trunk/arch/m68k/include/asm/sigcontext_no.h new file mode 100644 index 000000000000..36c293fc133d --- /dev/null +++ b/trunk/arch/m68k/include/asm/sigcontext_no.h @@ -0,0 +1,17 @@ +#ifndef _ASM_M68KNOMMU_SIGCONTEXT_H +#define _ASM_M68KNOMMU_SIGCONTEXT_H + +struct sigcontext { + unsigned long sc_mask; /* old sigmask */ + unsigned long sc_usp; /* old user stack pointer */ + unsigned long sc_d0; + unsigned long sc_d1; + unsigned long sc_a0; + unsigned long sc_a1; + unsigned long sc_a5; + unsigned short sc_sr; + unsigned long sc_pc; + unsigned short sc_formatvec; +}; + +#endif diff --git a/trunk/arch/m68k/include/asm/siginfo.h b/trunk/arch/m68k/include/asm/siginfo.h index ca7dde8fd223..61219d7affc8 100644 --- a/trunk/arch/m68k/include/asm/siginfo.h +++ b/trunk/arch/m68k/include/asm/siginfo.h @@ -1,97 +1,5 @@ -#ifndef _M68K_SIGINFO_H -#define _M68K_SIGINFO_H - -#ifndef __uClinux__ -#define HAVE_ARCH_SIGINFO_T -#define HAVE_ARCH_COPY_SIGINFO -#endif - -#include - -#ifndef __uClinux__ - -typedef struct siginfo { - int si_signo; - int si_errno; - int si_code; - - union { - int _pad[SI_PAD_SIZE]; - - /* kill() */ - struct { - __kernel_pid_t _pid; /* sender's pid */ - __kernel_uid_t _uid; /* backwards compatibility */ - __kernel_uid32_t _uid32; /* sender's uid */ - } _kill; - - /* POSIX.1b timers */ - struct { - timer_t _tid; /* timer id */ - int _overrun; /* overrun count */ - char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; - sigval_t _sigval; /* same as below */ - int _sys_private; /* not to be passed to user */ - } _timer; - - /* POSIX.1b signals */ - struct { - __kernel_pid_t _pid; /* sender's pid */ - __kernel_uid_t _uid; /* backwards compatibility */ - sigval_t _sigval; - __kernel_uid32_t _uid32; /* sender's uid */ - } _rt; - - /* SIGCHLD */ - struct { - __kernel_pid_t _pid; /* which child */ - __kernel_uid_t _uid; /* backwards compatibility */ - int _status; /* exit code */ - clock_t _utime; - clock_t _stime; - __kernel_uid32_t _uid32; /* sender's uid */ - } _sigchld; - - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ - struct { - void *_addr; /* faulting insn/memory ref. */ - } _sigfault; - - /* SIGPOLL */ - struct { - int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ - int _fd; - } _sigpoll; - } _sifields; -} siginfo_t; - -#define UID16_SIGINFO_COMPAT_NEEDED - -/* - * How these fields are to be accessed. - */ -#undef si_uid -#ifdef __KERNEL__ -#define si_uid _sifields._kill._uid32 -#define si_uid16 _sifields._kill._uid +#ifdef __uClinux__ +#include "siginfo_no.h" #else -#define si_uid _sifields._kill._uid -#endif - -#ifdef __KERNEL__ - -#include - -static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) -{ - if (from->si_code < 0) - memcpy(to, from, sizeof(*to)); - else - /* _sigchld is currently the largest know union member */ - memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); -} - -#endif /* __KERNEL__ */ -#endif /* !__uClinux__ */ - +#include "siginfo_mm.h" #endif diff --git a/trunk/arch/m68k/include/asm/siginfo_mm.h b/trunk/arch/m68k/include/asm/siginfo_mm.h new file mode 100644 index 000000000000..05a8d6d90b58 --- /dev/null +++ b/trunk/arch/m68k/include/asm/siginfo_mm.h @@ -0,0 +1,92 @@ +#ifndef _M68K_SIGINFO_H +#define _M68K_SIGINFO_H + +#define HAVE_ARCH_SIGINFO_T +#define HAVE_ARCH_COPY_SIGINFO + +#include + +typedef struct siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[SI_PAD_SIZE]; + + /* kill() */ + struct { + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ + __kernel_uid32_t _uid32; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; + sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; + + /* POSIX.1b signals */ + struct { + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ + sigval_t _sigval; + __kernel_uid32_t _uid32; /* sender's uid */ + } _rt; + + /* SIGCHLD */ + struct { + __kernel_pid_t _pid; /* which child */ + __kernel_uid_t _uid; /* backwards compatibility */ + int _status; /* exit code */ + clock_t _utime; + clock_t _stime; + __kernel_uid32_t _uid32; /* sender's uid */ + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + void *_addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} siginfo_t; + +#define UID16_SIGINFO_COMPAT_NEEDED + +/* + * How these fields are to be accessed. + */ +#undef si_uid +#ifdef __KERNEL__ +#define si_uid _sifields._kill._uid32 +#define si_uid16 _sifields._kill._uid +#else +#define si_uid _sifields._kill._uid +#endif + +#ifdef __KERNEL__ + +#include + +static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) +{ + if (from->si_code < 0) + memcpy(to, from, sizeof(*to)); + else + /* _sigchld is currently the largest know union member */ + memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/trunk/arch/m68k/include/asm/siginfo_no.h b/trunk/arch/m68k/include/asm/siginfo_no.h new file mode 100644 index 000000000000..b18e5f4064ae --- /dev/null +++ b/trunk/arch/m68k/include/asm/siginfo_no.h @@ -0,0 +1,6 @@ +#ifndef _M68KNOMMU_SIGINFO_H +#define _M68KNOMMU_SIGINFO_H + +#include + +#endif diff --git a/trunk/arch/m68k/include/asm/signal.h b/trunk/arch/m68k/include/asm/signal.h index 08788fdefde0..3c19988bd93c 100644 --- a/trunk/arch/m68k/include/asm/signal.h +++ b/trunk/arch/m68k/include/asm/signal.h @@ -1,213 +1,5 @@ -#ifndef _M68K_SIGNAL_H -#define _M68K_SIGNAL_H - -#include - -/* Avoid too many header ordering problems. */ -struct siginfo; - -#ifdef __KERNEL__ -/* Most things should be clean enough to redefine this at will, if care - is taken to make libc match. */ - -#define _NSIG 64 -#define _NSIG_BPW 32 -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - -typedef unsigned long old_sigset_t; /* at least 32 bits */ - -typedef struct { - unsigned long sig[_NSIG_WORDS]; -} sigset_t; - +#ifdef __uClinux__ +#include "signal_no.h" #else -/* Here we must cater to libcs that poke about in kernel headers. */ - -#define NSIG 32 -typedef unsigned long sigset_t; - -#endif /* __KERNEL__ */ - -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGIOT 6 -#define SIGBUS 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGUSR1 10 -#define SIGSEGV 11 -#define SIGUSR2 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGSTKFLT 16 -#define SIGCHLD 17 -#define SIGCONT 18 -#define SIGSTOP 19 -#define SIGTSTP 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGURG 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGIO 29 -#define SIGPOLL SIGIO -/* -#define SIGLOST 29 -*/ -#define SIGPWR 30 -#define SIGSYS 31 -#define SIGUNUSED 31 - -/* These should not be considered constants from userland. */ -#define SIGRTMIN 32 -#define SIGRTMAX _NSIG - -/* - * SA_FLAGS values: - * - * SA_ONSTACK indicates that a registered stack_t will be used. - * SA_RESTART flag to get restarting signals (which were the default long ago) - * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. - * SA_RESETHAND clears the handler when the signal is delivered. - * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. - * SA_NODEFER prevents the current signal from being masked in the handler. - * - * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single - * Unix names RESETHAND and NODEFER respectively. - */ -#define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 -#define SA_SIGINFO 0x00000004 -#define SA_ONSTACK 0x08000000 -#define SA_RESTART 0x10000000 -#define SA_NODEFER 0x40000000 -#define SA_RESETHAND 0x80000000 - -#define SA_NOMASK SA_NODEFER -#define SA_ONESHOT SA_RESETHAND - -/* - * sigaltstack controls - */ -#define SS_ONSTACK 1 -#define SS_DISABLE 2 - -#define MINSIGSTKSZ 2048 -#define SIGSTKSZ 8192 - -#include - -#ifdef __KERNEL__ -struct old_sigaction { - __sighandler_t sa_handler; - old_sigset_t sa_mask; - unsigned long sa_flags; - __sigrestore_t sa_restorer; -}; - -struct sigaction { - __sighandler_t sa_handler; - unsigned long sa_flags; - __sigrestore_t sa_restorer; - sigset_t sa_mask; /* mask last for extensibility */ -}; - -struct k_sigaction { - struct sigaction sa; -}; -#else -/* Here we must cater to libcs that poke about in kernel headers. */ - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo *, void *); - } _u; - sigset_t sa_mask; - unsigned long sa_flags; - void (*sa_restorer)(void); -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -#endif /* __KERNEL__ */ - -typedef struct sigaltstack { - void __user *ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; - -#ifdef __KERNEL__ -#include - -#ifndef __uClinux__ -#define __HAVE_ARCH_SIG_BITOPS - -static inline void sigaddset(sigset_t *set, int _sig) -{ - asm ("bfset %0{%1,#1}" - : "+od" (*set) - : "id" ((_sig - 1) ^ 31) - : "cc"); -} - -static inline void sigdelset(sigset_t *set, int _sig) -{ - asm ("bfclr %0{%1,#1}" - : "+od" (*set) - : "id" ((_sig - 1) ^ 31) - : "cc"); -} - -static inline int __const_sigismember(sigset_t *set, int _sig) -{ - unsigned long sig = _sig - 1; - return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); -} - -static inline int __gen_sigismember(sigset_t *set, int _sig) -{ - int ret; - asm ("bfextu %1{%2,#1},%0" - : "=d" (ret) - : "od" (*set), "id" ((_sig-1) ^ 31) - : "cc"); - return ret; -} - -#define sigismember(set,sig) \ - (__builtin_constant_p(sig) ? \ - __const_sigismember(set,sig) : \ - __gen_sigismember(set,sig)) - -static inline int sigfindinword(unsigned long word) -{ - asm ("bfffo %1{#0,#0},%0" - : "=d" (word) - : "d" (word & -word) - : "cc"); - return word ^ 31; -} - -struct pt_regs; -extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); - -#else - -#undef __HAVE_ARCH_SIG_BITOPS -#define ptrace_signal_deliver(regs, cookie) do { } while (0) - -#endif /* __uClinux__ */ -#endif /* __KERNEL__ */ - -#endif /* _M68K_SIGNAL_H */ +#include "signal_mm.h" +#endif diff --git a/trunk/arch/m68k/include/asm/signal_mm.h b/trunk/arch/m68k/include/asm/signal_mm.h new file mode 100644 index 000000000000..3db8a81942f1 --- /dev/null +++ b/trunk/arch/m68k/include/asm/signal_mm.h @@ -0,0 +1,206 @@ +#ifndef _M68K_SIGNAL_H +#define _M68K_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + __sigrestore_t sa_restorer; +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + __sigrestore_t sa_restorer; + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +#include + +#define __HAVE_ARCH_SIG_BITOPS + +static inline void sigaddset(sigset_t *set, int _sig) +{ + asm ("bfset %0{%1,#1}" + : "+od" (*set) + : "id" ((_sig - 1) ^ 31) + : "cc"); +} + +static inline void sigdelset(sigset_t *set, int _sig) +{ + asm ("bfclr %0{%1,#1}" + : "+od" (*set) + : "id" ((_sig - 1) ^ 31) + : "cc"); +} + +static inline int __const_sigismember(sigset_t *set, int _sig) +{ + unsigned long sig = _sig - 1; + return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); +} + +static inline int __gen_sigismember(sigset_t *set, int _sig) +{ + int ret; + asm ("bfextu %1{%2,#1},%0" + : "=d" (ret) + : "od" (*set), "id" ((_sig-1) ^ 31) + : "cc"); + return ret; +} + +#define sigismember(set,sig) \ + (__builtin_constant_p(sig) ? \ + __const_sigismember(set,sig) : \ + __gen_sigismember(set,sig)) + +static inline int sigfindinword(unsigned long word) +{ + asm ("bfffo %1{#0,#0},%0" + : "=d" (word) + : "d" (word & -word) + : "cc"); + return word ^ 31; +} + +struct pt_regs; +extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); + +#endif /* __KERNEL__ */ + +#endif /* _M68K_SIGNAL_H */ diff --git a/trunk/arch/m68k/include/asm/signal_no.h b/trunk/arch/m68k/include/asm/signal_no.h new file mode 100644 index 000000000000..216c08be54a0 --- /dev/null +++ b/trunk/arch/m68k/include/asm/signal_no.h @@ -0,0 +1,159 @@ +#ifndef _M68KNOMMU_SIGNAL_H +#define _M68KNOMMU_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ + +#include +#undef __HAVE_ARCH_SIG_BITOPS + +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + +#endif /* __KERNEL__ */ + +#endif /* _M68KNOMMU_SIGNAL_H */ diff --git a/trunk/arch/m68k/include/asm/swab.h b/trunk/arch/m68k/include/asm/swab.h index 9e3054ea59e9..7d7dde1c73ec 100644 --- a/trunk/arch/m68k/include/asm/swab.h +++ b/trunk/arch/m68k/include/asm/swab.h @@ -1,27 +1,5 @@ -#ifndef _M68K_SWAB_H -#define _M68K_SWAB_H - -#include -#include - -#define __SWAB_64_THRU_32__ - -#if defined (__mcfisaaplus__) || defined (__mcfisac__) -static inline __attribute_const__ __u32 __arch_swab32(__u32 val) -{ - __asm__("byterev %0" : "=d" (val) : "0" (val)); - return val; -} - -#define __arch_swab32 __arch_swab32 -#elif !defined(__uClinux__) - -static inline __attribute_const__ __u32 __arch_swab32(__u32 val) -{ - __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); - return val; -} -#define __arch_swab32 __arch_swab32 +#ifdef __uClinux__ +#include "swab_no.h" +#else +#include "swab_mm.h" #endif - -#endif /* _M68K_SWAB_H */ diff --git a/trunk/arch/m68k/include/asm/swab_mm.h b/trunk/arch/m68k/include/asm/swab_mm.h new file mode 100644 index 000000000000..7221e3066825 --- /dev/null +++ b/trunk/arch/m68k/include/asm/swab_mm.h @@ -0,0 +1,16 @@ +#ifndef _M68K_SWAB_H +#define _M68K_SWAB_H + +#include +#include + +#define __SWAB_64_THRU_32__ + +static inline __attribute_const__ __u32 __arch_swab32(__u32 val) +{ + __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); + return val; +} +#define __arch_swab32 __arch_swab32 + +#endif /* _M68K_SWAB_H */ diff --git a/trunk/arch/m68k/include/asm/swab_no.h b/trunk/arch/m68k/include/asm/swab_no.h new file mode 100644 index 000000000000..e582257db300 --- /dev/null +++ b/trunk/arch/m68k/include/asm/swab_no.h @@ -0,0 +1,24 @@ +#ifndef _M68KNOMMU_SWAB_H +#define _M68KNOMMU_SWAB_H + +#include + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __SWAB_64_THRU_32__ +#endif + +#if defined (__mcfisaaplus__) || defined (__mcfisac__) +static inline __attribute_const__ __u32 __arch_swab32(__u32 val) +{ + asm( + "byterev %0" + : "=d" (val) + : "0" (val) + ); + return val; +} + +#define __arch_swab32 __arch_swab32 +#endif + +#endif /* _M68KNOMMU_SWAB_H */ diff --git a/trunk/arch/m68k/include/asm/unistd.h b/trunk/arch/m68k/include/asm/unistd.h index 3c19027331fa..df1d9d4cb1fd 100644 --- a/trunk/arch/m68k/include/asm/unistd.h +++ b/trunk/arch/m68k/include/asm/unistd.h @@ -1,372 +1,5 @@ -#ifndef _ASM_M68K_UNISTD_H_ -#define _ASM_M68K_UNISTD_H_ - -/* - * This file contains the system call numbers. - */ - -#define __NR_restart_syscall 0 -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_chown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_umount2 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_oldolduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_olduname 109 -#define __NR_iopl /* 110 */ not supported -#define __NR_vhangup 111 -#define __NR_idle /* 112 */ Obsolete -#define __NR_vm86 /* 113 */ not supported -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_cacheflush 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -#define __NR_msync 144 -#define __NR_readv 145 -#define __NR_writev 146 -#define __NR_getsid 147 -#define __NR_fdatasync 148 -#define __NR__sysctl 149 -#define __NR_mlock 150 -#define __NR_munlock 151 -#define __NR_mlockall 152 -#define __NR_munlockall 153 -#define __NR_sched_setparam 154 -#define __NR_sched_getparam 155 -#define __NR_sched_setscheduler 156 -#define __NR_sched_getscheduler 157 -#define __NR_sched_yield 158 -#define __NR_sched_get_priority_max 159 -#define __NR_sched_get_priority_min 160 -#define __NR_sched_rr_get_interval 161 -#define __NR_nanosleep 162 -#define __NR_mremap 163 -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_getpagesize 166 -#define __NR_query_module 167 -#define __NR_poll 168 -#define __NR_nfsservctl 169 -#define __NR_setresgid 170 -#define __NR_getresgid 171 -#define __NR_prctl 172 -#define __NR_rt_sigreturn 173 -#define __NR_rt_sigaction 174 -#define __NR_rt_sigprocmask 175 -#define __NR_rt_sigpending 176 -#define __NR_rt_sigtimedwait 177 -#define __NR_rt_sigqueueinfo 178 -#define __NR_rt_sigsuspend 179 -#define __NR_pread64 180 -#define __NR_pwrite64 181 -#define __NR_lchown 182 -#define __NR_getcwd 183 -#define __NR_capget 184 -#define __NR_capset 185 -#define __NR_sigaltstack 186 -#define __NR_sendfile 187 -#define __NR_getpmsg 188 /* some people actually want streams */ -#define __NR_putpmsg 189 /* some people actually want streams */ -#define __NR_vfork 190 -#define __NR_ugetrlimit 191 -#define __NR_mmap2 192 -#define __NR_truncate64 193 -#define __NR_ftruncate64 194 -#define __NR_stat64 195 -#define __NR_lstat64 196 -#define __NR_fstat64 197 -#define __NR_chown32 198 -#define __NR_getuid32 199 -#define __NR_getgid32 200 -#define __NR_geteuid32 201 -#define __NR_getegid32 202 -#define __NR_setreuid32 203 -#define __NR_setregid32 204 -#define __NR_getgroups32 205 -#define __NR_setgroups32 206 -#define __NR_fchown32 207 -#define __NR_setresuid32 208 -#define __NR_getresuid32 209 -#define __NR_setresgid32 210 -#define __NR_getresgid32 211 -#define __NR_lchown32 212 -#define __NR_setuid32 213 -#define __NR_setgid32 214 -#define __NR_setfsuid32 215 -#define __NR_setfsgid32 216 -#define __NR_pivot_root 217 -#define __NR_getdents64 220 -#define __NR_gettid 221 -#define __NR_tkill 222 -#define __NR_setxattr 223 -#define __NR_lsetxattr 224 -#define __NR_fsetxattr 225 -#define __NR_getxattr 226 -#define __NR_lgetxattr 227 -#define __NR_fgetxattr 228 -#define __NR_listxattr 229 -#define __NR_llistxattr 230 -#define __NR_flistxattr 231 -#define __NR_removexattr 232 -#define __NR_lremovexattr 233 -#define __NR_fremovexattr 234 -#define __NR_futex 235 -#define __NR_sendfile64 236 -#define __NR_mincore 237 -#define __NR_madvise 238 -#define __NR_fcntl64 239 -#define __NR_readahead 240 -#define __NR_io_setup 241 -#define __NR_io_destroy 242 -#define __NR_io_getevents 243 -#define __NR_io_submit 244 -#define __NR_io_cancel 245 -#define __NR_fadvise64 246 -#define __NR_exit_group 247 -#define __NR_lookup_dcookie 248 -#define __NR_epoll_create 249 -#define __NR_epoll_ctl 250 -#define __NR_epoll_wait 251 -#define __NR_remap_file_pages 252 -#define __NR_set_tid_address 253 -#define __NR_timer_create 254 -#define __NR_timer_settime 255 -#define __NR_timer_gettime 256 -#define __NR_timer_getoverrun 257 -#define __NR_timer_delete 258 -#define __NR_clock_settime 259 -#define __NR_clock_gettime 260 -#define __NR_clock_getres 261 -#define __NR_clock_nanosleep 262 -#define __NR_statfs64 263 -#define __NR_fstatfs64 264 -#define __NR_tgkill 265 -#define __NR_utimes 266 -#define __NR_fadvise64_64 267 -#define __NR_mbind 268 -#define __NR_get_mempolicy 269 -#define __NR_set_mempolicy 270 -#define __NR_mq_open 271 -#define __NR_mq_unlink 272 -#define __NR_mq_timedsend 273 -#define __NR_mq_timedreceive 274 -#define __NR_mq_notify 275 -#define __NR_mq_getsetattr 276 -#define __NR_waitid 277 -#define __NR_vserver 278 -#define __NR_add_key 279 -#define __NR_request_key 280 -#define __NR_keyctl 281 -#define __NR_ioprio_set 282 -#define __NR_ioprio_get 283 -#define __NR_inotify_init 284 -#define __NR_inotify_add_watch 285 -#define __NR_inotify_rm_watch 286 -#define __NR_migrate_pages 287 -#define __NR_openat 288 -#define __NR_mkdirat 289 -#define __NR_mknodat 290 -#define __NR_fchownat 291 -#define __NR_futimesat 292 -#define __NR_fstatat64 293 -#define __NR_unlinkat 294 -#define __NR_renameat 295 -#define __NR_linkat 296 -#define __NR_symlinkat 297 -#define __NR_readlinkat 298 -#define __NR_fchmodat 299 -#define __NR_faccessat 300 -#define __NR_pselect6 301 -#define __NR_ppoll 302 -#define __NR_unshare 303 -#define __NR_set_robust_list 304 -#define __NR_get_robust_list 305 -#define __NR_splice 306 -#define __NR_sync_file_range 307 -#define __NR_tee 308 -#define __NR_vmsplice 309 -#define __NR_move_pages 310 -#define __NR_sched_setaffinity 311 -#define __NR_sched_getaffinity 312 -#define __NR_kexec_load 313 -#define __NR_getcpu 314 -#define __NR_epoll_pwait 315 -#define __NR_utimensat 316 -#define __NR_signalfd 317 -#define __NR_timerfd_create 318 -#define __NR_eventfd 319 -#define __NR_fallocate 320 -#define __NR_timerfd_settime 321 -#define __NR_timerfd_gettime 322 -#define __NR_signalfd4 323 -#define __NR_eventfd2 324 -#define __NR_epoll_create1 325 -#define __NR_dup3 326 -#define __NR_pipe2 327 -#define __NR_inotify_init1 328 - -#ifdef __KERNEL__ - -#define NR_syscalls 329 - -#define __ARCH_WANT_IPC_PARSE_VERSION -#define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_SGETMASK -#define __ARCH_WANT_SYS_SIGNAL -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_SOCKETCALL -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT -#define __ARCH_WANT_SYS_OLDUMOUNT -#define __ARCH_WANT_SYS_SIGPENDING -#define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION - -/* - * "Conditional" syscalls - * - * What we want is __attribute__((weak,alias("sys_ni_syscall"))), - * but it doesn't work on all toolchains, so we just do it by hand - */ -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") - -#endif /* __KERNEL__ */ -#endif /* _ASM_M68K_UNISTD_H_ */ +#ifdef __uClinux__ +#include "unistd_no.h" +#else +#include "unistd_mm.h" +#endif diff --git a/trunk/arch/m68k/include/asm/unistd_mm.h b/trunk/arch/m68k/include/asm/unistd_mm.h new file mode 100644 index 000000000000..3c19027331fa --- /dev/null +++ b/trunk/arch/m68k/include/asm/unistd_mm.h @@ -0,0 +1,372 @@ +#ifndef _ASM_M68K_UNISTD_H_ +#define _ASM_M68K_UNISTD_H_ + +/* + * This file contains the system call numbers. + */ + +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl /* 110 */ not supported +#define __NR_vhangup 111 +#define __NR_idle /* 112 */ Obsolete +#define __NR_vm86 /* 113 */ not supported +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_getpagesize 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_lchown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_chown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_lchown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_getdents64 220 +#define __NR_gettid 221 +#define __NR_tkill 222 +#define __NR_setxattr 223 +#define __NR_lsetxattr 224 +#define __NR_fsetxattr 225 +#define __NR_getxattr 226 +#define __NR_lgetxattr 227 +#define __NR_fgetxattr 228 +#define __NR_listxattr 229 +#define __NR_llistxattr 230 +#define __NR_flistxattr 231 +#define __NR_removexattr 232 +#define __NR_lremovexattr 233 +#define __NR_fremovexattr 234 +#define __NR_futex 235 +#define __NR_sendfile64 236 +#define __NR_mincore 237 +#define __NR_madvise 238 +#define __NR_fcntl64 239 +#define __NR_readahead 240 +#define __NR_io_setup 241 +#define __NR_io_destroy 242 +#define __NR_io_getevents 243 +#define __NR_io_submit 244 +#define __NR_io_cancel 245 +#define __NR_fadvise64 246 +#define __NR_exit_group 247 +#define __NR_lookup_dcookie 248 +#define __NR_epoll_create 249 +#define __NR_epoll_ctl 250 +#define __NR_epoll_wait 251 +#define __NR_remap_file_pages 252 +#define __NR_set_tid_address 253 +#define __NR_timer_create 254 +#define __NR_timer_settime 255 +#define __NR_timer_gettime 256 +#define __NR_timer_getoverrun 257 +#define __NR_timer_delete 258 +#define __NR_clock_settime 259 +#define __NR_clock_gettime 260 +#define __NR_clock_getres 261 +#define __NR_clock_nanosleep 262 +#define __NR_statfs64 263 +#define __NR_fstatfs64 264 +#define __NR_tgkill 265 +#define __NR_utimes 266 +#define __NR_fadvise64_64 267 +#define __NR_mbind 268 +#define __NR_get_mempolicy 269 +#define __NR_set_mempolicy 270 +#define __NR_mq_open 271 +#define __NR_mq_unlink 272 +#define __NR_mq_timedsend 273 +#define __NR_mq_timedreceive 274 +#define __NR_mq_notify 275 +#define __NR_mq_getsetattr 276 +#define __NR_waitid 277 +#define __NR_vserver 278 +#define __NR_add_key 279 +#define __NR_request_key 280 +#define __NR_keyctl 281 +#define __NR_ioprio_set 282 +#define __NR_ioprio_get 283 +#define __NR_inotify_init 284 +#define __NR_inotify_add_watch 285 +#define __NR_inotify_rm_watch 286 +#define __NR_migrate_pages 287 +#define __NR_openat 288 +#define __NR_mkdirat 289 +#define __NR_mknodat 290 +#define __NR_fchownat 291 +#define __NR_futimesat 292 +#define __NR_fstatat64 293 +#define __NR_unlinkat 294 +#define __NR_renameat 295 +#define __NR_linkat 296 +#define __NR_symlinkat 297 +#define __NR_readlinkat 298 +#define __NR_fchmodat 299 +#define __NR_faccessat 300 +#define __NR_pselect6 301 +#define __NR_ppoll 302 +#define __NR_unshare 303 +#define __NR_set_robust_list 304 +#define __NR_get_robust_list 305 +#define __NR_splice 306 +#define __NR_sync_file_range 307 +#define __NR_tee 308 +#define __NR_vmsplice 309 +#define __NR_move_pages 310 +#define __NR_sched_setaffinity 311 +#define __NR_sched_getaffinity 312 +#define __NR_kexec_load 313 +#define __NR_getcpu 314 +#define __NR_epoll_pwait 315 +#define __NR_utimensat 316 +#define __NR_signalfd 317 +#define __NR_timerfd_create 318 +#define __NR_eventfd 319 +#define __NR_fallocate 320 +#define __NR_timerfd_settime 321 +#define __NR_timerfd_gettime 322 +#define __NR_signalfd4 323 +#define __NR_eventfd2 324 +#define __NR_epoll_create1 325 +#define __NR_dup3 326 +#define __NR_pipe2 327 +#define __NR_inotify_init1 328 + +#ifdef __KERNEL__ + +#define NR_syscalls 329 + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") + +#endif /* __KERNEL__ */ +#endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/trunk/arch/m68k/include/asm/unistd_no.h b/trunk/arch/m68k/include/asm/unistd_no.h new file mode 100644 index 000000000000..b034a2f7b444 --- /dev/null +++ b/trunk/arch/m68k/include/asm/unistd_no.h @@ -0,0 +1,372 @@ +#ifndef _ASM_M68K_UNISTD_H_ +#define _ASM_M68K_UNISTD_H_ + +/* + * This file contains the system call numbers. + */ + +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl /* 110 */ not supported +#define __NR_vhangup 111 +#define __NR_idle /* 112 */ Obsolete +#define __NR_vm86 /* 113 */ not supported +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_getpagesize 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_lchown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_chown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_lchown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_getdents64 220 +#define __NR_gettid 221 +#define __NR_tkill 222 +#define __NR_setxattr 223 +#define __NR_lsetxattr 224 +#define __NR_fsetxattr 225 +#define __NR_getxattr 226 +#define __NR_lgetxattr 227 +#define __NR_fgetxattr 228 +#define __NR_listxattr 229 +#define __NR_llistxattr 230 +#define __NR_flistxattr 231 +#define __NR_removexattr 232 +#define __NR_lremovexattr 233 +#define __NR_fremovexattr 234 +#define __NR_futex 235 +#define __NR_sendfile64 236 +#define __NR_mincore 237 +#define __NR_madvise 238 +#define __NR_fcntl64 239 +#define __NR_readahead 240 +#define __NR_io_setup 241 +#define __NR_io_destroy 242 +#define __NR_io_getevents 243 +#define __NR_io_submit 244 +#define __NR_io_cancel 245 +#define __NR_fadvise64 246 +#define __NR_exit_group 247 +#define __NR_lookup_dcookie 248 +#define __NR_epoll_create 249 +#define __NR_epoll_ctl 250 +#define __NR_epoll_wait 251 +#define __NR_remap_file_pages 252 +#define __NR_set_tid_address 253 +#define __NR_timer_create 254 +#define __NR_timer_settime 255 +#define __NR_timer_gettime 256 +#define __NR_timer_getoverrun 257 +#define __NR_timer_delete 258 +#define __NR_clock_settime 259 +#define __NR_clock_gettime 260 +#define __NR_clock_getres 261 +#define __NR_clock_nanosleep 262 +#define __NR_statfs64 263 +#define __NR_fstatfs64 264 +#define __NR_tgkill 265 +#define __NR_utimes 266 +#define __NR_fadvise64_64 267 +#define __NR_mbind 268 +#define __NR_get_mempolicy 269 +#define __NR_set_mempolicy 270 +#define __NR_mq_open 271 +#define __NR_mq_unlink 272 +#define __NR_mq_timedsend 273 +#define __NR_mq_timedreceive 274 +#define __NR_mq_notify 275 +#define __NR_mq_getsetattr 276 +#define __NR_waitid 277 +#define __NR_vserver 278 +#define __NR_add_key 279 +#define __NR_request_key 280 +#define __NR_keyctl 281 +#define __NR_ioprio_set 282 +#define __NR_ioprio_get 283 +#define __NR_inotify_init 284 +#define __NR_inotify_add_watch 285 +#define __NR_inotify_rm_watch 286 +#define __NR_migrate_pages 287 +#define __NR_openat 288 +#define __NR_mkdirat 289 +#define __NR_mknodat 290 +#define __NR_fchownat 291 +#define __NR_futimesat 292 +#define __NR_fstatat64 293 +#define __NR_unlinkat 294 +#define __NR_renameat 295 +#define __NR_linkat 296 +#define __NR_symlinkat 297 +#define __NR_readlinkat 298 +#define __NR_fchmodat 299 +#define __NR_faccessat 300 +#define __NR_pselect6 301 +#define __NR_ppoll 302 +#define __NR_unshare 303 +#define __NR_set_robust_list 304 +#define __NR_get_robust_list 305 +#define __NR_splice 306 +#define __NR_sync_file_range 307 +#define __NR_tee 308 +#define __NR_vmsplice 309 +#define __NR_move_pages 310 +#define __NR_sched_setaffinity 311 +#define __NR_sched_getaffinity 312 +#define __NR_kexec_load 313 +#define __NR_getcpu 314 +#define __NR_epoll_pwait 315 +#define __NR_utimensat 316 +#define __NR_signalfd 317 +#define __NR_timerfd_create 318 +#define __NR_eventfd 319 +#define __NR_fallocate 320 +#define __NR_timerfd_settime 321 +#define __NR_timerfd_gettime 322 +#define __NR_signalfd4 323 +#define __NR_eventfd2 324 +#define __NR_epoll_create1 325 +#define __NR_dup3 326 +#define __NR_pipe2 327 +#define __NR_inotify_init1 328 + +#ifdef __KERNEL__ + +#define NR_syscalls 329 + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") + +#endif /* __KERNEL__ */ +#endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 206cb7953b0c..e61465a18c7e 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -238,12 +238,8 @@ config MIPS_SIM This option enables support for MIPS Technologies MIPSsim software emulator. -config NEC_MARKEINS - bool "NEC EMMA2RH Mark-eins board" - select SOC_EMMA2RH - select HW_HAS_PCI - help - This enables support for the NEC Electronics Mark-eins boards. +config MACH_EMMA + bool "NEC EMMA series based machines" config MACH_VR41XX bool "NEC VR4100 series based machines" @@ -641,6 +637,7 @@ endchoice source "arch/mips/alchemy/Kconfig" source "arch/mips/basler/excite/Kconfig" +source "arch/mips/emma/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/lasat/Kconfig" source "arch/mips/pmc-sierra/Kconfig" @@ -898,18 +895,6 @@ config MIPS_RM9122 bool select SERIAL_RM9000 -config SOC_EMMA2RH - bool - select CEVT_R4K - select CSRC_R4K - select DMA_NONCOHERENT - select IRQ_CPU - select SWAP_IO_SPACE - select SYS_HAS_CPU_R5500 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - config SOC_PNX833X bool select CEVT_R4K @@ -945,6 +930,11 @@ config SOC_PNX8550 config SWAP_IO_SPACE bool +config EMMA2RH + bool + depends on MARKEINS + default y + config SERIAL_RM9000 bool diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index 22dab2e14348..21b00e95daef 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -416,7 +416,7 @@ load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000 # # Common NEC EMMAXXX # -core-$(CONFIG_SOC_EMMA2RH) += arch/mips/emma/common/ +core-$(CONFIG_SOC_EMMA) += arch/mips/emma/common/ cflags-$(CONFIG_SOC_EMMA2RH) += -I$(srctree)/arch/mips/include/asm/mach-emma2rh # diff --git a/trunk/arch/mips/configs/markeins_defconfig b/trunk/arch/mips/configs/emma2rh_defconfig similarity index 99% rename from trunk/arch/mips/configs/markeins_defconfig rename to trunk/arch/mips/configs/emma2rh_defconfig index bad8901f8f3c..fea9bc9865a3 100644 --- a/trunk/arch/mips/configs/markeins_defconfig +++ b/trunk/arch/mips/configs/emma2rh_defconfig @@ -35,7 +35,7 @@ CONFIG_ZONE_DMA=y # CONFIG_PNX8550_STB810 is not set # CONFIG_MACH_VR41XX is not set # CONFIG_PMC_YOSEMITE is not set -CONFIG_NEC_MARKEINS=y +CONFIG_MARKEINS=y # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP32 is not set @@ -68,7 +68,7 @@ CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y CONFIG_SWAP_IO_SPACE=y -CONFIG_SOC_EMMA2RH=y +CONFIG_EMMA2RH=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # @@ -574,9 +574,9 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x0 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=0 +CONFIG_MTD_PHYSMAP_START=0x1e000000 +CONFIG_MTD_PHYSMAP_LEN=0x02000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_PLATRAM is not set # diff --git a/trunk/arch/mips/emma/Kconfig b/trunk/arch/mips/emma/Kconfig new file mode 100644 index 000000000000..9669c72123c9 --- /dev/null +++ b/trunk/arch/mips/emma/Kconfig @@ -0,0 +1,29 @@ +choice + prompt "Machine type" + depends on MACH_EMMA + default NEC_MARKEINS + +config NEC_MARKEINS + bool "NEC EMMA2RH Mark-eins board" + select SOC_EMMA2RH + select HW_HAS_PCI + help + This enables support for the NEC Electronics Mark-eins boards. + +endchoice + +config SOC_EMMA2RH + bool + select SOC_EMMA + select SYS_HAS_CPU_R5500 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + +config SOC_EMMA + bool + select CEVT_R4K + select CSRC_R4K + select DMA_NONCOHERENT + select IRQ_CPU + select SWAP_IO_SPACE + select SYS_SUPPORTS_BIG_ENDIAN diff --git a/trunk/arch/mips/emma/markeins/platform.c b/trunk/arch/mips/emma/markeins/platform.c index d5f47e4f0d18..88e87f6b3442 100644 --- a/trunk/arch/mips/emma/markeins/platform.c +++ b/trunk/arch/mips/emma/markeins/platform.c @@ -141,6 +141,13 @@ static struct platform_device serial_emma = { }, }; +static struct platform_device *devices[] = { + &i2c_emma_devices[0], + &i2c_emma_devices[1], + &i2c_emma_devices[2], + &serial_emma, +}; + static struct mtd_partition markeins_parts[] = { [0] = { .name = "RootFS", @@ -174,39 +181,11 @@ static struct mtd_partition markeins_parts[] = { }, }; -static struct physmap_flash_data markeins_flash_data = { - .width = 2, - .nr_parts = ARRAY_SIZE(markeins_parts), - .parts = markeins_parts -}; - -static struct resource markeins_flash_resource = { - .start = 0x1e000000, - .end = 0x02000000, - .flags = IORESOURCE_MEM -}; - -static struct platform_device markeins_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &markeins_flash_data, - }, - .num_resources = 1, - .resource = &markeins_flash_resource, -}; - -static struct platform_device *devices[] = { - i2c_emma_devices, - i2c_emma_devices + 1, - i2c_emma_devices + 2, - &serial_emma, - &markeins_flash_device, -}; - static int __init platform_devices_setup(void) { + physmap_set_partitions(markeins_parts, ARRAY_SIZE(markeins_parts)); return platform_add_devices(devices, ARRAY_SIZE(devices)); } arch_initcall(platform_devices_setup); + diff --git a/trunk/arch/mips/include/asm/seccomp.h b/trunk/arch/mips/include/asm/seccomp.h index ae6306ebdcad..a6772e9507f5 100644 --- a/trunk/arch/mips/include/asm/seccomp.h +++ b/trunk/arch/mips/include/asm/seccomp.h @@ -15,6 +15,8 @@ */ #ifdef CONFIG_MIPS32_O32 +#define TIF_32BIT TIF_32BIT_REGS + #define __NR_seccomp_read_32 4003 #define __NR_seccomp_write_32 4004 #define __NR_seccomp_exit_32 4001 @@ -22,6 +24,8 @@ #elif defined(CONFIG_MIPS32_N32) +#define TIF_32BIT _TIF_32BIT_ADDR + #define __NR_seccomp_read_32 6000 #define __NR_seccomp_write_32 6001 #define __NR_seccomp_exit_32 6058 diff --git a/trunk/arch/mips/include/asm/thread_info.h b/trunk/arch/mips/include/asm/thread_info.h index 676aa2ae1913..3f76de73c943 100644 --- a/trunk/arch/mips/include/asm/thread_info.h +++ b/trunk/arch/mips/include/asm/thread_info.h @@ -127,12 +127,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ -#ifdef CONFIG_MIPS32_O32 -#define TIF_32BIT TIF_32BIT_REGS -#elif defined(CONFIG_MIPS32_N32) -#define TIF_32BIT _TIF_32BIT_ADDR -#endif /* CONFIG_MIPS32_O32 */ - #define _TIF_SYSCALL_TRACE (1< #include -#include #include @@ -130,27 +129,27 @@ /* Shift Left - note the r and t can NOT be the same! */ .macro shl r, sa, t - dep,z \r, 31-(\sa), 32-(\sa), \t + dep,z \r, 31-\sa, 32-\sa, \t .endm /* The PA 2.0 shift left */ .macro shlw r, sa, t - depw,z \r, 31-(\sa), 32-(\sa), \t + depw,z \r, 31-\sa, 32-\sa, \t .endm /* And the PA 2.0W shift left */ .macro shld r, sa, t - depd,z \r, 63-(\sa), 64-(\sa), \t + depd,z \r, 63-\sa, 64-\sa, \t .endm /* Shift Right - note the r and t can NOT be the same! */ .macro shr r, sa, t - extru \r, 31-(\sa), 32-(\sa), \t + extru \r, 31-\sa, 32-\sa, \t .endm /* pa20w version of shift right */ .macro shrd r, sa, t - extrd,u \r, 63-(\sa), 64-(\sa), \t + extrd,u \r, 63-\sa, 64-\sa, \t .endm /* load 32-bit 'value' into 'reg' compensating for the ldil diff --git a/trunk/arch/parisc/include/asm/io.h b/trunk/arch/parisc/include/asm/io.h index 1f6d2ae7aba5..d3031d1f9d03 100644 --- a/trunk/arch/parisc/include/asm/io.h +++ b/trunk/arch/parisc/include/asm/io.h @@ -174,48 +174,15 @@ static inline void __raw_writeq(unsigned long long b, volatile void __iomem *add *(volatile unsigned long long __force *) addr = b; } -static inline unsigned char readb(const volatile void __iomem *addr) -{ - return __raw_readb(addr); -} -static inline unsigned short readw(const volatile void __iomem *addr) -{ - return le16_to_cpu(__raw_readw(addr)); -} -static inline unsigned int readl(const volatile void __iomem *addr) -{ - return le32_to_cpu(__raw_readl(addr)); -} -static inline unsigned long long readq(const volatile void __iomem *addr) -{ - return le64_to_cpu(__raw_readq(addr)); -} - -static inline void writeb(unsigned char b, volatile void __iomem *addr) -{ - __raw_writeb(b, addr); -} -static inline void writew(unsigned short w, volatile void __iomem *addr) -{ - __raw_writew(cpu_to_le16(w), addr); -} -static inline void writel(unsigned int l, volatile void __iomem *addr) -{ - __raw_writel(cpu_to_le32(l), addr); -} -static inline void writeq(unsigned long long q, volatile void __iomem *addr) -{ - __raw_writeq(cpu_to_le64(q), addr); -} - -#define readb readb -#define readw readw -#define readl readl -#define readq readq -#define writeb writeb -#define writew writew -#define writel writel -#define writeq writeq +/* readb can never be const, so use __fswab instead of le*_to_cpu */ +#define readb(addr) __raw_readb(addr) +#define readw(addr) le16_to_cpu(__raw_readw(addr)) +#define readl(addr) le32_to_cpu(__raw_readl(addr)) +#define readq(addr) le64_to_cpu(__raw_readq(addr)) +#define writeb(b, addr) __raw_writeb(b, addr) +#define writew(b, addr) __raw_writew(cpu_to_le16(b), addr) +#define writel(b, addr) __raw_writel(cpu_to_le32(b), addr) +#define writeq(b, addr) __raw_writeq(cpu_to_le64(b), addr) #define readb_relaxed(addr) readb(addr) #define readw_relaxed(addr) readw(addr) diff --git a/trunk/arch/parisc/include/asm/irq.h b/trunk/arch/parisc/include/asm/irq.h index dfa26b67f919..399c81981ed5 100644 --- a/trunk/arch/parisc/include/asm/irq.h +++ b/trunk/arch/parisc/include/asm/irq.h @@ -49,7 +49,7 @@ extern unsigned long txn_alloc_addr(unsigned int); extern unsigned long txn_affinity_addr(unsigned int irq, int cpu); extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *); -extern int cpu_check_affinity(unsigned int irq, const struct cpumask *dest); +extern int cpu_check_affinity(unsigned int irq, cpumask_t *dest); /* soft power switch support (power.c) */ extern struct tasklet_struct power_tasklet; diff --git a/trunk/arch/parisc/include/asm/uaccess.h b/trunk/arch/parisc/include/asm/uaccess.h index cd4c0b2a8e70..1c6dbb6f6e56 100644 --- a/trunk/arch/parisc/include/asm/uaccess.h +++ b/trunk/arch/parisc/include/asm/uaccess.h @@ -241,7 +241,6 @@ unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned lo #define __copy_to_user_inatomic __copy_to_user #define __copy_from_user_inatomic __copy_from_user -struct pt_regs; int fixup_exception(struct pt_regs *regs); #endif /* __PARISC_UACCESS_H */ diff --git a/trunk/arch/parisc/kernel/cache.c b/trunk/arch/parisc/kernel/cache.c index 837530ea32e7..5259d8c20676 100644 --- a/trunk/arch/parisc/kernel/cache.c +++ b/trunk/arch/parisc/kernel/cache.c @@ -551,7 +551,10 @@ void flush_cache_range(struct vm_area_struct *vma, { int sr3; - BUG_ON(!vma->vm_mm->context); + if (!vma->vm_mm->context) { + BUG(); + return; + } sr3 = mfsp(3); if (vma->vm_mm->context == sr3) { diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index 0db9fdcb7709..d1fa4edd2d80 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -368,7 +368,7 @@ * abstractions for the macros */ .macro EXTR reg1,start,length,reg2 #ifdef CONFIG_64BIT - extrd,u \reg1,32+(\start),\length,\reg2 + extrd,u \reg1,32+\start,\length,\reg2 #else extrw,u \reg1,\start,\length,\reg2 #endif @@ -376,7 +376,7 @@ .macro DEP reg1,start,length,reg2 #ifdef CONFIG_64BIT - depd \reg1,32+(\start),\length,\reg2 + depd \reg1,32+\start,\length,\reg2 #else depw \reg1,\start,\length,\reg2 #endif @@ -384,7 +384,7 @@ .macro DEPI val,start,length,reg #ifdef CONFIG_64BIT - depdi \val,32+(\start),\length,\reg + depdi \val,32+\start,\length,\reg #else depwi \val,\start,\length,\reg #endif diff --git a/trunk/arch/parisc/kernel/firmware.c b/trunk/arch/parisc/kernel/firmware.c index f6d241238a78..03f26bd75bd8 100644 --- a/trunk/arch/parisc/kernel/firmware.c +++ b/trunk/arch/parisc/kernel/firmware.c @@ -151,7 +151,7 @@ static void convert_to_wide(unsigned long *addr) } #ifdef CONFIG_64BIT -void __cpuinit set_firmware_width_unlocked(void) +void __init set_firmware_width_unlocked(void) { int ret; @@ -168,7 +168,7 @@ void __cpuinit set_firmware_width_unlocked(void) * This function must be called before any pdc_* function that uses the * convert_to_wide function. */ -void __cpuinit set_firmware_width(void) +void __init set_firmware_width(void) { unsigned long flags; spin_lock_irqsave(&pdc_lock, flags); @@ -176,11 +176,11 @@ void __cpuinit set_firmware_width(void) spin_unlock_irqrestore(&pdc_lock, flags); } #else -void __cpuinit set_firmware_width_unlocked(void) { +void __init set_firmware_width_unlocked(void) { return; } -void __cpuinit set_firmware_width(void) { +void __init set_firmware_width(void) { return; } #endif /*CONFIG_64BIT*/ @@ -302,7 +302,7 @@ int pdc_chassis_warn(unsigned long *warn) return retval; } -int __cpuinit pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info) +int __init pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info) { int ret; @@ -323,7 +323,7 @@ int __cpuinit pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info) * This PDC call returns the presence and status of all the coprocessors * attached to the processor. */ -int __cpuinit pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info) +int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info) { int ret; unsigned long flags; diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index 29e70e16ede8..ac2c822928c7 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -112,7 +112,7 @@ void cpu_end_irq(unsigned int irq) } #ifdef CONFIG_SMP -int cpu_check_affinity(unsigned int irq, const struct cpumask *dest) +int cpu_check_affinity(unsigned int irq, cpumask_t *dest) { int cpu_dest; @@ -120,25 +120,23 @@ int cpu_check_affinity(unsigned int irq, const struct cpumask *dest) if (CHECK_IRQ_PER_CPU(irq)) { /* Bad linux design decision. The mask has already * been set; we must reset it */ - cpumask_setall(&irq_desc[irq].affinity); + irq_desc[irq].affinity = CPU_MASK_ALL; return -EINVAL; } /* whatever mask they set, we just allow one CPU */ cpu_dest = first_cpu(*dest); + *dest = cpumask_of_cpu(cpu_dest); - return cpu_dest; + return 0; } static void cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest) { - int cpu_dest; - - cpu_dest = cpu_check_affinity(irq, dest); - if (cpu_dest < 0) + if (cpu_check_affinity(irq, dest)) return; - cpumask_copy(&irq_desc[irq].affinity, &cpumask_of_cpu(cpu_dest)); + irq_desc[irq].affinity = *dest; } #endif @@ -297,7 +295,7 @@ int txn_alloc_irq(unsigned int bits_wide) unsigned long txn_affinity_addr(unsigned int irq, int cpu) { #ifdef CONFIG_SMP - cpumask_copy(&irq_desc[irq].affinity, cpumask_of(cpu)); + irq_desc[irq].affinity = cpumask_of_cpu(cpu); #endif return per_cpu(cpu_data, cpu).txn_addr; @@ -354,7 +352,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) irq = eirr_to_irq(eirr_val); #ifdef CONFIG_SMP - cpumask_copy(&dest, &irq_desc[irq].affinity); + dest = irq_desc[irq].affinity; if (CHECK_IRQ_PER_CPU(irq_desc[irq].status) && !cpu_isset(smp_processor_id(), dest)) { int cpu = first_cpu(dest); diff --git a/trunk/arch/parisc/kernel/pci-dma.c b/trunk/arch/parisc/kernel/pci-dma.c index 7d927eac932b..df47895db828 100644 --- a/trunk/arch/parisc/kernel/pci-dma.c +++ b/trunk/arch/parisc/kernel/pci-dma.c @@ -447,7 +447,10 @@ static void pa11_dma_free_consistent (struct device *dev, size_t size, void *vad static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); + if (direction == DMA_NONE) { + printk(KERN_ERR "pa11_dma_map_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0)); + BUG(); + } flush_kernel_dcache_range((unsigned long) addr, size); return virt_to_phys(addr); @@ -455,7 +458,10 @@ static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t siz static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); + if (direction == DMA_NONE) { + printk(KERN_ERR "pa11_dma_unmap_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0)); + BUG(); + } if (direction == DMA_TO_DEVICE) return; @@ -474,7 +480,8 @@ static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist, int n { int i; - BUG_ON(direction == DMA_NONE); + if (direction == DMA_NONE) + BUG(); for (i = 0; i < nents; i++, sglist++ ) { unsigned long vaddr = sg_virt_addr(sglist); @@ -489,7 +496,8 @@ static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, in { int i; - BUG_ON(direction == DMA_NONE); + if (direction == DMA_NONE) + BUG(); if (direction == DMA_TO_DEVICE) return; @@ -503,14 +511,16 @@ static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, in static void pa11_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); + if (direction == DMA_NONE) + BUG(); flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size); } static void pa11_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); + if (direction == DMA_NONE) + BUG(); flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size); } diff --git a/trunk/arch/parisc/mm/init.c b/trunk/arch/parisc/mm/init.c index 9d704d9831d1..7c155c254e72 100644 --- a/trunk/arch/parisc/mm/init.c +++ b/trunk/arch/parisc/mm/init.c @@ -304,8 +304,10 @@ static void __init setup_bootmem(void) */ max_low_pfn = max_pfn; - /* bootmap sizing messed up? */ - BUG_ON((bootmap_pfn - bootmap_start_pfn) != bootmap_pages); + if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) { + printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n"); + BUG(); + } /* reserve PAGE0 pdc memory, kernel text/data/bss & bootmap */ diff --git a/trunk/arch/powerpc/configs/ps3_defconfig b/trunk/arch/powerpc/configs/ps3_defconfig index ac14f5245d2a..b6eee7c93cdd 100644 --- a/trunk/arch/powerpc/configs/ps3_defconfig +++ b/trunk/arch/powerpc/configs/ps3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc8 -# Fri Mar 13 09:28:45 2009 +# Linux kernel version: 2.6.27-rc3 +# Wed Aug 20 08:16:53 2008 # CONFIG_PPC64=y @@ -16,14 +16,13 @@ CONFIG_PPC_FPU=y CONFIG_ALTIVEC=y # CONFIG_VSX is not set CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_64=y CONFIG_PPC_MM_SLICES=y CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_64BIT=y CONFIG_WORD_SIZE=64 -CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_TIME=y @@ -47,7 +46,7 @@ CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y CONFIG_SYSVIPC_COMPAT=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -75,19 +74,10 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -96,13 +86,11 @@ CONFIG_NAMESPACES=y # CONFIG_IPC_NS is not set # CONFIG_USER_NS is not set # CONFIG_PID_NS is not set -# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y +# CONFIG_EMBEDDED is not set CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y @@ -111,36 +99,37 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y -# CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y -CONFIG_MARKERS=y +# CONFIG_MARKERS is not set CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_SYSCALL_WRAPPERS=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_USE_GENERIC_SMP_HELPERS=y +# CONFIG_HAVE_CLK is not set +CONFIG_PROC_PAGE_MONITOR=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -148,6 +137,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set @@ -167,7 +157,7 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_FREEZER is not set +CONFIG_CLASSIC_RCU=y # # Platform support @@ -193,20 +183,18 @@ CONFIG_PS3_STORAGE=y CONFIG_PS3_DISK=y CONFIG_PS3_ROM=y CONFIG_PS3_FLASH=y -CONFIG_PS3_VRAM=m +CONFIG_OPROFILE_PS3=y CONFIG_PS3_LPM=m CONFIG_PPC_CELL=y # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_IBM_CELL_BLADE is not set # CONFIG_PPC_CELLEB is not set -# CONFIG_PPC_CELL_QPACE is not set # # Cell Broadband Engine options # CONFIG_SPU_FS=y CONFIG_SPU_FS_64K_LS=y -# CONFIG_SPU_TRACE is not set CONFIG_SPU_BASE=y # CONFIG_PQ2ADS is not set # CONFIG_IPIC is not set @@ -222,7 +210,6 @@ CONFIG_SPU_BASE=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set -# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -242,8 +229,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=y CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y # CONFIG_IOMMU_VMERGE is not set @@ -266,6 +251,7 @@ CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y # CONFIG_SPARSEMEM_VMEMMAP is not set @@ -275,14 +261,11 @@ CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y -CONFIG_UNEVICTABLE_LRU=y CONFIG_ARCH_MEMORY_PROBE=y CONFIG_PPC_HAS_HASH_64K=y -CONFIG_PPC_4K_PAGES=y -# CONFIG_PPC_16K_PAGES is not set # CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_SCHED_SMT=y @@ -316,7 +299,6 @@ CONFIG_NET=y # # Networking options # -CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -379,7 +361,6 @@ CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -390,7 +371,6 @@ CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set # # Network testing @@ -412,37 +392,39 @@ CONFIG_BT_HIDP=m # # Bluetooth device drivers # -CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y # CONFIG_BT_HCIUART is not set # CONFIG_BT_HCIBCM203X is not set # CONFIG_BT_HCIBPA10X is not set # CONFIG_BT_HCIBFUSB is not set # CONFIG_BT_HCIVHCI is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y + +# +# Wireless +# CONFIG_CFG80211=m -# CONFIG_CFG80211_REG_DEBUG is not set CONFIG_NL80211=y -# CONFIG_WIRELESS_OLD_REGULATORY is not set CONFIG_WIRELESS_EXT=y # CONFIG_WIRELESS_EXT_SYSFS is not set -# CONFIG_LIB80211 is not set CONFIG_MAC80211=m # # Rate control algorithm selection # CONFIG_MAC80211_RC_PID=y -# CONFIG_MAC80211_RC_MINSTREL is not set CONFIG_MAC80211_RC_DEFAULT_PID=y -# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set CONFIG_MAC80211_RC_DEFAULT="pid" # CONFIG_MAC80211_MESH is not set # CONFIG_MAC80211_LEDS is not set # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_WIMAX is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -468,7 +450,6 @@ CONFIG_MTD_DEBUG=y CONFIG_MTD_DEBUG_VERBOSE=0 # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_PARTITIONS is not set -# CONFIG_MTD_TESTS is not set # # User Modules And Translation Layers @@ -513,6 +494,7 @@ CONFIG_MTD_CFI_I2=y # # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set +CONFIG_MTD_PS3VRAM=y # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLOCK2MTD is not set @@ -525,11 +507,6 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set - # # UBI - Unsorted block images # @@ -551,13 +528,8 @@ CONFIG_BLK_DEV_RAM_SIZE=65535 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# # CONFIG_EEPROM_93CX6 is not set +# CONFIG_ENCLOSURE_SERVICES is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -603,17 +575,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set # CONFIG_ATA is not set -CONFIG_MD=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -# CONFIG_DM_CRYPT is not set -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_UEVENT is not set +# CONFIG_MD is not set # CONFIG_MACINTOSH_DRIVERS is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set @@ -629,9 +591,6 @@ CONFIG_MII=m # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set CONFIG_NETDEV_1000=y CONFIG_GELIC_NET=y @@ -645,7 +604,6 @@ CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=y # CONFIG_WLAN_PRE80211 is not set CONFIG_WLAN_80211=y # CONFIG_LIBERTAS is not set -# CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_USB_ZD1201 is not set # CONFIG_USB_NET_RNDIS_WLAN is not set # CONFIG_RTL8187 is not set @@ -657,11 +615,13 @@ CONFIG_WLAN_80211=y # CONFIG_B43LEGACY is not set CONFIG_ZD1211RW=m # CONFIG_ZD1211RW_DEBUG is not set -# CONFIG_RT2X00 is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# +CONFIG_RT2X00=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +# CONFIG_RT2500USB is not set +CONFIG_RT73USB=m +# CONFIG_RT2X00_DEBUG is not set # # USB Network Adapters @@ -674,7 +634,6 @@ CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m # CONFIG_USB_NET_CDCETHER is not set # CONFIG_USB_NET_DM9601 is not set -# CONFIG_USB_NET_SMSC95XX is not set # CONFIG_USB_NET_GL620A is not set # CONFIG_USB_NET_NET1080 is not set # CONFIG_USB_NET_PLUSB is not set @@ -705,7 +664,7 @@ CONFIG_SLHC=m # Input device support # CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set # @@ -776,10 +735,8 @@ CONFIG_DEVKMEM=y # Non-8250 serial port support # CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=16 -# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -796,11 +753,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_THERMAL is not set # CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # +CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -810,7 +767,6 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set -# CONFIG_REGULATOR is not set # # Multimedia devices @@ -836,7 +792,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set # CONFIG_FB_CFB_FILLRECT is not set # CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_IMAGEBLIT is not set @@ -862,8 +817,6 @@ CONFIG_FB_SYS_FOPS=y CONFIG_FB_PS3=y CONFIG_FB_PS3_DEFAULT_SIZE_M=9 # CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -888,7 +841,6 @@ CONFIG_FB_LOGO_EXTRA=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=m -# CONFIG_SOUND_OSS_CORE is not set CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -897,7 +849,6 @@ CONFIG_SND_RAWMIDI=m # CONFIG_SND_SEQUENCER is not set # CONFIG_SND_MIXER_OSS is not set # CONFIG_SND_PCM_OSS is not set -# CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y @@ -922,40 +873,15 @@ CONFIG_HIDRAW=y # USB Input Devices # CONFIG_USB_HID=m -# CONFIG_HID_PID is not set -CONFIG_USB_HIDDEV=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set # # USB HID Boot Protocol drivers # # CONFIG_USB_KBD is not set # CONFIG_USB_MOUSE is not set - -# -# Special HID drivers -# -# CONFIG_HID_COMPAT is not set -# CONFIG_HID_A4TECH is not set -# CONFIG_HID_APPLE is not set -# CONFIG_HID_BELKIN is not set -# CONFIG_HID_CHERRY is not set -# CONFIG_HID_CHICONY is not set -# CONFIG_HID_CYPRESS is not set -# CONFIG_HID_EZKEY is not set -# CONFIG_HID_GYRATION is not set -# CONFIG_HID_LOGITECH is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -# CONFIG_HID_NTRIG is not set -# CONFIG_HID_PANTHERLORD is not set -# CONFIG_HID_PETALYNX is not set -# CONFIG_HID_SAMSUNG is not set -# CONFIG_HID_SONY is not set -# CONFIG_HID_SUNPLUS is not set -# CONFIG_GREENASIA_FF is not set -# CONFIG_HID_TOPSEED is not set -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_ZEROPLUS_FF is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -972,11 +898,7 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_DYNAMIC_MINORS is not set CONFIG_USB_SUSPEND=y # CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=m -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set +CONFIG_USB_MON=y # # USB Host Controller Drivers @@ -987,7 +909,6 @@ CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_TT_NEWSCHED is not set CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y # CONFIG_USB_EHCI_HCD_PPC_OF is not set -# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set CONFIG_USB_OHCI_HCD=m @@ -997,7 +918,6 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HWA_HCD is not set # # Enable Host or Gadget support to see Inventra options @@ -1009,20 +929,20 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set # CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # # -# see USB_STORAGE Help for more information +# may also be needed; see USB_STORAGE Help for more information # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1030,6 +950,7 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_SIERRA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set @@ -1050,7 +971,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set @@ -1068,12 +988,7 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -1099,15 +1014,12 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1116,7 +1028,6 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_PPC=m # CONFIG_DMADEVICES is not set # CONFIG_UIO is not set -# CONFIG_STAGING is not set # # File systems @@ -1124,35 +1035,26 @@ CONFIG_RTC_DRV_PPC=m CONFIG_EXT2_FS=m # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=m +CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -CONFIG_EXT4_FS=y -# CONFIG_EXT4DEV_COMPAT is not set -CONFIG_EXT4_FS_XATTR=y -# CONFIG_EXT4_FS_POSIX_ACL is not set -# CONFIG_EXT4_FS_SECURITY is not set -CONFIG_JBD=m +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y # CONFIG_QUOTA_NETLINK_INTERFACE is not set CONFIG_PRINT_QUOTA_WARNING=y -CONFIG_QUOTA_TREE=y # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y @@ -1185,14 +1087,16 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y # CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1202,7 +1106,6 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1223,7 +1126,6 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y -# CONFIG_SUNRPC_REGISTER_V4 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1288,9 +1190,9 @@ CONFIG_NLS_ISO8859_1=y # Library routines # CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set CONFIG_CRC_CCITT=m -CONFIG_CRC16=y +# CONFIG_CRC16 is not set CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=m CONFIG_CRC32=y @@ -1348,44 +1250,27 @@ CONFIG_DEBUG_WRITECOUNT=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_LIST=y # CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_RING_BUFFER=y -CONFIG_TRACING=y - -# -# Tracers -# -# CONFIG_FUNCTION_TRACER is not set +# CONFIG_FTRACE is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_FTRACE_STARTUP_TEST is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set -CONFIG_PRINT_STACK_DEPTH=64 CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_CODE_PATCHING_SELFTEST is not set # CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_MSI_BITMAP_SELFTEST is not set # CONFIG_XMON is not set CONFIG_IRQSTACKS=y # CONFIG_VIRQ_DEBUG is not set @@ -1397,26 +1282,16 @@ CONFIG_IRQSTACKS=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=m -CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_GF128MUL=m # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set @@ -1488,11 +1363,6 @@ CONFIG_CRYPTO_SALSA20=m # # CONFIG_CRYPTO_DEFLATE is not set CONFIG_CRYPTO_LZO=m - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_PPC_CLOCK is not set # CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/include/asm/cputable.h b/trunk/arch/powerpc/include/asm/cputable.h index 21172badd708..4911104791c3 100644 --- a/trunk/arch/powerpc/include/asm/cputable.h +++ b/trunk/arch/powerpc/include/asm/cputable.h @@ -241,11 +241,9 @@ extern const char *powerpc_base_platform; /* We need to mark all pages as being coherent if we're SMP or we have a * 74[45]x and an MPC107 host bridge. Also 83xx and PowerQUICC II * require it for PCI "streaming/prefetch" to work properly. - * This is also required by 52xx family. */ #if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE) \ - || defined(CONFIG_PPC_83xx) || defined(CONFIG_8260) \ - || defined(CONFIG_PPC_MPC52xx) + || defined(CONFIG_PPC_83xx) || defined(CONFIG_8260) #define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT #else #define CPU_FTR_COMMON 0 diff --git a/trunk/arch/powerpc/kernel/head_32.S b/trunk/arch/powerpc/kernel/head_32.S index d794a637e421..a1c4cfd25ded 100644 --- a/trunk/arch/powerpc/kernel/head_32.S +++ b/trunk/arch/powerpc/kernel/head_32.S @@ -511,11 +511,8 @@ InstructionTLBMiss: and r1,r1,r2 /* writable if _RW and _DIRTY */ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ - ori r1,r1,0xe04 /* clear out reserved bits */ + ori r1,r1,0xe14 /* clear out reserved bits and M */ andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ -BEGIN_FTR_SECTION - rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ -END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) mtspr SPRN_RPA,r1 mfspr r3,SPRN_IMISS tlbli r3 @@ -588,11 +585,8 @@ DataLoadTLBMiss: and r1,r1,r2 /* writable if _RW and _DIRTY */ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ - ori r1,r1,0xe04 /* clear out reserved bits */ + ori r1,r1,0xe14 /* clear out reserved bits and M */ andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ -BEGIN_FTR_SECTION - rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ -END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) mtspr SPRN_RPA,r1 mfspr r3,SPRN_DMISS tlbld r3 @@ -659,11 +653,8 @@ DataStoreTLBMiss: stw r3,0(r2) /* update PTE (accessed/dirty bits) */ /* Convert linux-style PTE to low word of PPC-style PTE */ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ - li r1,0xe05 /* clear out reserved bits & PP lsb */ + li r1,0xe15 /* clear out reserved bits and M */ andc r1,r3,r1 /* PP = user? 2: 0 */ -BEGIN_FTR_SECTION - rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ -END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) mtspr SPRN_RPA,r1 mfspr r3,SPRN_DMISS tlbld r3 diff --git a/trunk/arch/powerpc/platforms/ps3/Kconfig b/trunk/arch/powerpc/platforms/ps3/Kconfig index 740ef56a1550..920cf7a454b1 100644 --- a/trunk/arch/powerpc/platforms/ps3/Kconfig +++ b/trunk/arch/powerpc/platforms/ps3/Kconfig @@ -128,13 +128,6 @@ config PS3_FLASH be disabled on the kernel command line using "ps3flash=off", to not allocate this fixed buffer. -config PS3_VRAM - tristate "PS3 Video RAM Storage Driver" - depends on FB_PS3=y && BLOCK && m - help - This driver allows you to use excess PS3 video RAM as volatile - storage or system swap. - config PS3_LPM tristate "PS3 Logical Performance Monitor support" depends on PPC_PS3 diff --git a/trunk/arch/s390/include/asm/mman.h b/trunk/arch/s390/include/asm/mman.h index da01432e8f44..7839767d837e 100644 --- a/trunk/arch/s390/include/asm/mman.h +++ b/trunk/arch/s390/include/asm/mman.h @@ -22,9 +22,4 @@ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#if defined(__KERNEL__) && !defined(__ASSEMBLY__) && defined(CONFIG_64BIT) -int s390_mmap_check(unsigned long addr, unsigned long len); -#define arch_mmap_check(addr,len,flags) s390_mmap_check(addr,len) -#endif - #endif /* __S390_MMAN_H__ */ diff --git a/trunk/arch/s390/include/asm/processor.h b/trunk/arch/s390/include/asm/processor.h index db4523fe38ac..066b99502e09 100644 --- a/trunk/arch/s390/include/asm/processor.h +++ b/trunk/arch/s390/include/asm/processor.h @@ -61,7 +61,7 @@ extern void print_cpu_info(struct cpuinfo_S390 *); extern int get_cpu_capability(unsigned int *); /* - * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. + * User space process size: 2GB for 31 bit, 4TB for 64 bit. */ #ifndef __s390x__ @@ -70,7 +70,8 @@ extern int get_cpu_capability(unsigned int *); #else /* __s390x__ */ -#define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit) +#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \ + (1UL << 31) : (1UL << 53)) #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ (1UL << 30) : (1UL << 41)) #define TASK_SIZE TASK_SIZE_OF(current) diff --git a/trunk/arch/s390/include/asm/topology.h b/trunk/arch/s390/include/asm/topology.h index c979c3b56ab0..c93eb50e1d09 100644 --- a/trunk/arch/s390/include/asm/topology.h +++ b/trunk/arch/s390/include/asm/topology.h @@ -30,8 +30,6 @@ static inline void s390_init_cpu_topology(void) }; #endif -#define SD_MC_INIT SD_CPU_INIT - #include #endif /* _ASM_S390_TOPOLOGY_H */ diff --git a/trunk/arch/s390/kernel/mcount.S b/trunk/arch/s390/kernel/mcount.S index 80641224a095..397d131a345f 100644 --- a/trunk/arch/s390/kernel/mcount.S +++ b/trunk/arch/s390/kernel/mcount.S @@ -5,8 +5,6 @@ * */ -#include - #ifndef CONFIG_64BIT .globl _mcount _mcount: @@ -16,7 +14,7 @@ _mcount: ahi %r15,-96 l %r3,100(%r15) la %r2,0(%r14) - st %r1,__SF_BACKCHAIN(%r15) + st %r1,0(%r15) la %r3,0(%r3) bras %r14,0f .long ftrace_trace_function @@ -40,7 +38,7 @@ _mcount: stg %r14,112(%r15) lgr %r1,%r15 aghi %r15,-160 - stg %r1,__SF_BACKCHAIN(%r15) + stg %r1,0(%r15) lgr %r2,%r14 lg %r3,168(%r15) larl %r14,ftrace_trace_function diff --git a/trunk/arch/s390/lib/div64.c b/trunk/arch/s390/lib/div64.c index d9e62c0b576a..a5f8300bf3ee 100644 --- a/trunk/arch/s390/lib/div64.c +++ b/trunk/arch/s390/lib/div64.c @@ -61,7 +61,7 @@ static uint32_t __div64_31(uint64_t *n, uint32_t base) " clr %0,%3\n" " jl 0f\n" " slr %0,%3\n" - " ahi %1,1\n" + " alr %1,%2\n" "0:\n" : "+d" (reg2), "+d" (reg3), "=d" (tmp) : "d" (base), "2" (1UL) : "cc" ); diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c index b0b84c35b0ad..d66215b0fde9 100644 --- a/trunk/arch/s390/lib/uaccess_pt.c +++ b/trunk/arch/s390/lib/uaccess_pt.c @@ -119,6 +119,8 @@ static size_t __user_copy_pt(unsigned long uaddr, void *kptr, goto fault; pfn = pte_pfn(*pte); + if (!pfn_valid(pfn)) + goto out; offset = uaddr & (PAGE_SIZE - 1); size = min(n - done, PAGE_SIZE - offset); @@ -133,6 +135,7 @@ static size_t __user_copy_pt(unsigned long uaddr, void *kptr, done += size; uaddr += size; } while (done < n); +out: spin_unlock(&mm->page_table_lock); return n - done; fault: @@ -160,6 +163,9 @@ static unsigned long __dat_user_addr(unsigned long uaddr) goto fault; pfn = pte_pfn(*pte); + if (!pfn_valid(pfn)) + goto out; + ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1)); out: return ret; @@ -238,6 +244,11 @@ static size_t strnlen_user_pt(size_t count, const char __user *src) goto fault; pfn = pte_pfn(*pte); + if (!pfn_valid(pfn)) { + done = -1; + goto out; + } + offset = uaddr & (PAGE_SIZE-1); addr = (char *)(pfn << PAGE_SHIFT) + offset; len = min(count - done, PAGE_SIZE - offset); @@ -245,6 +256,7 @@ static size_t strnlen_user_pt(size_t count, const char __user *src) done += len_str; uaddr += len_str; } while ((len_str == len) && (done < count)); +out: spin_unlock(&mm->page_table_lock); return done + 1; fault: @@ -313,7 +325,12 @@ static size_t copy_in_user_pt(size_t n, void __user *to, } pfn_from = pte_pfn(*pte_from); + if (!pfn_valid(pfn_from)) + goto out; pfn_to = pte_pfn(*pte_to); + if (!pfn_valid(pfn_to)) + goto out; + offset_from = uaddr_from & (PAGE_SIZE-1); offset_to = uaddr_from & (PAGE_SIZE-1); offset_max = max(offset_from, offset_to); @@ -325,6 +342,7 @@ static size_t copy_in_user_pt(size_t n, void __user *to, uaddr_from += size; uaddr_to += size; } while (done < n); +out: spin_unlock(&mm->page_table_lock); return n - done; fault: diff --git a/trunk/arch/s390/mm/mmap.c b/trunk/arch/s390/mm/mmap.c index e008d236cc15..5932a824547a 100644 --- a/trunk/arch/s390/mm/mmap.c +++ b/trunk/arch/s390/mm/mmap.c @@ -35,7 +35,7 @@ * Leave an at least ~128 MB hole. */ #define MIN_GAP (128*1024*1024) -#define MAX_GAP (STACK_TOP/6*5) +#define MAX_GAP (TASK_SIZE/6*5) static inline unsigned long mmap_base(void) { @@ -46,7 +46,7 @@ static inline unsigned long mmap_base(void) else if (gap > MAX_GAP) gap = MAX_GAP; - return STACK_TOP - (gap & PAGE_MASK); + return TASK_SIZE - (gap & PAGE_MASK); } static inline int mmap_is_legacy(void) @@ -89,58 +89,42 @@ EXPORT_SYMBOL_GPL(arch_pick_mmap_layout); #else -int s390_mmap_check(unsigned long addr, unsigned long len) -{ - if (!test_thread_flag(TIF_31BIT) && - len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) - return crst_table_upgrade(current->mm, 1UL << 53); - return 0; -} - static unsigned long s390_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { struct mm_struct *mm = current->mm; - unsigned long area; int rc; - area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); - if (!(area & ~PAGE_MASK)) - return area; - if (area == -ENOMEM && - !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { - /* Upgrade the page table to 4 levels and retry. */ - rc = crst_table_upgrade(mm, 1UL << 53); + addr = arch_get_unmapped_area(filp, addr, len, pgoff, flags); + if (addr & ~PAGE_MASK) + return addr; + if (unlikely(mm->context.asce_limit < addr + len)) { + rc = crst_table_upgrade(mm, addr + len); if (rc) return (unsigned long) rc; - area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); } - return area; + return addr; } static unsigned long -s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, +s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, const unsigned long len, const unsigned long pgoff, const unsigned long flags) { struct mm_struct *mm = current->mm; - unsigned long area; + unsigned long addr = addr0; int rc; - area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); - if (!(area & ~PAGE_MASK)) - return area; - if (area == -ENOMEM && - !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { - /* Upgrade the page table to 4 levels and retry. */ - rc = crst_table_upgrade(mm, 1UL << 53); + addr = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); + if (addr & ~PAGE_MASK) + return addr; + if (unlikely(mm->context.asce_limit < addr + len)) { + rc = crst_table_upgrade(mm, addr + len); if (rc) return (unsigned long) rc; - area = arch_get_unmapped_area_topdown(filp, addr, len, - pgoff, flags); } - return area; + return addr; } /* * This function, called very early during the creation of a new diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index 6b6ddc4ea02b..0767827540b1 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -117,7 +117,6 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long limit) crst_table_init(table, entry); pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); mm->pgd = (pgd_t *) table; - mm->task_size = mm->context.asce_limit; table = NULL; } spin_unlock(&mm->page_table_lock); @@ -155,7 +154,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) BUG(); } mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); - mm->task_size = mm->context.asce_limit; crst_table_free(mm, (unsigned long *) pgd); } update_mm(mm, current); diff --git a/trunk/arch/sparc/include/asm/pil.h b/trunk/arch/sparc/include/asm/pil.h index 266937030546..32a7efe76d00 100644 --- a/trunk/arch/sparc/include/asm/pil.h +++ b/trunk/arch/sparc/include/asm/pil.h @@ -24,7 +24,6 @@ #define PIL_DEVICE_IRQ 5 #define PIL_SMP_CALL_FUNC_SNGL 6 #define PIL_DEFERRED_PCR_WORK 7 -#define PIL_KGDB_CAPTURE 8 #define PIL_NORMAL_MAX 14 #define PIL_NMI 15 diff --git a/trunk/arch/sparc/kernel/kgdb_64.c b/trunk/arch/sparc/kernel/kgdb_64.c index f5a0fd490b59..fefbe6dc51be 100644 --- a/trunk/arch/sparc/kernel/kgdb_64.c +++ b/trunk/arch/sparc/kernel/kgdb_64.c @@ -108,7 +108,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) } #ifdef CONFIG_SMP -void smp_kgdb_capture_client(int irq, struct pt_regs *regs) +void smp_kgdb_capture_client(struct pt_regs *regs) { unsigned long flags; diff --git a/trunk/arch/sparc/kernel/pci_common.c b/trunk/arch/sparc/kernel/pci_common.c index b775658a927d..64e6edf17b9d 100644 --- a/trunk/arch/sparc/kernel/pci_common.c +++ b/trunk/arch/sparc/kernel/pci_common.c @@ -368,7 +368,7 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); if (vdma) { - struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); + struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL); if (!rp) { prom_printf("Cannot allocate IOMMU resource.\n"); diff --git a/trunk/arch/sparc/kernel/ttable.S b/trunk/arch/sparc/kernel/ttable.S index 76d837fc47d3..d9bdfb9d5c18 100644 --- a/trunk/arch/sparc/kernel/ttable.S +++ b/trunk/arch/sparc/kernel/ttable.S @@ -64,12 +64,7 @@ tl0_irq6: TRAP_IRQ(smp_call_function_single_client, 6) tl0_irq6: BTRAP(0x46) #endif tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7) -#ifdef CONFIG_KGDB -tl0_irq8: TRAP_IRQ(smp_kgdb_capture_client, 8) -#else -tl0_irq8: BTRAP(0x48) -#endif -tl0_irq9: BTRAP(0x49) +tl0_irq8: BTRAP(0x48) BTRAP(0x49) tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) tl0_irq14: TRAP_IRQ(timer_interrupt, 14) tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15) diff --git a/trunk/arch/sparc/mm/ultra.S b/trunk/arch/sparc/mm/ultra.S index b57a5942ba64..80c788ec7c32 100644 --- a/trunk/arch/sparc/mm/ultra.S +++ b/trunk/arch/sparc/mm/ultra.S @@ -679,8 +679,28 @@ xcall_new_mmu_context_version: #ifdef CONFIG_KGDB .globl xcall_kgdb_capture xcall_kgdb_capture: - wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint - retry +661: rdpr %pstate, %g2 + wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate + .section .sun4v_2insn_patch, "ax" + .word 661b + nop + nop + .previous + + rdpr %pil, %g2 + wrpr %g0, PIL_NORMAL_MAX, %pil + sethi %hi(109f), %g7 + ba,pt %xcc, etrap_irq +109: or %g7, %lo(109b), %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif + call smp_kgdb_capture_client + add %sp, PTREGS_OFF, %o0 + /* Has to be a non-v9 branch due to the large distance. */ + ba rtrap_xcall + ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 #endif #endif /* CONFIG_SMP */ diff --git a/trunk/arch/x86/kernel/kprobes.c b/trunk/arch/x86/kernel/kprobes.c index 4558dd3918cf..e948b28a5a9a 100644 --- a/trunk/arch/x86/kernel/kprobes.c +++ b/trunk/arch/x86/kernel/kprobes.c @@ -193,9 +193,6 @@ static int __kprobes can_boost(kprobe_opcode_t *opcodes) kprobe_opcode_t opcode; kprobe_opcode_t *orig_opcodes = opcodes; - if (search_exception_tables(opcodes)) - return 0; /* Page fault may occur on this address. */ - retry: if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) return 0; diff --git a/trunk/arch/x86/kernel/tsc.c b/trunk/arch/x86/kernel/tsc.c index d5cebb52d45b..599e58168631 100644 --- a/trunk/arch/x86/kernel/tsc.c +++ b/trunk/arch/x86/kernel/tsc.c @@ -273,43 +273,30 @@ static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin) * use the TSC value at the transitions to calculate a pretty * good value for the TSC frequencty. */ -static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *deltap) +static inline int pit_expect_msb(unsigned char val) { - int count; - u64 tsc = 0; + int count = 0; for (count = 0; count < 50000; count++) { /* Ignore LSB */ inb(0x42); if (inb(0x42) != val) break; - tsc = get_cycles(); } - *deltap = get_cycles() - tsc; - *tscp = tsc; - - /* - * We require _some_ success, but the quality control - * will be based on the error terms on the TSC values. - */ - return count > 5; + return count > 50; } /* - * How many MSB values do we want to see? We aim for - * a maximum error rate of 500ppm (in practice the - * real error is much smaller), but refuse to spend - * more than 25ms on it. + * How many MSB values do we want to see? We aim for a + * 15ms calibration, which assuming a 2us counter read + * error should give us roughly 150 ppm precision for + * the calibration. */ -#define MAX_QUICK_PIT_MS 25 -#define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) +#define QUICK_PIT_MS 15 +#define QUICK_PIT_ITERATIONS (QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) static unsigned long quick_pit_calibrate(void) { - int i; - u64 tsc, delta; - unsigned long d1, d2; - /* Set the Gate high, disable speaker */ outb((inb(0x61) & ~0x02) | 0x01, 0x61); @@ -328,52 +315,45 @@ static unsigned long quick_pit_calibrate(void) outb(0xff, 0x42); outb(0xff, 0x42); - /* - * The PIT starts counting at the next edge, so we - * need to delay for a microsecond. The easiest way - * to do that is to just read back the 16-bit counter - * once from the PIT. - */ - inb(0x42); - inb(0x42); - - if (pit_expect_msb(0xff, &tsc, &d1)) { - for (i = 1; i <= MAX_QUICK_PIT_ITERATIONS; i++) { - if (!pit_expect_msb(0xff-i, &delta, &d2)) - break; - - /* - * Iterate until the error is less than 500 ppm - */ - delta -= tsc; - if (d1+d2 < delta >> 11) - goto success; + if (pit_expect_msb(0xff)) { + int i; + u64 t1, t2, delta; + unsigned char expect = 0xfe; + + t1 = get_cycles(); + for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) { + if (!pit_expect_msb(expect)) + goto failed; } + t2 = get_cycles(); + + /* + * Make sure we can rely on the second TSC timestamp: + */ + if (!pit_expect_msb(expect)) + goto failed; + + /* + * Ok, if we get here, then we've seen the + * MSB of the PIT decrement QUICK_PIT_ITERATIONS + * times, and each MSB had many hits, so we never + * had any sudden jumps. + * + * As a result, we can depend on there not being + * any odd delays anywhere, and the TSC reads are + * reliable. + * + * kHz = ticks / time-in-seconds / 1000; + * kHz = (t2 - t1) / (QPI * 256 / PIT_TICK_RATE) / 1000 + * kHz = ((t2 - t1) * PIT_TICK_RATE) / (QPI * 256 * 1000) + */ + delta = (t2 - t1)*PIT_TICK_RATE; + do_div(delta, QUICK_PIT_ITERATIONS*256*1000); + printk("Fast TSC calibration using PIT\n"); + return delta; } - printk("Fast TSC calibration failed\n"); +failed: return 0; - -success: - /* - * Ok, if we get here, then we've seen the - * MSB of the PIT decrement 'i' times, and the - * error has shrunk to less than 500 ppm. - * - * As a result, we can depend on there not being - * any odd delays anywhere, and the TSC reads are - * reliable (within the error). We also adjust the - * delta to the middle of the error bars, just - * because it looks nicer. - * - * kHz = ticks / time-in-seconds / 1000; - * kHz = (t2 - t1) / (I * 256 / PIT_TICK_RATE) / 1000 - * kHz = ((t2 - t1) * PIT_TICK_RATE) / (I * 256 * 1000) - */ - delta += (long)(d2 - d1)/2; - delta *= PIT_TICK_RATE; - do_div(delta, i*256*1000); - printk("Fast TSC calibration using PIT\n"); - return delta; } /** diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index bee64b73c919..765fd1c56cd6 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -758,7 +758,8 @@ static int __init acpi_bus_init(void) acpi_status status = AE_OK; extern acpi_status acpi_os_initialize1(void); - acpi_os_initialize1(); + + status = acpi_os_initialize1(); status = acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE); @@ -768,6 +769,12 @@ static int __init acpi_bus_init(void) goto error1; } + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX + "Unable to initialize ACPI OS objects\n"); + goto error1; + } + /* * ACPI 2.0 requires the EC driver to be loaded and work before * the EC device is found in the namespace (i.e. before acpi_initialize_objects() diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index 3a0d8ef25c75..c5e292aab0e3 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -277,7 +277,7 @@ int acpi_get_node(acpi_handle *handle) int pxm, node = -1; pxm = acpi_get_pxm(handle); - if (pxm >= 0 && pxm < MAX_PXM_DOMAINS) + if (pxm >= 0) node = acpi_map_pxm_to_node(pxm); return node; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 1e35f342957c..b3193ec0a2ef 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -1317,6 +1317,54 @@ acpi_os_validate_interface (char *interface) return AE_SUPPORT; } +#ifdef CONFIG_X86 + +struct aml_port_desc { + uint start; + uint end; + char* name; + char warned; +}; + +static struct aml_port_desc aml_invalid_port_list[] = { + {0x20, 0x21, "PIC0", 0}, + {0xA0, 0xA1, "PIC1", 0}, + {0x4D0, 0x4D1, "ELCR", 0} +}; + +/* + * valid_aml_io_address() + * + * if valid, return true + * else invalid, warn once, return false + */ +static bool valid_aml_io_address(uint address, uint length) +{ + int i; + int entries = sizeof(aml_invalid_port_list) / sizeof(struct aml_port_desc); + + for (i = 0; i < entries; ++i) { + if ((address >= aml_invalid_port_list[i].start && + address <= aml_invalid_port_list[i].end) || + (address + length >= aml_invalid_port_list[i].start && + address + length <= aml_invalid_port_list[i].end)) + { + if (!aml_invalid_port_list[i].warned) + { + printk(KERN_ERR "ACPI: Denied BIOS AML access" + " to invalid port 0x%x+0x%x (%s)\n", + address, length, + aml_invalid_port_list[i].name); + aml_invalid_port_list[i].warned = 1; + } + return false; /* invalid */ + } + } + return true; /* valid */ +} +#else +static inline bool valid_aml_io_address(uint address, uint length) { return true; } +#endif /****************************************************************************** * * FUNCTION: acpi_os_validate_address @@ -1346,6 +1394,8 @@ acpi_os_validate_address ( switch (space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: + if (!valid_aml_io_address(address, length)) + return AE_AML_ILLEGAL_ADDRESS; case ACPI_ADR_SPACE_SYSTEM_MEMORY: /* Only interference checks against SystemIO and SytemMemory are needed */ diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index 00456fccfa38..519266654f06 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -378,22 +378,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), }, }, - { - .callback = init_old_suspend_ordering, - .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "M2N8L"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Toshiba Satellite L300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), - }, - }, {}, }; #endif /* CONFIG_SUSPEND */ diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index ef8b30d577bd..54961c0b2c73 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -1289,39 +1289,6 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev, return map; } -static bool piix_no_sidpr(struct ata_host *host) -{ - struct pci_dev *pdev = to_pci_dev(host->dev); - - /* - * Samsung DB-P70 only has three ATA ports exposed and - * curiously the unconnected first port reports link online - * while not responding to SRST protocol causing excessive - * detection delay. - * - * Unfortunately, the system doesn't carry enough DMI - * information to identify the machine but does have subsystem - * vendor and device set. As it's unclear whether the - * subsystem vendor/device is used only for this specific - * board, the port can't be disabled solely with the - * information; however, turning off SIDPR access works around - * the problem. Turn it off. - * - * This problem is reported in bnc#441240. - * - * https://bugzilla.novell.com/show_bug.cgi?id=441420 - */ - if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2920 && - pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG && - pdev->subsystem_device == 0xb049) { - dev_printk(KERN_WARNING, host->dev, - "Samsung DB-P70 detected, disabling SIDPR\n"); - return true; - } - - return false; -} - static int __devinit piix_init_sidpr(struct ata_host *host) { struct pci_dev *pdev = to_pci_dev(host->dev); @@ -1335,10 +1302,6 @@ static int __devinit piix_init_sidpr(struct ata_host *host) if (hpriv->map[i] == IDE) return 0; - /* is it blacklisted? */ - if (piix_no_sidpr(host)) - return 0; - if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) return 0; diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index f93dc029dfde..714cb046b594 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -2066,7 +2066,6 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask, iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr); udelay(20); /* FIXME: flush */ iowrite8(ap->ctl, ioaddr->ctl_addr); - ap->last_ctl = ap->ctl; /* wait the port to become ready */ return ata_sff_wait_after_reset(&ap->link, devmask, deadline); @@ -2191,10 +2190,8 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes) } /* set up device control */ - if (ap->ioaddr.ctl_addr) { + if (ap->ioaddr.ctl_addr) iowrite8(ap->ctl, ap->ioaddr.ctl_addr); - ap->last_ctl = ap->ctl; - } } EXPORT_SYMBOL_GPL(ata_sff_postreset); @@ -2537,7 +2534,6 @@ void ata_bus_reset(struct ata_port *ap) if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) { /* set up device control for ATA_FLAG_SATA_RESET */ iowrite8(ap->ctl, ioaddr->ctl_addr); - ap->last_ctl = ap->ctl; } DPRINTK("EXIT\n"); diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 74b1080d116d..7007edd2d451 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -2218,13 +2218,12 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) else handled = mv_host_intr(host, pending_irqs); } + spin_unlock(&host->lock); /* for MSI: unmask; interrupt cause bits will retrigger now */ if (using_msi) writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr); - spin_unlock(&host->lock); - return IRQ_RETVAL(handled); } diff --git a/trunk/drivers/block/Makefile b/trunk/drivers/block/Makefile index 87e120e0a79c..204332b29578 100644 --- a/trunk/drivers/block/Makefile +++ b/trunk/drivers/block/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_BLK_DEV_FD) += floppy.o obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o obj-$(CONFIG_PS3_DISK) += ps3disk.o -obj-$(CONFIG_PS3_VRAM) += ps3vram.o obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o obj-$(CONFIG_BLK_DEV_RAM) += brd.o diff --git a/trunk/drivers/block/ps3vram.c b/trunk/drivers/block/ps3vram.c deleted file mode 100644 index 393ed6760d78..000000000000 --- a/trunk/drivers/block/ps3vram.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * ps3vram - Use extra PS3 video ram as MTD block device. - * - * Copyright 2009 Sony Corporation - * - * Based on the MTD ps3vram driver, which is - * Copyright (c) 2007-2008 Jim Paris - * Added support RSX DMA Vivien Chappelier - */ - -#include -#include -#include -#include - -#include -#include -#include - - -#define DEVICE_NAME "ps3vram" - - -#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */ -#define XDR_IOIF 0x0c000000 - -#define FIFO_BASE XDR_IOIF -#define FIFO_SIZE (64 * 1024) - -#define DMA_PAGE_SIZE (4 * 1024) - -#define CACHE_PAGE_SIZE (256 * 1024) -#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE) - -#define CACHE_OFFSET CACHE_PAGE_SIZE -#define FIFO_OFFSET 0 - -#define CTRL_PUT 0x10 -#define CTRL_GET 0x11 -#define CTRL_TOP 0x15 - -#define UPLOAD_SUBCH 1 -#define DOWNLOAD_SUBCH 2 - -#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c -#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 - -#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 - -#define CACHE_PAGE_PRESENT 1 -#define CACHE_PAGE_DIRTY 2 - -struct ps3vram_tag { - unsigned int address; - unsigned int flags; -}; - -struct ps3vram_cache { - unsigned int page_count; - unsigned int page_size; - struct ps3vram_tag *tags; - unsigned int hit; - unsigned int miss; -}; - -struct ps3vram_priv { - struct request_queue *queue; - struct gendisk *gendisk; - - u64 size; - - u64 memory_handle; - u64 context_handle; - u32 *ctrl; - u32 *reports; - u8 __iomem *ddr_base; - u8 *xdr_buf; - - u32 *fifo_base; - u32 *fifo_ptr; - - struct ps3vram_cache cache; - - /* Used to serialize cache/DMA operations */ - struct mutex lock; -}; - - -static int ps3vram_major; - - -static struct block_device_operations ps3vram_fops = { - .owner = THIS_MODULE, -}; - - -#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ -#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */ -#define DMA_NOTIFIER_SIZE 0x40 -#define NOTIFIER 7 /* notifier used for completion report */ - -static char *size = "256M"; -module_param(size, charp, 0); -MODULE_PARM_DESC(size, "memory size"); - -static u32 *ps3vram_get_notifier(u32 *reports, int notifier) -{ - return (void *)reports + DMA_NOTIFIER_OFFSET_BASE + - DMA_NOTIFIER_SIZE * notifier; -} - -static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); - int i; - - for (i = 0; i < 4; i++) - notify[i] = 0xffffffff; -} - -static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, - unsigned int timeout_ms) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); - unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); - - do { - if (!notify[3]) - return 0; - msleep(1); - } while (time_before(jiffies, timeout)); - - return -ETIMEDOUT; -} - -static void ps3vram_init_ring(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - - priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; - priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; -} - -static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, - unsigned int timeout_ms) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); - - do { - if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) - return 0; - msleep(1); - } while (time_before(jiffies, timeout)); - - dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n", - priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], - priv->ctrl[CTRL_TOP]); - - return -ETIMEDOUT; -} - -static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) -{ - *(priv->fifo_ptr)++ = data; -} - -static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag, - u32 size) -{ - ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); -} - -static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - int status; - - ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); - - priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; - - /* asking the HV for a blit will kick the FIFO */ - status = lv1_gpu_context_attribute(priv->context_handle, - L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0, - 0, 0, 0); - if (status) - dev_err(&dev->core, - "%s: lv1_gpu_context_attribute failed %d\n", __func__, - status); - - priv->fifo_ptr = priv->fifo_base; -} - -static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - int status; - - mutex_lock(&ps3_gpu_mutex); - - priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + - (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); - - /* asking the HV for a blit will kick the FIFO */ - status = lv1_gpu_context_attribute(priv->context_handle, - L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0, - 0, 0, 0); - if (status) - dev_err(&dev->core, - "%s: lv1_gpu_context_attribute failed %d\n", __func__, - status); - - if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > - FIFO_SIZE - 1024) { - dev_dbg(&dev->core, "FIFO full, rewinding\n"); - ps3vram_wait_ring(dev, 200); - ps3vram_rewind_ring(dev); - } - - mutex_unlock(&ps3_gpu_mutex); -} - -static void ps3vram_bind(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - - ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); - ps3vram_out_ring(priv, 0x31337303); - ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3); - ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); - ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ - ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ - - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1); - ps3vram_out_ring(priv, 0x3137c0de); - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3); - ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); - ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ - ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ - - ps3vram_fire_ring(dev); -} - -static int ps3vram_upload(struct ps3_system_bus_device *dev, - unsigned int src_offset, unsigned int dst_offset, - int len, int count) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - - ps3vram_begin_ring(priv, UPLOAD_SUBCH, - NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - ps3vram_out_ring(priv, XDR_IOIF + src_offset); - ps3vram_out_ring(priv, dst_offset); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, count); - ps3vram_out_ring(priv, (1 << 8) | 1); - ps3vram_out_ring(priv, 0); - - ps3vram_notifier_reset(dev); - ps3vram_begin_ring(priv, UPLOAD_SUBCH, - NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - ps3vram_out_ring(priv, 0); - ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1); - ps3vram_out_ring(priv, 0); - ps3vram_fire_ring(dev); - if (ps3vram_notifier_wait(dev, 200) < 0) { - dev_warn(&dev->core, "%s: Notifier timeout\n", __func__); - return -1; - } - - return 0; -} - -static int ps3vram_download(struct ps3_system_bus_device *dev, - unsigned int src_offset, unsigned int dst_offset, - int len, int count) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, - NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - ps3vram_out_ring(priv, src_offset); - ps3vram_out_ring(priv, XDR_IOIF + dst_offset); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, count); - ps3vram_out_ring(priv, (1 << 8) | 1); - ps3vram_out_ring(priv, 0); - - ps3vram_notifier_reset(dev); - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, - NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - ps3vram_out_ring(priv, 0); - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1); - ps3vram_out_ring(priv, 0); - ps3vram_fire_ring(dev); - if (ps3vram_notifier_wait(dev, 200) < 0) { - dev_warn(&dev->core, "%s: Notifier timeout\n", __func__); - return -1; - } - - return 0; -} - -static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - struct ps3vram_cache *cache = &priv->cache; - - if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY)) - return; - - dev_dbg(&dev->core, "Flushing %d: 0x%08x\n", entry, - cache->tags[entry].address); - if (ps3vram_upload(dev, CACHE_OFFSET + entry * cache->page_size, - cache->tags[entry].address, DMA_PAGE_SIZE, - cache->page_size / DMA_PAGE_SIZE) < 0) { - dev_err(&dev->core, - "Failed to upload from 0x%x to " "0x%x size 0x%x\n", - entry * cache->page_size, cache->tags[entry].address, - cache->page_size); - } - cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; -} - -static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry, - unsigned int address) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - struct ps3vram_cache *cache = &priv->cache; - - dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address); - if (ps3vram_download(dev, address, - CACHE_OFFSET + entry * cache->page_size, - DMA_PAGE_SIZE, - cache->page_size / DMA_PAGE_SIZE) < 0) { - dev_err(&dev->core, - "Failed to download from 0x%x to 0x%x size 0x%x\n", - address, entry * cache->page_size, cache->page_size); - } - - cache->tags[entry].address = address; - cache->tags[entry].flags |= CACHE_PAGE_PRESENT; -} - - -static void ps3vram_cache_flush(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - struct ps3vram_cache *cache = &priv->cache; - int i; - - dev_dbg(&dev->core, "FLUSH\n"); - for (i = 0; i < cache->page_count; i++) { - ps3vram_cache_evict(dev, i); - cache->tags[i].flags = 0; - } -} - -static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev, - loff_t address) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - struct ps3vram_cache *cache = &priv->cache; - unsigned int base; - unsigned int offset; - int i; - static int counter; - - offset = (unsigned int) (address & (cache->page_size - 1)); - base = (unsigned int) (address - offset); - - /* fully associative check */ - for (i = 0; i < cache->page_count; i++) { - if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && - cache->tags[i].address == base) { - cache->hit++; - dev_dbg(&dev->core, "Found entry %d: 0x%08x\n", i, - cache->tags[i].address); - return i; - } - } - - /* choose a random entry */ - i = (jiffies + (counter++)) % cache->page_count; - dev_dbg(&dev->core, "Using entry %d\n", i); - - ps3vram_cache_evict(dev, i); - ps3vram_cache_load(dev, i, base); - - cache->miss++; - return i; -} - -static int ps3vram_cache_init(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - - priv->cache.page_count = CACHE_PAGE_COUNT; - priv->cache.page_size = CACHE_PAGE_SIZE; - priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * - CACHE_PAGE_COUNT, GFP_KERNEL); - if (priv->cache.tags == NULL) { - dev_err(&dev->core, "Could not allocate cache tags\n"); - return -ENOMEM; - } - - dev_info(&dev->core, "Created ram cache: %d entries, %d KiB each\n", - CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); - - return 0; -} - -static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - - ps3vram_cache_flush(dev); - kfree(priv->cache.tags); -} - -static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, - size_t len, size_t *retlen, u_char *buf) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - unsigned int cached, count; - - dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__, - (unsigned int)from, len); - - if (from >= priv->size) - return -EIO; - - if (len > priv->size - from) - len = priv->size - from; - - /* Copy from vram to buf */ - count = len; - while (count) { - unsigned int offset, avail; - unsigned int entry; - - offset = (unsigned int) (from & (priv->cache.page_size - 1)); - avail = priv->cache.page_size - offset; - - mutex_lock(&priv->lock); - - entry = ps3vram_cache_match(dev, from); - cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; - - dev_dbg(&dev->core, "%s: from=%08x cached=%08x offset=%08x " - "avail=%08x count=%08x\n", __func__, - (unsigned int)from, cached, offset, avail, count); - - if (avail > count) - avail = count; - memcpy(buf, priv->xdr_buf + cached, avail); - - mutex_unlock(&priv->lock); - - buf += avail; - count -= avail; - from += avail; - } - - *retlen = len; - return 0; -} - -static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, - size_t len, size_t *retlen, const u_char *buf) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - unsigned int cached, count; - - if (to >= priv->size) - return -EIO; - - if (len > priv->size - to) - len = priv->size - to; - - /* Copy from buf to vram */ - count = len; - while (count) { - unsigned int offset, avail; - unsigned int entry; - - offset = (unsigned int) (to & (priv->cache.page_size - 1)); - avail = priv->cache.page_size - offset; - - mutex_lock(&priv->lock); - - entry = ps3vram_cache_match(dev, to); - cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; - - dev_dbg(&dev->core, "%s: to=%08x cached=%08x offset=%08x " - "avail=%08x count=%08x\n", __func__, (unsigned int)to, - cached, offset, avail, count); - - if (avail > count) - avail = count; - memcpy(priv->xdr_buf + cached, buf, avail); - - priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; - - mutex_unlock(&priv->lock); - - buf += avail; - count -= avail; - to += avail; - } - - *retlen = len; - return 0; -} - -static int ps3vram_proc_show(struct seq_file *m, void *v) -{ - struct ps3vram_priv *priv = m->private; - - seq_printf(m, "hit:%u\nmiss:%u\n", priv->cache.hit, priv->cache.miss); - return 0; -} - -static int ps3vram_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ps3vram_proc_show, PDE(inode)->data); -} - -static const struct file_operations ps3vram_proc_fops = { - .owner = THIS_MODULE, - .open = ps3vram_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - struct proc_dir_entry *pde; - - pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops); - if (!pde) { - dev_warn(&dev->core, "failed to create /proc entry\n"); - return; - } - - pde->owner = THIS_MODULE; - pde->data = priv; -} - -static int ps3vram_make_request(struct request_queue *q, struct bio *bio) -{ - struct ps3_system_bus_device *dev = q->queuedata; - int write = bio_data_dir(bio) == WRITE; - const char *op = write ? "write" : "read"; - loff_t offset = bio->bi_sector << 9; - int error = 0; - struct bio_vec *bvec; - unsigned int i; - - dev_dbg(&dev->core, "%s\n", __func__); - - bio_for_each_segment(bvec, bio, i) { - /* PS3 is ppc64, so we don't handle highmem */ - char *ptr = page_address(bvec->bv_page) + bvec->bv_offset; - size_t len = bvec->bv_len, retlen; - - dev_dbg(&dev->core, " %s %zu bytes at offset %llu\n", op, - len, offset); - if (write) - error = ps3vram_write(dev, offset, len, &retlen, ptr); - else - error = ps3vram_read(dev, offset, len, &retlen, ptr); - - if (error) { - dev_err(&dev->core, "%s failed\n", op); - goto out; - } - - if (retlen != len) { - dev_err(&dev->core, "Short %s\n", op); - goto out; - } - - offset += len; - } - - dev_dbg(&dev->core, "%s completed\n", op); - -out: - bio_endio(bio, error); - return 0; -} - -static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv; - int error, status; - struct request_queue *queue; - struct gendisk *gendisk; - u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size, - reports_size; - char *rest; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - error = -ENOMEM; - goto fail; - } - - mutex_init(&priv->lock); - dev->core.driver_data = priv; - - priv = dev->core.driver_data; - - /* Allocate XDR buffer (1MiB aligned) */ - priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, - get_order(XDR_BUF_SIZE)); - if (priv->xdr_buf == NULL) { - dev_err(&dev->core, "Could not allocate XDR buffer\n"); - error = -ENOMEM; - goto fail_free_priv; - } - - /* Put FIFO at begginning of XDR buffer */ - priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); - priv->fifo_ptr = priv->fifo_base; - - /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ - if (ps3_open_hv_device(dev)) { - dev_err(&dev->core, "ps3_open_hv_device failed\n"); - error = -EAGAIN; - goto out_close_gpu; - } - - /* Request memory */ - status = -1; - ddr_size = ALIGN(memparse(size, &rest), 1024*1024); - if (!ddr_size) { - dev_err(&dev->core, "Specified size is too small\n"); - error = -EINVAL; - goto out_close_gpu; - } - - while (ddr_size > 0) { - status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, - &priv->memory_handle, - &ddr_lpar); - if (!status) - break; - ddr_size -= 1024*1024; - } - if (status) { - dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n", - status); - error = -ENOMEM; - goto out_free_xdr_buf; - } - - /* Request context */ - status = lv1_gpu_context_allocate(priv->memory_handle, 0, - &priv->context_handle, &ctrl_lpar, - &info_lpar, &reports_lpar, - &reports_size); - if (status) { - dev_err(&dev->core, "lv1_gpu_context_allocate failed %d\n", - status); - error = -ENOMEM; - goto out_free_memory; - } - - /* Map XDR buffer to RSX */ - status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, - ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), - XDR_BUF_SIZE, 0); - if (status) { - dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n", - status); - error = -ENOMEM; - goto out_free_context; - } - - priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); - - if (!priv->ddr_base) { - dev_err(&dev->core, "ioremap DDR failed\n"); - error = -ENOMEM; - goto out_free_context; - } - - priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); - if (!priv->ctrl) { - dev_err(&dev->core, "ioremap CTRL failed\n"); - error = -ENOMEM; - goto out_unmap_vram; - } - - priv->reports = ioremap(reports_lpar, reports_size); - if (!priv->reports) { - dev_err(&dev->core, "ioremap REPORTS failed\n"); - error = -ENOMEM; - goto out_unmap_ctrl; - } - - mutex_lock(&ps3_gpu_mutex); - ps3vram_init_ring(dev); - mutex_unlock(&ps3_gpu_mutex); - - priv->size = ddr_size; - - ps3vram_bind(dev); - - mutex_lock(&ps3_gpu_mutex); - error = ps3vram_wait_ring(dev, 100); - mutex_unlock(&ps3_gpu_mutex); - if (error < 0) { - dev_err(&dev->core, "Failed to initialize channels\n"); - error = -ETIMEDOUT; - goto out_unmap_reports; - } - - ps3vram_cache_init(dev); - ps3vram_proc_init(dev); - - queue = blk_alloc_queue(GFP_KERNEL); - if (!queue) { - dev_err(&dev->core, "blk_alloc_queue failed\n"); - error = -ENOMEM; - goto out_cache_cleanup; - } - - priv->queue = queue; - queue->queuedata = dev; - blk_queue_make_request(queue, ps3vram_make_request); - blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS); - blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS); - blk_queue_max_segment_size(queue, MAX_SEGMENT_SIZE); - blk_queue_max_sectors(queue, SAFE_MAX_SECTORS); - - gendisk = alloc_disk(1); - if (!gendisk) { - dev_err(&dev->core, "alloc_disk failed\n"); - error = -ENOMEM; - goto fail_cleanup_queue; - } - - priv->gendisk = gendisk; - gendisk->major = ps3vram_major; - gendisk->first_minor = 0; - gendisk->fops = &ps3vram_fops; - gendisk->queue = queue; - gendisk->private_data = dev; - gendisk->driverfs_dev = &dev->core; - strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name)); - set_capacity(gendisk, priv->size >> 9); - - dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n", - gendisk->disk_name, get_capacity(gendisk) >> 11); - - add_disk(gendisk); - return 0; - -fail_cleanup_queue: - blk_cleanup_queue(queue); -out_cache_cleanup: - remove_proc_entry(DEVICE_NAME, NULL); - ps3vram_cache_cleanup(dev); -out_unmap_reports: - iounmap(priv->reports); -out_unmap_ctrl: - iounmap(priv->ctrl); -out_unmap_vram: - iounmap(priv->ddr_base); -out_free_context: - lv1_gpu_context_free(priv->context_handle); -out_free_memory: - lv1_gpu_memory_free(priv->memory_handle); -out_close_gpu: - ps3_close_hv_device(dev); -out_free_xdr_buf: - free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); -fail_free_priv: - kfree(priv); - dev->core.driver_data = NULL; -fail: - return error; -} - -static int ps3vram_remove(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv = dev->core.driver_data; - - del_gendisk(priv->gendisk); - put_disk(priv->gendisk); - blk_cleanup_queue(priv->queue); - remove_proc_entry(DEVICE_NAME, NULL); - ps3vram_cache_cleanup(dev); - iounmap(priv->reports); - iounmap(priv->ctrl); - iounmap(priv->ddr_base); - lv1_gpu_context_free(priv->context_handle); - lv1_gpu_memory_free(priv->memory_handle); - ps3_close_hv_device(dev); - free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); - kfree(priv); - dev->core.driver_data = NULL; - return 0; -} - -static struct ps3_system_bus_driver ps3vram = { - .match_id = PS3_MATCH_ID_GPU, - .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK, - .core.name = DEVICE_NAME, - .core.owner = THIS_MODULE, - .probe = ps3vram_probe, - .remove = ps3vram_remove, - .shutdown = ps3vram_remove, -}; - - -static int __init ps3vram_init(void) -{ - int error; - - if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) - return -ENODEV; - - error = register_blkdev(0, DEVICE_NAME); - if (error <= 0) { - pr_err("%s: register_blkdev failed %d\n", DEVICE_NAME, error); - return error; - } - ps3vram_major = error; - - pr_info("%s: registered block device major %d\n", DEVICE_NAME, - ps3vram_major); - - error = ps3_system_bus_driver_register(&ps3vram); - if (error) - unregister_blkdev(ps3vram_major, DEVICE_NAME); - - return error; -} - -static void __exit ps3vram_exit(void) -{ - ps3_system_bus_driver_unregister(&ps3vram); - unregister_blkdev(ps3vram_major, DEVICE_NAME); -} - -module_init(ps3vram_init); -module_exit(ps3vram_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("PS3 Video RAM Storage Driver"); -MODULE_AUTHOR("Sony Corporation"); -MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); diff --git a/trunk/drivers/block/xsysace.c b/trunk/drivers/block/xsysace.c index 119be3442f28..381d686fc1a3 100644 --- a/trunk/drivers/block/xsysace.c +++ b/trunk/drivers/block/xsysace.c @@ -489,28 +489,6 @@ static void ace_fsm_dostate(struct ace_device *ace) ace->fsm_state, ace->id_req_count); #endif - /* Verify that there is actually a CF in the slot. If not, then - * bail out back to the idle state and wake up all the waiters */ - status = ace_in32(ace, ACE_STATUS); - if ((status & ACE_STATUS_CFDETECT) == 0) { - ace->fsm_state = ACE_FSM_STATE_IDLE; - ace->media_change = 1; - set_capacity(ace->gd, 0); - dev_info(ace->dev, "No CF in slot\n"); - - /* Drop all pending requests */ - while ((req = elv_next_request(ace->queue)) != NULL) - end_request(req, 0); - - /* Drop back to IDLE state and notify waiters */ - ace->fsm_state = ACE_FSM_STATE_IDLE; - ace->id_result = -EIO; - while (ace->id_req_count) { - complete(&ace->id_completion); - ace->id_req_count--; - } - } - switch (ace->fsm_state) { case ACE_FSM_STATE_IDLE: /* See if there is anything to do */ diff --git a/trunk/drivers/char/agp/parisc-agp.c b/trunk/drivers/char/agp/parisc-agp.c index 699e3422ad93..db60539bf67a 100644 --- a/trunk/drivers/char/agp/parisc-agp.c +++ b/trunk/drivers/char/agp/parisc-agp.c @@ -359,16 +359,9 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa) return error; } -static int -find_quicksilver(struct device *dev, void *data) -{ - struct parisc_device **lba = data; - struct parisc_device *padev = to_parisc_device(dev); - - if (IS_QUICKSILVER(padev)) - *lba = padev; - - return 0; +static struct device *next_device(struct klist_iter *i) { + struct klist_node * n = klist_next(i); + return n ? container_of(n, struct device, knode_parent) : NULL; } static int @@ -379,6 +372,8 @@ parisc_agp_init(void) int err = -1; struct parisc_device *sba = NULL, *lba = NULL; struct lba_device *lbadev = NULL; + struct device *dev = NULL; + struct klist_iter i; if (!sba_list) goto out; @@ -391,7 +386,13 @@ parisc_agp_init(void) } /* Now search our Pluto for our precious AGP device... */ - device_for_each_child(&sba->dev, &lba, find_quicksilver); + klist_iter_init(&sba->dev.klist_children, &i); + while ((dev = next_device(&i))) { + struct parisc_device *padev = to_parisc_device(dev); + if (IS_QUICKSILVER(padev)) + lba = padev; + } + klist_iter_exit(&i); if (!lba) { printk(KERN_INFO DRVPFX "No AGP devices found.\n"); diff --git a/trunk/drivers/dca/dca-sysfs.c b/trunk/drivers/dca/dca-sysfs.c index ee916c9857ee..bb538b9690e0 100644 --- a/trunk/drivers/dca/dca-sysfs.c +++ b/trunk/drivers/dca/dca-sysfs.c @@ -1,24 +1,3 @@ -/* - * Copyright(c) 2007 - 2009 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. - */ - #include #include #include diff --git a/trunk/drivers/hid/usbhid/hiddev.c b/trunk/drivers/hid/usbhid/hiddev.c index 1f5b5d4c3c34..4940e4d70c2d 100644 --- a/trunk/drivers/hid/usbhid/hiddev.c +++ b/trunk/drivers/hid/usbhid/hiddev.c @@ -306,7 +306,7 @@ static int hiddev_open(struct inode *inode, struct file *file) return 0; bail: file->private_data = NULL; - kfree(list); + kfree(list->hiddev); return res; } @@ -323,7 +323,7 @@ static ssize_t hiddev_write(struct file * file, const char __user * buffer, size */ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) { - DEFINE_WAIT(wait); + DECLARE_WAITQUEUE(wait, current); struct hiddev_list *list = file->private_data; int event_size; int retval; diff --git a/trunk/drivers/ide/ide-atapi.c b/trunk/drivers/ide/ide-atapi.c index e9d042dba0e0..e96c01260598 100644 --- a/trunk/drivers/ide/ide-atapi.c +++ b/trunk/drivers/ide/ide-atapi.c @@ -140,12 +140,6 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, rq->cmd_flags |= REQ_PREEMPT; rq->buffer = (char *)pc; rq->rq_disk = disk; - - if (pc->req_xfer) { - rq->data = pc->buf; - rq->data_len = pc->req_xfer; - } - memcpy(rq->cmd, pc->c, 12); if (drive->media == ide_tape) rq->cmd[13] = REQ_IDETAPE_PC1; @@ -165,12 +159,6 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; rq->buffer = (char *)pc; - - if (pc->req_xfer) { - rq->data = pc->buf; - rq->data_len = pc->req_xfer; - } - memcpy(rq->cmd, pc->c, 12); if (drive->media == ide_tape) rq->cmd[13] = REQ_IDETAPE_PC1; diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index 059c90bb5ad2..72ebab0bc755 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -128,7 +128,6 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; - int i; ide_map_sg(drive, rq); @@ -137,13 +136,8 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq) else hwif->sg_dma_direction = DMA_TO_DEVICE; - i = dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction); - if (i) { - hwif->orig_sg_nents = hwif->sg_nents; - hwif->sg_nents = i; - } - - return i; + return dma_map_sg(hwif->dev, sg, hwif->sg_nents, + hwif->sg_dma_direction); } EXPORT_SYMBOL_GPL(ide_build_sglist); @@ -162,7 +156,7 @@ void ide_destroy_dmatable(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->orig_sg_nents, + dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->sg_nents, hwif->sg_dma_direction); } EXPORT_SYMBOL_GPL(ide_destroy_dmatable); diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index 317ec62c33d4..3eab1c6c9b31 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -327,10 +327,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, return ide_stopped; } - if (blk_fs_request(rq) || pc->req_xfer) { - ide_init_sg_cmd(drive, rq); - ide_map_sg(drive, rq); - } + ide_init_sg_cmd(drive, rq); + ide_map_sg(drive, rq); pc->sg = hwif->sg_table; pc->sg_cnt = hwif->sg_nents; diff --git a/trunk/drivers/isdn/gigaset/bas-gigaset.c b/trunk/drivers/isdn/gigaset/bas-gigaset.c index 831ddce1467b..18dd8aacbe8d 100644 --- a/trunk/drivers/isdn/gigaset/bas-gigaset.c +++ b/trunk/drivers/isdn/gigaset/bas-gigaset.c @@ -46,9 +46,6 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"); /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ #define IF_WRITEBUF 264 -/* interrupt pipe message size according to ibid. ch. 2.2 */ -#define IP_MSGSIZE 3 - /* Values for the Gigaset 307x */ #define USB_GIGA_VENDOR_ID 0x0681 #define USB_3070_PRODUCT_ID 0x0001 @@ -113,7 +110,7 @@ struct bas_cardstate { unsigned char *rcvbuf; /* AT reply receive buffer */ struct urb *urb_int_in; /* URB for interrupt pipe */ - unsigned char *int_in_buf; + unsigned char int_in_buf[3]; spinlock_t lock; /* locks all following */ int basstate; /* bitmap (BS_*) */ @@ -660,7 +657,7 @@ static void read_int_callback(struct urb *urb) } /* drop incomplete packets even if the missing bytes wouldn't matter */ - if (unlikely(urb->actual_length < IP_MSGSIZE)) { + if (unlikely(urb->actual_length < 3)) { dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n", urb->actual_length); goto resubmit; @@ -2130,7 +2127,6 @@ static void gigaset_reinitbcshw(struct bc_state *bcs) static void gigaset_freecshw(struct cardstate *cs) { /* timers, URBs and rcvbuf are disposed of in disconnect */ - kfree(cs->hw.bas->int_in_buf); kfree(cs->hw.bas); cs->hw.bas = NULL; } @@ -2144,12 +2140,6 @@ static int gigaset_initcshw(struct cardstate *cs) pr_err("out of memory\n"); return 0; } - ucs->int_in_buf = kmalloc(IP_MSGSIZE, GFP_KERNEL); - if (!ucs->int_in_buf) { - kfree(ucs); - pr_err("out of memory\n"); - return 0; - } ucs->urb_cmd_in = NULL; ucs->urb_cmd_out = NULL; @@ -2302,7 +2292,7 @@ static int gigaset_probe(struct usb_interface *interface, usb_fill_int_urb(ucs->urb_int_in, udev, usb_rcvintpipe(udev, (endpoint->bEndpointAddress) & 0x0f), - ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs, + ucs->int_in_buf, 3, read_int_callback, cs, endpoint->bInterval); if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) { dev_err(cs->dev, "could not submit interrupt URB: %s\n", diff --git a/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index bfefd079a955..35bda49796fb 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/drivers/md/dm-crypt.c @@ -60,7 +60,6 @@ struct dm_crypt_io { }; struct dm_crypt_request { - struct convert_context *ctx; struct scatterlist sg_in; struct scatterlist sg_out; }; @@ -336,18 +335,6 @@ static void crypt_convert_init(struct crypt_config *cc, init_completion(&ctx->restart); } -static struct dm_crypt_request *dmreq_of_req(struct crypt_config *cc, - struct ablkcipher_request *req) -{ - return (struct dm_crypt_request *)((char *)req + cc->dmreq_start); -} - -static struct ablkcipher_request *req_of_dmreq(struct crypt_config *cc, - struct dm_crypt_request *dmreq) -{ - return (struct ablkcipher_request *)((char *)dmreq - cc->dmreq_start); -} - static int crypt_convert_block(struct crypt_config *cc, struct convert_context *ctx, struct ablkcipher_request *req) @@ -358,11 +345,10 @@ static int crypt_convert_block(struct crypt_config *cc, u8 *iv; int r = 0; - dmreq = dmreq_of_req(cc, req); + dmreq = (struct dm_crypt_request *)((char *)req + cc->dmreq_start); iv = (u8 *)ALIGN((unsigned long)(dmreq + 1), crypto_ablkcipher_alignmask(cc->tfm) + 1); - dmreq->ctx = ctx; sg_init_table(&dmreq->sg_in, 1); sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, bv_in->bv_offset + ctx->offset_in); @@ -409,9 +395,8 @@ static void crypt_alloc_req(struct crypt_config *cc, cc->req = mempool_alloc(cc->req_pool, GFP_NOIO); ablkcipher_request_set_tfm(cc->req, cc->tfm); ablkcipher_request_set_callback(cc->req, CRYPTO_TFM_REQ_MAY_BACKLOG | - CRYPTO_TFM_REQ_MAY_SLEEP, - kcryptd_async_done, - dmreq_of_req(cc, cc->req)); + CRYPTO_TFM_REQ_MAY_SLEEP, + kcryptd_async_done, ctx); } /* @@ -568,22 +553,19 @@ static void crypt_inc_pending(struct dm_crypt_io *io) static void crypt_dec_pending(struct dm_crypt_io *io) { struct crypt_config *cc = io->target->private; - struct bio *base_bio = io->base_bio; - struct dm_crypt_io *base_io = io->base_io; - int error = io->error; if (!atomic_dec_and_test(&io->pending)) return; - mempool_free(io, cc->io_pool); - - if (likely(!base_io)) - bio_endio(base_bio, error); + if (likely(!io->base_io)) + bio_endio(io->base_bio, io->error); else { - if (error && !base_io->error) - base_io->error = error; - crypt_dec_pending(base_io); + if (io->error && !io->base_io->error) + io->base_io->error = io->error; + crypt_dec_pending(io->base_io); } + + mempool_free(io, cc->io_pool); } /* @@ -839,8 +821,7 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) static void kcryptd_async_done(struct crypto_async_request *async_req, int error) { - struct dm_crypt_request *dmreq = async_req->data; - struct convert_context *ctx = dmreq->ctx; + struct convert_context *ctx = async_req->data; struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx); struct crypt_config *cc = io->target->private; @@ -849,7 +830,7 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, return; } - mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool); + mempool_free(ablkcipher_request_cast(async_req), cc->req_pool); if (!atomic_dec_and_test(&ctx->pending)) return; diff --git a/trunk/drivers/md/dm-io.c b/trunk/drivers/md/dm-io.c index 36e2b5e46a6b..f14813be4eff 100644 --- a/trunk/drivers/md/dm-io.c +++ b/trunk/drivers/md/dm-io.c @@ -292,8 +292,6 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, (PAGE_SIZE >> SECTOR_SHIFT)); num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs); - if (unlikely(num_bvecs > BIO_MAX_PAGES)) - num_bvecs = BIO_MAX_PAGES; bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); bio->bi_sector = where->sector + (where->count - remaining); bio->bi_bdev = where->bdev; diff --git a/trunk/drivers/md/dm-ioctl.c b/trunk/drivers/md/dm-ioctl.c index f01096549a93..54d0588fc1f6 100644 --- a/trunk/drivers/md/dm-ioctl.c +++ b/trunk/drivers/md/dm-ioctl.c @@ -704,8 +704,7 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size) char *new_name = (char *) param + param->data_start; if (new_name < param->data || - invalid_str(new_name, (void *) param + param_size) || - strlen(new_name) > DM_NAME_LEN - 1) { + invalid_str(new_name, (void *) param + param_size)) { DMWARN("Invalid new logical volume name supplied."); return -EINVAL; } @@ -1064,7 +1063,7 @@ static int table_load(struct dm_ioctl *param, size_t param_size) r = populate_table(t, param, param_size); if (r) { - dm_table_destroy(t); + dm_table_put(t); goto out; } @@ -1072,7 +1071,7 @@ static int table_load(struct dm_ioctl *param, size_t param_size) hc = dm_get_mdptr(md); if (!hc || hc->md != md) { DMWARN("device has been removed from the dev hash table."); - dm_table_destroy(t); + dm_table_put(t); up_write(&_hash_lock); r = -ENXIO; goto out; diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 8d40f27cce89..51ba1db4b3e7 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -525,12 +525,9 @@ static int __noflush_suspending(struct mapped_device *md) static void dec_pending(struct dm_io *io, int error) { unsigned long flags; - int io_error; - struct bio *bio; - struct mapped_device *md = io->md; /* Push-back supersedes any I/O errors */ - if (error && !(io->error > 0 && __noflush_suspending(md))) + if (error && !(io->error > 0 && __noflush_suspending(io->md))) io->error = error; if (atomic_dec_and_test(&io->io_count)) { @@ -540,27 +537,24 @@ static void dec_pending(struct dm_io *io, int error) * This must be handled before the sleeper on * suspend queue merges the pushback list. */ - spin_lock_irqsave(&md->pushback_lock, flags); - if (__noflush_suspending(md)) - bio_list_add(&md->pushback, io->bio); + spin_lock_irqsave(&io->md->pushback_lock, flags); + if (__noflush_suspending(io->md)) + bio_list_add(&io->md->pushback, io->bio); else /* noflush suspend was interrupted. */ io->error = -EIO; - spin_unlock_irqrestore(&md->pushback_lock, flags); + spin_unlock_irqrestore(&io->md->pushback_lock, flags); } end_io_acct(io); - io_error = io->error; - bio = io->bio; - - free_io(md, io); - - if (io_error != DM_ENDIO_REQUEUE) { - trace_block_bio_complete(md->queue, bio); + if (io->error != DM_ENDIO_REQUEUE) { + trace_block_bio_complete(io->md->queue, io->bio); - bio_endio(bio, io_error); + bio_endio(io->bio, io->error); } + + free_io(io->md, io); } } @@ -568,7 +562,6 @@ static void clone_endio(struct bio *bio, int error) { int r = 0; struct dm_target_io *tio = bio->bi_private; - struct dm_io *io = tio->io; struct mapped_device *md = tio->io->md; dm_endio_fn endio = tio->ti->type->end_io; @@ -592,14 +585,15 @@ static void clone_endio(struct bio *bio, int error) } } + dec_pending(tio->io, error); + /* * Store md for cleanup instead of tio which is about to get freed. */ bio->bi_private = md->bs; - free_tio(md, tio); bio_put(bio); - dec_pending(io, error); + free_tio(md, tio); } static sector_t max_io_len(struct mapped_device *md, diff --git a/trunk/drivers/media/dvb/bt8xx/dst.c b/trunk/drivers/media/dvb/bt8xx/dst.c index fec1d77fa855..29e8f1546ab6 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst.c +++ b/trunk/drivers/media/dvb/bt8xx/dst.c @@ -1683,7 +1683,7 @@ static int dst_tune_frontend(struct dvb_frontend* fe, static int dst_get_tuning_algo(struct dvb_frontend *fe) { - return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW; + return dst_algo; } static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index 8dcb3fbf7acd..843407785083 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1290,6 +1290,9 @@ static int dtv_property_process_set(struct dvb_frontend *fe, dprintk("%s() Finalised property cache\n", __func__); dtv_property_cache_submit(fe); + /* Request the search algorithm to search */ + fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; + r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, &fepriv->parameters); break; @@ -1714,10 +1717,6 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000; fepriv->state = FESTATE_RETUNE; - - /* Request the search algorithm to search */ - fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; - dvb_frontend_wakeup(fe); dvb_frontend_add_event(fe, 0); fepriv->status = 0; diff --git a/trunk/drivers/media/dvb/frontends/stb0899_algo.c b/trunk/drivers/media/dvb/frontends/stb0899_algo.c index 2da55ec20392..a67d1775a43c 100644 --- a/trunk/drivers/media/dvb/frontends/stb0899_algo.c +++ b/trunk/drivers/media/dvb/frontends/stb0899_algo.c @@ -156,7 +156,7 @@ static void stb0899_first_subrange(struct stb0899_state *state) } if (range > 0) - internal->sub_range = min(internal->srch_range, range); + internal->sub_range = MIN(internal->srch_range, range); else internal->sub_range = 0; @@ -185,7 +185,7 @@ static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state) timing = stb0899_read_reg(state, STB0899_RTF); if (lock >= 42) { - if ((lock > 48) && (abs(timing) >= 110)) { + if ((lock > 48) && (ABS(timing) >= 110)) { internal->status = ANALOGCARRIER; dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !"); } else { @@ -222,7 +222,7 @@ static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state) index++; derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */ - if (abs(derot_freq) > derot_limit) + if (ABS(derot_freq) > derot_limit) next_loop--; if (next_loop) { @@ -298,7 +298,7 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state) last_derot_freq = derot_freq; derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */ - if(abs(derot_freq) > derot_limit) + if(ABS(derot_freq) > derot_limit) next_loop--; if (next_loop) { @@ -400,7 +400,7 @@ static enum stb0899_status stb0899_search_data(struct stb0899_state *state) if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) { derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ - if (abs(derot_freq) > derot_limit) + if (ABS(derot_freq) > derot_limit) next_loop--; if (next_loop) { @@ -467,7 +467,7 @@ static void next_sub_range(struct stb0899_state *state) if (internal->sub_dir > 0) { old_sub_range = internal->sub_range; - internal->sub_range = min((internal->srch_range / 2) - + internal->sub_range = MIN((internal->srch_range / 2) - (internal->tuner_offst + internal->sub_range / 2), internal->sub_range); @@ -771,7 +771,7 @@ static long Log2Int(int number) int i; i = 0; - while ((1 << i) <= abs(number)) + while ((1 << i) <= ABS(number)) i++; if (number == 0) diff --git a/trunk/drivers/media/dvb/frontends/stb0899_drv.c b/trunk/drivers/media/dvb/frontends/stb0899_drv.c index a04c782fff8d..10613acf18f5 100644 --- a/trunk/drivers/media/dvb/frontends/stb0899_drv.c +++ b/trunk/drivers/media/dvb/frontends/stb0899_drv.c @@ -794,7 +794,7 @@ static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t reg = stb0899_read_reg(state, STB0899_DISCNTRL1); old_state = reg; /* set to burst mode */ - STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x03); + STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02); STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01); stb0899_write_reg(state, STB0899_DISCNTRL1, reg); switch (burst) { diff --git a/trunk/drivers/media/dvb/frontends/stb0899_priv.h b/trunk/drivers/media/dvb/frontends/stb0899_priv.h index 82395b912815..24619e3689db 100644 --- a/trunk/drivers/media/dvb/frontends/stb0899_priv.h +++ b/trunk/drivers/media/dvb/frontends/stb0899_priv.h @@ -59,6 +59,10 @@ #define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) #define MAKEWORD16(a, b) (((a) << 8) | (b)) +#define MIN(x, y) ((x) <= (y) ? (x) : (y)) +#define MAX(x, y) ((x) >= (y) ? (x) : (y)) +#define ABS(x) ((x) >= 0 ? (x) : -(x)) + #define LSB(x) ((x & 0xff)) #define MSB(y) ((y >> 8) & 0xff) @@ -164,10 +168,10 @@ struct stb0899_internal { u32 freq; /* Demod internal Frequency */ u32 srate; /* Demod internal Symbol rate */ enum stb0899_fec fecrate; /* Demod internal FEC rate */ - s32 srch_range; /* Demod internal Search Range */ - s32 sub_range; /* Demod current sub range (Hz) */ - s32 tuner_step; /* Tuner step (Hz) */ - s32 tuner_offst; /* Relative offset to carrier (Hz) */ + u32 srch_range; /* Demod internal Search Range */ + u32 sub_range; /* Demod current sub range (Hz) */ + u32 tuner_step; /* Tuner step (Hz) */ + u32 tuner_offst; /* Relative offset to carrier (Hz) */ u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */ s32 mclk; /* Masterclock Divider factor (binary) */ diff --git a/trunk/drivers/media/dvb/frontends/stb6100.c b/trunk/drivers/media/dvb/frontends/stb6100.c index 1ed5a7db4c5e..ff39275ab49c 100644 --- a/trunk/drivers/media/dvb/frontends/stb6100.c +++ b/trunk/drivers/media/dvb/frontends/stb6100.c @@ -427,11 +427,11 @@ static int stb6100_init(struct dvb_frontend *fe) status->refclock = 27000000; /* Hz */ status->iqsense = 1; status->bandwidth = 36000; /* kHz */ - state->bandwidth = status->bandwidth * 1000; /* Hz */ + state->bandwidth = status->bandwidth * 1000; /* MHz */ state->reference = status->refclock / 1000; /* kHz */ /* Set default bandwidth. */ - return stb6100_set_bandwidth(fe, state->bandwidth); + return stb6100_set_bandwidth(fe, status->bandwidth); } static int stb6100_get_state(struct dvb_frontend *fe, diff --git a/trunk/drivers/media/dvb/frontends/zl10353.c b/trunk/drivers/media/dvb/frontends/zl10353.c index b150ed306696..170720b02815 100644 --- a/trunk/drivers/media/dvb/frontends/zl10353.c +++ b/trunk/drivers/media/dvb/frontends/zl10353.c @@ -590,7 +590,7 @@ static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) struct zl10353_state *state = fe->demodulator_priv; u8 val = 0x0a; - if (state->config.disable_i2c_gate_ctrl) { + if (state->config.no_tuner) { /* No tuner attached to the internal I2C bus */ /* If set enable I2C bridge, the main I2C bus stopped hardly */ return 0; diff --git a/trunk/drivers/media/dvb/frontends/zl10353.h b/trunk/drivers/media/dvb/frontends/zl10353.h index 2287bac46243..fdbb88ff75fe 100644 --- a/trunk/drivers/media/dvb/frontends/zl10353.h +++ b/trunk/drivers/media/dvb/frontends/zl10353.h @@ -38,9 +38,6 @@ struct zl10353_config /* set if parallel ts output is required */ int parallel_ts; - - /* set if i2c_gate_ctrl disable is required */ - u8 disable_i2c_gate_ctrl:1; }; #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) diff --git a/trunk/drivers/media/video/cx88/cx88-alsa.c b/trunk/drivers/media/video/cx88/cx88-alsa.c index ce98d955231a..66c755c116dc 100644 --- a/trunk/drivers/media/video/cx88/cx88-alsa.c +++ b/trunk/drivers/media/video/cx88/cx88-alsa.c @@ -803,10 +803,9 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, return (-ENOENT); } - err = snd_card_create(index[devno], id[devno], THIS_MODULE, - sizeof(snd_cx88_card_t), &card); - if (err < 0) - return err; + card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t)); + if (!card) + return (-ENOMEM); card->private_free = snd_cx88_dev_free; diff --git a/trunk/drivers/media/video/em28xx/em28xx-audio.c b/trunk/drivers/media/video/em28xx/em28xx-audio.c index f132e31f6edd..2ac738fa6a07 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-audio.c +++ b/trunk/drivers/media/video/em28xx/em28xx-audio.c @@ -448,10 +448,9 @@ static int em28xx_audio_init(struct em28xx *dev) printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " "Rechberger\n"); - err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0, - &card); - if (err < 0) - return err; + card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; spin_lock_init(&adev->slock); err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 48892b5715d5..e564a61a72d7 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c @@ -102,11 +102,7 @@ int s5k4aa_probe(struct sd *sd) } /* Test some registers, but we don't know their exact meaning yet */ - if (m5602_read_sensor(sd, 0x00, prod_id, 2)) - return -ENODEV; - if (m5602_read_sensor(sd, 0x02, prod_id+2, 2)) - return -ENODEV; - if (m5602_read_sensor(sd, 0x04, prod_id+4, 2)) + if (m5602_read_sensor(sd, 0x00, prod_id, sizeof(prod_id))) return -ENODEV; if (memcmp(prod_id, expected_prod_id, sizeof(prod_id))) diff --git a/trunk/drivers/media/video/saa7134/saa7134-alsa.c b/trunk/drivers/media/video/saa7134/saa7134-alsa.c index 8b0b64a89874..c750d3dd57d2 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-alsa.c +++ b/trunk/drivers/media/video/saa7134/saa7134-alsa.c @@ -990,10 +990,10 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) if (!enable[devnum]) return -ENODEV; - err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, - sizeof(snd_card_saa7134_t), &card); - if (err < 0) - return err; + card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t)); + + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "SAA7134"); diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index b5370b3e1a3d..0776ecf56d27 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -860,7 +860,6 @@ static struct zl10353_config behold_h6_config = { .demod_address = 0x1e>>1, .no_tuner = 1, .parallel_ts = 1, - .disable_i2c_gate_ctrl = 1, }; /* ================================================================== diff --git a/trunk/drivers/media/video/tvaudio.c b/trunk/drivers/media/video/tvaudio.c index 076ed5bf48b1..5aeccb301cea 100644 --- a/trunk/drivers/media/video/tvaudio.c +++ b/trunk/drivers/media/video/tvaudio.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); /* ---------------------------------------------------------------------- */ /* our structs */ -#define MAXREGS 256 +#define MAXREGS 64 struct CHIPSTATE; typedef int (*getvalue)(int); diff --git a/trunk/drivers/media/video/zoran/Kconfig b/trunk/drivers/media/video/zoran/Kconfig index 8666e19f31a7..4ea5fa71de89 100644 --- a/trunk/drivers/media/video/zoran/Kconfig +++ b/trunk/drivers/media/video/zoran/Kconfig @@ -68,7 +68,6 @@ config VIDEO_ZORAN_AVS6EYES tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO help Support for the AverMedia 6 Eyes video surveillance card. diff --git a/trunk/drivers/mtd/devices/Kconfig b/trunk/drivers/mtd/devices/Kconfig index 6fde0a2e3567..bc33200535fc 100644 --- a/trunk/drivers/mtd/devices/Kconfig +++ b/trunk/drivers/mtd/devices/Kconfig @@ -120,6 +120,13 @@ config MTD_PHRAM doesn't have access to, memory beyond the mem=xxx limit, nvram, memory on the video card, etc... +config MTD_PS3VRAM + tristate "PS3 video RAM" + depends on FB_PS3 + help + This driver allows you to use excess PS3 video RAM as volatile + storage or system swap. + config MTD_LART tristate "28F160xx flash driver for LART" depends on SA1100_LART diff --git a/trunk/drivers/mtd/devices/Makefile b/trunk/drivers/mtd/devices/Makefile index 0993d5cf3923..e51521df4e40 100644 --- a/trunk/drivers/mtd/devices/Makefile +++ b/trunk/drivers/mtd/devices/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_LART) += lart.o obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o +obj-$(CONFIG_MTD_PS3VRAM) += ps3vram.o diff --git a/trunk/drivers/mtd/devices/ps3vram.c b/trunk/drivers/mtd/devices/ps3vram.c new file mode 100644 index 000000000000..d21e9beb7ed2 --- /dev/null +++ b/trunk/drivers/mtd/devices/ps3vram.c @@ -0,0 +1,768 @@ +/** + * ps3vram - Use extra PS3 video ram as MTD block device. + * + * Copyright (c) 2007-2008 Jim Paris + * Added support RSX DMA Vivien Chappelier + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DEVICE_NAME "ps3vram" + +#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */ +#define XDR_IOIF 0x0c000000 + +#define FIFO_BASE XDR_IOIF +#define FIFO_SIZE (64 * 1024) + +#define DMA_PAGE_SIZE (4 * 1024) + +#define CACHE_PAGE_SIZE (256 * 1024) +#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE) + +#define CACHE_OFFSET CACHE_PAGE_SIZE +#define FIFO_OFFSET 0 + +#define CTRL_PUT 0x10 +#define CTRL_GET 0x11 +#define CTRL_TOP 0x15 + +#define UPLOAD_SUBCH 1 +#define DOWNLOAD_SUBCH 2 + +#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 + +#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 + +struct mtd_info ps3vram_mtd; + +#define CACHE_PAGE_PRESENT 1 +#define CACHE_PAGE_DIRTY 2 + +struct ps3vram_tag { + unsigned int address; + unsigned int flags; +}; + +struct ps3vram_cache { + unsigned int page_count; + unsigned int page_size; + struct ps3vram_tag *tags; +}; + +struct ps3vram_priv { + u64 memory_handle; + u64 context_handle; + u32 *ctrl; + u32 *reports; + u8 __iomem *ddr_base; + u8 *xdr_buf; + + u32 *fifo_base; + u32 *fifo_ptr; + + struct device *dev; + struct ps3vram_cache cache; + + /* Used to serialize cache/DMA operations */ + struct mutex lock; +}; + +#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ +#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */ +#define DMA_NOTIFIER_SIZE 0x40 +#define NOTIFIER 7 /* notifier used for completion report */ + +/* A trailing '-' means to subtract off ps3fb_videomemory.size */ +char *size = "256M-"; +module_param(size, charp, 0); +MODULE_PARM_DESC(size, "memory size"); + +static u32 *ps3vram_get_notifier(u32 *reports, int notifier) +{ + return (void *) reports + + DMA_NOTIFIER_OFFSET_BASE + + DMA_NOTIFIER_SIZE * notifier; +} + +static void ps3vram_notifier_reset(struct mtd_info *mtd) +{ + int i; + + struct ps3vram_priv *priv = mtd->priv; + u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); + for (i = 0; i < 4; i++) + notify[i] = 0xffffffff; +} + +static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms) +{ + struct ps3vram_priv *priv = mtd->priv; + u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); + unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); + + do { + if (!notify[3]) + return 0; + msleep(1); + } while (time_before(jiffies, timeout)); + + return -ETIMEDOUT; +} + +static void ps3vram_init_ring(struct mtd_info *mtd) +{ + struct ps3vram_priv *priv = mtd->priv; + + priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; + priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; +} + +static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms) +{ + struct ps3vram_priv *priv = mtd->priv; + unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); + + do { + if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) + return 0; + msleep(1); + } while (time_before(jiffies, timeout)); + + dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__, + __LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], + priv->ctrl[CTRL_TOP]); + + return -ETIMEDOUT; +} + +static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) +{ + *(priv->fifo_ptr)++ = data; +} + +static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, + u32 tag, u32 size) +{ + ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); +} + +static void ps3vram_rewind_ring(struct mtd_info *mtd) +{ + struct ps3vram_priv *priv = mtd->priv; + u64 status; + + ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); + + priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; + + /* asking the HV for a blit will kick the fifo */ + status = lv1_gpu_context_attribute(priv->context_handle, + L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, + 0, 0, 0, 0); + if (status) + dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", + __func__, __LINE__); + + priv->fifo_ptr = priv->fifo_base; +} + +static void ps3vram_fire_ring(struct mtd_info *mtd) +{ + struct ps3vram_priv *priv = mtd->priv; + u64 status; + + mutex_lock(&ps3_gpu_mutex); + + priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + + (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); + + /* asking the HV for a blit will kick the fifo */ + status = lv1_gpu_context_attribute(priv->context_handle, + L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, + 0, 0, 0, 0); + if (status) + dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", + __func__, __LINE__); + + if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > + FIFO_SIZE - 1024) { + dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__, + __LINE__); + ps3vram_wait_ring(mtd, 200); + ps3vram_rewind_ring(mtd); + } + + mutex_unlock(&ps3_gpu_mutex); +} + +static void ps3vram_bind(struct mtd_info *mtd) +{ + struct ps3vram_priv *priv = mtd->priv; + + ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); + ps3vram_out_ring(priv, 0x31337303); + ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3); + ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); + ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ + ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ + + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1); + ps3vram_out_ring(priv, 0x3137c0de); + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3); + ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); + ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ + ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ + + ps3vram_fire_ring(mtd); +} + +static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset, + unsigned int dst_offset, int len, int count) +{ + struct ps3vram_priv *priv = mtd->priv; + + ps3vram_begin_ring(priv, UPLOAD_SUBCH, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + ps3vram_out_ring(priv, XDR_IOIF + src_offset); + ps3vram_out_ring(priv, dst_offset); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, count); + ps3vram_out_ring(priv, (1 << 8) | 1); + ps3vram_out_ring(priv, 0); + + ps3vram_notifier_reset(mtd); + ps3vram_begin_ring(priv, UPLOAD_SUBCH, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); + ps3vram_out_ring(priv, 0); + ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1); + ps3vram_out_ring(priv, 0); + ps3vram_fire_ring(mtd); + if (ps3vram_notifier_wait(mtd, 200) < 0) { + dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, + __LINE__); + return -1; + } + + return 0; +} + +static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset, + unsigned int dst_offset, int len, int count) +{ + struct ps3vram_priv *priv = mtd->priv; + + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + ps3vram_out_ring(priv, src_offset); + ps3vram_out_ring(priv, XDR_IOIF + dst_offset); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, count); + ps3vram_out_ring(priv, (1 << 8) | 1); + ps3vram_out_ring(priv, 0); + + ps3vram_notifier_reset(mtd); + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); + ps3vram_out_ring(priv, 0); + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1); + ps3vram_out_ring(priv, 0); + ps3vram_fire_ring(mtd); + if (ps3vram_notifier_wait(mtd, 200) < 0) { + dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, + __LINE__); + return -1; + } + + return 0; +} + +static void ps3vram_cache_evict(struct mtd_info *mtd, int entry) +{ + struct ps3vram_priv *priv = mtd->priv; + struct ps3vram_cache *cache = &priv->cache; + + if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) { + dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__, + __LINE__, entry, cache->tags[entry].address); + if (ps3vram_upload(mtd, + CACHE_OFFSET + entry * cache->page_size, + cache->tags[entry].address, + DMA_PAGE_SIZE, + cache->page_size / DMA_PAGE_SIZE) < 0) { + dev_dbg(priv->dev, "%s:%d: failed to upload from " + "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, + entry * cache->page_size, + cache->tags[entry].address, cache->page_size); + } + cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; + } +} + +static void ps3vram_cache_load(struct mtd_info *mtd, int entry, + unsigned int address) +{ + struct ps3vram_priv *priv = mtd->priv; + struct ps3vram_cache *cache = &priv->cache; + + dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__, + entry, address); + if (ps3vram_download(mtd, + address, + CACHE_OFFSET + entry * cache->page_size, + DMA_PAGE_SIZE, + cache->page_size / DMA_PAGE_SIZE) < 0) { + dev_err(priv->dev, "%s:%d: failed to download from " + "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address, + entry * cache->page_size, cache->page_size); + } + + cache->tags[entry].address = address; + cache->tags[entry].flags |= CACHE_PAGE_PRESENT; +} + + +static void ps3vram_cache_flush(struct mtd_info *mtd) +{ + struct ps3vram_priv *priv = mtd->priv; + struct ps3vram_cache *cache = &priv->cache; + int i; + + dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__); + for (i = 0; i < cache->page_count; i++) { + ps3vram_cache_evict(mtd, i); + cache->tags[i].flags = 0; + } +} + +static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address) +{ + struct ps3vram_priv *priv = mtd->priv; + struct ps3vram_cache *cache = &priv->cache; + unsigned int base; + unsigned int offset; + int i; + static int counter; + + offset = (unsigned int) (address & (cache->page_size - 1)); + base = (unsigned int) (address - offset); + + /* fully associative check */ + for (i = 0; i < cache->page_count; i++) { + if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && + cache->tags[i].address == base) { + dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n", + __func__, __LINE__, i, cache->tags[i].address); + return i; + } + } + + /* choose a random entry */ + i = (jiffies + (counter++)) % cache->page_count; + dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i); + + ps3vram_cache_evict(mtd, i); + ps3vram_cache_load(mtd, i, base); + + return i; +} + +static int ps3vram_cache_init(struct mtd_info *mtd) +{ + struct ps3vram_priv *priv = mtd->priv; + + priv->cache.page_count = CACHE_PAGE_COUNT; + priv->cache.page_size = CACHE_PAGE_SIZE; + priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * + CACHE_PAGE_COUNT, GFP_KERNEL); + if (priv->cache.tags == NULL) { + dev_err(priv->dev, "%s:%d: could not allocate cache tags\n", + __func__, __LINE__); + return -ENOMEM; + } + + dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n", + CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); + + return 0; +} + +static void ps3vram_cache_cleanup(struct mtd_info *mtd) +{ + struct ps3vram_priv *priv = mtd->priv; + + ps3vram_cache_flush(mtd); + kfree(priv->cache.tags); +} + +static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + struct ps3vram_priv *priv = mtd->priv; + + if (instr->addr + instr->len > mtd->size) + return -EINVAL; + + mutex_lock(&priv->lock); + + ps3vram_cache_flush(mtd); + + /* Set bytes to 0xFF */ + memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len); + + mutex_unlock(&priv->lock); + + instr->state = MTD_ERASE_DONE; + mtd_erase_callback(instr); + + return 0; +} + +static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct ps3vram_priv *priv = mtd->priv; + unsigned int cached, count; + + dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__, + (unsigned int)from, len); + + if (from >= mtd->size) + return -EINVAL; + + if (len > mtd->size - from) + len = mtd->size - from; + + /* Copy from vram to buf */ + count = len; + while (count) { + unsigned int offset, avail; + unsigned int entry; + + offset = (unsigned int) (from & (priv->cache.page_size - 1)); + avail = priv->cache.page_size - offset; + + mutex_lock(&priv->lock); + + entry = ps3vram_cache_match(mtd, from); + cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; + + dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x " + "avail=%08x count=%08x\n", __func__, __LINE__, + (unsigned int)from, cached, offset, avail, count); + + if (avail > count) + avail = count; + memcpy(buf, priv->xdr_buf + cached, avail); + + mutex_unlock(&priv->lock); + + buf += avail; + count -= avail; + from += avail; + } + + *retlen = len; + return 0; +} + +static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + struct ps3vram_priv *priv = mtd->priv; + unsigned int cached, count; + + if (to >= mtd->size) + return -EINVAL; + + if (len > mtd->size - to) + len = mtd->size - to; + + /* Copy from buf to vram */ + count = len; + while (count) { + unsigned int offset, avail; + unsigned int entry; + + offset = (unsigned int) (to & (priv->cache.page_size - 1)); + avail = priv->cache.page_size - offset; + + mutex_lock(&priv->lock); + + entry = ps3vram_cache_match(mtd, to); + cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; + + dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x " + "avail=%08x count=%08x\n", __func__, __LINE__, + (unsigned int)to, cached, offset, avail, count); + + if (avail > count) + avail = count; + memcpy(priv->xdr_buf + cached, buf, avail); + + priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; + + mutex_unlock(&priv->lock); + + buf += avail; + count -= avail; + to += avail; + } + + *retlen = len; + return 0; +} + +static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv; + int status; + u64 ddr_lpar; + u64 ctrl_lpar; + u64 info_lpar; + u64 reports_lpar; + u64 ddr_size; + u64 reports_size; + int ret = -ENOMEM; + char *rest; + + ret = -EIO; + ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL); + if (!ps3vram_mtd.priv) + goto out; + priv = ps3vram_mtd.priv; + + mutex_init(&priv->lock); + priv->dev = &dev->core; + + /* Allocate XDR buffer (1MiB aligned) */ + priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, + get_order(XDR_BUF_SIZE)); + if (priv->xdr_buf == NULL) { + dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n", + __func__, __LINE__); + ret = -ENOMEM; + goto out_free_priv; + } + + /* Put FIFO at begginning of XDR buffer */ + priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); + priv->fifo_ptr = priv->fifo_base; + + /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ + if (ps3_open_hv_device(dev)) { + dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n", + __func__, __LINE__); + ret = -EAGAIN; + goto out_close_gpu; + } + + /* Request memory */ + status = -1; + ddr_size = memparse(size, &rest); + if (*rest == '-') + ddr_size -= ps3fb_videomemory.size; + ddr_size = ALIGN(ddr_size, 1024*1024); + if (ddr_size <= 0) { + dev_err(&dev->core, "%s:%d: specified size is too small\n", + __func__, __LINE__); + ret = -EINVAL; + goto out_close_gpu; + } + + while (ddr_size > 0) { + status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, + &priv->memory_handle, + &ddr_lpar); + if (!status) + break; + ddr_size -= 1024*1024; + } + if (status || ddr_size <= 0) { + dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n", + __func__, __LINE__); + ret = -ENOMEM; + goto out_free_xdr_buf; + } + + /* Request context */ + status = lv1_gpu_context_allocate(priv->memory_handle, + 0, + &priv->context_handle, + &ctrl_lpar, + &info_lpar, + &reports_lpar, + &reports_size); + if (status) { + dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n", + __func__, __LINE__); + ret = -ENOMEM; + goto out_free_memory; + } + + /* Map XDR buffer to RSX */ + status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, + ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), + XDR_BUF_SIZE, 0); + if (status) { + dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n", + __func__, __LINE__); + ret = -ENOMEM; + goto out_free_context; + } + + priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); + + if (!priv->ddr_base) { + dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, + __LINE__); + ret = -ENOMEM; + goto out_free_context; + } + + priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); + if (!priv->ctrl) { + dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, + __LINE__); + ret = -ENOMEM; + goto out_unmap_vram; + } + + priv->reports = ioremap(reports_lpar, reports_size); + if (!priv->reports) { + dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, + __LINE__); + ret = -ENOMEM; + goto out_unmap_ctrl; + } + + mutex_lock(&ps3_gpu_mutex); + ps3vram_init_ring(&ps3vram_mtd); + mutex_unlock(&ps3_gpu_mutex); + + ps3vram_mtd.name = "ps3vram"; + ps3vram_mtd.size = ddr_size; + ps3vram_mtd.flags = MTD_CAP_RAM; + ps3vram_mtd.erase = ps3vram_erase; + ps3vram_mtd.point = NULL; + ps3vram_mtd.unpoint = NULL; + ps3vram_mtd.read = ps3vram_read; + ps3vram_mtd.write = ps3vram_write; + ps3vram_mtd.owner = THIS_MODULE; + ps3vram_mtd.type = MTD_RAM; + ps3vram_mtd.erasesize = CACHE_PAGE_SIZE; + ps3vram_mtd.writesize = 1; + + ps3vram_bind(&ps3vram_mtd); + + mutex_lock(&ps3_gpu_mutex); + ret = ps3vram_wait_ring(&ps3vram_mtd, 100); + mutex_unlock(&ps3_gpu_mutex); + if (ret < 0) { + dev_err(&dev->core, "%s:%d: failed to initialize channels\n", + __func__, __LINE__); + ret = -ETIMEDOUT; + goto out_unmap_reports; + } + + ps3vram_cache_init(&ps3vram_mtd); + + if (add_mtd_device(&ps3vram_mtd)) { + dev_err(&dev->core, "%s:%d: add_mtd_device failed\n", + __func__, __LINE__); + ret = -EAGAIN; + goto out_cache_cleanup; + } + + dev_info(&dev->core, "reserved %u MiB of gpu memory\n", + (unsigned int)(ddr_size / 1024 / 1024)); + + return 0; + +out_cache_cleanup: + ps3vram_cache_cleanup(&ps3vram_mtd); +out_unmap_reports: + iounmap(priv->reports); +out_unmap_ctrl: + iounmap(priv->ctrl); +out_unmap_vram: + iounmap(priv->ddr_base); +out_free_context: + lv1_gpu_context_free(priv->context_handle); +out_free_memory: + lv1_gpu_memory_free(priv->memory_handle); +out_close_gpu: + ps3_close_hv_device(dev); +out_free_xdr_buf: + free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); +out_free_priv: + kfree(ps3vram_mtd.priv); + ps3vram_mtd.priv = NULL; +out: + return ret; +} + +static int ps3vram_shutdown(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv; + + priv = ps3vram_mtd.priv; + + del_mtd_device(&ps3vram_mtd); + ps3vram_cache_cleanup(&ps3vram_mtd); + iounmap(priv->reports); + iounmap(priv->ctrl); + iounmap(priv->ddr_base); + lv1_gpu_context_free(priv->context_handle); + lv1_gpu_memory_free(priv->memory_handle); + ps3_close_hv_device(dev); + free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); + kfree(priv); + return 0; +} + +static struct ps3_system_bus_driver ps3vram_driver = { + .match_id = PS3_MATCH_ID_GPU, + .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK, + .core.name = DEVICE_NAME, + .core.owner = THIS_MODULE, + .probe = ps3vram_probe, + .remove = ps3vram_shutdown, + .shutdown = ps3vram_shutdown, +}; + +static int __init ps3vram_init(void) +{ + return ps3_system_bus_driver_register(&ps3vram_driver); +} + +static void __exit ps3vram_exit(void) +{ + ps3_system_bus_driver_unregister(&ps3vram_driver); +} + +module_init(ps3vram_init); +module_exit(ps3vram_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jim Paris "); +MODULE_DESCRIPTION("MTD driver for PS3 video RAM"); +MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 62d732a886f1..a2f185fd7072 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1040,17 +1040,6 @@ config NI65 To compile this driver as a module, choose M here. The module will be called ni65. -config DNET - tristate "Dave ethernet support (DNET)" - depends on NET_ETHERNET && HAS_IOMEM - select PHYLIB - help - The Dave ethernet interface (DNET) is found on Qong Board FPGA. - Say Y to include support for the DNET chip. - - To compile this driver as a module, choose M here: the module - will be called dnet. - source "drivers/net/tulip/Kconfig" config AT1700 @@ -2630,8 +2619,6 @@ config QLGE source "drivers/net/sfc/Kconfig" -source "drivers/net/benet/Kconfig" - endif # NETDEV_10000 source "drivers/net/tokenring/Kconfig" diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 471baaff229f..aca8492db654 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -22,7 +22,6 @@ obj-$(CONFIG_GIANFAR) += gianfar_driver.o obj-$(CONFIG_TEHUTI) += tehuti.o obj-$(CONFIG_ENIC) += enic/ obj-$(CONFIG_JME) += jme.o -obj-$(CONFIG_BE2NET) += benet/ gianfar_driver-objs := gianfar.o \ gianfar_ethtool.o \ @@ -232,7 +231,6 @@ obj-$(CONFIG_ENC28J60) += enc28j60.o obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o -obj-$(CONFIG_DNET) += dnet.o obj-$(CONFIG_MACB) += macb.o obj-$(CONFIG_ARM) += arm/ diff --git a/trunk/drivers/net/benet/Kconfig b/trunk/drivers/net/benet/Kconfig deleted file mode 100644 index c6934f179c09..000000000000 --- a/trunk/drivers/net/benet/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config BE2NET - tristate "ServerEngines' 10Gbps NIC - BladeEngine 2" - depends on PCI && INET - select INET_LRO - help - This driver implements the NIC functionality for ServerEngines' - 10Gbps network adapter - BladeEngine 2. diff --git a/trunk/drivers/net/benet/Makefile b/trunk/drivers/net/benet/Makefile deleted file mode 100644 index a60cd8051135..000000000000 --- a/trunk/drivers/net/benet/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile to build the network driver for ServerEngine's BladeEngine. -# - -obj-$(CONFIG_BE2NET) += be2net.o - -be2net-y := be_main.o be_cmds.o be_ethtool.o diff --git a/trunk/drivers/net/benet/be.h b/trunk/drivers/net/benet/be.h deleted file mode 100644 index f327be57ca96..000000000000 --- a/trunk/drivers/net/benet/be.h +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (C) 2005 - 2009 ServerEngines - * 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 version 2 - * as published by the Free Software Foundation. The full GNU General - * Public License is included in this distribution in the file called COPYING. - * - * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 - */ - -#ifndef BE_H -#define BE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "be_hw.h" - -#define DRV_VER "2.0.348" -#define DRV_NAME "be2net" -#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" -#define DRV_DESC BE_NAME "Driver" - -/* Number of bytes of an RX frame that are copied to skb->data */ -#define BE_HDR_LEN 64 -#define BE_MAX_JUMBO_FRAME_SIZE 9018 -#define BE_MIN_MTU 256 - -#define BE_NUM_VLANS_SUPPORTED 64 -#define BE_MAX_EQD 96 -#define BE_MAX_TX_FRAG_COUNT 30 - -#define EVNT_Q_LEN 1024 -#define TX_Q_LEN 2048 -#define TX_CQ_LEN 1024 -#define RX_Q_LEN 1024 /* Does not support any other value */ -#define RX_CQ_LEN 1024 -#define MCC_Q_LEN 64 /* total size not to exceed 8 pages */ -#define MCC_CQ_LEN 256 - -#define BE_NAPI_WEIGHT 64 -#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ -#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) - -#define BE_MAX_LRO_DESCRIPTORS 16 -#define BE_MAX_FRAGS_PER_FRAME 16 - -struct be_dma_mem { - void *va; - dma_addr_t dma; - u32 size; -}; - -struct be_queue_info { - struct be_dma_mem dma_mem; - u16 len; - u16 entry_size; /* Size of an element in the queue */ - u16 id; - u16 tail, head; - bool created; - atomic_t used; /* Number of valid elements in the queue */ -}; - -struct be_ctrl_info { - u8 __iomem *csr; - u8 __iomem *db; /* Door Bell */ - u8 __iomem *pcicfg; /* PCI config space */ - int pci_func; - - /* Mbox used for cmd request/response */ - spinlock_t cmd_lock; /* For serializing cmds to BE card */ - struct be_dma_mem mbox_mem; - /* Mbox mem is adjusted to align to 16 bytes. The allocated addr - * is stored for freeing purpose */ - struct be_dma_mem mbox_mem_alloced; -}; - -#include "be_cmds.h" - -struct be_drvr_stats { - u32 be_tx_reqs; /* number of TX requests initiated */ - u32 be_tx_stops; /* number of times TX Q was stopped */ - u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */ - u32 be_tx_wrbs; /* number of tx WRBs used */ - u32 be_tx_events; /* number of tx completion events */ - u32 be_tx_compl; /* number of tx completion entries processed */ - u64 be_tx_jiffies; - ulong be_tx_bytes; - ulong be_tx_bytes_prev; - u32 be_tx_rate; - - u32 cache_barrier[16]; - - u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */ - u32 be_polls; /* number of times NAPI called poll function */ - u32 be_rx_events; /* number of ucast rx completion events */ - u32 be_rx_compl; /* number of rx completion entries processed */ - u32 be_lro_hgram_data[8]; /* histogram of LRO data packets */ - u32 be_lro_hgram_ack[8]; /* histogram of LRO ACKs */ - u64 be_rx_jiffies; - ulong be_rx_bytes; - ulong be_rx_bytes_prev; - u32 be_rx_rate; - /* number of non ether type II frames dropped where - * frame len > length field of Mac Hdr */ - u32 be_802_3_dropped_frames; - /* number of non ether type II frames malformed where - * in frame len < length field of Mac Hdr */ - u32 be_802_3_malformed_frames; - u32 be_rxcp_err; /* Num rx completion entries w/ err set. */ - ulong rx_fps_jiffies; /* jiffies at last FPS calc */ - u32 be_rx_frags; - u32 be_prev_rx_frags; - u32 be_rx_fps; /* Rx frags per second */ -}; - -struct be_stats_obj { - struct be_drvr_stats drvr_stats; - struct net_device_stats net_stats; - struct be_dma_mem cmd; -}; - -struct be_eq_obj { - struct be_queue_info q; - char desc[32]; - - /* Adaptive interrupt coalescing (AIC) info */ - bool enable_aic; - u16 min_eqd; /* in usecs */ - u16 max_eqd; /* in usecs */ - u16 cur_eqd; /* in usecs */ - - struct napi_struct napi; -}; - -struct be_tx_obj { - struct be_queue_info q; - struct be_queue_info cq; - /* Remember the skbs that were transmitted */ - struct sk_buff *sent_skb_list[TX_Q_LEN]; -}; - -/* Struct to remember the pages posted for rx frags */ -struct be_rx_page_info { - struct page *page; - dma_addr_t bus; - u16 page_offset; - bool last_page_user; -}; - -struct be_rx_obj { - struct be_queue_info q; - struct be_queue_info cq; - struct be_rx_page_info page_info_tbl[RX_Q_LEN]; - struct net_lro_mgr lro_mgr; - struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS]; -}; - -#define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ -struct be_adapter { - struct pci_dev *pdev; - struct net_device *netdev; - - /* Mbox, pci config, csr address information */ - struct be_ctrl_info ctrl; - - struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS]; - bool msix_enabled; - bool isr_registered; - - /* TX Rings */ - struct be_eq_obj tx_eq; - struct be_tx_obj tx_obj; - - u32 cache_line_break[8]; - - /* Rx rings */ - struct be_eq_obj rx_eq; - struct be_rx_obj rx_obj; - u32 big_page_size; /* Compounded page size shared by rx wrbs */ - bool rx_post_starved; /* Zero rx frags have been posted to BE */ - - struct vlan_group *vlan_grp; - u16 num_vlans; - u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; - - struct be_stats_obj stats; - /* Work queue used to perform periodic tasks like getting statistics */ - struct delayed_work work; - - /* Ethtool knobs and info */ - bool rx_csum; /* BE card must perform rx-checksumming */ - u32 max_rx_coal; - char fw_ver[FW_VER_LEN]; - u32 if_handle; /* Used to configure filtering */ - u32 pmac_id; /* MAC addr handle used by BE card */ - - struct be_link_info link; - u32 port_num; -}; - -extern struct ethtool_ops be_ethtool_ops; - -#define drvr_stats(adapter) (&adapter->stats.drvr_stats) - -#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) - -static inline u32 MODULO(u16 val, u16 limit) -{ - BUG_ON(limit & (limit - 1)); - return val & (limit - 1); -} - -static inline void index_adv(u16 *index, u16 val, u16 limit) -{ - *index = MODULO((*index + val), limit); -} - -static inline void index_inc(u16 *index, u16 limit) -{ - *index = MODULO((*index + 1), limit); -} - -#define PAGE_SHIFT_4K 12 -#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) - -/* Returns number of pages spanned by the data starting at the given addr */ -#define PAGES_4K_SPANNED(_address, size) \ - ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \ - (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K)) - -/* Byte offset into the page corresponding to given address */ -#define OFFSET_IN_PAGE(addr) \ - ((size_t)(addr) & (PAGE_SIZE_4K-1)) - -/* Returns bit offset within a DWORD of a bitfield */ -#define AMAP_BIT_OFFSET(_struct, field) \ - (((size_t)&(((_struct *)0)->field))%32) - -/* Returns the bit mask of the field that is NOT shifted into location. */ -static inline u32 amap_mask(u32 bitsize) -{ - return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1); -} - -static inline void -amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value) -{ - u32 *dw = (u32 *) ptr + dw_offset; - *dw &= ~(mask << offset); - *dw |= (mask & value) << offset; -} - -#define AMAP_SET_BITS(_struct, field, ptr, val) \ - amap_set(ptr, \ - offsetof(_struct, field)/32, \ - amap_mask(sizeof(((_struct *)0)->field)), \ - AMAP_BIT_OFFSET(_struct, field), \ - val) - -static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset) -{ - u32 *dw = (u32 *) ptr; - return mask & (*(dw + dw_offset) >> offset); -} - -#define AMAP_GET_BITS(_struct, field, ptr) \ - amap_get(ptr, \ - offsetof(_struct, field)/32, \ - amap_mask(sizeof(((_struct *)0)->field)), \ - AMAP_BIT_OFFSET(_struct, field)) - -#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len) -#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len) -static inline void swap_dws(void *wrb, int len) -{ -#ifdef __BIG_ENDIAN - u32 *dw = wrb; - BUG_ON(len % 4); - do { - *dw = cpu_to_le32(*dw); - dw++; - len -= 4; - } while (len); -#endif /* __BIG_ENDIAN */ -} - -static inline u8 is_tcp_pkt(struct sk_buff *skb) -{ - u8 val = 0; - - if (ip_hdr(skb)->version == 4) - val = (ip_hdr(skb)->protocol == IPPROTO_TCP); - else if (ip_hdr(skb)->version == 6) - val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP); - - return val; -} - -static inline u8 is_udp_pkt(struct sk_buff *skb) -{ - u8 val = 0; - - if (ip_hdr(skb)->version == 4) - val = (ip_hdr(skb)->protocol == IPPROTO_UDP); - else if (ip_hdr(skb)->version == 6) - val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP); - - return val; -} - -#endif /* BE_H */ diff --git a/trunk/drivers/net/benet/be_cmds.c b/trunk/drivers/net/benet/be_cmds.c deleted file mode 100644 index d444aed962bc..000000000000 --- a/trunk/drivers/net/benet/be_cmds.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * Copyright (C) 2005 - 2009 ServerEngines - * 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 version 2 - * as published by the Free Software Foundation. The full GNU General - * Public License is included in this distribution in the file called COPYING. - * - * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 - */ - -#include "be.h" - -static int be_mbox_db_ready_wait(void __iomem *db) -{ - int cnt = 0, wait = 5; - u32 ready; - - do { - ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; - if (ready) - break; - - if (cnt > 200000) { - printk(KERN_WARNING DRV_NAME - ": mbox_db poll timed out\n"); - return -1; - } - - if (cnt > 50) - wait = 200; - cnt += wait; - udelay(wait); - } while (true); - - return 0; -} - -/* - * Insert the mailbox address into the doorbell in two steps - */ -static int be_mbox_db_ring(struct be_ctrl_info *ctrl) -{ - int status; - u16 compl_status, extd_status; - u32 val = 0; - void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; - struct be_dma_mem *mbox_mem = &ctrl->mbox_mem; - struct be_mcc_mailbox *mbox = mbox_mem->va; - struct be_mcc_cq_entry *cqe = &mbox->cqe; - - memset(cqe, 0, sizeof(*cqe)); - - val &= ~MPU_MAILBOX_DB_RDY_MASK; - val |= MPU_MAILBOX_DB_HI_MASK; - /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */ - val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2; - iowrite32(val, db); - - /* wait for ready to be set */ - status = be_mbox_db_ready_wait(db); - if (status != 0) - return status; - - val = 0; - val &= ~MPU_MAILBOX_DB_RDY_MASK; - val &= ~MPU_MAILBOX_DB_HI_MASK; - /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */ - val |= (u32)(mbox_mem->dma >> 4) << 2; - iowrite32(val, db); - - status = be_mbox_db_ready_wait(db); - if (status != 0) - return status; - - /* compl entry has been made now */ - be_dws_le_to_cpu(cqe, sizeof(*cqe)); - if (!(cqe->flags & CQE_FLAGS_VALID_MASK)) { - printk(KERN_WARNING DRV_NAME ": ERROR invalid mbox compl\n"); - return -1; - } - - compl_status = (cqe->status >> CQE_STATUS_COMPL_SHIFT) & - CQE_STATUS_COMPL_MASK; - if (compl_status != MCC_STATUS_SUCCESS) { - extd_status = (cqe->status >> CQE_STATUS_EXTD_SHIFT) & - CQE_STATUS_EXTD_MASK; - printk(KERN_WARNING DRV_NAME - ": ERROR in cmd compl. status(compl/extd)=%d/%d\n", - compl_status, extd_status); - } - - return compl_status; -} - -static int be_POST_stage_get(struct be_ctrl_info *ctrl, u16 *stage) -{ - u32 sem = ioread32(ctrl->csr + MPU_EP_SEMAPHORE_OFFSET); - - *stage = sem & EP_SEMAPHORE_POST_STAGE_MASK; - if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK) - return -1; - else - return 0; -} - -static int be_POST_stage_poll(struct be_ctrl_info *ctrl, u16 poll_stage) -{ - u16 stage, cnt, error; - for (cnt = 0; cnt < 5000; cnt++) { - error = be_POST_stage_get(ctrl, &stage); - if (error) - return -1; - - if (stage == poll_stage) - break; - udelay(1000); - } - if (stage != poll_stage) - return -1; - return 0; -} - - -int be_cmd_POST(struct be_ctrl_info *ctrl) -{ - u16 stage, error; - - error = be_POST_stage_get(ctrl, &stage); - if (error) - goto err; - - if (stage == POST_STAGE_ARMFW_RDY) - return 0; - - if (stage != POST_STAGE_AWAITING_HOST_RDY) - goto err; - - /* On awaiting host rdy, reset and again poll on awaiting host rdy */ - iowrite32(POST_STAGE_BE_RESET, ctrl->csr + MPU_EP_SEMAPHORE_OFFSET); - error = be_POST_stage_poll(ctrl, POST_STAGE_AWAITING_HOST_RDY); - if (error) - goto err; - - /* Now kickoff POST and poll on armfw ready */ - iowrite32(POST_STAGE_HOST_RDY, ctrl->csr + MPU_EP_SEMAPHORE_OFFSET); - error = be_POST_stage_poll(ctrl, POST_STAGE_ARMFW_RDY); - if (error) - goto err; - - return 0; -err: - printk(KERN_WARNING DRV_NAME ": ERROR, stage=%d\n", stage); - return -1; -} - -static inline void *embedded_payload(struct be_mcc_wrb *wrb) -{ - return wrb->payload.embedded_payload; -} - -static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb) -{ - return &wrb->payload.sgl[0]; -} - -/* Don't touch the hdr after it's prepared */ -static void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, - bool embedded, u8 sge_cnt) -{ - if (embedded) - wrb->embedded |= MCC_WRB_EMBEDDED_MASK; - else - wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) << - MCC_WRB_SGE_CNT_SHIFT; - wrb->payload_length = payload_len; - be_dws_cpu_to_le(wrb, 20); -} - -/* Don't touch the hdr after it's prepared */ -static void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr, - u8 subsystem, u8 opcode, int cmd_len) -{ - req_hdr->opcode = opcode; - req_hdr->subsystem = subsystem; - req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr)); -} - -static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages, - struct be_dma_mem *mem) -{ - int i, buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages); - u64 dma = (u64)mem->dma; - - for (i = 0; i < buf_pages; i++) { - pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF); - pages[i].hi = cpu_to_le32(upper_32_bits(dma)); - dma += PAGE_SIZE_4K; - } -} - -/* Converts interrupt delay in microseconds to multiplier value */ -static u32 eq_delay_to_mult(u32 usec_delay) -{ -#define MAX_INTR_RATE 651042 - const u32 round = 10; - u32 multiplier; - - if (usec_delay == 0) - multiplier = 0; - else { - u32 interrupt_rate = 1000000 / usec_delay; - /* Max delay, corresponding to the lowest interrupt rate */ - if (interrupt_rate == 0) - multiplier = 1023; - else { - multiplier = (MAX_INTR_RATE - interrupt_rate) * round; - multiplier /= interrupt_rate; - /* Round the multiplier to the closest value.*/ - multiplier = (multiplier + round/2) / round; - multiplier = min(multiplier, (u32)1023); - } - } - return multiplier; -} - -static inline struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem) -{ - return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb; -} - -int be_cmd_eq_create(struct be_ctrl_info *ctrl, - struct be_queue_info *eq, int eq_delay) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_eq_create *req = embedded_payload(wrb); - struct be_cmd_resp_eq_create *resp = embedded_payload(wrb); - struct be_dma_mem *q_mem = &eq->dma_mem; - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_EQ_CREATE, sizeof(*req)); - - req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); - - AMAP_SET_BITS(struct amap_eq_context, func, req->context, - ctrl->pci_func); - AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1); - /* 4byte eqe*/ - AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0); - AMAP_SET_BITS(struct amap_eq_context, count, req->context, - __ilog2_u32(eq->len/256)); - AMAP_SET_BITS(struct amap_eq_context, delaymult, req->context, - eq_delay_to_mult(eq_delay)); - be_dws_cpu_to_le(req->context, sizeof(req->context)); - - be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); - - status = be_mbox_db_ring(ctrl); - if (!status) { - eq->id = le16_to_cpu(resp->eq_id); - eq->created = true; - } - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr, - u8 type, bool permanent, u32 if_handle) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_mac_query *req = embedded_payload(wrb); - struct be_cmd_resp_mac_query *resp = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req)); - - req->type = type; - if (permanent) { - req->permanent = 1; - } else { - req->if_id = cpu_to_le16((u16)if_handle); - req->permanent = 0; - } - - status = be_mbox_db_ring(ctrl); - if (!status) - memcpy(mac_addr, resp->mac.addr, ETH_ALEN); - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr, - u32 if_id, u32 *pmac_id) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_pmac_add *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req)); - - req->if_id = cpu_to_le32(if_id); - memcpy(req->mac_address, mac_addr, ETH_ALEN); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb); - *pmac_id = le32_to_cpu(resp->pmac_id); - } - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_pmac_del *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req)); - - req->if_id = cpu_to_le32(if_id); - req->pmac_id = cpu_to_le32(pmac_id); - - status = be_mbox_db_ring(ctrl); - spin_unlock(&ctrl->cmd_lock); - - return status; -} - -int be_cmd_cq_create(struct be_ctrl_info *ctrl, - struct be_queue_info *cq, struct be_queue_info *eq, - bool sol_evts, bool no_delay, int coalesce_wm) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_cq_create *req = embedded_payload(wrb); - struct be_cmd_resp_cq_create *resp = embedded_payload(wrb); - struct be_dma_mem *q_mem = &cq->dma_mem; - void *ctxt = &req->context; - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_CQ_CREATE, sizeof(*req)); - - req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); - - AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm); - AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay); - AMAP_SET_BITS(struct amap_cq_context, count, ctxt, - __ilog2_u32(cq->len/256)); - AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts); - AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); - AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 0); - AMAP_SET_BITS(struct amap_cq_context, func, ctxt, ctrl->pci_func); - be_dws_cpu_to_le(ctxt, sizeof(req->context)); - - be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); - - status = be_mbox_db_ring(ctrl); - if (!status) { - cq->id = le16_to_cpu(resp->cq_id); - cq->created = true; - } - spin_unlock(&ctrl->cmd_lock); - - return status; -} - -int be_cmd_txq_create(struct be_ctrl_info *ctrl, - struct be_queue_info *txq, - struct be_queue_info *cq) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_eth_tx_create *req = embedded_payload(wrb); - struct be_dma_mem *q_mem = &txq->dma_mem; - void *ctxt = &req->context; - int status; - u32 len_encoded; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE, - sizeof(*req)); - - req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); - req->ulp_num = BE_ULP1_NUM; - req->type = BE_ETH_TX_RING_TYPE_STANDARD; - - len_encoded = fls(txq->len); /* log2(len) + 1 */ - if (len_encoded == 16) - len_encoded = 0; - AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, len_encoded); - AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt, - ctrl->pci_func); - AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); - AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id); - - be_dws_cpu_to_le(ctxt, sizeof(req->context)); - - be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb); - txq->id = le16_to_cpu(resp->cid); - txq->created = true; - } - spin_unlock(&ctrl->cmd_lock); - - return status; -} - -int be_cmd_rxq_create(struct be_ctrl_info *ctrl, - struct be_queue_info *rxq, u16 cq_id, u16 frag_size, - u16 max_frame_size, u32 if_id, u32 rss) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_eth_rx_create *req = embedded_payload(wrb); - struct be_dma_mem *q_mem = &rxq->dma_mem; - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_RX_CREATE, - sizeof(*req)); - - req->cq_id = cpu_to_le16(cq_id); - req->frag_size = fls(frag_size) - 1; - req->num_pages = 2; - be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); - req->interface_id = cpu_to_le32(if_id); - req->max_frame_size = cpu_to_le16(max_frame_size); - req->rss_queue = cpu_to_le32(rss); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb); - rxq->id = le16_to_cpu(resp->id); - rxq->created = true; - } - spin_unlock(&ctrl->cmd_lock); - - return status; -} - -/* Generic destroyer function for all types of queues */ -int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, - int queue_type) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_q_destroy *req = embedded_payload(wrb); - u8 subsys = 0, opcode = 0; - int status; - - spin_lock(&ctrl->cmd_lock); - - memset(wrb, 0, sizeof(*wrb)); - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - switch (queue_type) { - case QTYPE_EQ: - subsys = CMD_SUBSYSTEM_COMMON; - opcode = OPCODE_COMMON_EQ_DESTROY; - break; - case QTYPE_CQ: - subsys = CMD_SUBSYSTEM_COMMON; - opcode = OPCODE_COMMON_CQ_DESTROY; - break; - case QTYPE_TXQ: - subsys = CMD_SUBSYSTEM_ETH; - opcode = OPCODE_ETH_TX_DESTROY; - break; - case QTYPE_RXQ: - subsys = CMD_SUBSYSTEM_ETH; - opcode = OPCODE_ETH_RX_DESTROY; - break; - default: - printk(KERN_WARNING DRV_NAME ":bad Q type in Q destroy cmd\n"); - status = -1; - goto err; - } - be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req)); - req->id = cpu_to_le16(q->id); - - status = be_mbox_db_ring(ctrl); -err: - spin_unlock(&ctrl->cmd_lock); - - return status; -} - -/* Create an rx filtering policy configuration on an i/f */ -int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 flags, u8 *mac, - bool pmac_invalid, u32 *if_handle, u32 *pmac_id) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_if_create *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req)); - - req->capability_flags = cpu_to_le32(flags); - req->enable_flags = cpu_to_le32(flags); - if (!pmac_invalid) - memcpy(req->mac_addr, mac, ETH_ALEN); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_if_create *resp = embedded_payload(wrb); - *if_handle = le32_to_cpu(resp->interface_id); - if (!pmac_invalid) - *pmac_id = le32_to_cpu(resp->pmac_id); - } - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 interface_id) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_if_destroy *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req)); - - req->interface_id = cpu_to_le32(interface_id); - status = be_mbox_db_ring(ctrl); - - spin_unlock(&ctrl->cmd_lock); - - return status; -} - -/* Get stats is a non embedded command: the request is not embedded inside - * WRB but is a separate dma memory block - */ -int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_get_stats *req = nonemb_cmd->va; - struct be_sge *sge = nonembedded_sgl(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - memset(req, 0, sizeof(*req)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, - OPCODE_ETH_GET_STATISTICS, sizeof(*req)); - sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); - sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); - sge->len = cpu_to_le32(nonemb_cmd->size); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_get_stats *resp = nonemb_cmd->va; - be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); - } - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_link_status_query(struct be_ctrl_info *ctrl, - struct be_link_info *link) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_link_status *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req)); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_link_status *resp = embedded_payload(wrb); - link->speed = resp->mac_speed; - link->duplex = resp->mac_duplex; - link->fault = resp->mac_fault; - } else { - link->speed = PHY_LINK_SPEED_ZERO; - } - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_get_fw_version *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_GET_FW_VERSION, sizeof(*req)); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb); - strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); - } - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -/* set the EQ delay interval of an EQ to specified value */ -int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req)); - - req->num_eq = cpu_to_le32(1); - req->delay[0].eq_id = cpu_to_le32(eq_id); - req->delay[0].phase = 0; - req->delay[0].delay_multiplier = cpu_to_le32(eqd); - - status = be_mbox_db_ring(ctrl); - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, u16 *vtag_array, - u32 num, bool untagged, bool promiscuous) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_vlan_config *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req)); - - req->interface_id = if_id; - req->promiscuous = promiscuous; - req->untagged = untagged; - req->num_vlan = num; - if (!promiscuous) { - memcpy(req->normal_vlan, vtag_array, - req->num_vlan * sizeof(vtag_array[0])); - } - - status = be_mbox_db_ring(ctrl); - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_promiscuous_config *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, - OPCODE_ETH_PROMISCUOUS, sizeof(*req)); - - if (port_num) - req->port1_promiscuous = en; - else - req->port0_promiscuous = en; - - status = be_mbox_db_ring(ctrl); - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table, - u32 num, bool promiscuous) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_mcast_mac_config *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req)); - - req->interface_id = if_id; - req->promiscuous = promiscuous; - if (!promiscuous) { - req->num_mac = cpu_to_le16(num); - if (num) - memcpy(req->mac, mac_table, ETH_ALEN * num); - } - - status = be_mbox_db_ring(ctrl); - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_set_flow_control *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req)); - - req->tx_flow_control = cpu_to_le16((u16)tx_fc); - req->rx_flow_control = cpu_to_le16((u16)rx_fc); - - status = be_mbox_db_ring(ctrl); - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, u32 *tx_fc, u32 *rx_fc) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_get_flow_control *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req)); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_get_flow_control *resp = - embedded_payload(wrb); - *tx_fc = le16_to_cpu(resp->tx_flow_control); - *rx_fc = le16_to_cpu(resp->rx_flow_control); - } - - spin_unlock(&ctrl->cmd_lock); - return status; -} - -int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb); - int status; - - spin_lock(&ctrl->cmd_lock); - - memset(wrb, 0, sizeof(*wrb)); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req)); - - status = be_mbox_db_ring(ctrl); - if (!status) { - struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); - *port_num = le32_to_cpu(resp->phys_port); - } - - spin_unlock(&ctrl->cmd_lock); - return status; -} diff --git a/trunk/drivers/net/benet/be_cmds.h b/trunk/drivers/net/benet/be_cmds.h deleted file mode 100644 index e499e2d5b8c3..000000000000 --- a/trunk/drivers/net/benet/be_cmds.h +++ /dev/null @@ -1,688 +0,0 @@ -/* - * Copyright (C) 2005 - 2009 ServerEngines - * 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 version 2 - * as published by the Free Software Foundation. The full GNU General - * Public License is included in this distribution in the file called COPYING. - * - * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 - */ - -/* - * The driver sends configuration and managements command requests to the - * firmware in the BE. These requests are communicated to the processor - * using Work Request Blocks (WRBs) submitted to the MCC-WRB ring or via one - * WRB inside a MAILBOX. - * The commands are serviced by the ARM processor in the BladeEngine's MPU. - */ - -struct be_sge { - u32 pa_lo; - u32 pa_hi; - u32 len; -}; - -#define MCC_WRB_EMBEDDED_MASK 1 /* bit 0 of dword 0*/ -#define MCC_WRB_SGE_CNT_SHIFT 3 /* bits 3 - 7 of dword 0 */ -#define MCC_WRB_SGE_CNT_MASK 0x1F /* bits 3 - 7 of dword 0 */ -struct be_mcc_wrb { - u32 embedded; /* dword 0 */ - u32 payload_length; /* dword 1 */ - u32 tag0; /* dword 2 */ - u32 tag1; /* dword 3 */ - u32 rsvd; /* dword 4 */ - union { - u8 embedded_payload[236]; /* used by embedded cmds */ - struct be_sge sgl[19]; /* used by non-embedded cmds */ - } payload; -}; - -#define CQE_FLAGS_VALID_MASK (1 << 31) -#define CQE_FLAGS_ASYNC_MASK (1 << 30) -#define CQE_FLAGS_COMPLETED_MASK (1 << 28) -#define CQE_FLAGS_CONSUMED_MASK (1 << 27) - -/* Completion Status */ -enum { - MCC_STATUS_SUCCESS = 0x0, -/* The client does not have sufficient privileges to execute the command */ - MCC_STATUS_INSUFFICIENT_PRIVILEGES = 0x1, -/* A parameter in the command was invalid. */ - MCC_STATUS_INVALID_PARAMETER = 0x2, -/* There are insufficient chip resources to execute the command */ - MCC_STATUS_INSUFFICIENT_RESOURCES = 0x3, -/* The command is completing because the queue was getting flushed */ - MCC_STATUS_QUEUE_FLUSHING = 0x4, -/* The command is completing with a DMA error */ - MCC_STATUS_DMA_FAILED = 0x5 -}; - -#define CQE_STATUS_COMPL_MASK 0xFFFF -#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ -#define CQE_STATUS_EXTD_MASK 0xFFFF -#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */ - -struct be_mcc_cq_entry { - u32 status; /* dword 0 */ - u32 tag0; /* dword 1 */ - u32 tag1; /* dword 2 */ - u32 flags; /* dword 3 */ -}; - -struct be_mcc_mailbox { - struct be_mcc_wrb wrb; - struct be_mcc_cq_entry cqe; -}; - -#define CMD_SUBSYSTEM_COMMON 0x1 -#define CMD_SUBSYSTEM_ETH 0x3 - -#define OPCODE_COMMON_NTWK_MAC_QUERY 1 -#define OPCODE_COMMON_NTWK_MAC_SET 2 -#define OPCODE_COMMON_NTWK_MULTICAST_SET 3 -#define OPCODE_COMMON_NTWK_VLAN_CONFIG 4 -#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY 5 -#define OPCODE_COMMON_CQ_CREATE 12 -#define OPCODE_COMMON_EQ_CREATE 13 -#define OPCODE_COMMON_MCC_CREATE 21 -#define OPCODE_COMMON_NTWK_RX_FILTER 34 -#define OPCODE_COMMON_GET_FW_VERSION 35 -#define OPCODE_COMMON_SET_FLOW_CONTROL 36 -#define OPCODE_COMMON_GET_FLOW_CONTROL 37 -#define OPCODE_COMMON_SET_FRAME_SIZE 39 -#define OPCODE_COMMON_MODIFY_EQ_DELAY 41 -#define OPCODE_COMMON_FIRMWARE_CONFIG 42 -#define OPCODE_COMMON_NTWK_INTERFACE_CREATE 50 -#define OPCODE_COMMON_NTWK_INTERFACE_DESTROY 51 -#define OPCODE_COMMON_CQ_DESTROY 54 -#define OPCODE_COMMON_EQ_DESTROY 55 -#define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58 -#define OPCODE_COMMON_NTWK_PMAC_ADD 59 -#define OPCODE_COMMON_NTWK_PMAC_DEL 60 - -#define OPCODE_ETH_ACPI_CONFIG 2 -#define OPCODE_ETH_PROMISCUOUS 3 -#define OPCODE_ETH_GET_STATISTICS 4 -#define OPCODE_ETH_TX_CREATE 7 -#define OPCODE_ETH_RX_CREATE 8 -#define OPCODE_ETH_TX_DESTROY 9 -#define OPCODE_ETH_RX_DESTROY 10 - -struct be_cmd_req_hdr { - u8 opcode; /* dword 0 */ - u8 subsystem; /* dword 0 */ - u8 port_number; /* dword 0 */ - u8 domain; /* dword 0 */ - u32 timeout; /* dword 1 */ - u32 request_length; /* dword 2 */ - u32 rsvd; /* dword 3 */ -}; - -#define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */ -#define RESP_HDR_INFO_SUBSYS_SHIFT 8 /* bits 8 - 15 */ -struct be_cmd_resp_hdr { - u32 info; /* dword 0 */ - u32 status; /* dword 1 */ - u32 response_length; /* dword 2 */ - u32 actual_resp_len; /* dword 3 */ -}; - -struct phys_addr { - u32 lo; - u32 hi; -}; - -/************************** - * BE Command definitions * - **************************/ - -/* Pseudo amap definition in which each bit of the actual structure is defined - * as a byte: used to calculate offset/shift/mask of each field */ -struct amap_eq_context { - u8 cidx[13]; /* dword 0*/ - u8 rsvd0[3]; /* dword 0*/ - u8 epidx[13]; /* dword 0*/ - u8 valid; /* dword 0*/ - u8 rsvd1; /* dword 0*/ - u8 size; /* dword 0*/ - u8 pidx[13]; /* dword 1*/ - u8 rsvd2[3]; /* dword 1*/ - u8 pd[10]; /* dword 1*/ - u8 count[3]; /* dword 1*/ - u8 solevent; /* dword 1*/ - u8 stalled; /* dword 1*/ - u8 armed; /* dword 1*/ - u8 rsvd3[4]; /* dword 2*/ - u8 func[8]; /* dword 2*/ - u8 rsvd4; /* dword 2*/ - u8 delaymult[10]; /* dword 2*/ - u8 rsvd5[2]; /* dword 2*/ - u8 phase[2]; /* dword 2*/ - u8 nodelay; /* dword 2*/ - u8 rsvd6[4]; /* dword 2*/ - u8 rsvd7[32]; /* dword 3*/ -} __packed; - -struct be_cmd_req_eq_create { - struct be_cmd_req_hdr hdr; - u16 num_pages; /* sword */ - u16 rsvd0; /* sword */ - u8 context[sizeof(struct amap_eq_context) / 8]; - struct phys_addr pages[8]; -} __packed; - -struct be_cmd_resp_eq_create { - struct be_cmd_resp_hdr resp_hdr; - u16 eq_id; /* sword */ - u16 rsvd0; /* sword */ -} __packed; - -/******************** Mac query ***************************/ -enum { - MAC_ADDRESS_TYPE_STORAGE = 0x0, - MAC_ADDRESS_TYPE_NETWORK = 0x1, - MAC_ADDRESS_TYPE_PD = 0x2, - MAC_ADDRESS_TYPE_MANAGEMENT = 0x3 -}; - -struct mac_addr { - u16 size_of_struct; - u8 addr[ETH_ALEN]; -} __packed; - -struct be_cmd_req_mac_query { - struct be_cmd_req_hdr hdr; - u8 type; - u8 permanent; - u16 if_id; -} __packed; - -struct be_cmd_resp_mac_query { - struct be_cmd_resp_hdr hdr; - struct mac_addr mac; -}; - -/******************** PMac Add ***************************/ -struct be_cmd_req_pmac_add { - struct be_cmd_req_hdr hdr; - u32 if_id; - u8 mac_address[ETH_ALEN]; - u8 rsvd0[2]; -} __packed; - -struct be_cmd_resp_pmac_add { - struct be_cmd_resp_hdr hdr; - u32 pmac_id; -}; - -/******************** PMac Del ***************************/ -struct be_cmd_req_pmac_del { - struct be_cmd_req_hdr hdr; - u32 if_id; - u32 pmac_id; -}; - -/******************** Create CQ ***************************/ -/* Pseudo amap definition in which each bit of the actual structure is defined - * as a byte: used to calculate offset/shift/mask of each field */ -struct amap_cq_context { - u8 cidx[11]; /* dword 0*/ - u8 rsvd0; /* dword 0*/ - u8 coalescwm[2]; /* dword 0*/ - u8 nodelay; /* dword 0*/ - u8 epidx[11]; /* dword 0*/ - u8 rsvd1; /* dword 0*/ - u8 count[2]; /* dword 0*/ - u8 valid; /* dword 0*/ - u8 solevent; /* dword 0*/ - u8 eventable; /* dword 0*/ - u8 pidx[11]; /* dword 1*/ - u8 rsvd2; /* dword 1*/ - u8 pd[10]; /* dword 1*/ - u8 eqid[8]; /* dword 1*/ - u8 stalled; /* dword 1*/ - u8 armed; /* dword 1*/ - u8 rsvd3[4]; /* dword 2*/ - u8 func[8]; /* dword 2*/ - u8 rsvd4[20]; /* dword 2*/ - u8 rsvd5[32]; /* dword 3*/ -} __packed; - -struct be_cmd_req_cq_create { - struct be_cmd_req_hdr hdr; - u16 num_pages; - u16 rsvd0; - u8 context[sizeof(struct amap_cq_context) / 8]; - struct phys_addr pages[8]; -} __packed; - -struct be_cmd_resp_cq_create { - struct be_cmd_resp_hdr hdr; - u16 cq_id; - u16 rsvd0; -} __packed; - -/******************** Create TxQ ***************************/ -#define BE_ETH_TX_RING_TYPE_STANDARD 2 -#define BE_ULP1_NUM 1 - -/* Pseudo amap definition in which each bit of the actual structure is defined - * as a byte: used to calculate offset/shift/mask of each field */ -struct amap_tx_context { - u8 rsvd0[16]; /* dword 0 */ - u8 tx_ring_size[4]; /* dword 0 */ - u8 rsvd1[26]; /* dword 0 */ - u8 pci_func_id[8]; /* dword 1 */ - u8 rsvd2[9]; /* dword 1 */ - u8 ctx_valid; /* dword 1 */ - u8 cq_id_send[16]; /* dword 2 */ - u8 rsvd3[16]; /* dword 2 */ - u8 rsvd4[32]; /* dword 3 */ - u8 rsvd5[32]; /* dword 4 */ - u8 rsvd6[32]; /* dword 5 */ - u8 rsvd7[32]; /* dword 6 */ - u8 rsvd8[32]; /* dword 7 */ - u8 rsvd9[32]; /* dword 8 */ - u8 rsvd10[32]; /* dword 9 */ - u8 rsvd11[32]; /* dword 10 */ - u8 rsvd12[32]; /* dword 11 */ - u8 rsvd13[32]; /* dword 12 */ - u8 rsvd14[32]; /* dword 13 */ - u8 rsvd15[32]; /* dword 14 */ - u8 rsvd16[32]; /* dword 15 */ -} __packed; - -struct be_cmd_req_eth_tx_create { - struct be_cmd_req_hdr hdr; - u8 num_pages; - u8 ulp_num; - u8 type; - u8 bound_port; - u8 context[sizeof(struct amap_tx_context) / 8]; - struct phys_addr pages[8]; -} __packed; - -struct be_cmd_resp_eth_tx_create { - struct be_cmd_resp_hdr hdr; - u16 cid; - u16 rsvd0; -} __packed; - -/******************** Create RxQ ***************************/ -struct be_cmd_req_eth_rx_create { - struct be_cmd_req_hdr hdr; - u16 cq_id; - u8 frag_size; - u8 num_pages; - struct phys_addr pages[2]; - u32 interface_id; - u16 max_frame_size; - u16 rsvd0; - u32 rss_queue; -} __packed; - -struct be_cmd_resp_eth_rx_create { - struct be_cmd_resp_hdr hdr; - u16 id; - u8 cpu_id; - u8 rsvd0; -} __packed; - -/******************** Q Destroy ***************************/ -/* Type of Queue to be destroyed */ -enum { - QTYPE_EQ = 1, - QTYPE_CQ, - QTYPE_TXQ, - QTYPE_RXQ -}; - -struct be_cmd_req_q_destroy { - struct be_cmd_req_hdr hdr; - u16 id; - u16 bypass_flush; /* valid only for rx q destroy */ -} __packed; - -/************ I/f Create (it's actually I/f Config Create)**********/ - -/* Capability flags for the i/f */ -enum be_if_flags { - BE_IF_FLAGS_RSS = 0x4, - BE_IF_FLAGS_PROMISCUOUS = 0x8, - BE_IF_FLAGS_BROADCAST = 0x10, - BE_IF_FLAGS_UNTAGGED = 0x20, - BE_IF_FLAGS_ULP = 0x40, - BE_IF_FLAGS_VLAN_PROMISCUOUS = 0x80, - BE_IF_FLAGS_VLAN = 0x100, - BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, - BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, - BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800 -}; - -/* An RX interface is an object with one or more MAC addresses and - * filtering capabilities. */ -struct be_cmd_req_if_create { - struct be_cmd_req_hdr hdr; - u32 version; /* ignore currntly */ - u32 capability_flags; - u32 enable_flags; - u8 mac_addr[ETH_ALEN]; - u8 rsvd0; - u8 pmac_invalid; /* if set, don't attach the mac addr to the i/f */ - u32 vlan_tag; /* not used currently */ -} __packed; - -struct be_cmd_resp_if_create { - struct be_cmd_resp_hdr hdr; - u32 interface_id; - u32 pmac_id; -}; - -/****** I/f Destroy(it's actually I/f Config Destroy )**********/ -struct be_cmd_req_if_destroy { - struct be_cmd_req_hdr hdr; - u32 interface_id; -}; - -/*************** HW Stats Get **********************************/ -struct be_port_rxf_stats { - u32 rx_bytes_lsd; /* dword 0*/ - u32 rx_bytes_msd; /* dword 1*/ - u32 rx_total_frames; /* dword 2*/ - u32 rx_unicast_frames; /* dword 3*/ - u32 rx_multicast_frames; /* dword 4*/ - u32 rx_broadcast_frames; /* dword 5*/ - u32 rx_crc_errors; /* dword 6*/ - u32 rx_alignment_symbol_errors; /* dword 7*/ - u32 rx_pause_frames; /* dword 8*/ - u32 rx_control_frames; /* dword 9*/ - u32 rx_in_range_errors; /* dword 10*/ - u32 rx_out_range_errors; /* dword 11*/ - u32 rx_frame_too_long; /* dword 12*/ - u32 rx_address_match_errors; /* dword 13*/ - u32 rx_vlan_mismatch; /* dword 14*/ - u32 rx_dropped_too_small; /* dword 15*/ - u32 rx_dropped_too_short; /* dword 16*/ - u32 rx_dropped_header_too_small; /* dword 17*/ - u32 rx_dropped_tcp_length; /* dword 18*/ - u32 rx_dropped_runt; /* dword 19*/ - u32 rx_64_byte_packets; /* dword 20*/ - u32 rx_65_127_byte_packets; /* dword 21*/ - u32 rx_128_256_byte_packets; /* dword 22*/ - u32 rx_256_511_byte_packets; /* dword 23*/ - u32 rx_512_1023_byte_packets; /* dword 24*/ - u32 rx_1024_1518_byte_packets; /* dword 25*/ - u32 rx_1519_2047_byte_packets; /* dword 26*/ - u32 rx_2048_4095_byte_packets; /* dword 27*/ - u32 rx_4096_8191_byte_packets; /* dword 28*/ - u32 rx_8192_9216_byte_packets; /* dword 29*/ - u32 rx_ip_checksum_errs; /* dword 30*/ - u32 rx_tcp_checksum_errs; /* dword 31*/ - u32 rx_udp_checksum_errs; /* dword 32*/ - u32 rx_non_rss_packets; /* dword 33*/ - u32 rx_ipv4_packets; /* dword 34*/ - u32 rx_ipv6_packets; /* dword 35*/ - u32 rx_ipv4_bytes_lsd; /* dword 36*/ - u32 rx_ipv4_bytes_msd; /* dword 37*/ - u32 rx_ipv6_bytes_lsd; /* dword 38*/ - u32 rx_ipv6_bytes_msd; /* dword 39*/ - u32 rx_chute1_packets; /* dword 40*/ - u32 rx_chute2_packets; /* dword 41*/ - u32 rx_chute3_packets; /* dword 42*/ - u32 rx_management_packets; /* dword 43*/ - u32 rx_switched_unicast_packets; /* dword 44*/ - u32 rx_switched_multicast_packets; /* dword 45*/ - u32 rx_switched_broadcast_packets; /* dword 46*/ - u32 tx_bytes_lsd; /* dword 47*/ - u32 tx_bytes_msd; /* dword 48*/ - u32 tx_unicastframes; /* dword 49*/ - u32 tx_multicastframes; /* dword 50*/ - u32 tx_broadcastframes; /* dword 51*/ - u32 tx_pauseframes; /* dword 52*/ - u32 tx_controlframes; /* dword 53*/ - u32 tx_64_byte_packets; /* dword 54*/ - u32 tx_65_127_byte_packets; /* dword 55*/ - u32 tx_128_256_byte_packets; /* dword 56*/ - u32 tx_256_511_byte_packets; /* dword 57*/ - u32 tx_512_1023_byte_packets; /* dword 58*/ - u32 tx_1024_1518_byte_packets; /* dword 59*/ - u32 tx_1519_2047_byte_packets; /* dword 60*/ - u32 tx_2048_4095_byte_packets; /* dword 61*/ - u32 tx_4096_8191_byte_packets; /* dword 62*/ - u32 tx_8192_9216_byte_packets; /* dword 63*/ - u32 rx_fifo_overflow; /* dword 64*/ - u32 rx_input_fifo_overflow; /* dword 65*/ -}; - -struct be_rxf_stats { - struct be_port_rxf_stats port[2]; - u32 rx_drops_no_pbuf; /* dword 132*/ - u32 rx_drops_no_txpb; /* dword 133*/ - u32 rx_drops_no_erx_descr; /* dword 134*/ - u32 rx_drops_no_tpre_descr; /* dword 135*/ - u32 management_rx_port_packets; /* dword 136*/ - u32 management_rx_port_bytes; /* dword 137*/ - u32 management_rx_port_pause_frames; /* dword 138*/ - u32 management_rx_port_errors; /* dword 139*/ - u32 management_tx_port_packets; /* dword 140*/ - u32 management_tx_port_bytes; /* dword 141*/ - u32 management_tx_port_pause; /* dword 142*/ - u32 management_rx_port_rxfifo_overflow; /* dword 143*/ - u32 rx_drops_too_many_frags; /* dword 144*/ - u32 rx_drops_invalid_ring; /* dword 145*/ - u32 forwarded_packets; /* dword 146*/ - u32 rx_drops_mtu; /* dword 147*/ - u32 rsvd0[15]; -}; - -struct be_erx_stats { - u32 rx_drops_no_fragments[44]; /* dwordS 0 to 43*/ - u32 debug_wdma_sent_hold; /* dword 44*/ - u32 debug_wdma_pbfree_sent_hold; /* dword 45*/ - u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/ - u32 debug_pmem_pbuf_dealloc; /* dword 47*/ -}; - -struct be_hw_stats { - struct be_rxf_stats rxf; - u32 rsvd[48]; - struct be_erx_stats erx; -}; - -struct be_cmd_req_get_stats { - struct be_cmd_req_hdr hdr; - u8 rsvd[sizeof(struct be_hw_stats)]; -}; - -struct be_cmd_resp_get_stats { - struct be_cmd_resp_hdr hdr; - struct be_hw_stats hw_stats; -}; - -struct be_cmd_req_vlan_config { - struct be_cmd_req_hdr hdr; - u8 interface_id; - u8 promiscuous; - u8 untagged; - u8 num_vlan; - u16 normal_vlan[64]; -} __packed; - -struct be_cmd_req_promiscuous_config { - struct be_cmd_req_hdr hdr; - u8 port0_promiscuous; - u8 port1_promiscuous; - u16 rsvd0; -} __packed; - -struct macaddr { - u8 byte[ETH_ALEN]; -}; - -struct be_cmd_req_mcast_mac_config { - struct be_cmd_req_hdr hdr; - u16 num_mac; - u8 promiscuous; - u8 interface_id; - struct macaddr mac[32]; -} __packed; - -static inline struct be_hw_stats * -hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd) -{ - return &cmd->hw_stats; -} - -/******************** Link Status Query *******************/ -struct be_cmd_req_link_status { - struct be_cmd_req_hdr hdr; - u32 rsvd; -}; - -struct be_link_info { - u8 duplex; - u8 speed; - u8 fault; -}; - -enum { - PHY_LINK_DUPLEX_NONE = 0x0, - PHY_LINK_DUPLEX_HALF = 0x1, - PHY_LINK_DUPLEX_FULL = 0x2 -}; - -enum { - PHY_LINK_SPEED_ZERO = 0x0, /* => No link */ - PHY_LINK_SPEED_10MBPS = 0x1, - PHY_LINK_SPEED_100MBPS = 0x2, - PHY_LINK_SPEED_1GBPS = 0x3, - PHY_LINK_SPEED_10GBPS = 0x4 -}; - -struct be_cmd_resp_link_status { - struct be_cmd_resp_hdr hdr; - u8 physical_port; - u8 mac_duplex; - u8 mac_speed; - u8 mac_fault; - u8 mgmt_mac_duplex; - u8 mgmt_mac_speed; - u16 rsvd0; -} __packed; - -/******************** Get FW Version *******************/ -#define FW_VER_LEN 32 -struct be_cmd_req_get_fw_version { - struct be_cmd_req_hdr hdr; - u8 rsvd0[FW_VER_LEN]; - u8 rsvd1[FW_VER_LEN]; -} __packed; - -struct be_cmd_resp_get_fw_version { - struct be_cmd_resp_hdr hdr; - u8 firmware_version_string[FW_VER_LEN]; - u8 fw_on_flash_version_string[FW_VER_LEN]; -} __packed; - -/******************** Set Flow Contrl *******************/ -struct be_cmd_req_set_flow_control { - struct be_cmd_req_hdr hdr; - u16 tx_flow_control; - u16 rx_flow_control; -} __packed; - -/******************** Get Flow Contrl *******************/ -struct be_cmd_req_get_flow_control { - struct be_cmd_req_hdr hdr; - u32 rsvd; -}; - -struct be_cmd_resp_get_flow_control { - struct be_cmd_resp_hdr hdr; - u16 tx_flow_control; - u16 rx_flow_control; -} __packed; - -/******************** Modify EQ Delay *******************/ -struct be_cmd_req_modify_eq_delay { - struct be_cmd_req_hdr hdr; - u32 num_eq; - struct { - u32 eq_id; - u32 phase; - u32 delay_multiplier; - } delay[8]; -} __packed; - -struct be_cmd_resp_modify_eq_delay { - struct be_cmd_resp_hdr hdr; - u32 rsvd0; -} __packed; - -/******************** Get FW Config *******************/ -struct be_cmd_req_query_fw_cfg { - struct be_cmd_req_hdr hdr; - u32 rsvd[30]; -}; - -struct be_cmd_resp_query_fw_cfg { - struct be_cmd_resp_hdr hdr; - u32 be_config_number; - u32 asic_revision; - u32 phys_port; - u32 function_mode; - u32 rsvd[26]; -}; - -extern int be_pci_fnum_get(struct be_ctrl_info *ctrl); -extern int be_cmd_POST(struct be_ctrl_info *ctrl); -extern int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr, - u8 type, bool permanent, u32 if_handle); -extern int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr, - u32 if_id, u32 *pmac_id); -extern int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id); -extern int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 if_flags, u8 *mac, - bool pmac_invalid, u32 *if_handle, u32 *pmac_id); -extern int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 if_handle); -extern int be_cmd_eq_create(struct be_ctrl_info *ctrl, - struct be_queue_info *eq, int eq_delay); -extern int be_cmd_cq_create(struct be_ctrl_info *ctrl, - struct be_queue_info *cq, struct be_queue_info *eq, - bool sol_evts, bool no_delay, - int num_cqe_dma_coalesce); -extern int be_cmd_txq_create(struct be_ctrl_info *ctrl, - struct be_queue_info *txq, - struct be_queue_info *cq); -extern int be_cmd_rxq_create(struct be_ctrl_info *ctrl, - struct be_queue_info *rxq, u16 cq_id, - u16 frag_size, u16 max_frame_size, u32 if_id, - u32 rss); -extern int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, - int type); -extern int be_cmd_link_status_query(struct be_ctrl_info *ctrl, - struct be_link_info *link); -extern int be_cmd_reset(struct be_ctrl_info *ctrl); -extern int be_cmd_get_stats(struct be_ctrl_info *ctrl, - struct be_dma_mem *nonemb_cmd); -extern int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver); - -extern int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd); -extern int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, - u16 *vtag_array, u32 num, bool untagged, - bool promiscuous); -extern int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, - u8 port_num, bool en); -extern int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, - u8 *mac_table, u32 num, bool promiscuous); -extern int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, - u32 tx_fc, u32 rx_fc); -extern int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, - u32 *tx_fc, u32 *rx_fc); -extern int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num); diff --git a/trunk/drivers/net/benet/be_ethtool.c b/trunk/drivers/net/benet/be_ethtool.c deleted file mode 100644 index 04f4b73fa8d8..000000000000 --- a/trunk/drivers/net/benet/be_ethtool.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (C) 2005 - 2009 ServerEngines - * 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 version 2 - * as published by the Free Software Foundation. The full GNU General - * Public License is included in this distribution in the file called COPYING. - * - * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 - */ - -#include "be.h" -#include - -struct be_ethtool_stat { - char desc[ETH_GSTRING_LEN]; - int type; - int size; - int offset; -}; - -enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT, ERXSTAT}; -#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ - offsetof(_struct, field) -#define NETSTAT_INFO(field) #field, NETSTAT,\ - FIELDINFO(struct net_device_stats,\ - field) -#define DRVSTAT_INFO(field) #field, DRVSTAT,\ - FIELDINFO(struct be_drvr_stats, field) -#define MISCSTAT_INFO(field) #field, MISCSTAT,\ - FIELDINFO(struct be_rxf_stats, field) -#define PORTSTAT_INFO(field) #field, PORTSTAT,\ - FIELDINFO(struct be_port_rxf_stats, \ - field) -#define ERXSTAT_INFO(field) #field, ERXSTAT,\ - FIELDINFO(struct be_erx_stats, field) - -static const struct be_ethtool_stat et_stats[] = { - {NETSTAT_INFO(rx_packets)}, - {NETSTAT_INFO(tx_packets)}, - {NETSTAT_INFO(rx_bytes)}, - {NETSTAT_INFO(tx_bytes)}, - {NETSTAT_INFO(rx_errors)}, - {NETSTAT_INFO(tx_errors)}, - {NETSTAT_INFO(rx_dropped)}, - {NETSTAT_INFO(tx_dropped)}, - {DRVSTAT_INFO(be_tx_reqs)}, - {DRVSTAT_INFO(be_tx_stops)}, - {DRVSTAT_INFO(be_fwd_reqs)}, - {DRVSTAT_INFO(be_tx_wrbs)}, - {DRVSTAT_INFO(be_polls)}, - {DRVSTAT_INFO(be_tx_events)}, - {DRVSTAT_INFO(be_rx_events)}, - {DRVSTAT_INFO(be_tx_compl)}, - {DRVSTAT_INFO(be_rx_compl)}, - {DRVSTAT_INFO(be_ethrx_post_fail)}, - {DRVSTAT_INFO(be_802_3_dropped_frames)}, - {DRVSTAT_INFO(be_802_3_malformed_frames)}, - {DRVSTAT_INFO(be_tx_rate)}, - {DRVSTAT_INFO(be_rx_rate)}, - {PORTSTAT_INFO(rx_unicast_frames)}, - {PORTSTAT_INFO(rx_multicast_frames)}, - {PORTSTAT_INFO(rx_broadcast_frames)}, - {PORTSTAT_INFO(rx_crc_errors)}, - {PORTSTAT_INFO(rx_alignment_symbol_errors)}, - {PORTSTAT_INFO(rx_pause_frames)}, - {PORTSTAT_INFO(rx_control_frames)}, - {PORTSTAT_INFO(rx_in_range_errors)}, - {PORTSTAT_INFO(rx_out_range_errors)}, - {PORTSTAT_INFO(rx_frame_too_long)}, - {PORTSTAT_INFO(rx_address_match_errors)}, - {PORTSTAT_INFO(rx_vlan_mismatch)}, - {PORTSTAT_INFO(rx_dropped_too_small)}, - {PORTSTAT_INFO(rx_dropped_too_short)}, - {PORTSTAT_INFO(rx_dropped_header_too_small)}, - {PORTSTAT_INFO(rx_dropped_tcp_length)}, - {PORTSTAT_INFO(rx_dropped_runt)}, - {PORTSTAT_INFO(rx_fifo_overflow)}, - {PORTSTAT_INFO(rx_input_fifo_overflow)}, - {PORTSTAT_INFO(rx_ip_checksum_errs)}, - {PORTSTAT_INFO(rx_tcp_checksum_errs)}, - {PORTSTAT_INFO(rx_udp_checksum_errs)}, - {PORTSTAT_INFO(rx_non_rss_packets)}, - {PORTSTAT_INFO(rx_ipv4_packets)}, - {PORTSTAT_INFO(rx_ipv6_packets)}, - {PORTSTAT_INFO(tx_unicastframes)}, - {PORTSTAT_INFO(tx_multicastframes)}, - {PORTSTAT_INFO(tx_broadcastframes)}, - {PORTSTAT_INFO(tx_pauseframes)}, - {PORTSTAT_INFO(tx_controlframes)}, - {MISCSTAT_INFO(rx_drops_no_pbuf)}, - {MISCSTAT_INFO(rx_drops_no_txpb)}, - {MISCSTAT_INFO(rx_drops_no_erx_descr)}, - {MISCSTAT_INFO(rx_drops_no_tpre_descr)}, - {MISCSTAT_INFO(rx_drops_too_many_frags)}, - {MISCSTAT_INFO(rx_drops_invalid_ring)}, - {MISCSTAT_INFO(forwarded_packets)}, - {MISCSTAT_INFO(rx_drops_mtu)}, - {ERXSTAT_INFO(rx_drops_no_fragments)}, -}; -#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) - -static void -be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - strcpy(drvinfo->driver, DRV_NAME); - strcpy(drvinfo->version, DRV_VER); - strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN); - strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); - drvinfo->testinfo_len = 0; - drvinfo->regdump_len = 0; - drvinfo->eedump_len = 0; -} - -static int -be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_eq_obj *tx_eq = &adapter->tx_eq; - - coalesce->rx_max_coalesced_frames = adapter->max_rx_coal; - - coalesce->rx_coalesce_usecs = rx_eq->cur_eqd; - coalesce->rx_coalesce_usecs_high = rx_eq->max_eqd; - coalesce->rx_coalesce_usecs_low = rx_eq->min_eqd; - - coalesce->tx_coalesce_usecs = tx_eq->cur_eqd; - coalesce->tx_coalesce_usecs_high = tx_eq->max_eqd; - coalesce->tx_coalesce_usecs_low = tx_eq->min_eqd; - - coalesce->use_adaptive_rx_coalesce = rx_eq->enable_aic; - coalesce->use_adaptive_tx_coalesce = tx_eq->enable_aic; - - return 0; -} - -/* - * This routine is used to set interrup coalescing delay *as well as* - * the number of pkts to coalesce for LRO. - */ -static int -be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct be_ctrl_info *ctrl = &adapter->ctrl; - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_eq_obj *tx_eq = &adapter->tx_eq; - u32 tx_max, tx_min, tx_cur; - u32 rx_max, rx_min, rx_cur; - int status = 0; - - if (coalesce->use_adaptive_tx_coalesce == 1) - return -EINVAL; - - adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; - if (adapter->max_rx_coal > MAX_SKB_FRAGS) - adapter->max_rx_coal = MAX_SKB_FRAGS - 1; - - /* if AIC is being turned on now, start with an EQD of 0 */ - if (rx_eq->enable_aic == 0 && - coalesce->use_adaptive_rx_coalesce == 1) { - rx_eq->cur_eqd = 0; - } - rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce; - - rx_max = coalesce->rx_coalesce_usecs_high; - rx_min = coalesce->rx_coalesce_usecs_low; - rx_cur = coalesce->rx_coalesce_usecs; - - tx_max = coalesce->tx_coalesce_usecs_high; - tx_min = coalesce->tx_coalesce_usecs_low; - tx_cur = coalesce->tx_coalesce_usecs; - - if (tx_cur > BE_MAX_EQD) - tx_cur = BE_MAX_EQD; - if (tx_eq->cur_eqd != tx_cur) { - status = be_cmd_modify_eqd(ctrl, tx_eq->q.id, tx_cur); - if (!status) - tx_eq->cur_eqd = tx_cur; - } - - if (rx_eq->enable_aic) { - if (rx_max > BE_MAX_EQD) - rx_max = BE_MAX_EQD; - if (rx_min > rx_max) - rx_min = rx_max; - rx_eq->max_eqd = rx_max; - rx_eq->min_eqd = rx_min; - if (rx_eq->cur_eqd > rx_max) - rx_eq->cur_eqd = rx_max; - if (rx_eq->cur_eqd < rx_min) - rx_eq->cur_eqd = rx_min; - } else { - if (rx_cur > BE_MAX_EQD) - rx_cur = BE_MAX_EQD; - if (rx_eq->cur_eqd != rx_cur) { - status = be_cmd_modify_eqd(ctrl, rx_eq->q.id, rx_cur); - if (!status) - rx_eq->cur_eqd = rx_cur; - } - } - return 0; -} - -static u32 be_get_rx_csum(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - return adapter->rx_csum; -} - -static int be_set_rx_csum(struct net_device *netdev, uint32_t data) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - if (data) - adapter->rx_csum = true; - else - adapter->rx_csum = false; - - return 0; -} - -static void -be_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, uint64_t *data) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats; - struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); - struct be_rxf_stats *rxf_stats = &hw_stats->rxf; - struct be_port_rxf_stats *port_stats = - &rxf_stats->port[adapter->port_num]; - struct net_device_stats *net_stats = &adapter->stats.net_stats; - struct be_erx_stats *erx_stats = &hw_stats->erx; - void *p = NULL; - int i; - - for (i = 0; i < ETHTOOL_STATS_NUM; i++) { - switch (et_stats[i].type) { - case NETSTAT: - p = net_stats; - break; - case DRVSTAT: - p = drvr_stats; - break; - case PORTSTAT: - p = port_stats; - break; - case MISCSTAT: - p = rxf_stats; - break; - case ERXSTAT: /* Currently only one ERX stat is provided */ - p = (u32 *)erx_stats + adapter->rx_obj.q.id; - break; - } - - p = (u8 *)p + et_stats[i].offset; - data[i] = (et_stats[i].size == sizeof(u64)) ? - *(u64 *)p: *(u32 *)p; - } - - return; -} - -static void -be_get_stat_strings(struct net_device *netdev, uint32_t stringset, - uint8_t *data) -{ - int i; - switch (stringset) { - case ETH_SS_STATS: - for (i = 0; i < ETHTOOL_STATS_NUM; i++) { - memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN); - data += ETH_GSTRING_LEN; - } - break; - } -} - -static int be_get_stats_count(struct net_device *netdev) -{ - return ETHTOOL_STATS_NUM; -} - -static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) -{ - ecmd->speed = SPEED_10000; - ecmd->duplex = DUPLEX_FULL; - ecmd->autoneg = AUTONEG_DISABLE; - return 0; -} - -static void -be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - ring->rx_max_pending = adapter->rx_obj.q.len; - ring->tx_max_pending = adapter->tx_obj.q.len; - - ring->rx_pending = atomic_read(&adapter->rx_obj.q.used); - ring->tx_pending = atomic_read(&adapter->tx_obj.q.used); -} - -static void -be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause, - &ecmd->rx_pause); - ecmd->autoneg = AUTONEG_ENABLE; -} - -static int -be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) -{ - struct be_adapter *adapter = netdev_priv(netdev); - int status; - - if (ecmd->autoneg != AUTONEG_ENABLE) - return -EINVAL; - - status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause, - ecmd->rx_pause); - if (!status) - dev_warn(&adapter->pdev->dev, "Pause param set failed.\n"); - - return status; -} - -struct ethtool_ops be_ethtool_ops = { - .get_settings = be_get_settings, - .get_drvinfo = be_get_drvinfo, - .get_link = ethtool_op_get_link, - .get_coalesce = be_get_coalesce, - .set_coalesce = be_set_coalesce, - .get_ringparam = be_get_ringparam, - .get_pauseparam = be_get_pauseparam, - .set_pauseparam = be_set_pauseparam, - .get_rx_csum = be_get_rx_csum, - .set_rx_csum = be_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, - .get_strings = be_get_stat_strings, - .get_stats_count = be_get_stats_count, - .get_ethtool_stats = be_get_ethtool_stats, -}; diff --git a/trunk/drivers/net/benet/be_hw.h b/trunk/drivers/net/benet/be_hw.h deleted file mode 100644 index b132aa4893ca..000000000000 --- a/trunk/drivers/net/benet/be_hw.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2005 - 2009 ServerEngines - * 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 version 2 - * as published by the Free Software Foundation. The full GNU General - * Public License is included in this distribution in the file called COPYING. - * - * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 - */ - -/********* Mailbox door bell *************/ -/* Used for driver communication with the FW. - * The software must write this register twice to post any command. First, - * it writes the register with hi=1 and the upper bits of the physical address - * for the MAILBOX structure. Software must poll the ready bit until this - * is acknowledged. Then, sotware writes the register with hi=0 with the lower - * bits in the address. It must poll the ready bit until the command is - * complete. Upon completion, the MAILBOX will contain a valid completion - * queue entry. - */ -#define MPU_MAILBOX_DB_OFFSET 0x160 -#define MPU_MAILBOX_DB_RDY_MASK 0x1 /* bit 0 */ -#define MPU_MAILBOX_DB_HI_MASK 0x2 /* bit 1 */ - -#define MPU_EP_CONTROL 0 - -/********** MPU semphore ******************/ -#define MPU_EP_SEMAPHORE_OFFSET 0xac -#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF -#define EP_SEMAPHORE_POST_ERR_MASK 0x1 -#define EP_SEMAPHORE_POST_ERR_SHIFT 31 -/* MPU semphore POST stage values */ -#define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */ -#define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */ -#define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */ -#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ - -/********* Memory BAR register ************/ -#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc -/* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt - * Disable" may still globally block interrupts in addition to individual - * interrupt masks; a mechanism for the device driver to block all interrupts - * atomically without having to arbitrate for the PCI Interrupt Disable bit - * with the OS. - */ -#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */ -/* PCI physical function number */ -#define MEMBAR_CTRL_INT_CTRL_PFUNC_MASK 0x7 /* bits 26 - 28 */ -#define MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT 26 - -/********* Event Q door bell *************/ -#define DB_EQ_OFFSET DB_CQ_OFFSET -#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */ -/* Clear the interrupt for this eq */ -#define DB_EQ_CLR_SHIFT (9) /* bit 9 */ -/* Must be 1 */ -#define DB_EQ_EVNT_SHIFT (10) /* bit 10 */ -/* Number of event entries processed */ -#define DB_EQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ -/* Rearm bit */ -#define DB_EQ_REARM_SHIFT (29) /* bit 29 */ - -/********* Compl Q door bell *************/ -#define DB_CQ_OFFSET 0x120 -#define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ -/* Number of event entries processed */ -#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ -/* Rearm bit */ -#define DB_CQ_REARM_SHIFT (29) /* bit 29 */ - -/********** TX ULP door bell *************/ -#define DB_TXULP1_OFFSET 0x60 -#define DB_TXULP_RING_ID_MASK 0x7FF /* bits 0 - 10 */ -/* Number of tx entries posted */ -#define DB_TXULP_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */ -#define DB_TXULP_NUM_POSTED_MASK 0x3FFF /* bits 16 - 29 */ - -/********** RQ(erx) door bell ************/ -#define DB_RQ_OFFSET 0x100 -#define DB_RQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ -/* Number of rx frags posted */ -#define DB_RQ_NUM_POSTED_SHIFT (24) /* bits 24 - 31 */ - -/* - * BE descriptors: host memory data structures whose formats - * are hardwired in BE silicon. - */ -/* Event Queue Descriptor */ -#define EQ_ENTRY_VALID_MASK 0x1 /* bit 0 */ -#define EQ_ENTRY_RES_ID_MASK 0xFFFF /* bits 16 - 31 */ -#define EQ_ENTRY_RES_ID_SHIFT 16 -struct be_eq_entry { - u32 evt; -}; - -/* TX Queue Descriptor */ -#define ETH_WRB_FRAG_LEN_MASK 0xFFFF -struct be_eth_wrb { - u32 frag_pa_hi; /* dword 0 */ - u32 frag_pa_lo; /* dword 1 */ - u32 rsvd0; /* dword 2 */ - u32 frag_len; /* dword 3: bits 0 - 15 */ -} __packed; - -/* Pseudo amap definition for eth_hdr_wrb in which each bit of the - * actual structure is defined as a byte : used to calculate - * offset/shift/mask of each field */ -struct amap_eth_hdr_wrb { - u8 rsvd0[32]; /* dword 0 */ - u8 rsvd1[32]; /* dword 1 */ - u8 complete; /* dword 2 */ - u8 event; - u8 crc; - u8 forward; - u8 ipsec; - u8 mgmt; - u8 ipcs; - u8 udpcs; - u8 tcpcs; - u8 lso; - u8 vlan; - u8 gso[2]; - u8 num_wrb[5]; - u8 lso_mss[14]; - u8 len[16]; /* dword 3 */ - u8 vlan_tag[16]; -} __packed; - -struct be_eth_hdr_wrb { - u32 dw[4]; -}; - -/* TX Compl Queue Descriptor */ - -/* Pseudo amap definition for eth_tx_compl in which each bit of the - * actual structure is defined as a byte: used to calculate - * offset/shift/mask of each field */ -struct amap_eth_tx_compl { - u8 wrb_index[16]; /* dword 0 */ - u8 ct[2]; /* dword 0 */ - u8 port[2]; /* dword 0 */ - u8 rsvd0[8]; /* dword 0 */ - u8 status[4]; /* dword 0 */ - u8 user_bytes[16]; /* dword 1 */ - u8 nwh_bytes[8]; /* dword 1 */ - u8 lso; /* dword 1 */ - u8 cast_enc[2]; /* dword 1 */ - u8 rsvd1[5]; /* dword 1 */ - u8 rsvd2[32]; /* dword 2 */ - u8 pkts[16]; /* dword 3 */ - u8 ringid[11]; /* dword 3 */ - u8 hash_val[4]; /* dword 3 */ - u8 valid; /* dword 3 */ -} __packed; - -struct be_eth_tx_compl { - u32 dw[4]; -}; - -/* RX Queue Descriptor */ -struct be_eth_rx_d { - u32 fragpa_hi; - u32 fragpa_lo; -}; - -/* RX Compl Queue Descriptor */ - -/* Pseudo amap definition for eth_rx_compl in which each bit of the - * actual structure is defined as a byte: used to calculate - * offset/shift/mask of each field */ -struct amap_eth_rx_compl { - u8 vlan_tag[16]; /* dword 0 */ - u8 pktsize[14]; /* dword 0 */ - u8 port; /* dword 0 */ - u8 ip_opt; /* dword 0 */ - u8 err; /* dword 1 */ - u8 rsshp; /* dword 1 */ - u8 ipf; /* dword 1 */ - u8 tcpf; /* dword 1 */ - u8 udpf; /* dword 1 */ - u8 ipcksm; /* dword 1 */ - u8 l4_cksm; /* dword 1 */ - u8 ip_version; /* dword 1 */ - u8 macdst[6]; /* dword 1 */ - u8 vtp; /* dword 1 */ - u8 rsvd0; /* dword 1 */ - u8 fragndx[10]; /* dword 1 */ - u8 ct[2]; /* dword 1 */ - u8 sw; /* dword 1 */ - u8 numfrags[3]; /* dword 1 */ - u8 rss_flush; /* dword 2 */ - u8 cast_enc[2]; /* dword 2 */ - u8 qnq; /* dword 2 */ - u8 rss_bank; /* dword 2 */ - u8 rsvd1[23]; /* dword 2 */ - u8 lro_pkt; /* dword 2 */ - u8 rsvd2[2]; /* dword 2 */ - u8 valid; /* dword 2 */ - u8 rsshash[32]; /* dword 3 */ -} __packed; - -struct be_eth_rx_compl { - u32 dw[4]; -}; diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c deleted file mode 100644 index 0ecaffb70e58..000000000000 --- a/trunk/drivers/net/benet/be_main.c +++ /dev/null @@ -1,1911 +0,0 @@ -/* - * Copyright (C) 2005 - 2009 ServerEngines - * 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 version 2 - * as published by the Free Software Foundation. The full GNU General - * Public License is included in this distribution in the file called COPYING. - * - * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 - */ - -#include "be.h" - -MODULE_VERSION(DRV_VER); -MODULE_DEVICE_TABLE(pci, be_dev_ids); -MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); -MODULE_AUTHOR("ServerEngines Corporation"); -MODULE_LICENSE("GPL"); - -static unsigned int rx_frag_size = 2048; -module_param(rx_frag_size, uint, S_IRUGO); -MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); - -#define BE_VENDOR_ID 0x19a2 -#define BE2_DEVICE_ID_1 0x0211 -static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { - { PCI_DEVICE(BE_VENDOR_ID, BE2_DEVICE_ID_1) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, be_dev_ids); - -static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) -{ - struct be_dma_mem *mem = &q->dma_mem; - if (mem->va) - pci_free_consistent(adapter->pdev, mem->size, - mem->va, mem->dma); -} - -static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, - u16 len, u16 entry_size) -{ - struct be_dma_mem *mem = &q->dma_mem; - - memset(q, 0, sizeof(*q)); - q->len = len; - q->entry_size = entry_size; - mem->size = len * entry_size; - mem->va = pci_alloc_consistent(adapter->pdev, mem->size, &mem->dma); - if (!mem->va) - return -1; - memset(mem->va, 0, mem->size); - return 0; -} - -static inline void *queue_head_node(struct be_queue_info *q) -{ - return q->dma_mem.va + q->head * q->entry_size; -} - -static inline void *queue_tail_node(struct be_queue_info *q) -{ - return q->dma_mem.va + q->tail * q->entry_size; -} - -static inline void queue_head_inc(struct be_queue_info *q) -{ - index_inc(&q->head, q->len); -} - -static inline void queue_tail_inc(struct be_queue_info *q) -{ - index_inc(&q->tail, q->len); -} - -static void be_intr_set(struct be_ctrl_info *ctrl, bool enable) -{ - u8 __iomem *addr = ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET; - u32 reg = ioread32(addr); - u32 enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; - if (!enabled && enable) { - reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; - } else if (enabled && !enable) { - reg &= ~MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; - } else { - printk(KERN_WARNING DRV_NAME - ": bad value in membar_int_ctrl reg=0x%x\n", reg); - return; - } - iowrite32(reg, addr); -} - -static void be_rxq_notify(struct be_ctrl_info *ctrl, u16 qid, u16 posted) -{ - u32 val = 0; - val |= qid & DB_RQ_RING_ID_MASK; - val |= posted << DB_RQ_NUM_POSTED_SHIFT; - iowrite32(val, ctrl->db + DB_RQ_OFFSET); -} - -static void be_txq_notify(struct be_ctrl_info *ctrl, u16 qid, u16 posted) -{ - u32 val = 0; - val |= qid & DB_TXULP_RING_ID_MASK; - val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT; - iowrite32(val, ctrl->db + DB_TXULP1_OFFSET); -} - -static void be_eq_notify(struct be_ctrl_info *ctrl, u16 qid, - bool arm, bool clear_int, u16 num_popped) -{ - u32 val = 0; - val |= qid & DB_EQ_RING_ID_MASK; - if (arm) - val |= 1 << DB_EQ_REARM_SHIFT; - if (clear_int) - val |= 1 << DB_EQ_CLR_SHIFT; - val |= 1 << DB_EQ_EVNT_SHIFT; - val |= num_popped << DB_EQ_NUM_POPPED_SHIFT; - iowrite32(val, ctrl->db + DB_EQ_OFFSET); -} - -static void be_cq_notify(struct be_ctrl_info *ctrl, u16 qid, - bool arm, u16 num_popped) -{ - u32 val = 0; - val |= qid & DB_CQ_RING_ID_MASK; - if (arm) - val |= 1 << DB_CQ_REARM_SHIFT; - val |= num_popped << DB_CQ_NUM_POPPED_SHIFT; - iowrite32(val, ctrl->db + DB_CQ_OFFSET); -} - - -static int be_mac_addr_set(struct net_device *netdev, void *p) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct sockaddr *addr = p; - int status = 0; - - if (netif_running(netdev)) { - status = be_cmd_pmac_del(&adapter->ctrl, adapter->if_handle, - adapter->pmac_id); - if (status) - return status; - - status = be_cmd_pmac_add(&adapter->ctrl, (u8 *)addr->sa_data, - adapter->if_handle, &adapter->pmac_id); - } - - if (!status) - memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - - return status; -} - -static void netdev_stats_update(struct be_adapter *adapter) -{ - struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); - struct be_rxf_stats *rxf_stats = &hw_stats->rxf; - struct be_port_rxf_stats *port_stats = - &rxf_stats->port[adapter->port_num]; - struct net_device_stats *dev_stats = &adapter->stats.net_stats; - - dev_stats->rx_packets = port_stats->rx_total_frames; - dev_stats->tx_packets = port_stats->tx_unicastframes + - port_stats->tx_multicastframes + port_stats->tx_broadcastframes; - dev_stats->rx_bytes = (u64) port_stats->rx_bytes_msd << 32 | - (u64) port_stats->rx_bytes_lsd; - dev_stats->tx_bytes = (u64) port_stats->tx_bytes_msd << 32 | - (u64) port_stats->tx_bytes_lsd; - - /* bad pkts received */ - dev_stats->rx_errors = port_stats->rx_crc_errors + - port_stats->rx_alignment_symbol_errors + - port_stats->rx_in_range_errors + - port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; - - /* packet transmit problems */ - dev_stats->tx_errors = 0; - - /* no space in linux buffers */ - dev_stats->rx_dropped = 0; - - /* no space available in linux */ - dev_stats->tx_dropped = 0; - - dev_stats->multicast = port_stats->tx_multicastframes; - dev_stats->collisions = 0; - - /* detailed rx errors */ - dev_stats->rx_length_errors = port_stats->rx_in_range_errors + - port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; - /* receive ring buffer overflow */ - dev_stats->rx_over_errors = 0; - dev_stats->rx_crc_errors = port_stats->rx_crc_errors; - - /* frame alignment errors */ - dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; - /* receiver fifo overrun */ - /* drops_no_pbuf is no per i/f, it's per BE card */ - dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + - port_stats->rx_input_fifo_overflow + - rxf_stats->rx_drops_no_pbuf; - /* receiver missed packetd */ - dev_stats->rx_missed_errors = 0; - /* detailed tx_errors */ - dev_stats->tx_aborted_errors = 0; - dev_stats->tx_carrier_errors = 0; - dev_stats->tx_fifo_errors = 0; - dev_stats->tx_heartbeat_errors = 0; - dev_stats->tx_window_errors = 0; -} - -static void be_link_status_update(struct be_adapter *adapter) -{ - struct be_link_info *prev = &adapter->link; - struct be_link_info now = { 0 }; - struct net_device *netdev = adapter->netdev; - - be_cmd_link_status_query(&adapter->ctrl, &now); - - /* If link came up or went down */ - if (now.speed != prev->speed && (now.speed == PHY_LINK_SPEED_ZERO || - prev->speed == PHY_LINK_SPEED_ZERO)) { - if (now.speed == PHY_LINK_SPEED_ZERO) { - netif_stop_queue(netdev); - netif_carrier_off(netdev); - printk(KERN_INFO "%s: Link down\n", netdev->name); - } else { - netif_start_queue(netdev); - netif_carrier_on(netdev); - printk(KERN_INFO "%s: Link up\n", netdev->name); - } - } - *prev = now; -} - -/* Update the EQ delay n BE based on the RX frags consumed / sec */ -static void be_rx_eqd_update(struct be_adapter *adapter) -{ - u32 eqd; - struct be_ctrl_info *ctrl = &adapter->ctrl; - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_drvr_stats *stats = &adapter->stats.drvr_stats; - - /* Update once a second */ - if (((jiffies - stats->rx_fps_jiffies) < HZ) || rx_eq->enable_aic == 0) - return; - - stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) / - ((jiffies - stats->rx_fps_jiffies) / HZ); - - stats->rx_fps_jiffies = jiffies; - stats->be_prev_rx_frags = stats->be_rx_frags; - eqd = stats->be_rx_fps / 110000; - eqd = eqd << 3; - if (eqd > rx_eq->max_eqd) - eqd = rx_eq->max_eqd; - if (eqd < rx_eq->min_eqd) - eqd = rx_eq->min_eqd; - if (eqd < 10) - eqd = 0; - if (eqd != rx_eq->cur_eqd) - be_cmd_modify_eqd(ctrl, rx_eq->q.id, eqd); - - rx_eq->cur_eqd = eqd; -} - -static struct net_device_stats *be_get_stats(struct net_device *dev) -{ - struct be_adapter *adapter = netdev_priv(dev); - - return &adapter->stats.net_stats; -} - -static void be_tx_stats_update(struct be_adapter *adapter, - u32 wrb_cnt, u32 copied, bool stopped) -{ - struct be_drvr_stats *stats = &adapter->stats.drvr_stats; - stats->be_tx_reqs++; - stats->be_tx_wrbs += wrb_cnt; - stats->be_tx_bytes += copied; - if (stopped) - stats->be_tx_stops++; - - /* Update tx rate once in two seconds */ - if ((jiffies - stats->be_tx_jiffies) > 2 * HZ) { - u32 r; - r = (stats->be_tx_bytes - stats->be_tx_bytes_prev) / - ((u32) (jiffies - stats->be_tx_jiffies) / HZ); - r = (r / 1000000); /* M bytes/s */ - stats->be_tx_rate = (r * 8); /* M bits/s */ - stats->be_tx_jiffies = jiffies; - stats->be_tx_bytes_prev = stats->be_tx_bytes; - } -} - -/* Determine number of WRB entries needed to xmit data in an skb */ -static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) -{ - int cnt = 0; - while (skb) { - if (skb->len > skb->data_len) - cnt++; - cnt += skb_shinfo(skb)->nr_frags; - skb = skb_shinfo(skb)->frag_list; - } - /* to account for hdr wrb */ - cnt++; - if (cnt & 1) { - /* add a dummy to make it an even num */ - cnt++; - *dummy = true; - } else - *dummy = false; - BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT); - return cnt; -} - -static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len) -{ - wrb->frag_pa_hi = upper_32_bits(addr); - wrb->frag_pa_lo = addr & 0xFFFFFFFF; - wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK; -} - -static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, - bool vlan, u32 wrb_cnt, u32 len) -{ - memset(hdr, 0, sizeof(*hdr)); - - AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1); - - if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) { - AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1); - AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss, - hdr, skb_shinfo(skb)->gso_size); - } else if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (is_tcp_pkt(skb)) - AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); - else if (is_udp_pkt(skb)) - AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); - } - - if (vlan && vlan_tx_tag_present(skb)) { - AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); - AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, - hdr, vlan_tx_tag_get(skb)); - } - - AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1); - AMAP_SET_BITS(struct amap_eth_hdr_wrb, complete, hdr, 1); - AMAP_SET_BITS(struct amap_eth_hdr_wrb, num_wrb, hdr, wrb_cnt); - AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len); -} - - -static int make_tx_wrbs(struct be_adapter *adapter, - struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb) -{ - u64 busaddr; - u32 i, copied = 0; - struct pci_dev *pdev = adapter->pdev; - struct sk_buff *first_skb = skb; - struct be_queue_info *txq = &adapter->tx_obj.q; - struct be_eth_wrb *wrb; - struct be_eth_hdr_wrb *hdr; - - atomic_add(wrb_cnt, &txq->used); - hdr = queue_head_node(txq); - queue_head_inc(txq); - - while (skb) { - if (skb->len > skb->data_len) { - int len = skb->len - skb->data_len; - busaddr = pci_map_single(pdev, skb->data, len, - PCI_DMA_TODEVICE); - wrb = queue_head_node(txq); - wrb_fill(wrb, busaddr, len); - be_dws_cpu_to_le(wrb, sizeof(*wrb)); - queue_head_inc(txq); - copied += len; - } - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - struct skb_frag_struct *frag = - &skb_shinfo(skb)->frags[i]; - busaddr = pci_map_page(pdev, frag->page, - frag->page_offset, - frag->size, PCI_DMA_TODEVICE); - wrb = queue_head_node(txq); - wrb_fill(wrb, busaddr, frag->size); - be_dws_cpu_to_le(wrb, sizeof(*wrb)); - queue_head_inc(txq); - copied += frag->size; - } - skb = skb_shinfo(skb)->frag_list; - } - - if (dummy_wrb) { - wrb = queue_head_node(txq); - wrb_fill(wrb, 0, 0); - be_dws_cpu_to_le(wrb, sizeof(*wrb)); - queue_head_inc(txq); - } - - wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false, - wrb_cnt, copied); - be_dws_cpu_to_le(hdr, sizeof(*hdr)); - - return copied; -} - -static int be_xmit(struct sk_buff *skb, struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct be_tx_obj *tx_obj = &adapter->tx_obj; - struct be_queue_info *txq = &tx_obj->q; - u32 wrb_cnt = 0, copied = 0; - u32 start = txq->head; - bool dummy_wrb, stopped = false; - - wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb); - - copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb); - - /* record the sent skb in the sent_skb table */ - BUG_ON(tx_obj->sent_skb_list[start]); - tx_obj->sent_skb_list[start] = skb; - - /* Ensure that txq has space for the next skb; Else stop the queue - * *BEFORE* ringing the tx doorbell, so that we serialze the - * tx compls of the current transmit which'll wake up the queue - */ - if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >= txq->len) { - netif_stop_queue(netdev); - stopped = true; - } - - be_txq_notify(&adapter->ctrl, txq->id, wrb_cnt); - - netdev->trans_start = jiffies; - - be_tx_stats_update(adapter, wrb_cnt, copied, stopped); - return NETDEV_TX_OK; -} - -static int be_change_mtu(struct net_device *netdev, int new_mtu) -{ - struct be_adapter *adapter = netdev_priv(netdev); - if (new_mtu < BE_MIN_MTU || - new_mtu > BE_MAX_JUMBO_FRAME_SIZE) { - dev_info(&adapter->pdev->dev, - "MTU must be between %d and %d bytes\n", - BE_MIN_MTU, BE_MAX_JUMBO_FRAME_SIZE); - return -EINVAL; - } - dev_info(&adapter->pdev->dev, "MTU changed from %d to %d bytes\n", - netdev->mtu, new_mtu); - netdev->mtu = new_mtu; - return 0; -} - -/* - * if there are BE_NUM_VLANS_SUPPORTED or lesser number of VLANS configured, - * program them in BE. If more than BE_NUM_VLANS_SUPPORTED are configured, - * set the BE in promiscuous VLAN mode. - */ -static void be_vid_config(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - u16 vtag[BE_NUM_VLANS_SUPPORTED]; - u16 ntags = 0, i; - - if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED) { - /* Construct VLAN Table to give to HW */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { - if (adapter->vlan_tag[i]) { - vtag[ntags] = cpu_to_le16(i); - ntags++; - } - } - be_cmd_vlan_config(&adapter->ctrl, adapter->if_handle, - vtag, ntags, 1, 0); - } else { - be_cmd_vlan_config(&adapter->ctrl, adapter->if_handle, - NULL, 0, 1, 1); - } -} - -static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_eq_obj *tx_eq = &adapter->tx_eq; - struct be_ctrl_info *ctrl = &adapter->ctrl; - - be_eq_notify(ctrl, rx_eq->q.id, false, false, 0); - be_eq_notify(ctrl, tx_eq->q.id, false, false, 0); - adapter->vlan_grp = grp; - be_eq_notify(ctrl, rx_eq->q.id, true, false, 0); - be_eq_notify(ctrl, tx_eq->q.id, true, false, 0); -} - -static void be_vlan_add_vid(struct net_device *netdev, u16 vid) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - adapter->num_vlans++; - adapter->vlan_tag[vid] = 1; - - be_vid_config(netdev); -} - -static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - adapter->num_vlans--; - adapter->vlan_tag[vid] = 0; - - vlan_group_set_device(adapter->vlan_grp, vid, NULL); - be_vid_config(netdev); -} - -static void be_set_multicast_filter(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct dev_mc_list *mc_ptr; - u8 mac_addr[32][ETH_ALEN]; - int i = 0; - - if (netdev->flags & IFF_ALLMULTI) { - /* set BE in Multicast promiscuous */ - be_cmd_mcast_mac_set(&adapter->ctrl, - adapter->if_handle, NULL, 0, true); - return; - } - - for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { - memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN); - if (++i >= 32) { - be_cmd_mcast_mac_set(&adapter->ctrl, - adapter->if_handle, &mac_addr[0][0], i, false); - i = 0; - } - - } - - if (i) { - /* reset the promiscuous mode also. */ - be_cmd_mcast_mac_set(&adapter->ctrl, - adapter->if_handle, &mac_addr[0][0], i, false); - } -} - -static void be_set_multicast_list(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - if (netdev->flags & IFF_PROMISC) { - be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 1); - } else { - be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 0); - be_set_multicast_filter(netdev); - } -} - -static void be_rx_rate_update(struct be_adapter *adapter, u32 pktsize, - u16 numfrags) -{ - struct be_drvr_stats *stats = &adapter->stats.drvr_stats; - u32 rate; - - stats->be_rx_compl++; - stats->be_rx_frags += numfrags; - stats->be_rx_bytes += pktsize; - - /* Update the rate once in two seconds */ - if ((jiffies - stats->be_rx_jiffies) < 2 * HZ) - return; - - rate = (stats->be_rx_bytes - stats->be_rx_bytes_prev) / - ((u32) (jiffies - stats->be_rx_jiffies) / HZ); - rate = (rate / 1000000); /* MB/Sec */ - stats->be_rx_rate = (rate * 8); /* Mega Bits/Sec */ - stats->be_rx_jiffies = jiffies; - stats->be_rx_bytes_prev = stats->be_rx_bytes; -} - -static struct be_rx_page_info * -get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) -{ - struct be_rx_page_info *rx_page_info; - struct be_queue_info *rxq = &adapter->rx_obj.q; - - rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx]; - BUG_ON(!rx_page_info->page); - - if (rx_page_info->last_page_user) - pci_unmap_page(adapter->pdev, pci_unmap_addr(rx_page_info, bus), - adapter->big_page_size, PCI_DMA_FROMDEVICE); - - atomic_dec(&rxq->used); - return rx_page_info; -} - -/* Throwaway the data in the Rx completion */ -static void be_rx_compl_discard(struct be_adapter *adapter, - struct be_eth_rx_compl *rxcp) -{ - struct be_queue_info *rxq = &adapter->rx_obj.q; - struct be_rx_page_info *page_info; - u16 rxq_idx, i, num_rcvd; - - rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); - num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - - for (i = 0; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxq_idx); - put_page(page_info->page); - memset(page_info, 0, sizeof(*page_info)); - index_inc(&rxq_idx, rxq->len); - } -} - -/* - * skb_fill_rx_data forms a complete skb for an ether frame - * indicated by rxcp. - */ -static void skb_fill_rx_data(struct be_adapter *adapter, - struct sk_buff *skb, struct be_eth_rx_compl *rxcp) -{ - struct be_queue_info *rxq = &adapter->rx_obj.q; - struct be_rx_page_info *page_info; - u16 rxq_idx, i, num_rcvd; - u32 pktsize, hdr_len, curr_frag_len; - u8 *start; - - rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); - pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); - num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - - page_info = get_rx_page_info(adapter, rxq_idx); - - start = page_address(page_info->page) + page_info->page_offset; - prefetch(start); - - /* Copy data in the first descriptor of this completion */ - curr_frag_len = min(pktsize, rx_frag_size); - - /* Copy the header portion into skb_data */ - hdr_len = min((u32)BE_HDR_LEN, curr_frag_len); - memcpy(skb->data, start, hdr_len); - skb->len = curr_frag_len; - if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */ - /* Complete packet has now been moved to data */ - put_page(page_info->page); - skb->data_len = 0; - skb->tail += curr_frag_len; - } else { - skb_shinfo(skb)->nr_frags = 1; - skb_shinfo(skb)->frags[0].page = page_info->page; - skb_shinfo(skb)->frags[0].page_offset = - page_info->page_offset + hdr_len; - skb_shinfo(skb)->frags[0].size = curr_frag_len - hdr_len; - skb->data_len = curr_frag_len - hdr_len; - skb->tail += hdr_len; - } - memset(page_info, 0, sizeof(*page_info)); - - if (pktsize <= rx_frag_size) { - BUG_ON(num_rcvd != 1); - return; - } - - /* More frags present for this completion */ - pktsize -= curr_frag_len; /* account for above copied frag */ - for (i = 1; i < num_rcvd; i++) { - index_inc(&rxq_idx, rxq->len); - page_info = get_rx_page_info(adapter, rxq_idx); - - curr_frag_len = min(pktsize, rx_frag_size); - - skb_shinfo(skb)->frags[i].page = page_info->page; - skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset; - skb_shinfo(skb)->frags[i].size = curr_frag_len; - skb->len += curr_frag_len; - skb->data_len += curr_frag_len; - skb_shinfo(skb)->nr_frags++; - pktsize -= curr_frag_len; - - memset(page_info, 0, sizeof(*page_info)); - } - - be_rx_rate_update(adapter, pktsize, num_rcvd); - return; -} - -/* Process the RX completion indicated by rxcp when LRO is disabled */ -static void be_rx_compl_process(struct be_adapter *adapter, - struct be_eth_rx_compl *rxcp) -{ - struct sk_buff *skb; - u32 vtp, vid; - int l4_cksm; - - l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); - vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); - - skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN); - if (!skb) { - if (net_ratelimit()) - dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); - be_rx_compl_discard(adapter, rxcp); - return; - } - - skb_reserve(skb, NET_IP_ALIGN); - - skb_fill_rx_data(adapter, skb, rxcp); - - if (l4_cksm && adapter->rx_csum) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb->ip_summed = CHECKSUM_NONE; - - skb->truesize = skb->len + sizeof(struct sk_buff); - skb->protocol = eth_type_trans(skb, adapter->netdev); - skb->dev = adapter->netdev; - - if (vtp) { - if (!adapter->vlan_grp || adapter->num_vlans == 0) { - kfree_skb(skb); - return; - } - vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); - vid = be16_to_cpu(vid); - vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); - } else { - netif_receive_skb(skb); - } - - adapter->netdev->last_rx = jiffies; - - return; -} - -/* Process the RX completion indicated by rxcp when LRO is enabled */ -static void be_rx_compl_process_lro(struct be_adapter *adapter, - struct be_eth_rx_compl *rxcp) -{ - struct be_rx_page_info *page_info; - struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; - struct be_queue_info *rxq = &adapter->rx_obj.q; - u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; - u16 i, rxq_idx = 0, vid; - - num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); - vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); - rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); - - remaining = pkt_size; - for (i = 0; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxq_idx); - - curr_frag_len = min(remaining, rx_frag_size); - - rx_frags[i].page = page_info->page; - rx_frags[i].page_offset = page_info->page_offset; - rx_frags[i].size = curr_frag_len; - remaining -= curr_frag_len; - - index_inc(&rxq_idx, rxq->len); - - memset(page_info, 0, sizeof(*page_info)); - } - - if (likely(!vlanf)) { - lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, - pkt_size, NULL, 0); - } else { - vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); - vid = be16_to_cpu(vid); - - if (!adapter->vlan_grp || adapter->num_vlans == 0) - return; - - lro_vlan_hwaccel_receive_frags(&adapter->rx_obj.lro_mgr, - rx_frags, pkt_size, pkt_size, adapter->vlan_grp, - vid, NULL, 0); - } - - be_rx_rate_update(adapter, pkt_size, num_rcvd); - return; -} - -static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) -{ - struct be_eth_rx_compl *rxcp = queue_tail_node(&adapter->rx_obj.cq); - - if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0) - return NULL; - - be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); - - rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; - - queue_tail_inc(&adapter->rx_obj.cq); - return rxcp; -} - -static inline struct page *be_alloc_pages(u32 size) -{ - gfp_t alloc_flags = GFP_ATOMIC; - u32 order = get_order(size); - if (order > 0) - alloc_flags |= __GFP_COMP; - return alloc_pages(alloc_flags, order); -} - -/* - * Allocate a page, split it to fragments of size rx_frag_size and post as - * receive buffers to BE - */ -static void be_post_rx_frags(struct be_adapter *adapter) -{ - struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl; - struct be_rx_page_info *page_info = NULL; - struct be_queue_info *rxq = &adapter->rx_obj.q; - struct page *pagep = NULL; - struct be_eth_rx_d *rxd; - u64 page_dmaaddr = 0, frag_dmaaddr; - u32 posted, page_offset = 0; - - - page_info = &page_info_tbl[rxq->head]; - for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) { - if (!pagep) { - pagep = be_alloc_pages(adapter->big_page_size); - if (unlikely(!pagep)) { - drvr_stats(adapter)->be_ethrx_post_fail++; - break; - } - page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0, - adapter->big_page_size, - PCI_DMA_FROMDEVICE); - page_info->page_offset = 0; - } else { - get_page(pagep); - page_info->page_offset = page_offset + rx_frag_size; - } - page_offset = page_info->page_offset; - page_info->page = pagep; - pci_unmap_addr_set(page_info, bus, page_dmaaddr); - frag_dmaaddr = page_dmaaddr + page_info->page_offset; - - rxd = queue_head_node(rxq); - rxd->fragpa_lo = cpu_to_le32(frag_dmaaddr & 0xFFFFFFFF); - rxd->fragpa_hi = cpu_to_le32(upper_32_bits(frag_dmaaddr)); - queue_head_inc(rxq); - - /* Any space left in the current big page for another frag? */ - if ((page_offset + rx_frag_size + rx_frag_size) > - adapter->big_page_size) { - pagep = NULL; - page_info->last_page_user = true; - } - page_info = &page_info_tbl[rxq->head]; - } - if (pagep) - page_info->last_page_user = true; - - if (posted) { - atomic_add(posted, &rxq->used); - be_rxq_notify(&adapter->ctrl, rxq->id, posted); - } else if (atomic_read(&rxq->used) == 0) { - /* Let be_worker replenish when memory is available */ - adapter->rx_post_starved = true; - } - - return; -} - -static struct be_eth_tx_compl * -be_tx_compl_get(struct be_adapter *adapter) -{ - struct be_queue_info *tx_cq = &adapter->tx_obj.cq; - struct be_eth_tx_compl *txcp = queue_tail_node(tx_cq); - - if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0) - return NULL; - - be_dws_le_to_cpu(txcp, sizeof(*txcp)); - - txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0; - - queue_tail_inc(tx_cq); - return txcp; -} - -static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) -{ - struct be_queue_info *txq = &adapter->tx_obj.q; - struct be_eth_wrb *wrb; - struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; - struct sk_buff *sent_skb; - u64 busaddr; - u16 cur_index, num_wrbs = 0; - - cur_index = txq->tail; - sent_skb = sent_skbs[cur_index]; - BUG_ON(!sent_skb); - sent_skbs[cur_index] = NULL; - - do { - cur_index = txq->tail; - wrb = queue_tail_node(txq); - be_dws_le_to_cpu(wrb, sizeof(*wrb)); - busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo; - if (busaddr != 0) { - pci_unmap_single(adapter->pdev, busaddr, - wrb->frag_len, PCI_DMA_TODEVICE); - } - num_wrbs++; - queue_tail_inc(txq); - } while (cur_index != last_index); - - atomic_sub(num_wrbs, &txq->used); - - kfree_skb(sent_skb); -} - -static void be_rx_q_clean(struct be_adapter *adapter) -{ - struct be_rx_page_info *page_info; - struct be_queue_info *rxq = &adapter->rx_obj.q; - struct be_queue_info *rx_cq = &adapter->rx_obj.cq; - struct be_eth_rx_compl *rxcp; - u16 tail; - - /* First cleanup pending rx completions */ - while ((rxcp = be_rx_compl_get(adapter)) != NULL) { - be_rx_compl_discard(adapter, rxcp); - be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1); - } - - /* Then free posted rx buffer that were not used */ - tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len; - for (; tail != rxq->head; index_inc(&tail, rxq->len)) { - page_info = get_rx_page_info(adapter, tail); - put_page(page_info->page); - memset(page_info, 0, sizeof(*page_info)); - } - BUG_ON(atomic_read(&rxq->used)); -} - -static void be_tx_q_clean(struct be_adapter *adapter) -{ - struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; - struct sk_buff *sent_skb; - struct be_queue_info *txq = &adapter->tx_obj.q; - u16 last_index; - bool dummy_wrb; - - while (atomic_read(&txq->used)) { - sent_skb = sent_skbs[txq->tail]; - last_index = txq->tail; - index_adv(&last_index, - wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len); - be_tx_compl_process(adapter, last_index); - } -} - -static void be_tx_queues_destroy(struct be_adapter *adapter) -{ - struct be_queue_info *q; - - q = &adapter->tx_obj.q; - if (q->created) - be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ); - be_queue_free(adapter, q); - - q = &adapter->tx_obj.cq; - if (q->created) - be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ); - be_queue_free(adapter, q); - - /* No more tx completions can be rcvd now; clean up if there are - * any pending completions or pending tx requests */ - be_tx_q_clean(adapter); - - q = &adapter->tx_eq.q; - if (q->created) - be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ); - be_queue_free(adapter, q); -} - -static int be_tx_queues_create(struct be_adapter *adapter) -{ - struct be_queue_info *eq, *q, *cq; - - adapter->tx_eq.max_eqd = 0; - adapter->tx_eq.min_eqd = 0; - adapter->tx_eq.cur_eqd = 96; - adapter->tx_eq.enable_aic = false; - /* Alloc Tx Event queue */ - eq = &adapter->tx_eq.q; - if (be_queue_alloc(adapter, eq, EVNT_Q_LEN, sizeof(struct be_eq_entry))) - return -1; - - /* Ask BE to create Tx Event queue */ - if (be_cmd_eq_create(&adapter->ctrl, eq, adapter->tx_eq.cur_eqd)) - goto tx_eq_free; - /* Alloc TX eth compl queue */ - cq = &adapter->tx_obj.cq; - if (be_queue_alloc(adapter, cq, TX_CQ_LEN, - sizeof(struct be_eth_tx_compl))) - goto tx_eq_destroy; - - /* Ask BE to create Tx eth compl queue */ - if (be_cmd_cq_create(&adapter->ctrl, cq, eq, false, false, 3)) - goto tx_cq_free; - - /* Alloc TX eth queue */ - q = &adapter->tx_obj.q; - if (be_queue_alloc(adapter, q, TX_Q_LEN, sizeof(struct be_eth_wrb))) - goto tx_cq_destroy; - - /* Ask BE to create Tx eth queue */ - if (be_cmd_txq_create(&adapter->ctrl, q, cq)) - goto tx_q_free; - return 0; - -tx_q_free: - be_queue_free(adapter, q); -tx_cq_destroy: - be_cmd_q_destroy(&adapter->ctrl, cq, QTYPE_CQ); -tx_cq_free: - be_queue_free(adapter, cq); -tx_eq_destroy: - be_cmd_q_destroy(&adapter->ctrl, eq, QTYPE_EQ); -tx_eq_free: - be_queue_free(adapter, eq); - return -1; -} - -static void be_rx_queues_destroy(struct be_adapter *adapter) -{ - struct be_queue_info *q; - - q = &adapter->rx_obj.q; - if (q->created) { - be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_RXQ); - be_rx_q_clean(adapter); - } - be_queue_free(adapter, q); - - q = &adapter->rx_obj.cq; - if (q->created) - be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ); - be_queue_free(adapter, q); - - q = &adapter->rx_eq.q; - if (q->created) - be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ); - be_queue_free(adapter, q); -} - -static int be_rx_queues_create(struct be_adapter *adapter) -{ - struct be_queue_info *eq, *q, *cq; - int rc; - - adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME; - adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; - adapter->rx_eq.max_eqd = BE_MAX_EQD; - adapter->rx_eq.min_eqd = 0; - adapter->rx_eq.cur_eqd = 0; - adapter->rx_eq.enable_aic = true; - - /* Alloc Rx Event queue */ - eq = &adapter->rx_eq.q; - rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, - sizeof(struct be_eq_entry)); - if (rc) - return rc; - - /* Ask BE to create Rx Event queue */ - rc = be_cmd_eq_create(&adapter->ctrl, eq, adapter->rx_eq.cur_eqd); - if (rc) - goto rx_eq_free; - - /* Alloc RX eth compl queue */ - cq = &adapter->rx_obj.cq; - rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, - sizeof(struct be_eth_rx_compl)); - if (rc) - goto rx_eq_destroy; - - /* Ask BE to create Rx eth compl queue */ - rc = be_cmd_cq_create(&adapter->ctrl, cq, eq, false, false, 3); - if (rc) - goto rx_cq_free; - - /* Alloc RX eth queue */ - q = &adapter->rx_obj.q; - rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d)); - if (rc) - goto rx_cq_destroy; - - /* Ask BE to create Rx eth queue */ - rc = be_cmd_rxq_create(&adapter->ctrl, q, cq->id, rx_frag_size, - BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false); - if (rc) - goto rx_q_free; - - return 0; -rx_q_free: - be_queue_free(adapter, q); -rx_cq_destroy: - be_cmd_q_destroy(&adapter->ctrl, cq, QTYPE_CQ); -rx_cq_free: - be_queue_free(adapter, cq); -rx_eq_destroy: - be_cmd_q_destroy(&adapter->ctrl, eq, QTYPE_EQ); -rx_eq_free: - be_queue_free(adapter, eq); - return rc; -} -static bool event_get(struct be_eq_obj *eq_obj, u16 *rid) -{ - struct be_eq_entry *entry = queue_tail_node(&eq_obj->q); - u32 evt = entry->evt; - - if (!evt) - return false; - - evt = le32_to_cpu(evt); - *rid = (evt >> EQ_ENTRY_RES_ID_SHIFT) & EQ_ENTRY_RES_ID_MASK; - entry->evt = 0; - queue_tail_inc(&eq_obj->q); - return true; -} - -static int event_handle(struct be_ctrl_info *ctrl, - struct be_eq_obj *eq_obj) -{ - u16 rid = 0, num = 0; - - while (event_get(eq_obj, &rid)) - num++; - - /* We can see an interrupt and no event */ - be_eq_notify(ctrl, eq_obj->q.id, true, true, num); - if (num) - napi_schedule(&eq_obj->napi); - - return num; -} - -static irqreturn_t be_intx(int irq, void *dev) -{ - struct be_adapter *adapter = dev; - struct be_ctrl_info *ctrl = &adapter->ctrl; - int rx, tx; - - tx = event_handle(ctrl, &adapter->tx_eq); - rx = event_handle(ctrl, &adapter->rx_eq); - - if (rx || tx) - return IRQ_HANDLED; - else - return IRQ_NONE; -} - -static irqreturn_t be_msix_rx(int irq, void *dev) -{ - struct be_adapter *adapter = dev; - - event_handle(&adapter->ctrl, &adapter->rx_eq); - - return IRQ_HANDLED; -} - -static irqreturn_t be_msix_tx(int irq, void *dev) -{ - struct be_adapter *adapter = dev; - - event_handle(&adapter->ctrl, &adapter->tx_eq); - - return IRQ_HANDLED; -} - -static inline bool do_lro(struct be_adapter *adapter, - struct be_eth_rx_compl *rxcp) -{ - int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); - int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); - - if (err) - drvr_stats(adapter)->be_rxcp_err++; - - return (!tcp_frame || err || (adapter->max_rx_coal <= 1)) ? - false : true; -} - -int be_poll_rx(struct napi_struct *napi, int budget) -{ - struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi); - struct be_adapter *adapter = - container_of(rx_eq, struct be_adapter, rx_eq); - struct be_queue_info *rx_cq = &adapter->rx_obj.cq; - struct be_eth_rx_compl *rxcp; - u32 work_done; - - for (work_done = 0; work_done < budget; work_done++) { - rxcp = be_rx_compl_get(adapter); - if (!rxcp) - break; - - if (do_lro(adapter, rxcp)) - be_rx_compl_process_lro(adapter, rxcp); - else - be_rx_compl_process(adapter, rxcp); - } - - lro_flush_all(&adapter->rx_obj.lro_mgr); - - /* Refill the queue */ - if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM) - be_post_rx_frags(adapter); - - /* All consumed */ - if (work_done < budget) { - napi_complete(napi); - be_cq_notify(&adapter->ctrl, rx_cq->id, true, work_done); - } else { - /* More to be consumed; continue with interrupts disabled */ - be_cq_notify(&adapter->ctrl, rx_cq->id, false, work_done); - } - return work_done; -} - -/* For TX we don't honour budget; consume everything */ -int be_poll_tx(struct napi_struct *napi, int budget) -{ - struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi); - struct be_adapter *adapter = - container_of(tx_eq, struct be_adapter, tx_eq); - struct be_tx_obj *tx_obj = &adapter->tx_obj; - struct be_queue_info *tx_cq = &tx_obj->cq; - struct be_queue_info *txq = &tx_obj->q; - struct be_eth_tx_compl *txcp; - u32 num_cmpl = 0; - u16 end_idx; - - while ((txcp = be_tx_compl_get(adapter))) { - end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, - wrb_index, txcp); - be_tx_compl_process(adapter, end_idx); - num_cmpl++; - } - - /* As Tx wrbs have been freed up, wake up netdev queue if - * it was stopped due to lack of tx wrbs. - */ - if (netif_queue_stopped(adapter->netdev) && - atomic_read(&txq->used) < txq->len / 2) { - netif_wake_queue(adapter->netdev); - } - - napi_complete(napi); - - be_cq_notify(&adapter->ctrl, tx_cq->id, true, num_cmpl); - - drvr_stats(adapter)->be_tx_events++; - drvr_stats(adapter)->be_tx_compl += num_cmpl; - - return 1; -} - -static void be_worker(struct work_struct *work) -{ - struct be_adapter *adapter = - container_of(work, struct be_adapter, work.work); - int status; - - /* Check link */ - be_link_status_update(adapter); - - /* Get Stats */ - status = be_cmd_get_stats(&adapter->ctrl, &adapter->stats.cmd); - if (!status) - netdev_stats_update(adapter); - - /* Set EQ delay */ - be_rx_eqd_update(adapter); - - if (adapter->rx_post_starved) { - adapter->rx_post_starved = false; - be_post_rx_frags(adapter); - } - - schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); -} - -static void be_msix_enable(struct be_adapter *adapter) -{ - int i, status; - - for (i = 0; i < BE_NUM_MSIX_VECTORS; i++) - adapter->msix_entries[i].entry = i; - - status = pci_enable_msix(adapter->pdev, adapter->msix_entries, - BE_NUM_MSIX_VECTORS); - if (status == 0) - adapter->msix_enabled = true; - return; -} - -static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) -{ - return adapter->msix_entries[eq_id - - 8 * adapter->ctrl.pci_func].vector; -} - -static int be_msix_register(struct be_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - struct be_eq_obj *tx_eq = &adapter->tx_eq; - struct be_eq_obj *rx_eq = &adapter->rx_eq; - int status, vec; - - sprintf(tx_eq->desc, "%s-tx", netdev->name); - vec = be_msix_vec_get(adapter, tx_eq->q.id); - status = request_irq(vec, be_msix_tx, 0, tx_eq->desc, adapter); - if (status) - goto err; - - sprintf(rx_eq->desc, "%s-rx", netdev->name); - vec = be_msix_vec_get(adapter, rx_eq->q.id); - status = request_irq(vec, be_msix_rx, 0, rx_eq->desc, adapter); - if (status) { /* Free TX IRQ */ - vec = be_msix_vec_get(adapter, tx_eq->q.id); - free_irq(vec, adapter); - goto err; - } - return 0; -err: - dev_warn(&adapter->pdev->dev, - "MSIX Request IRQ failed - err %d\n", status); - pci_disable_msix(adapter->pdev); - adapter->msix_enabled = false; - return status; -} - -static int be_irq_register(struct be_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - int status; - - if (adapter->msix_enabled) { - status = be_msix_register(adapter); - if (status == 0) - goto done; - } - - /* INTx */ - netdev->irq = adapter->pdev->irq; - status = request_irq(netdev->irq, be_intx, IRQF_SHARED, netdev->name, - adapter); - if (status) { - dev_err(&adapter->pdev->dev, - "INTx request IRQ failed - err %d\n", status); - return status; - } -done: - adapter->isr_registered = true; - return 0; -} - -static void be_irq_unregister(struct be_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - int vec; - - if (!adapter->isr_registered) - return; - - /* INTx */ - if (!adapter->msix_enabled) { - free_irq(netdev->irq, adapter); - goto done; - } - - /* MSIx */ - vec = be_msix_vec_get(adapter, adapter->tx_eq.q.id); - free_irq(vec, adapter); - vec = be_msix_vec_get(adapter, adapter->rx_eq.q.id); - free_irq(vec, adapter); -done: - adapter->isr_registered = false; - return; -} - -static int be_open(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct be_ctrl_info *ctrl = &adapter->ctrl; - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_eq_obj *tx_eq = &adapter->tx_eq; - u32 if_flags; - int status; - - if_flags = BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PROMISCUOUS | - BE_IF_FLAGS_MCAST_PROMISCUOUS | BE_IF_FLAGS_UNTAGGED | - BE_IF_FLAGS_PASS_L3L4_ERRORS; - status = be_cmd_if_create(ctrl, if_flags, netdev->dev_addr, - false/* pmac_invalid */, &adapter->if_handle, - &adapter->pmac_id); - if (status != 0) - goto do_none; - - be_vid_config(netdev); - - status = be_cmd_set_flow_control(ctrl, true, true); - if (status != 0) - goto if_destroy; - - status = be_tx_queues_create(adapter); - if (status != 0) - goto if_destroy; - - status = be_rx_queues_create(adapter); - if (status != 0) - goto tx_qs_destroy; - - /* First time posting */ - be_post_rx_frags(adapter); - - napi_enable(&rx_eq->napi); - napi_enable(&tx_eq->napi); - - be_irq_register(adapter); - - be_intr_set(ctrl, true); - - /* The evt queues are created in the unarmed state; arm them */ - be_eq_notify(ctrl, rx_eq->q.id, true, false, 0); - be_eq_notify(ctrl, tx_eq->q.id, true, false, 0); - - /* The compl queues are created in the unarmed state; arm them */ - be_cq_notify(ctrl, adapter->rx_obj.cq.id, true, 0); - be_cq_notify(ctrl, adapter->tx_obj.cq.id, true, 0); - - be_link_status_update(adapter); - - schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); - return 0; - -tx_qs_destroy: - be_tx_queues_destroy(adapter); -if_destroy: - be_cmd_if_destroy(ctrl, adapter->if_handle); -do_none: - return status; -} - -static int be_close(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - struct be_ctrl_info *ctrl = &adapter->ctrl; - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_eq_obj *tx_eq = &adapter->tx_eq; - int vec; - - cancel_delayed_work(&adapter->work); - - netif_stop_queue(netdev); - netif_carrier_off(netdev); - adapter->link.speed = PHY_LINK_SPEED_ZERO; - - be_intr_set(ctrl, false); - - if (adapter->msix_enabled) { - vec = be_msix_vec_get(adapter, tx_eq->q.id); - synchronize_irq(vec); - vec = be_msix_vec_get(adapter, rx_eq->q.id); - synchronize_irq(vec); - } else { - synchronize_irq(netdev->irq); - } - be_irq_unregister(adapter); - - napi_disable(&rx_eq->napi); - napi_disable(&tx_eq->napi); - - be_rx_queues_destroy(adapter); - be_tx_queues_destroy(adapter); - - be_cmd_if_destroy(ctrl, adapter->if_handle); - return 0; -} - -static int be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr, - void **ip_hdr, void **tcpudp_hdr, - u64 *hdr_flags, void *priv) -{ - struct ethhdr *eh; - struct vlan_ethhdr *veh; - struct iphdr *iph; - u8 *va = page_address(frag->page) + frag->page_offset; - unsigned long ll_hlen; - - prefetch(va); - eh = (struct ethhdr *)va; - *mac_hdr = eh; - ll_hlen = ETH_HLEN; - if (eh->h_proto != htons(ETH_P_IP)) { - if (eh->h_proto == htons(ETH_P_8021Q)) { - veh = (struct vlan_ethhdr *)va; - if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP)) - return -1; - - ll_hlen += VLAN_HLEN; - } else { - return -1; - } - } - *hdr_flags = LRO_IPV4; - iph = (struct iphdr *)(va + ll_hlen); - *ip_hdr = iph; - if (iph->protocol != IPPROTO_TCP) - return -1; - *hdr_flags |= LRO_TCP; - *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2); - - return 0; -} - -static void be_lro_init(struct be_adapter *adapter, struct net_device *netdev) -{ - struct net_lro_mgr *lro_mgr; - - lro_mgr = &adapter->rx_obj.lro_mgr; - lro_mgr->dev = netdev; - lro_mgr->features = LRO_F_NAPI; - lro_mgr->ip_summed = CHECKSUM_UNNECESSARY; - lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; - lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS; - lro_mgr->lro_arr = adapter->rx_obj.lro_desc; - lro_mgr->get_frag_header = be_get_frag_header; - lro_mgr->max_aggr = BE_MAX_FRAGS_PER_FRAME; -} - -static struct net_device_ops be_netdev_ops = { - .ndo_open = be_open, - .ndo_stop = be_close, - .ndo_start_xmit = be_xmit, - .ndo_get_stats = be_get_stats, - .ndo_set_rx_mode = be_set_multicast_list, - .ndo_set_mac_address = be_mac_addr_set, - .ndo_change_mtu = be_change_mtu, - .ndo_validate_addr = eth_validate_addr, - .ndo_vlan_rx_register = be_vlan_register, - .ndo_vlan_rx_add_vid = be_vlan_add_vid, - .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, -}; - -static void be_netdev_init(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | - NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_TSO6; - - netdev->flags |= IFF_MULTICAST; - - BE_SET_NETDEV_OPS(netdev, &be_netdev_ops); - - SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); - - be_lro_init(adapter, netdev); - - netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx, - BE_NAPI_WEIGHT); - netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx, - BE_NAPI_WEIGHT); - - netif_carrier_off(netdev); - netif_stop_queue(netdev); -} - -static void be_unmap_pci_bars(struct be_adapter *adapter) -{ - struct be_ctrl_info *ctrl = &adapter->ctrl; - if (ctrl->csr) - iounmap(ctrl->csr); - if (ctrl->db) - iounmap(ctrl->db); - if (ctrl->pcicfg) - iounmap(ctrl->pcicfg); -} - -static int be_map_pci_bars(struct be_adapter *adapter) -{ - u8 __iomem *addr; - - addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), - pci_resource_len(adapter->pdev, 2)); - if (addr == NULL) - return -ENOMEM; - adapter->ctrl.csr = addr; - - addr = ioremap_nocache(pci_resource_start(adapter->pdev, 4), - 128 * 1024); - if (addr == NULL) - goto pci_map_err; - adapter->ctrl.db = addr; - - addr = ioremap_nocache(pci_resource_start(adapter->pdev, 1), - pci_resource_len(adapter->pdev, 1)); - if (addr == NULL) - goto pci_map_err; - adapter->ctrl.pcicfg = addr; - - return 0; -pci_map_err: - be_unmap_pci_bars(adapter); - return -ENOMEM; -} - - -static void be_ctrl_cleanup(struct be_adapter *adapter) -{ - struct be_dma_mem *mem = &adapter->ctrl.mbox_mem_alloced; - - be_unmap_pci_bars(adapter); - - if (mem->va) - pci_free_consistent(adapter->pdev, mem->size, - mem->va, mem->dma); -} - -/* Initialize the mbox required to send cmds to BE */ -static int be_ctrl_init(struct be_adapter *adapter) -{ - struct be_ctrl_info *ctrl = &adapter->ctrl; - struct be_dma_mem *mbox_mem_alloc = &ctrl->mbox_mem_alloced; - struct be_dma_mem *mbox_mem_align = &ctrl->mbox_mem; - int status; - u32 val; - - status = be_map_pci_bars(adapter); - if (status) - return status; - - mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; - mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev, - mbox_mem_alloc->size, &mbox_mem_alloc->dma); - if (!mbox_mem_alloc->va) { - be_unmap_pci_bars(adapter); - return -1; - } - mbox_mem_align->size = sizeof(struct be_mcc_mailbox); - mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); - mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); - memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); - spin_lock_init(&ctrl->cmd_lock); - - val = ioread32(ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET); - ctrl->pci_func = (val >> MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT) & - MEMBAR_CTRL_INT_CTRL_PFUNC_MASK; - return 0; -} - -static void be_stats_cleanup(struct be_adapter *adapter) -{ - struct be_stats_obj *stats = &adapter->stats; - struct be_dma_mem *cmd = &stats->cmd; - - if (cmd->va) - pci_free_consistent(adapter->pdev, cmd->size, - cmd->va, cmd->dma); -} - -static int be_stats_init(struct be_adapter *adapter) -{ - struct be_stats_obj *stats = &adapter->stats; - struct be_dma_mem *cmd = &stats->cmd; - - cmd->size = sizeof(struct be_cmd_req_get_stats); - cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma); - if (cmd->va == NULL) - return -1; - return 0; -} - -static void __devexit be_remove(struct pci_dev *pdev) -{ - struct be_adapter *adapter = pci_get_drvdata(pdev); - if (!adapter) - return; - - unregister_netdev(adapter->netdev); - - be_stats_cleanup(adapter); - - be_ctrl_cleanup(adapter); - - if (adapter->msix_enabled) { - pci_disable_msix(adapter->pdev); - adapter->msix_enabled = false; - } - - pci_set_drvdata(pdev, NULL); - pci_release_regions(pdev); - pci_disable_device(pdev); - - free_netdev(adapter->netdev); -} - -static int be_hw_up(struct be_adapter *adapter) -{ - struct be_ctrl_info *ctrl = &adapter->ctrl; - int status; - - status = be_cmd_POST(ctrl); - if (status) - return status; - - status = be_cmd_get_fw_ver(ctrl, adapter->fw_ver); - if (status) - return status; - - status = be_cmd_query_fw_cfg(ctrl, &adapter->port_num); - return status; -} - -static int __devinit be_probe(struct pci_dev *pdev, - const struct pci_device_id *pdev_id) -{ - int status = 0; - struct be_adapter *adapter; - struct net_device *netdev; - struct be_ctrl_info *ctrl; - u8 mac[ETH_ALEN]; - - status = pci_enable_device(pdev); - if (status) - goto do_none; - - status = pci_request_regions(pdev, DRV_NAME); - if (status) - goto disable_dev; - pci_set_master(pdev); - - netdev = alloc_etherdev(sizeof(struct be_adapter)); - if (netdev == NULL) { - status = -ENOMEM; - goto rel_reg; - } - adapter = netdev_priv(netdev); - adapter->pdev = pdev; - pci_set_drvdata(pdev, adapter); - adapter->netdev = netdev; - - be_msix_enable(adapter); - - status = pci_set_dma_mask(pdev, DMA_64BIT_MASK); - if (!status) { - netdev->features |= NETIF_F_HIGHDMA; - } else { - status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (status) { - dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); - goto free_netdev; - } - } - - ctrl = &adapter->ctrl; - status = be_ctrl_init(adapter); - if (status) - goto free_netdev; - - status = be_stats_init(adapter); - if (status) - goto ctrl_clean; - - status = be_hw_up(adapter); - if (status) - goto stats_clean; - - status = be_cmd_mac_addr_query(ctrl, mac, MAC_ADDRESS_TYPE_NETWORK, - true /* permanent */, 0); - if (status) - goto stats_clean; - memcpy(netdev->dev_addr, mac, ETH_ALEN); - - INIT_DELAYED_WORK(&adapter->work, be_worker); - be_netdev_init(netdev); - SET_NETDEV_DEV(netdev, &adapter->pdev->dev); - - status = register_netdev(netdev); - if (status != 0) - goto stats_clean; - - dev_info(&pdev->dev, BE_NAME " port %d\n", adapter->port_num); - return 0; - -stats_clean: - be_stats_cleanup(adapter); -ctrl_clean: - be_ctrl_cleanup(adapter); -free_netdev: - free_netdev(adapter->netdev); -rel_reg: - pci_release_regions(pdev); -disable_dev: - pci_disable_device(pdev); -do_none: - dev_warn(&pdev->dev, BE_NAME " initialization failed\n"); - return status; -} - -static int be_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct be_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; - - netif_device_detach(netdev); - if (netif_running(netdev)) { - rtnl_lock(); - be_close(netdev); - rtnl_unlock(); - } - - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int be_resume(struct pci_dev *pdev) -{ - int status = 0; - struct be_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; - - netif_device_detach(netdev); - - status = pci_enable_device(pdev); - if (status) - return status; - - pci_set_power_state(pdev, 0); - pci_restore_state(pdev); - - if (netif_running(netdev)) { - rtnl_lock(); - be_open(netdev); - rtnl_unlock(); - } - netif_device_attach(netdev); - return 0; -} - -static struct pci_driver be_driver = { - .name = DRV_NAME, - .id_table = be_dev_ids, - .probe = be_probe, - .remove = be_remove, - .suspend = be_suspend, - .resume = be_resume -}; - -static int __init be_init_module(void) -{ - if (rx_frag_size != 8192 && rx_frag_size != 4096 - && rx_frag_size != 2048) { - printk(KERN_WARNING DRV_NAME - " : Module param rx_frag_size must be 2048/4096/8192." - " Using 2048\n"); - rx_frag_size = 2048; - } - /* Ensure rx_frag_size is aligned to chache line */ - if (SKB_DATA_ALIGN(rx_frag_size) != rx_frag_size) { - printk(KERN_WARNING DRV_NAME - " : Bad module param rx_frag_size. Using 2048\n"); - rx_frag_size = 2048; - } - - return pci_register_driver(&be_driver); -} -module_init(be_init_module); - -static void __exit be_exit_module(void) -{ - pci_unregister_driver(&be_driver); -} -module_exit(be_exit_module); diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 6b6530ffdf19..6500b7c4739f 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -57,8 +57,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.9.3" -#define DRV_MODULE_RELDATE "March 17, 2009" +#define DRV_MODULE_VERSION "1.9.2" +#define DRV_MODULE_RELDATE "Feb 11, 2009" #define RUN_AT(x) (jiffies + (x)) @@ -5843,6 +5843,9 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { msix_ent[i].entry = i; msix_ent[i].vector = 0; + + snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i); + bp->irq_tbl[i].handler = bnx2_msi_1shot; } rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC); @@ -5851,11 +5854,8 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) bp->irq_nvecs = msix_vecs; bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI; - for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { + for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) bp->irq_tbl[i].vector = msix_ent[i].vector; - snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i); - bp->irq_tbl[i].handler = bnx2_msi_1shot; - } } static void diff --git a/trunk/drivers/net/bnx2x.h b/trunk/drivers/net/bnx2x.h index 3cf2b92eef3b..15a5cf0f676b 100644 --- a/trunk/drivers/net/bnx2x.h +++ b/trunk/drivers/net/bnx2x.h @@ -152,7 +152,7 @@ struct sw_rx_page { #define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT) #define SGE_PAGE_SIZE PAGE_SIZE #define SGE_PAGE_SHIFT PAGE_SHIFT -#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))addr) +#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN(addr) #define BCM_RX_ETH_PAYLOAD_ALIGN 64 diff --git a/trunk/drivers/net/bnx2x_init.h b/trunk/drivers/net/bnx2x_init.h index 3b0c2499ef17..a6c0b3abba29 100644 --- a/trunk/drivers/net/bnx2x_init.h +++ b/trunk/drivers/net/bnx2x_init.h @@ -150,6 +150,7 @@ static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) { +#ifdef USE_DMAE int offset = 0; if (bp->dmae_ready) { @@ -163,6 +164,9 @@ static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) addr + offset, len); } else bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len); +#else + bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len); +#endif } static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) diff --git a/trunk/drivers/net/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c index 2e346a5e98cf..d3e7775a9ccf 100644 --- a/trunk/drivers/net/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -57,7 +57,7 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "1.45.27" +#define DRV_MODULE_VERSION "1.45.26" #define DRV_MODULE_RELDATE "2009/01/26" #define BNX2X_BC_VER 0x040200 @@ -4035,10 +4035,10 @@ static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id) { int port = BP_PORT(bp); - bnx2x_init_fill(bp, USTORM_INTMEM_ADDR + + bnx2x_init_fill(bp, BAR_USTRORM_INTMEM + USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0, sizeof(struct ustorm_status_block)/4); - bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR + + bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM + CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0, sizeof(struct cstorm_status_block)/4); } @@ -4092,18 +4092,18 @@ static void bnx2x_zero_def_sb(struct bnx2x *bp) { int func = BP_FUNC(bp); - bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct tstorm_def_status_block)/4); - bnx2x_init_fill(bp, USTORM_INTMEM_ADDR + + bnx2x_init_fill(bp, BAR_USTRORM_INTMEM + USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, sizeof(struct ustorm_def_status_block)/4); - bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR + + bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM + CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, sizeof(struct cstorm_def_status_block)/4); - bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR + + bnx2x_init_fill(bp, BAR_XSTRORM_INTMEM + XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, sizeof(struct xstorm_def_status_block)/4); + bnx2x_init_fill(bp, BAR_TSTRORM_INTMEM + + TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, + sizeof(struct tstorm_def_status_block)/4); } static void bnx2x_init_def_sb(struct bnx2x *bp, @@ -4518,8 +4518,7 @@ static void bnx2x_init_context(struct bnx2x *bp) (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA | USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING); context->ustorm_st_context.common.sge_buff_size = - (u16)min((u32)SGE_PAGE_SIZE*PAGES_PER_SGE, - (u32)0xffff); + (u16)(BCM_PAGE_SIZE*PAGES_PER_SGE); context->ustorm_st_context.common.sge_page_base_hi = U64_HI(fp->rx_sge_mapping); context->ustorm_st_context.common.sge_page_base_lo = diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 3d76686dceca..e0578fe8c0db 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -3537,26 +3537,11 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave } break; case NETDEV_CHANGE: - if (bond->params.mode == BOND_MODE_8023AD || bond_is_lb(bond)) { - struct slave *slave; - - slave = bond_get_slave_by_dev(bond, slave_dev); - if (slave) { - u16 old_speed = slave->speed; - u16 old_duplex = slave->duplex; - - bond_update_speed_duplex(slave); - - if (bond_is_lb(bond)) - break; - - if (old_speed != slave->speed) - bond_3ad_adapter_speed_changed(slave); - if (old_duplex != slave->duplex) - bond_3ad_adapter_duplex_changed(slave); - } - } - + /* + * TODO: is this what we get if somebody + * sets up a hierarchical bond, then rmmod's + * one of the slave bonding devices? + */ break; case NETDEV_DOWN: /* diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index 254ec62b5f58..bcf92917bbf3 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -930,15 +930,13 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id) struct net_device *dev = dev_id; board_info_t *db = netdev_priv(dev); int int_status; - unsigned long flags; u8 reg_save; dm9000_dbg(db, 3, "entering %s\n", __func__); /* A real interrupt coming */ - /* holders of db->lock must always block IRQs */ - spin_lock_irqsave(&db->lock, flags); + spin_lock(&db->lock); /* Save previous register address */ reg_save = readb(db->io_addr); @@ -974,7 +972,7 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id) /* Restore previous register address */ writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); + spin_unlock(&db->lock); return IRQ_HANDLED; } diff --git a/trunk/drivers/net/dnet.c b/trunk/drivers/net/dnet.c deleted file mode 100644 index 1b4063222a82..000000000000 --- a/trunk/drivers/net/dnet.c +++ /dev/null @@ -1,994 +0,0 @@ -/* - * Dave DNET Ethernet Controller driver - * - * Copyright (C) 2008 Dave S.r.l. - * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dnet.h" - -#undef DEBUG - -/* function for reading internal MAC register */ -u16 dnet_readw_mac(struct dnet *bp, u16 reg) -{ - u16 data_read; - - /* issue a read */ - dnet_writel(bp, reg, MACREG_ADDR); - - /* since a read/write op to the MAC is very slow, - * we must wait before reading the data */ - ndelay(500); - - /* read data read from the MAC register */ - data_read = dnet_readl(bp, MACREG_DATA); - - /* all done */ - return data_read; -} - -/* function for writing internal MAC register */ -void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val) -{ - /* load data to write */ - dnet_writel(bp, val, MACREG_DATA); - - /* issue a write */ - dnet_writel(bp, reg | DNET_INTERNAL_WRITE, MACREG_ADDR); - - /* since a read/write op to the MAC is very slow, - * we must wait before exiting */ - ndelay(500); -} - -static void __dnet_set_hwaddr(struct dnet *bp) -{ - u16 tmp; - - tmp = cpu_to_be16(*((u16 *) bp->dev->dev_addr)); - dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG, tmp); - tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 2))); - dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG, tmp); - tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 4))); - dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG, tmp); -} - -static void __devinit dnet_get_hwaddr(struct dnet *bp) -{ - u16 tmp; - u8 addr[6]; - - /* - * from MAC docs: - * "Note that the MAC address is stored in the registers in Hexadecimal - * form. For example, to set the MAC Address to: AC-DE-48-00-00-80 - * would require writing 0xAC (octet 0) to address 0x0B (high byte of - * Mac_addr[15:0]), 0xDE (octet 1) to address 0x0A (Low byte of - * Mac_addr[15:0]), 0x48 (octet 2) to address 0x0D (high byte of - * Mac_addr[15:0]), 0x00 (octet 3) to address 0x0C (Low byte of - * Mac_addr[15:0]), 0x00 (octet 4) to address 0x0F (high byte of - * Mac_addr[15:0]), and 0x80 (octet 5) to address * 0x0E (Low byte of - * Mac_addr[15:0]). - */ - tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG); - *((u16 *) addr) = be16_to_cpu(tmp); - tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG); - *((u16 *) (addr + 2)) = be16_to_cpu(tmp); - tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG); - *((u16 *) (addr + 4)) = be16_to_cpu(tmp); - - if (is_valid_ether_addr(addr)) - memcpy(bp->dev->dev_addr, addr, sizeof(addr)); -} - -static int dnet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) -{ - struct dnet *bp = bus->priv; - u16 value; - - while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG) - & DNET_INTERNAL_GMII_MNG_CMD_FIN)) - cpu_relax(); - - /* only 5 bits allowed for phy-addr and reg_offset */ - mii_id &= 0x1f; - regnum &= 0x1f; - - /* prepare reg_value for a read */ - value = (mii_id << 8); - value |= regnum; - - /* write control word */ - dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG, value); - - /* wait for end of transfer */ - while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG) - & DNET_INTERNAL_GMII_MNG_CMD_FIN)) - cpu_relax(); - - value = dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_DAT_REG); - - pr_debug("mdio_read %02x:%02x <- %04x\n", mii_id, regnum, value); - - return value; -} - -static int dnet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, - u16 value) -{ - struct dnet *bp = bus->priv; - u16 tmp; - - pr_debug("mdio_write %02x:%02x <- %04x\n", mii_id, regnum, value); - - while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG) - & DNET_INTERNAL_GMII_MNG_CMD_FIN)) - cpu_relax(); - - /* prepare for a write operation */ - tmp = (1 << 13); - - /* only 5 bits allowed for phy-addr and reg_offset */ - mii_id &= 0x1f; - regnum &= 0x1f; - - /* only 16 bits on data */ - value &= 0xffff; - - /* prepare reg_value for a write */ - tmp |= (mii_id << 8); - tmp |= regnum; - - /* write data to write first */ - dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_DAT_REG, value); - - /* write control word */ - dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG, tmp); - - while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG) - & DNET_INTERNAL_GMII_MNG_CMD_FIN)) - cpu_relax(); - - return 0; -} - -static int dnet_mdio_reset(struct mii_bus *bus) -{ - return 0; -} - -static void dnet_handle_link_change(struct net_device *dev) -{ - struct dnet *bp = netdev_priv(dev); - struct phy_device *phydev = bp->phy_dev; - unsigned long flags; - u32 mode_reg, ctl_reg; - - int status_change = 0; - - spin_lock_irqsave(&bp->lock, flags); - - mode_reg = dnet_readw_mac(bp, DNET_INTERNAL_MODE_REG); - ctl_reg = dnet_readw_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG); - - if (phydev->link) { - if (bp->duplex != phydev->duplex) { - if (phydev->duplex) - ctl_reg &= - ~(DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP); - else - ctl_reg |= - DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP; - - bp->duplex = phydev->duplex; - status_change = 1; - } - - if (bp->speed != phydev->speed) { - status_change = 1; - switch (phydev->speed) { - case 1000: - mode_reg |= DNET_INTERNAL_MODE_GBITEN; - break; - case 100: - case 10: - mode_reg &= ~DNET_INTERNAL_MODE_GBITEN; - break; - default: - printk(KERN_WARNING - "%s: Ack! Speed (%d) is not " - "10/100/1000!\n", dev->name, - phydev->speed); - break; - } - bp->speed = phydev->speed; - } - } - - if (phydev->link != bp->link) { - if (phydev->link) { - mode_reg |= - (DNET_INTERNAL_MODE_RXEN | DNET_INTERNAL_MODE_TXEN); - } else { - mode_reg &= - ~(DNET_INTERNAL_MODE_RXEN | - DNET_INTERNAL_MODE_TXEN); - bp->speed = 0; - bp->duplex = -1; - } - bp->link = phydev->link; - - status_change = 1; - } - - if (status_change) { - dnet_writew_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG, ctl_reg); - dnet_writew_mac(bp, DNET_INTERNAL_MODE_REG, mode_reg); - } - - spin_unlock_irqrestore(&bp->lock, flags); - - if (status_change) { - if (phydev->link) - printk(KERN_INFO "%s: link up (%d/%s)\n", - dev->name, phydev->speed, - DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); - else - printk(KERN_INFO "%s: link down\n", dev->name); - } -} - -static int dnet_mii_probe(struct net_device *dev) -{ - struct dnet *bp = netdev_priv(dev); - struct phy_device *phydev = NULL; - int phy_addr; - - /* find the first phy */ - for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { - if (bp->mii_bus->phy_map[phy_addr]) { - phydev = bp->mii_bus->phy_map[phy_addr]; - break; - } - } - - if (!phydev) { - printk(KERN_ERR "%s: no PHY found\n", dev->name); - return -ENODEV; - } - - /* TODO : add pin_irq */ - - /* attach the mac to the phy */ - if (bp->capabilities & DNET_HAS_RMII) { - phydev = phy_connect(dev, dev_name(&phydev->dev), - &dnet_handle_link_change, 0, - PHY_INTERFACE_MODE_RMII); - } else { - phydev = phy_connect(dev, dev_name(&phydev->dev), - &dnet_handle_link_change, 0, - PHY_INTERFACE_MODE_MII); - } - - if (IS_ERR(phydev)) { - printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(phydev); - } - - /* mask with MAC supported features */ - if (bp->capabilities & DNET_HAS_GIGABIT) - phydev->supported &= PHY_GBIT_FEATURES; - else - phydev->supported &= PHY_BASIC_FEATURES; - - phydev->supported |= SUPPORTED_Asym_Pause | SUPPORTED_Pause; - - phydev->advertising = phydev->supported; - - bp->link = 0; - bp->speed = 0; - bp->duplex = -1; - bp->phy_dev = phydev; - - return 0; -} - -static int dnet_mii_init(struct dnet *bp) -{ - int err, i; - - bp->mii_bus = mdiobus_alloc(); - if (bp->mii_bus == NULL) - return -ENOMEM; - - bp->mii_bus->name = "dnet_mii_bus"; - bp->mii_bus->read = &dnet_mdio_read; - bp->mii_bus->write = &dnet_mdio_write; - bp->mii_bus->reset = &dnet_mdio_reset; - - snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); - - bp->mii_bus->priv = bp; - - bp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (!bp->mii_bus->irq) { - err = -ENOMEM; - goto err_out; - } - - for (i = 0; i < PHY_MAX_ADDR; i++) - bp->mii_bus->irq[i] = PHY_POLL; - - platform_set_drvdata(bp->dev, bp->mii_bus); - - if (mdiobus_register(bp->mii_bus)) { - err = -ENXIO; - goto err_out_free_mdio_irq; - } - - if (dnet_mii_probe(bp->dev) != 0) { - err = -ENXIO; - goto err_out_unregister_bus; - } - - return 0; - -err_out_unregister_bus: - mdiobus_unregister(bp->mii_bus); -err_out_free_mdio_irq: - kfree(bp->mii_bus->irq); -err_out: - mdiobus_free(bp->mii_bus); - return err; -} - -/* For Neptune board: LINK1000 as Link LED and TX as activity LED */ -int dnet_phy_marvell_fixup(struct phy_device *phydev) -{ - return phy_write(phydev, 0x18, 0x4148); -} - -static void dnet_update_stats(struct dnet *bp) -{ - u32 __iomem *reg = bp->regs + DNET_RX_PKT_IGNR_CNT; - u32 *p = &bp->hw_stats.rx_pkt_ignr; - u32 *end = &bp->hw_stats.rx_byte + 1; - - WARN_ON((unsigned long)(end - p - 1) != - (DNET_RX_BYTE_CNT - DNET_RX_PKT_IGNR_CNT) / 4); - - for (; p < end; p++, reg++) - *p += readl(reg); - - reg = bp->regs + DNET_TX_UNICAST_CNT; - p = &bp->hw_stats.tx_unicast; - end = &bp->hw_stats.tx_byte + 1; - - WARN_ON((unsigned long)(end - p - 1) != - (DNET_TX_BYTE_CNT - DNET_TX_UNICAST_CNT) / 4); - - for (; p < end; p++, reg++) - *p += readl(reg); -} - -static int dnet_poll(struct napi_struct *napi, int budget) -{ - struct dnet *bp = container_of(napi, struct dnet, napi); - struct net_device *dev = bp->dev; - int npackets = 0; - unsigned int pkt_len; - struct sk_buff *skb; - unsigned int *data_ptr; - u32 int_enable; - u32 cmd_word; - int i; - - while (npackets < budget) { - /* - * break out of while loop if there are no more - * packets waiting - */ - if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) { - napi_complete(napi); - int_enable = dnet_readl(bp, INTR_ENB); - int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; - dnet_writel(bp, int_enable, INTR_ENB); - return 0; - } - - cmd_word = dnet_readl(bp, RX_LEN_FIFO); - pkt_len = cmd_word & 0xFFFF; - - if (cmd_word & 0xDF180000) - printk(KERN_ERR "%s packet receive error %x\n", - __func__, cmd_word); - - skb = dev_alloc_skb(pkt_len + 5); - if (skb != NULL) { - /* Align IP on 16 byte boundaries */ - skb_reserve(skb, 2); - /* - * 'skb_put()' points to the start of sk_buff - * data area. - */ - data_ptr = (unsigned int *)skb_put(skb, pkt_len); - for (i = 0; i < (pkt_len + 3) >> 2; i++) - *data_ptr++ = dnet_readl(bp, RX_DATA_FIFO); - skb->protocol = eth_type_trans(skb, dev); - netif_receive_skb(skb); - npackets++; - } else - printk(KERN_NOTICE - "%s: No memory to allocate a sk_buff of " - "size %u.\n", dev->name, pkt_len); - } - - budget -= npackets; - - if (npackets < budget) { - /* We processed all packets available. Tell NAPI it can - * stop polling then re-enable rx interrupts */ - napi_complete(napi); - int_enable = dnet_readl(bp, INTR_ENB); - int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; - dnet_writel(bp, int_enable, INTR_ENB); - return 0; - } - - /* There are still packets waiting */ - return 1; -} - -static irqreturn_t dnet_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct dnet *bp = netdev_priv(dev); - u32 int_src, int_enable, int_current; - unsigned long flags; - unsigned int handled = 0; - - spin_lock_irqsave(&bp->lock, flags); - - /* read and clear the DNET irq (clear on read) */ - int_src = dnet_readl(bp, INTR_SRC); - int_enable = dnet_readl(bp, INTR_ENB); - int_current = int_src & int_enable; - - /* restart the queue if we had stopped it for TX fifo almost full */ - if (int_current & DNET_INTR_SRC_TX_FIFOAE) { - int_enable = dnet_readl(bp, INTR_ENB); - int_enable &= ~DNET_INTR_ENB_TX_FIFOAE; - dnet_writel(bp, int_enable, INTR_ENB); - netif_wake_queue(dev); - handled = 1; - } - - /* RX FIFO error checking */ - if (int_current & - (DNET_INTR_SRC_RX_CMDFIFOFF | DNET_INTR_SRC_RX_DATAFIFOFF)) { - printk(KERN_ERR "%s: RX fifo error %x, irq %x\n", __func__, - dnet_readl(bp, RX_STATUS), int_current); - /* we can only flush the RX FIFOs */ - dnet_writel(bp, DNET_SYS_CTL_RXFIFOFLUSH, SYS_CTL); - ndelay(500); - dnet_writel(bp, 0, SYS_CTL); - handled = 1; - } - - /* TX FIFO error checking */ - if (int_current & - (DNET_INTR_SRC_TX_FIFOFULL | DNET_INTR_SRC_TX_DISCFRM)) { - printk(KERN_ERR "%s: TX fifo error %x, irq %x\n", __func__, - dnet_readl(bp, TX_STATUS), int_current); - /* we can only flush the TX FIFOs */ - dnet_writel(bp, DNET_SYS_CTL_TXFIFOFLUSH, SYS_CTL); - ndelay(500); - dnet_writel(bp, 0, SYS_CTL); - handled = 1; - } - - if (int_current & DNET_INTR_SRC_RX_CMDFIFOAF) { - if (napi_schedule_prep(&bp->napi)) { - /* - * There's no point taking any more interrupts - * until we have processed the buffers - */ - /* Disable Rx interrupts and schedule NAPI poll */ - int_enable = dnet_readl(bp, INTR_ENB); - int_enable &= ~DNET_INTR_SRC_RX_CMDFIFOAF; - dnet_writel(bp, int_enable, INTR_ENB); - __napi_schedule(&bp->napi); - } - handled = 1; - } - - if (!handled) - pr_debug("%s: irq %x remains\n", __func__, int_current); - - spin_unlock_irqrestore(&bp->lock, flags); - - return IRQ_RETVAL(handled); -} - -#ifdef DEBUG -static inline void dnet_print_skb(struct sk_buff *skb) -{ - int k; - printk(KERN_DEBUG PFX "data:"); - for (k = 0; k < skb->len; k++) - printk(" %02x", (unsigned int)skb->data[k]); - printk("\n"); -} -#else -#define dnet_print_skb(skb) do {} while (0) -#endif - -static int dnet_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - - struct dnet *bp = netdev_priv(dev); - u32 tx_status, irq_enable; - unsigned int len, i, tx_cmd, wrsz; - unsigned long flags; - unsigned int *bufp; - - tx_status = dnet_readl(bp, TX_STATUS); - - pr_debug("start_xmit: len %u head %p data %p\n", - skb->len, skb->head, skb->data); - dnet_print_skb(skb); - - /* frame size (words) */ - len = (skb->len + 3) >> 2; - - spin_lock_irqsave(&bp->lock, flags); - - tx_status = dnet_readl(bp, TX_STATUS); - - bufp = (unsigned int *)(((unsigned long) skb->data) & ~0x3UL); - wrsz = (u32) skb->len + 3; - wrsz += ((unsigned long) skb->data) & 0x3; - wrsz >>= 2; - tx_cmd = ((((unsigned long)(skb->data)) & 0x03) << 16) | (u32) skb->len; - - /* check if there is enough room for the current frame */ - if (wrsz < (DNET_FIFO_SIZE - dnet_readl(bp, TX_FIFO_WCNT))) { - for (i = 0; i < wrsz; i++) - dnet_writel(bp, *bufp++, TX_DATA_FIFO); - - /* - * inform MAC that a packet's written and ready to be - * shipped out - */ - dnet_writel(bp, tx_cmd, TX_LEN_FIFO); - } - - if (dnet_readl(bp, TX_FIFO_WCNT) > DNET_FIFO_TX_DATA_AF_TH) { - netif_stop_queue(dev); - tx_status = dnet_readl(bp, INTR_SRC); - irq_enable = dnet_readl(bp, INTR_ENB); - irq_enable |= DNET_INTR_ENB_TX_FIFOAE; - dnet_writel(bp, irq_enable, INTR_ENB); - } - - /* free the buffer */ - dev_kfree_skb(skb); - - spin_unlock_irqrestore(&bp->lock, flags); - - dev->trans_start = jiffies; - - return 0; -} - -static void dnet_reset_hw(struct dnet *bp) -{ - /* put ts_mac in IDLE state i.e. disable rx/tx */ - dnet_writew_mac(bp, DNET_INTERNAL_MODE_REG, DNET_INTERNAL_MODE_FCEN); - - /* - * RX FIFO almost full threshold: only cmd FIFO almost full is - * implemented for RX side - */ - dnet_writel(bp, DNET_FIFO_RX_CMD_AF_TH, RX_FIFO_TH); - /* - * TX FIFO almost empty threshold: only data FIFO almost empty - * is implemented for TX side - */ - dnet_writel(bp, DNET_FIFO_TX_DATA_AE_TH, TX_FIFO_TH); - - /* flush rx/tx fifos */ - dnet_writel(bp, DNET_SYS_CTL_RXFIFOFLUSH | DNET_SYS_CTL_TXFIFOFLUSH, - SYS_CTL); - msleep(1); - dnet_writel(bp, 0, SYS_CTL); -} - -static void dnet_init_hw(struct dnet *bp) -{ - u32 config; - - dnet_reset_hw(bp); - __dnet_set_hwaddr(bp); - - config = dnet_readw_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG); - - if (bp->dev->flags & IFF_PROMISC) - /* Copy All Frames */ - config |= DNET_INTERNAL_RXTX_CONTROL_ENPROMISC; - if (!(bp->dev->flags & IFF_BROADCAST)) - /* No BroadCast */ - config |= DNET_INTERNAL_RXTX_CONTROL_RXMULTICAST; - - config |= DNET_INTERNAL_RXTX_CONTROL_RXPAUSE | - DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST | - DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL | - DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS; - - dnet_writew_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG, config); - - /* clear irq before enabling them */ - config = dnet_readl(bp, INTR_SRC); - - /* enable RX/TX interrupt, recv packet ready interrupt */ - dnet_writel(bp, DNET_INTR_ENB_GLOBAL_ENABLE | DNET_INTR_ENB_RX_SUMMARY | - DNET_INTR_ENB_TX_SUMMARY | DNET_INTR_ENB_RX_FIFOERR | - DNET_INTR_ENB_RX_ERROR | DNET_INTR_ENB_RX_FIFOFULL | - DNET_INTR_ENB_TX_FIFOFULL | DNET_INTR_ENB_TX_DISCFRM | - DNET_INTR_ENB_RX_PKTRDY, INTR_ENB); -} - -static int dnet_open(struct net_device *dev) -{ - struct dnet *bp = netdev_priv(dev); - - /* if the phy is not yet register, retry later */ - if (!bp->phy_dev) - return -EAGAIN; - - if (!is_valid_ether_addr(dev->dev_addr)) - return -EADDRNOTAVAIL; - - napi_enable(&bp->napi); - dnet_init_hw(bp); - - phy_start_aneg(bp->phy_dev); - - /* schedule a link state check */ - phy_start(bp->phy_dev); - - netif_start_queue(dev); - - return 0; -} - -static int dnet_close(struct net_device *dev) -{ - struct dnet *bp = netdev_priv(dev); - - netif_stop_queue(dev); - napi_disable(&bp->napi); - - if (bp->phy_dev) - phy_stop(bp->phy_dev); - - dnet_reset_hw(bp); - netif_carrier_off(dev); - - return 0; -} - -static inline void dnet_print_pretty_hwstats(struct dnet_stats *hwstat) -{ - pr_debug("%s\n", __func__); - pr_debug("----------------------------- RX statistics " - "-------------------------------\n"); - pr_debug("RX_PKT_IGNR_CNT %-8x\n", hwstat->rx_pkt_ignr); - pr_debug("RX_LEN_CHK_ERR_CNT %-8x\n", hwstat->rx_len_chk_err); - pr_debug("RX_LNG_FRM_CNT %-8x\n", hwstat->rx_lng_frm); - pr_debug("RX_SHRT_FRM_CNT %-8x\n", hwstat->rx_shrt_frm); - pr_debug("RX_IPG_VIOL_CNT %-8x\n", hwstat->rx_ipg_viol); - pr_debug("RX_CRC_ERR_CNT %-8x\n", hwstat->rx_crc_err); - pr_debug("RX_OK_PKT_CNT %-8x\n", hwstat->rx_ok_pkt); - pr_debug("RX_CTL_FRM_CNT %-8x\n", hwstat->rx_ctl_frm); - pr_debug("RX_PAUSE_FRM_CNT %-8x\n", hwstat->rx_pause_frm); - pr_debug("RX_MULTICAST_CNT %-8x\n", hwstat->rx_multicast); - pr_debug("RX_BROADCAST_CNT %-8x\n", hwstat->rx_broadcast); - pr_debug("RX_VLAN_TAG_CNT %-8x\n", hwstat->rx_vlan_tag); - pr_debug("RX_PRE_SHRINK_CNT %-8x\n", hwstat->rx_pre_shrink); - pr_debug("RX_DRIB_NIB_CNT %-8x\n", hwstat->rx_drib_nib); - pr_debug("RX_UNSUP_OPCD_CNT %-8x\n", hwstat->rx_unsup_opcd); - pr_debug("RX_BYTE_CNT %-8x\n", hwstat->rx_byte); - pr_debug("----------------------------- TX statistics " - "-------------------------------\n"); - pr_debug("TX_UNICAST_CNT %-8x\n", hwstat->tx_unicast); - pr_debug("TX_PAUSE_FRM_CNT %-8x\n", hwstat->tx_pause_frm); - pr_debug("TX_MULTICAST_CNT %-8x\n", hwstat->tx_multicast); - pr_debug("TX_BRDCAST_CNT %-8x\n", hwstat->tx_brdcast); - pr_debug("TX_VLAN_TAG_CNT %-8x\n", hwstat->tx_vlan_tag); - pr_debug("TX_BAD_FCS_CNT %-8x\n", hwstat->tx_bad_fcs); - pr_debug("TX_JUMBO_CNT %-8x\n", hwstat->tx_jumbo); - pr_debug("TX_BYTE_CNT %-8x\n", hwstat->tx_byte); -} - -static struct net_device_stats *dnet_get_stats(struct net_device *dev) -{ - - struct dnet *bp = netdev_priv(dev); - struct net_device_stats *nstat = &dev->stats; - struct dnet_stats *hwstat = &bp->hw_stats; - - /* read stats from hardware */ - dnet_update_stats(bp); - - /* Convert HW stats into netdevice stats */ - nstat->rx_errors = (hwstat->rx_len_chk_err + - hwstat->rx_lng_frm + hwstat->rx_shrt_frm + - /* ignore IGP violation error - hwstat->rx_ipg_viol + */ - hwstat->rx_crc_err + - hwstat->rx_pre_shrink + - hwstat->rx_drib_nib + hwstat->rx_unsup_opcd); - nstat->tx_errors = hwstat->tx_bad_fcs; - nstat->rx_length_errors = (hwstat->rx_len_chk_err + - hwstat->rx_lng_frm + - hwstat->rx_shrt_frm + hwstat->rx_pre_shrink); - nstat->rx_crc_errors = hwstat->rx_crc_err; - nstat->rx_frame_errors = hwstat->rx_pre_shrink + hwstat->rx_drib_nib; - nstat->rx_packets = hwstat->rx_ok_pkt; - nstat->tx_packets = (hwstat->tx_unicast + - hwstat->tx_multicast + hwstat->tx_brdcast); - nstat->rx_bytes = hwstat->rx_byte; - nstat->tx_bytes = hwstat->tx_byte; - nstat->multicast = hwstat->rx_multicast; - nstat->rx_missed_errors = hwstat->rx_pkt_ignr; - - dnet_print_pretty_hwstats(hwstat); - - return nstat; -} - -static int dnet_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct dnet *bp = netdev_priv(dev); - struct phy_device *phydev = bp->phy_dev; - - if (!phydev) - return -ENODEV; - - return phy_ethtool_gset(phydev, cmd); -} - -static int dnet_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct dnet *bp = netdev_priv(dev); - struct phy_device *phydev = bp->phy_dev; - - if (!phydev) - return -ENODEV; - - return phy_ethtool_sset(phydev, cmd); -} - -static int dnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct dnet *bp = netdev_priv(dev); - struct phy_device *phydev = bp->phy_dev; - - if (!netif_running(dev)) - return -EINVAL; - - if (!phydev) - return -ENODEV; - - return phy_mii_ioctl(phydev, if_mii(rq), cmd); -} - -static void dnet_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, DRV_NAME); - strcpy(info->version, DRV_VERSION); - strcpy(info->bus_info, "0"); -} - -static const struct ethtool_ops dnet_ethtool_ops = { - .get_settings = dnet_get_settings, - .set_settings = dnet_set_settings, - .get_drvinfo = dnet_get_drvinfo, - .get_link = ethtool_op_get_link, -}; - -static const struct net_device_ops dnet_netdev_ops = { - .ndo_open = dnet_open, - .ndo_stop = dnet_close, - .ndo_get_stats = dnet_get_stats, - .ndo_start_xmit = dnet_start_xmit, - .ndo_do_ioctl = dnet_ioctl, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, -}; - -static int __devinit dnet_probe(struct platform_device *pdev) -{ - struct resource *res; - struct net_device *dev; - struct dnet *bp; - struct phy_device *phydev; - int err = -ENXIO; - unsigned int mem_base, mem_size, irq; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no mmio resource defined\n"); - goto err_out; - } - mem_base = res->start; - mem_size = resource_size(res); - irq = platform_get_irq(pdev, 0); - - if (!request_mem_region(mem_base, mem_size, DRV_NAME)) { - dev_err(&pdev->dev, "no memory region available\n"); - err = -EBUSY; - goto err_out; - } - - err = -ENOMEM; - dev = alloc_etherdev(sizeof(*bp)); - if (!dev) { - dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); - goto err_out; - } - - /* TODO: Actually, we have some interesting features... */ - dev->features |= 0; - - bp = netdev_priv(dev); - bp->dev = dev; - - SET_NETDEV_DEV(dev, &pdev->dev); - - spin_lock_init(&bp->lock); - - bp->regs = ioremap(mem_base, mem_size); - if (!bp->regs) { - dev_err(&pdev->dev, "failed to map registers, aborting.\n"); - err = -ENOMEM; - goto err_out_free_dev; - } - - dev->irq = irq; - err = request_irq(dev->irq, dnet_interrupt, 0, DRV_NAME, dev); - if (err) { - dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", - irq, err); - goto err_out_iounmap; - } - - dev->netdev_ops = &dnet_netdev_ops; - netif_napi_add(dev, &bp->napi, dnet_poll, 64); - dev->ethtool_ops = &dnet_ethtool_ops; - - dev->base_addr = (unsigned long)bp->regs; - - bp->capabilities = dnet_readl(bp, VERCAPS) & DNET_CAPS_MASK; - - dnet_get_hwaddr(bp); - - if (!is_valid_ether_addr(dev->dev_addr)) { - /* choose a random ethernet address */ - random_ether_addr(dev->dev_addr); - __dnet_set_hwaddr(bp); - } - - err = register_netdev(dev); - if (err) { - dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); - goto err_out_free_irq; - } - - /* register the PHY board fixup (for Marvell 88E1111) */ - err = phy_register_fixup_for_uid(0x01410cc0, 0xfffffff0, - dnet_phy_marvell_fixup); - /* we can live without it, so just issue a warning */ - if (err) - dev_warn(&pdev->dev, "Cannot register PHY board fixup.\n"); - - if (dnet_mii_init(bp) != 0) - goto err_out_unregister_netdev; - - dev_info(&pdev->dev, "Dave DNET at 0x%p (0x%08x) irq %d %pM\n", - bp->regs, mem_base, dev->irq, dev->dev_addr); - dev_info(&pdev->dev, "has %smdio, %sirq, %sgigabit, %sdma \n", - (bp->capabilities & DNET_HAS_MDIO) ? "" : "no ", - (bp->capabilities & DNET_HAS_IRQ) ? "" : "no ", - (bp->capabilities & DNET_HAS_GIGABIT) ? "" : "no ", - (bp->capabilities & DNET_HAS_DMA) ? "" : "no "); - phydev = bp->phy_dev; - dev_info(&pdev->dev, "attached PHY driver [%s] " - "(mii_bus:phy_addr=%s, irq=%d)\n", - phydev->drv->name, dev_name(&phydev->dev), phydev->irq); - - return 0; - -err_out_unregister_netdev: - unregister_netdev(dev); -err_out_free_irq: - free_irq(dev->irq, dev); -err_out_iounmap: - iounmap(bp->regs); -err_out_free_dev: - free_netdev(dev); -err_out: - return err; -} - -static int __devexit dnet_remove(struct platform_device *pdev) -{ - - struct net_device *dev; - struct dnet *bp; - - dev = platform_get_drvdata(pdev); - - if (dev) { - bp = netdev_priv(dev); - if (bp->phy_dev) - phy_disconnect(bp->phy_dev); - mdiobus_unregister(bp->mii_bus); - kfree(bp->mii_bus->irq); - mdiobus_free(bp->mii_bus); - unregister_netdev(dev); - free_irq(dev->irq, dev); - iounmap(bp->regs); - free_netdev(dev); - } - - return 0; -} - -static struct platform_driver dnet_driver = { - .probe = dnet_probe, - .remove = __devexit_p(dnet_remove), - .driver = { - .name = "dnet", - }, -}; - -static int __init dnet_init(void) -{ - return platform_driver_register(&dnet_driver); -} - -static void __exit dnet_exit(void) -{ - platform_driver_unregister(&dnet_driver); -} - -module_init(dnet_init); -module_exit(dnet_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Dave DNET Ethernet driver"); -MODULE_AUTHOR("Ilya Yanok , " - "Matteo Vit "); diff --git a/trunk/drivers/net/dnet.h b/trunk/drivers/net/dnet.h deleted file mode 100644 index 37f5b30fa78b..000000000000 --- a/trunk/drivers/net/dnet.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Dave DNET Ethernet Controller driver - * - * Copyright (C) 2008 Dave S.r.l. - * - * 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. - */ -#ifndef _DNET_H -#define _DNET_H - -#define DRV_NAME "dnet" -#define DRV_VERSION "0.9.1" -#define PFX DRV_NAME ": " - -/* Register access macros */ -#define dnet_writel(port, value, reg) \ - writel((value), (port)->regs + DNET_##reg) -#define dnet_readl(port, reg) readl((port)->regs + DNET_##reg) - -/* ALL DNET FIFO REGISTERS */ -#define DNET_RX_LEN_FIFO 0x000 /* RX_LEN_FIFO */ -#define DNET_RX_DATA_FIFO 0x004 /* RX_DATA_FIFO */ -#define DNET_TX_LEN_FIFO 0x008 /* TX_LEN_FIFO */ -#define DNET_TX_DATA_FIFO 0x00C /* TX_DATA_FIFO */ - -/* ALL DNET CONTROL/STATUS REGISTERS OFFSETS */ -#define DNET_VERCAPS 0x100 /* VERCAPS */ -#define DNET_INTR_SRC 0x104 /* INTR_SRC */ -#define DNET_INTR_ENB 0x108 /* INTR_ENB */ -#define DNET_RX_STATUS 0x10C /* RX_STATUS */ -#define DNET_TX_STATUS 0x110 /* TX_STATUS */ -#define DNET_RX_FRAMES_CNT 0x114 /* RX_FRAMES_CNT */ -#define DNET_TX_FRAMES_CNT 0x118 /* TX_FRAMES_CNT */ -#define DNET_RX_FIFO_TH 0x11C /* RX_FIFO_TH */ -#define DNET_TX_FIFO_TH 0x120 /* TX_FIFO_TH */ -#define DNET_SYS_CTL 0x124 /* SYS_CTL */ -#define DNET_PAUSE_TMR 0x128 /* PAUSE_TMR */ -#define DNET_RX_FIFO_WCNT 0x12C /* RX_FIFO_WCNT */ -#define DNET_TX_FIFO_WCNT 0x130 /* TX_FIFO_WCNT */ - -/* ALL DNET MAC REGISTERS */ -#define DNET_MACREG_DATA 0x200 /* Mac-Reg Data */ -#define DNET_MACREG_ADDR 0x204 /* Mac-Reg Addr */ - -/* ALL DNET RX STATISTICS COUNTERS */ -#define DNET_RX_PKT_IGNR_CNT 0x300 -#define DNET_RX_LEN_CHK_ERR_CNT 0x304 -#define DNET_RX_LNG_FRM_CNT 0x308 -#define DNET_RX_SHRT_FRM_CNT 0x30C -#define DNET_RX_IPG_VIOL_CNT 0x310 -#define DNET_RX_CRC_ERR_CNT 0x314 -#define DNET_RX_OK_PKT_CNT 0x318 -#define DNET_RX_CTL_FRM_CNT 0x31C -#define DNET_RX_PAUSE_FRM_CNT 0x320 -#define DNET_RX_MULTICAST_CNT 0x324 -#define DNET_RX_BROADCAST_CNT 0x328 -#define DNET_RX_VLAN_TAG_CNT 0x32C -#define DNET_RX_PRE_SHRINK_CNT 0x330 -#define DNET_RX_DRIB_NIB_CNT 0x334 -#define DNET_RX_UNSUP_OPCD_CNT 0x338 -#define DNET_RX_BYTE_CNT 0x33C - -/* DNET TX STATISTICS COUNTERS */ -#define DNET_TX_UNICAST_CNT 0x400 -#define DNET_TX_PAUSE_FRM_CNT 0x404 -#define DNET_TX_MULTICAST_CNT 0x408 -#define DNET_TX_BRDCAST_CNT 0x40C -#define DNET_TX_VLAN_TAG_CNT 0x410 -#define DNET_TX_BAD_FCS_CNT 0x414 -#define DNET_TX_JUMBO_CNT 0x418 -#define DNET_TX_BYTE_CNT 0x41C - -/* SOME INTERNAL MAC-CORE REGISTER */ -#define DNET_INTERNAL_MODE_REG 0x0 -#define DNET_INTERNAL_RXTX_CONTROL_REG 0x2 -#define DNET_INTERNAL_MAX_PKT_SIZE_REG 0x4 -#define DNET_INTERNAL_IGP_REG 0x8 -#define DNET_INTERNAL_MAC_ADDR_0_REG 0xa -#define DNET_INTERNAL_MAC_ADDR_1_REG 0xc -#define DNET_INTERNAL_MAC_ADDR_2_REG 0xe -#define DNET_INTERNAL_TX_RX_STS_REG 0x12 -#define DNET_INTERNAL_GMII_MNG_CTL_REG 0x14 -#define DNET_INTERNAL_GMII_MNG_DAT_REG 0x16 - -#define DNET_INTERNAL_GMII_MNG_CMD_FIN (1 << 14) - -#define DNET_INTERNAL_WRITE (1 << 31) - -/* MAC-CORE REGISTER FIELDS */ - -/* MAC-CORE MODE REGISTER FIELDS */ -#define DNET_INTERNAL_MODE_GBITEN (1 << 0) -#define DNET_INTERNAL_MODE_FCEN (1 << 1) -#define DNET_INTERNAL_MODE_RXEN (1 << 2) -#define DNET_INTERNAL_MODE_TXEN (1 << 3) - -/* MAC-CORE RXTX CONTROL REGISTER FIELDS */ -#define DNET_INTERNAL_RXTX_CONTROL_RXSHORTFRAME (1 << 8) -#define DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST (1 << 7) -#define DNET_INTERNAL_RXTX_CONTROL_RXMULTICAST (1 << 4) -#define DNET_INTERNAL_RXTX_CONTROL_RXPAUSE (1 << 3) -#define DNET_INTERNAL_RXTX_CONTROL_DISTXFCS (1 << 2) -#define DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS (1 << 1) -#define DNET_INTERNAL_RXTX_CONTROL_ENPROMISC (1 << 0) -#define DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL (1 << 6) -#define DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP (1 << 5) - -/* SYSTEM CONTROL REGISTER FIELDS */ -#define DNET_SYS_CTL_IGNORENEXTPKT (1 << 0) -#define DNET_SYS_CTL_SENDPAUSE (1 << 2) -#define DNET_SYS_CTL_RXFIFOFLUSH (1 << 3) -#define DNET_SYS_CTL_TXFIFOFLUSH (1 << 4) - -/* TX STATUS REGISTER FIELDS */ -#define DNET_TX_STATUS_FIFO_ALMOST_EMPTY (1 << 2) -#define DNET_TX_STATUS_FIFO_ALMOST_FULL (1 << 1) - -/* INTERRUPT SOURCE REGISTER FIELDS */ -#define DNET_INTR_SRC_TX_PKTSENT (1 << 0) -#define DNET_INTR_SRC_TX_FIFOAF (1 << 1) -#define DNET_INTR_SRC_TX_FIFOAE (1 << 2) -#define DNET_INTR_SRC_TX_DISCFRM (1 << 3) -#define DNET_INTR_SRC_TX_FIFOFULL (1 << 4) -#define DNET_INTR_SRC_RX_CMDFIFOAF (1 << 8) -#define DNET_INTR_SRC_RX_CMDFIFOFF (1 << 9) -#define DNET_INTR_SRC_RX_DATAFIFOFF (1 << 10) -#define DNET_INTR_SRC_TX_SUMMARY (1 << 16) -#define DNET_INTR_SRC_RX_SUMMARY (1 << 17) -#define DNET_INTR_SRC_PHY (1 << 19) - -/* INTERRUPT ENABLE REGISTER FIELDS */ -#define DNET_INTR_ENB_TX_PKTSENT (1 << 0) -#define DNET_INTR_ENB_TX_FIFOAF (1 << 1) -#define DNET_INTR_ENB_TX_FIFOAE (1 << 2) -#define DNET_INTR_ENB_TX_DISCFRM (1 << 3) -#define DNET_INTR_ENB_TX_FIFOFULL (1 << 4) -#define DNET_INTR_ENB_RX_PKTRDY (1 << 8) -#define DNET_INTR_ENB_RX_FIFOAF (1 << 9) -#define DNET_INTR_ENB_RX_FIFOERR (1 << 10) -#define DNET_INTR_ENB_RX_ERROR (1 << 11) -#define DNET_INTR_ENB_RX_FIFOFULL (1 << 12) -#define DNET_INTR_ENB_RX_FIFOAE (1 << 13) -#define DNET_INTR_ENB_TX_SUMMARY (1 << 16) -#define DNET_INTR_ENB_RX_SUMMARY (1 << 17) -#define DNET_INTR_ENB_GLOBAL_ENABLE (1 << 18) - -/* default values: - * almost empty = less than one full sized ethernet frame (no jumbo) inside - * the fifo almost full = can write less than one full sized ethernet frame - * (no jumbo) inside the fifo - */ -#define DNET_CFG_TX_FIFO_FULL_THRES 25 -#define DNET_CFG_RX_FIFO_FULL_THRES 20 - -/* - * Capabilities. Used by the driver to know the capabilities that the ethernet - * controller inside the FPGA have. - */ - -#define DNET_HAS_MDIO (1 << 0) -#define DNET_HAS_IRQ (1 << 1) -#define DNET_HAS_GIGABIT (1 << 2) -#define DNET_HAS_DMA (1 << 3) - -#define DNET_HAS_MII (1 << 4) /* or GMII */ -#define DNET_HAS_RMII (1 << 5) /* or RGMII */ - -#define DNET_CAPS_MASK 0xFFFF - -#define DNET_FIFO_SIZE 1024 /* 1K x 32 bit */ -#define DNET_FIFO_TX_DATA_AF_TH (DNET_FIFO_SIZE - 384) /* 384 = 1536 / 4 */ -#define DNET_FIFO_TX_DATA_AE_TH 384 - -#define DNET_FIFO_RX_CMD_AF_TH (1 << 16) /* just one frame inside the FIFO */ - -/* - * Hardware-collected statistics. - */ -struct dnet_stats { - u32 rx_pkt_ignr; - u32 rx_len_chk_err; - u32 rx_lng_frm; - u32 rx_shrt_frm; - u32 rx_ipg_viol; - u32 rx_crc_err; - u32 rx_ok_pkt; - u32 rx_ctl_frm; - u32 rx_pause_frm; - u32 rx_multicast; - u32 rx_broadcast; - u32 rx_vlan_tag; - u32 rx_pre_shrink; - u32 rx_drib_nib; - u32 rx_unsup_opcd; - u32 rx_byte; - u32 tx_unicast; - u32 tx_pause_frm; - u32 tx_multicast; - u32 tx_brdcast; - u32 tx_vlan_tag; - u32 tx_bad_fcs; - u32 tx_jumbo; - u32 tx_byte; -}; - -struct dnet { - void __iomem *regs; - spinlock_t lock; - struct platform_device *pdev; - struct net_device *dev; - struct dnet_stats hw_stats; - unsigned int capabilities; /* read from FPGA */ - struct napi_struct napi; - - /* PHY stuff */ - struct mii_bus *mii_bus; - struct phy_device *phy_dev; - unsigned int link; - unsigned int speed; - unsigned int duplex; -}; - -#endif /* _DNET_H */ diff --git a/trunk/drivers/net/ibm_newemac/core.c b/trunk/drivers/net/ibm_newemac/core.c index 6fd7aa61736e..87a706694fb3 100644 --- a/trunk/drivers/net/ibm_newemac/core.c +++ b/trunk/drivers/net/ibm_newemac/core.c @@ -2594,9 +2594,6 @@ static int __devinit emac_init_config(struct emac_instance *dev) if (of_device_is_compatible(np, "ibm,emac-460ex") || of_device_is_compatible(np, "ibm,emac-460gt")) dev->features |= EMAC_FTR_460EX_PHY_CLK_FIX; - if (of_device_is_compatible(np, "ibm,emac-405ex") || - of_device_is_compatible(np, "ibm,emac-405exr")) - dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; } else if (of_device_is_compatible(np, "ibm,emac4")) { dev->features |= EMAC_FTR_EMAC4; if (of_device_is_compatible(np, "ibm,emac-440gx")) diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index 9dd13ad12ce4..a50db5398fa5 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -1023,10 +1023,11 @@ static int __devinit igb_probe(struct pci_dev *pdev, struct net_device *netdev; struct igb_adapter *adapter; struct e1000_hw *hw; + struct pci_dev *us_dev; const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; unsigned long mmio_start, mmio_len; - int i, err, pci_using_dac; - u16 eeprom_data = 0; + int i, err, pci_using_dac, pos; + u16 eeprom_data = 0, state = 0; u16 eeprom_apme_mask = IGB_EEPROM_APME; u32 part_num; int bars, need_ioport; @@ -1061,6 +1062,27 @@ static int __devinit igb_probe(struct pci_dev *pdev, } } + /* 82575 requires that the pci-e link partner disable the L0s state */ + switch (pdev->device) { + case E1000_DEV_ID_82575EB_COPPER: + case E1000_DEV_ID_82575EB_FIBER_SERDES: + case E1000_DEV_ID_82575GB_QUAD_COPPER: + us_dev = pdev->bus->self; + pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP); + if (pos) { + pci_read_config_word(us_dev, pos + PCI_EXP_LNKCTL, + &state); + state &= ~PCIE_LINK_STATE_L0S; + pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL, + state); + dev_info(&pdev->dev, + "Disabling ASPM L0s upstream switch port %s\n", + pci_name(us_dev)); + } + default: + break; + } + err = pci_request_selected_regions(pdev, bars, igb_driver_name); if (err) goto err_pci_reg; diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 5d364a96e35d..d2f4d5f508b7 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -3973,7 +3973,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_stop = ixgbe_close, .ndo_start_xmit = ixgbe_xmit_frame, .ndo_get_stats = ixgbe_get_stats, - .ndo_set_rx_mode = ixgbe_set_rx_mode, .ndo_set_multicast_list = ixgbe_set_rx_mode, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ixgbe_set_mac, diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index b0bc3bc18e9c..13f11f402a99 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -2029,6 +2029,11 @@ static void port_start(struct mv643xx_eth_private *mp) txq_set_fixed_prio_mode(txq); } + /* + * Add configured unicast address to address filter table. + */ + mv643xx_eth_program_unicast_filter(mp->dev); + /* * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast * frames to RX queue #0, and include the pseudo-header when @@ -2041,11 +2046,6 @@ static void port_start(struct mv643xx_eth_private *mp) */ wrlp(mp, PORT_CONFIG_EXT, 0x00000000); - /* - * Add configured unicast addresses to address filter table. - */ - mv643xx_eth_program_unicast_filter(mp->dev); - /* * Enable the receive queues. */ diff --git a/trunk/drivers/net/netxen/netxen_nic.h b/trunk/drivers/net/netxen/netxen_nic.h index 1ff066b2281a..f4dd9acb6877 100644 --- a/trunk/drivers/net/netxen/netxen_nic.h +++ b/trunk/drivers/net/netxen/netxen_nic.h @@ -1595,6 +1595,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter) } +int netxen_is_flash_supported(struct netxen_adapter *adapter); int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); extern void netxen_change_ringparam(struct netxen_adapter *adapter); diff --git a/trunk/drivers/net/netxen/netxen_nic_hw.c b/trunk/drivers/net/netxen/netxen_nic_hw.c index 7fea77088108..821cff68b3f3 100644 --- a/trunk/drivers/net/netxen/netxen_nic_hw.c +++ b/trunk/drivers/net/netxen/netxen_nic_hw.c @@ -706,6 +706,28 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu) return rc; } +int netxen_is_flash_supported(struct netxen_adapter *adapter) +{ + const int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 }; + int addr, val01, val02, i, j; + + /* if the flash size less than 4Mb, make huge war cry and die */ + for (j = 1; j < 4; j++) { + addr = j * NETXEN_NIC_WINDOW_MARGIN; + for (i = 0; i < ARRAY_SIZE(locs); i++) { + if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0 + && netxen_rom_fast_read(adapter, (addr + locs[i]), + &val02) == 0) { + if (val01 == val02) + return -1; + } else + return -1; + } + } + + return 0; +} + static int netxen_get_flash_block(struct netxen_adapter *adapter, int base, int size, __le32 * buf) { diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index c172b6e24a96..13087782ac40 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -405,6 +405,9 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; + if (netxen_is_flash_supported(adapter) != 0) + return -EIO; + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0) return -EIO; diff --git a/trunk/drivers/net/qlge/qlge.h b/trunk/drivers/net/qlge/qlge.h index aff9c5fec738..e6fdce9206cc 100644 --- a/trunk/drivers/net/qlge/qlge.h +++ b/trunk/drivers/net/qlge/qlge.h @@ -927,7 +927,6 @@ struct ib_mac_iocb_rsp { u8 flags1; #define IB_MAC_IOCB_RSP_OI 0x01 /* Overide intr delay */ #define IB_MAC_IOCB_RSP_I 0x02 /* Disble Intr Generation */ -#define IB_MAC_CSUM_ERR_MASK 0x1c /* A mask to use for csum errs */ #define IB_MAC_IOCB_RSP_TE 0x04 /* Checksum error */ #define IB_MAC_IOCB_RSP_NU 0x08 /* No checksum rcvd */ #define IB_MAC_IOCB_RSP_IE 0x10 /* IPv4 checksum error */ diff --git a/trunk/drivers/net/qlge/qlge_main.c b/trunk/drivers/net/qlge/qlge_main.c index 91191f761fba..8ea72dc60f79 100644 --- a/trunk/drivers/net/qlge/qlge_main.c +++ b/trunk/drivers/net/qlge/qlge_main.c @@ -1436,32 +1436,18 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) { QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n"); } - - skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; - - /* If rx checksum is on, and there are no - * csum or frame errors. - */ - if (qdev->rx_csum && - !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) && - !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { - /* TCP frame. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { - QPRINTK(qdev, RX_STATUS, DEBUG, - "TCP checksum done!\n"); - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && - (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { - /* Unfragmented ipv4 UDP frame. */ - struct iphdr *iph = (struct iphdr *) skb->data; - if (!(iph->frag_off & - cpu_to_be16(IP_MF|IP_OFFSET))) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - QPRINTK(qdev, RX_STATUS, DEBUG, - "TCP checksum done!\n"); - } - } + if (ib_mac_rsp->flags1 & (IB_MAC_IOCB_RSP_IE | IB_MAC_IOCB_RSP_TE)) { + QPRINTK(qdev, RX_STATUS, ERR, + "Bad checksum for this %s packet.\n", + ((ib_mac_rsp-> + flags2 & IB_MAC_IOCB_RSP_T) ? "TCP" : "UDP")); + skb->ip_summed = CHECKSUM_NONE; + } else if (qdev->rx_csum && + ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) || + ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && + !(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_NU)))) { + QPRINTK(qdev, RX_STATUS, DEBUG, "RX checksum done!\n"); + skb->ip_summed = CHECKSUM_UNNECESSARY; } qdev->stats.rx_packets++; qdev->stats.rx_bytes += skb->len; @@ -1941,9 +1927,6 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev) tx_ring = &qdev->tx_ring[tx_ring_idx]; - if (skb_padto(skb, ETH_ZLEN)) - return NETDEV_TX_OK; - if (unlikely(atomic_read(&tx_ring->tx_count) < 2)) { QPRINTK(qdev, TX_QUEUED, INFO, "%s: shutting down tx queue %d du to lack of resources.\n", @@ -2987,9 +2970,9 @@ static int ql_adapter_initialize(struct ql_adapter *qdev) mask = value << 16; ql_write32(qdev, SYS, mask | value); - /* Set the default queue, and VLAN behavior. */ - value = NIC_RCV_CFG_DFQ | NIC_RCV_CFG_RV; - mask = NIC_RCV_CFG_DFQ_MASK | (NIC_RCV_CFG_RV << 16); + /* Set the default queue. */ + value = NIC_RCV_CFG_DFQ; + mask = NIC_RCV_CFG_DFQ_MASK; ql_write32(qdev, NIC_RCV_CFG, (mask | value)); /* Set the MPI interrupt to enabled. */ @@ -3166,11 +3149,6 @@ static int ql_adapter_down(struct ql_adapter *qdev) ql_tx_ring_clean(qdev); - /* Call netif_napi_del() from common point. - */ - for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++) - netif_napi_del(&qdev->rx_ring[i].napi); - spin_lock(&qdev->hw_lock); status = ql_adapter_reset(qdev); if (status) @@ -3875,7 +3853,7 @@ static int qlge_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *ndev = pci_get_drvdata(pdev); struct ql_adapter *qdev = netdev_priv(ndev); - int err; + int err, i; netif_device_detach(ndev); @@ -3885,6 +3863,9 @@ static int qlge_suspend(struct pci_dev *pdev, pm_message_t state) return err; } + for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++) + netif_napi_del(&qdev->rx_ring[i].napi); + err = pci_save_state(pdev); if (err) return err; diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 43fedb9ecedb..b3473401c83a 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -81,9 +81,9 @@ static const int multicast_filter_limit = 32; #define RTL8169_TX_TIMEOUT (6*HZ) #define RTL8169_PHY_TIMEOUT (10*HZ) -#define RTL_EEPROM_SIG cpu_to_le32(0x8129) -#define RTL_EEPROM_SIG_MASK cpu_to_le32(0xffff) +#define RTL_EEPROM_SIG 0x8129 #define RTL_EEPROM_SIG_ADDR 0x0000 +#define RTL_EEPROM_MAC_ADDR 0x0007 /* write/read MMIO register */ #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) @@ -293,6 +293,11 @@ enum rtl_register_content { /* Cfg9346Bits */ Cfg9346_Lock = 0x00, Cfg9346_Unlock = 0xc0, + Cfg9346_Program = 0x80, /* Programming mode */ + Cfg9346_EECS = 0x08, /* Chip select */ + Cfg9346_EESK = 0x04, /* Serial data clock */ + Cfg9346_EEDI = 0x02, /* Data input */ + Cfg9346_EEDO = 0x01, /* Data output */ /* rx_mode_bits */ AcceptErr = 0x20, @@ -305,6 +310,7 @@ enum rtl_register_content { /* RxConfigBits */ RxCfgFIFOShift = 13, RxCfgDMAShift = 8, + RxCfg9356SEL = 6, /* EEPROM type: 0 = 9346, 1 = 9356 */ /* TxConfigBits */ TxInterFrameGapShift = 24, @@ -1963,6 +1969,108 @@ static const struct net_device_ops rtl8169_netdev_ops = { }; +/* Delay between EEPROM clock transitions. Force out buffered PCI writes. */ +#define RTL_EEPROM_DELAY() RTL_R8(Cfg9346) +#define RTL_EEPROM_READ_CMD 6 + +/* read 16bit word stored in EEPROM. EEPROM is addressed by words. */ +static u16 rtl_eeprom_read(void __iomem *ioaddr, int addr) +{ + u16 result = 0; + int cmd, cmd_len, i; + + /* check for EEPROM address size (in bits) */ + if (RTL_R32(RxConfig) & (1 << RxCfg9356SEL)) { + /* EEPROM is 93C56 */ + cmd_len = 3 + 8; /* 3 bits for command id and 8 for address */ + cmd = (RTL_EEPROM_READ_CMD << 8) | (addr & 0xff); + } else { + /* EEPROM is 93C46 */ + cmd_len = 3 + 6; /* 3 bits for command id and 6 for address */ + cmd = (RTL_EEPROM_READ_CMD << 6) | (addr & 0x3f); + } + + /* enter programming mode */ + RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS); + RTL_EEPROM_DELAY(); + + /* write command and requested address */ + while (cmd_len--) { + u8 x = Cfg9346_Program | Cfg9346_EECS; + + x |= (cmd & (1 << cmd_len)) ? Cfg9346_EEDI : 0; + + /* write a bit */ + RTL_W8(Cfg9346, x); + RTL_EEPROM_DELAY(); + + /* raise clock */ + RTL_W8(Cfg9346, x | Cfg9346_EESK); + RTL_EEPROM_DELAY(); + } + + /* lower clock */ + RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS); + RTL_EEPROM_DELAY(); + + /* read back 16bit value */ + for (i = 16; i > 0; i--) { + /* raise clock */ + RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS | Cfg9346_EESK); + RTL_EEPROM_DELAY(); + + result <<= 1; + result |= (RTL_R8(Cfg9346) & Cfg9346_EEDO) ? 1 : 0; + + /* lower clock */ + RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS); + RTL_EEPROM_DELAY(); + } + + RTL_W8(Cfg9346, Cfg9346_Program); + /* leave programming mode */ + RTL_W8(Cfg9346, Cfg9346_Lock); + + return result; +} + +static void rtl_init_mac_address(struct rtl8169_private *tp, + void __iomem *ioaddr) +{ + struct pci_dev *pdev = tp->pci_dev; + u16 x; + u8 mac[8]; + + /* read EEPROM signature */ + x = rtl_eeprom_read(ioaddr, RTL_EEPROM_SIG_ADDR); + + if (x != RTL_EEPROM_SIG) { + dev_info(&pdev->dev, "Missing EEPROM signature: %04x\n", x); + return; + } + + /* read MAC address */ + x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR); + mac[0] = x & 0xff; + mac[1] = x >> 8; + x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR + 1); + mac[2] = x & 0xff; + mac[3] = x >> 8; + x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR + 2); + mac[4] = x & 0xff; + mac[5] = x >> 8; + + if (netif_msg_probe(tp)) { + DECLARE_MAC_BUF(buf); + + dev_info(&pdev->dev, "MAC address found in EEPROM: %s\n", + print_mac(buf, mac)); + } + + if (is_valid_ether_addr(mac)) + rtl_rar_set(tp, mac); +} + static int __devinit rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -2141,6 +2249,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->mmio_addr = ioaddr; + rtl_init_mac_address(tp, ioaddr); + /* Get MAC address */ for (i = 0; i < MAC_ADDR_LEN; i++) dev->dev_addr[i] = RTL_R8(MAC0 + i); @@ -3253,6 +3363,13 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) opts1 |= FirstFrag; } else { len = skb->len; + + if (unlikely(len < ETH_ZLEN)) { + if (skb_padto(skb, ETH_ZLEN)) + goto err_update_stats; + len = ETH_ZLEN; + } + opts1 |= FirstFrag | LastFrag; tp->tx_skb[entry].skb = skb; } @@ -3290,6 +3407,7 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) err_stop: netif_stop_queue(dev); ret = NETDEV_TX_BUSY; +err_update_stats: dev->stats.tx_dropped++; goto out; } diff --git a/trunk/drivers/net/sh_eth.c b/trunk/drivers/net/sh_eth.c index 7b1882765a0c..7f8e514eb5e9 100644 --- a/trunk/drivers/net/sh_eth.c +++ b/trunk/drivers/net/sh_eth.c @@ -687,7 +687,6 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) { struct net_device *ndev = netdev; struct sh_eth_private *mdp = netdev_priv(ndev); - irqreturn_t ret = IRQ_NONE; u32 ioaddr, boguscnt = RX_RING_SIZE; u32 intr_status = 0; @@ -697,13 +696,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) /* Get interrpt stat */ intr_status = ctrl_inl(ioaddr + EESR); /* Clear interrupt */ - if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | - EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | - TX_CHECK | EESR_ERR_CHECK)) { - ctrl_outl(intr_status, ioaddr + EESR); - ret = IRQ_HANDLED; - } else - goto other_irq; + ctrl_outl(intr_status, ioaddr + EESR); if (intr_status & (EESR_FRC | /* Frame recv*/ EESR_RMAF | /* Multi cast address recv*/ @@ -730,10 +723,9 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) ndev->name, intr_status); } -other_irq: spin_unlock(&mdp->lock); - return ret; + return IRQ_HANDLED; } static void sh_eth_timer(unsigned long data) @@ -852,13 +844,7 @@ static int sh_eth_open(struct net_device *ndev) int ret = 0; struct sh_eth_private *mdp = netdev_priv(ndev); - ret = request_irq(ndev->irq, &sh_eth_interrupt, -#if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764) - IRQF_SHARED, -#else - 0, -#endif - ndev->name, ndev); + ret = request_irq(ndev->irq, &sh_eth_interrupt, 0, ndev->name, ndev); if (ret) { printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME); return ret; diff --git a/trunk/drivers/net/sh_eth.h b/trunk/drivers/net/sh_eth.h index 1537e13e623d..73bc7181cc18 100644 --- a/trunk/drivers/net/sh_eth.h +++ b/trunk/drivers/net/sh_eth.h @@ -43,8 +43,8 @@ #define SH7763_SKB_ALIGN 32 /* Chip Base Address */ -# define SH_TSU_ADDR 0xFEE01800 -# define ARSTR SH_TSU_ADDR +# define SH_TSU_ADDR 0xFFE01800 +# define ARSTR 0xFFE01800 /* Chip Registers */ /* E-DMAC */ diff --git a/trunk/drivers/net/smsc911x.c b/trunk/drivers/net/smsc911x.c index d1590ac55e4b..9a78daec2fe9 100644 --- a/trunk/drivers/net/smsc911x.c +++ b/trunk/drivers/net/smsc911x.c @@ -1225,10 +1225,6 @@ static int smsc911x_open(struct net_device *dev) dev_info(&dev->dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n", (unsigned long)pdata->ioaddr, dev->irq); - /* Reset the last known duplex and carrier */ - pdata->last_duplex = -1; - pdata->last_carrier = -1; - /* Bring the PHY up */ phy_start(pdata->phy_dev); diff --git a/trunk/drivers/net/sungem.c b/trunk/drivers/net/sungem.c index c9c7650826c0..0fcb7503363d 100644 --- a/trunk/drivers/net/sungem.c +++ b/trunk/drivers/net/sungem.c @@ -2998,11 +2998,8 @@ static const struct net_device_ops gem_netdev_ops = { .ndo_do_ioctl = gem_ioctl, .ndo_tx_timeout = gem_tx_timeout, .ndo_change_mtu = gem_change_mtu, + .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = gem_set_mac_address, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = gem_poll_controller, -#endif }; static int __devinit gem_init_one(struct pci_dev *pdev, @@ -3164,6 +3161,10 @@ static int __devinit gem_init_one(struct pci_dev *pdev, dev->watchdog_timeo = 5 * HZ; dev->irq = pdev->irq; dev->dma = 0; + dev->set_mac_address = gem_set_mac_address; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = gem_poll_controller; +#endif /* Set that now, in case PM kicks in now */ pci_set_drvdata(pdev, dev); diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index 2abb5d3becc6..bee75fa87a9c 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -255,7 +255,6 @@ const char tulip_media_cap[32] = static void tulip_tx_timeout(struct net_device *dev); static void tulip_init_ring(struct net_device *dev); -static void tulip_free_ring(struct net_device *dev); static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev); static int tulip_open(struct net_device *dev); static int tulip_close(struct net_device *dev); @@ -503,21 +502,16 @@ tulip_open(struct net_device *dev) { int retval; - tulip_init_ring (dev); + if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev))) + return retval; - retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev); - if (retval) - goto free_ring; + tulip_init_ring (dev); tulip_up (dev); netif_start_queue (dev); return 0; - -free_ring: - tulip_free_ring (dev); - return retval; } @@ -774,11 +768,23 @@ static void tulip_down (struct net_device *dev) tulip_set_power_state (tp, 0, 1); } -static void tulip_free_ring (struct net_device *dev) + +static int tulip_close (struct net_device *dev) { struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; int i; + netif_stop_queue (dev); + + tulip_down (dev); + + if (tulip_debug > 1) + printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", + dev->name, ioread32 (ioaddr + CSR5)); + + free_irq (dev->irq, dev); + /* Free all the skbuffs in the Rx queue. */ for (i = 0; i < RX_RING_SIZE; i++) { struct sk_buff *skb = tp->rx_buffers[i].skb; @@ -797,7 +803,6 @@ static void tulip_free_ring (struct net_device *dev) dev_kfree_skb (skb); } } - for (i = 0; i < TX_RING_SIZE; i++) { struct sk_buff *skb = tp->tx_buffers[i].skb; @@ -809,24 +814,6 @@ static void tulip_free_ring (struct net_device *dev) tp->tx_buffers[i].skb = NULL; tp->tx_buffers[i].mapping = 0; } -} - -static int tulip_close (struct net_device *dev) -{ - struct tulip_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->base_addr; - - netif_stop_queue (dev); - - tulip_down (dev); - - if (tulip_debug > 1) - printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", - dev->name, ioread32 (ioaddr + CSR5)); - - free_irq (dev->irq, dev); - - tulip_free_ring (dev); return 0; } diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index 1f61e42c641d..e87986867ba5 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -1536,15 +1536,32 @@ static void adjust_link(struct net_device *dev) static int init_phy(struct net_device *dev) { struct ucc_geth_private *priv = netdev_priv(dev); - struct ucc_geth_info *ug_info = priv->ug_info; + struct device_node *np = priv->node; + struct device_node *phy, *mdio; + const phandle *ph; + char bus_name[MII_BUS_ID_SIZE]; + const unsigned int *id; struct phy_device *phydev; + char phy_id[BUS_ID_SIZE]; priv->oldlink = 0; priv->oldspeed = 0; priv->oldduplex = -1; - phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0, - priv->phy_interface); + ph = of_get_property(np, "phy-handle", NULL); + phy = of_find_node_by_phandle(*ph); + mdio = of_get_parent(phy); + + id = of_get_property(phy, "reg", NULL); + + of_node_put(phy); + of_node_put(mdio); + + uec_mdio_bus_name(bus_name, mdio); + snprintf(phy_id, sizeof(phy_id), "%s:%02x", + bus_name, *id); + + phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface); if (IS_ERR(phydev)) { printk("%s: Could not attach to PHY\n", dev->name); @@ -3612,12 +3629,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); fixed_link = of_get_property(np, "fixed-link", NULL); if (fixed_link) { - snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id), - PHY_ID_FMT, "0", fixed_link[0]); + snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "0"); + ug_info->phy_address = fixed_link[0]; phy = NULL; } else { - char bus_name[MII_BUS_ID_SIZE]; - ph = of_get_property(np, "phy-handle", NULL); phy = of_find_node_by_phandle(*ph); @@ -3628,6 +3643,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma prop = of_get_property(phy, "reg", NULL); if (prop == NULL) return -1; + ug_info->phy_address = *prop; /* Set the bus id */ mdio = of_get_parent(phy); @@ -3641,9 +3657,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma if (err) return -1; - uec_mdio_bus_name(bus_name, mdio); - snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id), - "%s:%02x", bus_name, *prop); + snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "%x", res.start); } /* get the phy interface type, or default to MII */ diff --git a/trunk/drivers/net/ucc_geth.h b/trunk/drivers/net/ucc_geth.h index 611bdef2402b..16cbe42ba43c 100644 --- a/trunk/drivers/net/ucc_geth.h +++ b/trunk/drivers/net/ucc_geth.h @@ -1091,7 +1091,8 @@ struct ucc_geth_info { u32 eventRegMask; u16 pausePeriod; u16 extensionField; - char phy_bus_id[BUS_ID_SIZE]; + u8 phy_address; + char mdio_bus[MII_BUS_ID_SIZE]; u8 weightfactor[NUM_TX_QUEUES]; u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES]; u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX]; diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index fb53ef872df3..c5691fdb7079 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/drivers/net/via-velocity.c @@ -1838,19 +1838,17 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_ { struct sk_buff *skb = tdinfo->skb; int i; - int pktlen; /* * Don't unmap the pre-allocated tx_bufs */ if (tdinfo->skb_dma) { - pktlen = (skb->len > ETH_ZLEN ? : ETH_ZLEN); for (i = 0; i < tdinfo->nskb_dma; i++) { #ifdef VELOCITY_ZERO_COPY_SUPPORT pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], le16_to_cpu(td->tdesc1.len), PCI_DMA_TODEVICE); #else - pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], pktlen, PCI_DMA_TODEVICE); + pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], skb->len, PCI_DMA_TODEVICE); #endif tdinfo->skb_dma[i] = 0; } @@ -2082,14 +2080,17 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) struct tx_desc *td_ptr; struct velocity_td_info *tdinfo; unsigned long flags; - int pktlen; + int pktlen = skb->len; __le16 len; int index; - if (skb_padto(skb, ETH_ZLEN)) - goto out; - pktlen = max_t(unsigned int, skb->len, ETH_ZLEN); + + if (skb->len < ETH_ZLEN) { + if (skb_padto(skb, ETH_ZLEN)) + goto out; + pktlen = ETH_ZLEN; + } len = cpu_to_le16(pktlen); diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index e67d16c2e5f3..c68808336c8c 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -612,7 +612,6 @@ static struct ethtool_ops virtnet_ethtool_ops = { .set_tx_csum = virtnet_set_tx_csum, .set_sg = ethtool_op_set_sg, .set_tso = ethtool_op_set_tso, - .get_link = ethtool_op_get_link, }; #define MIN_MTU 68 @@ -740,8 +739,6 @@ static int virtnet_probe(struct virtio_device *vdev) goto unregister; } - netif_carrier_on(dev); - pr_debug("virtnet: registered device %s\n", dev->name); return 0; diff --git a/trunk/drivers/net/wireless/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath9k/ath9k.h index 6650f609ece4..d27813502953 100644 --- a/trunk/drivers/net/wireless/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath9k/ath9k.h @@ -587,8 +587,8 @@ struct ath9k_country_entry { u8 iso[3]; }; -#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val)) -#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg)) +#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg) +#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg) #define SM(_v, _f) (((_v) << _f##_S) & _f) #define MS(_v, _f) (((_v) & _f) >> _f##_S) diff --git a/trunk/drivers/net/wireless/ath9k/core.h b/trunk/drivers/net/wireless/ath9k/core.h index 139566cbbf65..4ca2aed236e0 100644 --- a/trunk/drivers/net/wireless/ath9k/core.h +++ b/trunk/drivers/net/wireless/ath9k/core.h @@ -701,7 +701,6 @@ struct ath_softc { struct ath_hal *sc_ah; void __iomem *mem; spinlock_t sc_resetlock; - spinlock_t sc_serial_rw; struct mutex mutex; u8 sc_curbssid[ETH_ALEN]; @@ -752,36 +751,4 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); int ath_cabq_update(struct ath_softc *); -/* - * Read and write, they both share the same lock. We do this to serialize - * reads and writes on Atheros 802.11n PCI devices only. This is required - * as the FIFO on these devices can only accept sanely 2 requests. After - * that the device goes bananas. Serializing the reads/writes prevents this - * from happening. - */ - -static inline void ath9k_iowrite32(struct ath_hal *ah, u32 reg_offset, u32 val) -{ - if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) { - unsigned long flags; - spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); - iowrite32(val, ah->ah_sc->mem + reg_offset); - spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); - } else - iowrite32(val, ah->ah_sc->mem + reg_offset); -} - -static inline unsigned int ath9k_ioread32(struct ath_hal *ah, u32 reg_offset) -{ - u32 val; - if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) { - unsigned long flags; - spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); - val = ioread32(ah->ah_sc->mem + reg_offset); - spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); - } else - val = ioread32(ah->ah_sc->mem + reg_offset); - return val; -} - #endif /* CORE_H */ diff --git a/trunk/drivers/net/wireless/ath9k/hw.c b/trunk/drivers/net/wireless/ath9k/hw.c index c38a00bbce64..34474edefc97 100644 --- a/trunk/drivers/net/wireless/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath9k/hw.c @@ -437,25 +437,6 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah) } ah->ah_config.intr_mitigation = 1; - - /* - * We need this for PCI devices only (Cardbus, PCI, miniPCI) - * _and_ if on non-uniprocessor systems (Multiprocessor/HT). - * This means we use it for all AR5416 devices, and the few - * minor PCI AR9280 devices out there. - * - * Serialization is required because these devices do not handle - * well the case of two concurrent reads/writes due to the latency - * involved. During one read/write another read/write can be issued - * on another CPU while the previous read/write may still be working - * on our hardware, if we hit this case the hardware poops in a loop. - * We prevent this by serializing reads and writes. - * - * This issue is not present on PCI-Express devices or pre-AR5416 - * devices (legacy, 802.11abg). - */ - if (num_possible_cpus() > 1) - ah->ah_config.serialize_regmode = SER_REG_MODE_AUTO; } static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, @@ -687,8 +668,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, } if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) { - if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI || - (AR_SREV_9280(ah) && !ah->ah_isPciExpress)) { + if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) { ah->ah_config.serialize_regmode = SER_REG_MODE_ON; } else { diff --git a/trunk/drivers/net/wireless/ath9k/main.c b/trunk/drivers/net/wireless/ath9k/main.c index 3c04044a60bd..0e80990d8e84 100644 --- a/trunk/drivers/net/wireless/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath9k/main.c @@ -1336,7 +1336,6 @@ static int ath_init(u16 devid, struct ath_softc *sc) printk(KERN_ERR "Unable to create debugfs files\n"); spin_lock_init(&sc->sc_resetlock); - spin_lock_init(&sc->sc_serial_rw); mutex_init(&sc->mutex); tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c index 847057d682b1..a611ad857983 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c @@ -575,17 +575,13 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) r = fill_ctrlset(mac, skb); if (r) - goto fail; + return r; info->rate_driver_data[0] = hw; r = zd_usb_tx(&mac->chip.usb, skb); if (r) - goto fail; - return 0; - -fail: - dev_kfree_skb(skb); + return r; return 0; } diff --git a/trunk/drivers/parisc/dino.c b/trunk/drivers/parisc/dino.c index bb5a1c9597cb..d539d9df88e7 100644 --- a/trunk/drivers/parisc/dino.c +++ b/trunk/drivers/parisc/dino.c @@ -479,7 +479,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr) res = &dino_dev->hba.lmmio_space; res->flags = IORESOURCE_MEM; size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)", - dev_name(bus->bridge)); + bus->bridge->bus_id); res->name = kmalloc(size+1, GFP_KERNEL); if(res->name) strcpy((char *)res->name, name); @@ -493,7 +493,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr) struct list_head *ln, *tmp_ln; printk(KERN_ERR "Dino: cannot attach bus %s\n", - dev_name(bus->bridge)); + bus->bridge->bus_id); /* kill the bus, we can't do anything with it */ list_for_each_safe(ln, tmp_ln, &bus->devices) { struct pci_dev *dev = pci_dev_b(ln); @@ -587,7 +587,7 @@ dino_fixup_bus(struct pci_bus *bus) bus->resource[i+1] = &res[i]; } - } else if (bus->parent) { + } else if(bus->self) { int i; pci_read_bridge_bases(bus); @@ -611,12 +611,12 @@ dino_fixup_bus(struct pci_bus *bus) } DBG("DEBUG %s assigning %d [0x%lx,0x%lx]\n", - dev_name(&bus->self->dev), i, + bus->self->dev.bus_id, i, bus->self->resource[i].start, bus->self->resource[i].end); pci_assign_resource(bus->self, i); DBG("DEBUG %s after assign %d [0x%lx,0x%lx]\n", - dev_name(&bus->self->dev), i, + bus->self->dev.bus_id, i, bus->self->resource[i].start, bus->self->resource[i].end); } @@ -1026,8 +1026,7 @@ static int __init dino_probe(struct parisc_device *dev) dino_current_bus = bus->subordinate + 1; pci_bus_assign_resources(bus); } else { - printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n", - dev_name(&dev->dev), dino_current_bus); + printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n", dev->dev.bus_id, dino_current_bus); /* increment the bus number in case of duplicates */ dino_current_bus++; } diff --git a/trunk/drivers/parisc/gsc.c b/trunk/drivers/parisc/gsc.c index d33632917696..e76db9e4d504 100644 --- a/trunk/drivers/parisc/gsc.c +++ b/trunk/drivers/parisc/gsc.c @@ -186,34 +186,29 @@ void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp) *irqp = irq; } -struct gsc_fixup_struct { - void (*choose_irq)(struct parisc_device *, void *); - void *ctrl; -}; - -static int gsc_fixup_irqs_callback(struct device *dev, void *data) +static struct device *next_device(struct klist_iter *i) { - struct parisc_device *padev = to_parisc_device(dev); - struct gsc_fixup_struct *gf = data; - - /* work-around for 715/64 and others which have parent - at path [5] and children at path [5/0/x] */ - if (padev->id.hw_type == HPHW_FAULTY) - gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq); - gf->choose_irq(padev, gf->ctrl); - - return 0; + struct klist_node * n = klist_next(i); + return n ? container_of(n, struct device, knode_parent) : NULL; } void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, void (*choose_irq)(struct parisc_device *, void *)) { - struct gsc_fixup_struct data = { - .choose_irq = choose_irq, - .ctrl = ctrl, - }; - - device_for_each_child(&parent->dev, &data, gsc_fixup_irqs_callback); + struct device *dev; + struct klist_iter i; + + klist_iter_init(&parent->dev.klist_children, &i); + while ((dev = next_device(&i))) { + struct parisc_device *padev = to_parisc_device(dev); + + /* work-around for 715/64 and others which have parent + at path [5] and children at path [5/0/x] */ + if (padev->id.hw_type == HPHW_FAULTY) + return gsc_fixup_irqs(padev, ctrl, choose_irq); + choose_irq(padev, ctrl); + } + klist_iter_exit(&i); } int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) diff --git a/trunk/drivers/parisc/iosapic.c b/trunk/drivers/parisc/iosapic.c index 501aaf1f253f..0797659ee016 100644 --- a/trunk/drivers/parisc/iosapic.c +++ b/trunk/drivers/parisc/iosapic.c @@ -487,7 +487,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev) } /* Check if pcidev behind a PPB */ - if (pcidev->bus->parent) { + if (NULL != pcidev->bus->self) { /* Convert pcidev INTR_PIN into something we ** can lookup in the IRT. */ @@ -523,9 +523,10 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev) #endif /* PCI_BRIDGE_FUNCS */ /* - * Locate the host slot of the PPB. - */ - while (p->parent->parent) + ** Locate the host slot the PPB nearest the Host bus + ** adapter. + */ + while (NULL != p->parent->self) p = p->parent; intr_slot = PCI_SLOT(p->self->devfn); @@ -708,14 +709,11 @@ static void iosapic_set_affinity_irq(unsigned int irq, struct vector_info *vi = iosapic_get_vector(irq); u32 d0, d1, dummy_d0; unsigned long flags; - int dest_cpu; - dest_cpu = cpu_check_affinity(irq, dest); - if (dest_cpu < 0) + if (cpu_check_affinity(irq, dest)) return; - irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu); - vi->txn_addr = txn_affinity_addr(irq, dest_cpu); + vi->txn_addr = txn_affinity_addr(irq, cpumask_first(dest)); spin_lock_irqsave(&iosapic_lock, flags); /* d1 contains the destination CPU, so only want to set that diff --git a/trunk/drivers/parisc/lba_pci.c b/trunk/drivers/parisc/lba_pci.c index 59fbbf128365..d8233de8c75d 100644 --- a/trunk/drivers/parisc/lba_pci.c +++ b/trunk/drivers/parisc/lba_pci.c @@ -644,7 +644,7 @@ lba_fixup_bus(struct pci_bus *bus) ** Properly Setup MMIO resources for this bus. ** pci_alloc_primary_bus() mangles this. */ - if (bus->parent) { + if (bus->self) { int i; /* PCI-PCI Bridge */ pci_read_bridge_bases(bus); @@ -802,7 +802,7 @@ lba_fixup_bus(struct pci_bus *bus) ** Can't fixup here anyway....garr... */ if (fbb_enable) { - if (bus->parent) { + if (bus->self) { u8 control; /* enable on PPB */ (void) pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &control); diff --git a/trunk/drivers/parisc/sba_iommu.c b/trunk/drivers/parisc/sba_iommu.c index e5999c4cedc8..a70cf16ee1ad 100644 --- a/trunk/drivers/parisc/sba_iommu.c +++ b/trunk/drivers/parisc/sba_iommu.c @@ -1206,48 +1206,30 @@ sba_alloc_pdir(unsigned int pdir_size) return (void *) pdir_base; } -struct ibase_data_struct { - struct ioc *ioc; - int ioc_num; -}; - -static int setup_ibase_imask_callback(struct device *dev, void *data) +static struct device *next_device(struct klist_iter *i) { - /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ - extern void lba_set_iregs(struct parisc_device *, u32, u32); - struct parisc_device *lba = to_parisc_device(dev); - struct ibase_data_struct *ibd = data; - int rope_num = (lba->hpa.start >> 13) & 0xf; - if (rope_num >> 3 == ibd->ioc_num) - lba_set_iregs(lba, ibd->ioc->ibase, ibd->ioc->imask); - return 0; + struct klist_node * n = klist_next(i); + return n ? container_of(n, struct device, knode_parent) : NULL; } /* setup Mercury or Elroy IBASE/IMASK registers. */ static void setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num) { - struct ibase_data_struct ibase_data = { - .ioc = ioc, - .ioc_num = ioc_num, - }; - - device_for_each_child(&sba->dev, &ibase_data, - setup_ibase_imask_callback); -} - -#ifdef SBA_AGP_SUPPORT -static int -sba_ioc_find_quicksilver(struct device *dev, void *data) -{ - int *agp_found = data; - struct parisc_device *lba = to_parisc_device(dev); - - if (IS_QUICKSILVER(lba)) - *agp_found = 1; - return 0; + /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ + extern void lba_set_iregs(struct parisc_device *, u32, u32); + struct device *dev; + struct klist_iter i; + + klist_iter_init(&sba->dev.klist_children, &i); + while ((dev = next_device(&i))) { + struct parisc_device *lba = to_parisc_device(dev); + int rope_num = (lba->hpa.start >> 13) & 0xf; + if (rope_num >> 3 == ioc_num) + lba_set_iregs(lba, ioc->ibase, ioc->imask); + } + klist_iter_exit(&i); } -#endif static void sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) @@ -1350,6 +1332,9 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM); #ifdef SBA_AGP_SUPPORT +{ + struct klist_iter i; + struct device *dev = NULL; /* ** If an AGP device is present, only use half of the IOV space @@ -1359,7 +1344,13 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ** We program the next pdir index after we stop w/ a key for ** the GART code to handshake on. */ - device_for_each_child(&sba->dev, &agp_found, sba_ioc_find_quicksilver); + klist_iter_init(&sba->dev.klist_children, &i); + while ((dev = next_device(&i))) { + struct parisc_device *lba = to_parisc_device(dev); + if (IS_QUICKSILVER(lba)) + agp_found = 1; + } + klist_iter_exit(&i); if (agp_found && sba_reserve_agpgart) { printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n", @@ -1367,7 +1358,9 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ioc->pdir_size /= 2; ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE; } +} #endif /*SBA_AGP_SUPPORT*/ + } static void diff --git a/trunk/drivers/platform/x86/Kconfig b/trunk/drivers/platform/x86/Kconfig index 3608081bc3e0..b3866ad50227 100644 --- a/trunk/drivers/platform/x86/Kconfig +++ b/trunk/drivers/platform/x86/Kconfig @@ -15,7 +15,8 @@ menuconfig X86_PLATFORM_DEVICES if X86_PLATFORM_DEVICES config ACER_WMI - tristate "Acer WMI Laptop Extras" + tristate "Acer WMI Laptop Extras (EXPERIMENTAL)" + depends on EXPERIMENTAL depends on ACPI depends on LEDS_CLASS depends on NEW_LEDS @@ -38,9 +39,9 @@ config ASUS_LAPTOP tristate "Asus Laptop Extras (EXPERIMENTAL)" depends on ACPI depends on EXPERIMENTAL && !ACPI_ASUS - select LEDS_CLASS - select NEW_LEDS - select BACKLIGHT_CLASS_DEVICE + depends on LEDS_CLASS + depends on NEW_LEDS + depends on BACKLIGHT_CLASS_DEVICE depends on INPUT ---help--- This is the new Linux driver for Asus laptops. It may also support some @@ -184,11 +185,11 @@ config SONYPI_COMPAT config THINKPAD_ACPI tristate "ThinkPad ACPI Laptop Extras" depends on ACPI - depends on INPUT select BACKLIGHT_LCD_SUPPORT select BACKLIGHT_CLASS_DEVICE select HWMON select NVRAM + select INPUT select NEW_LEDS select LEDS_CLASS select NET @@ -314,8 +315,9 @@ config EEEPC_LAPTOP config ACPI_WMI - tristate "WMI" + tristate "WMI (EXPERIMENTAL)" depends on ACPI + depends on EXPERIMENTAL help This driver adds support for the ACPI-WMI (Windows Management Instrumentation) mapper device (PNP0C14) found on some systems. diff --git a/trunk/drivers/platform/x86/acer-wmi.c b/trunk/drivers/platform/x86/acer-wmi.c index a6a42e8c060b..6bcca616a704 100644 --- a/trunk/drivers/platform/x86/acer-wmi.c +++ b/trunk/drivers/platform/x86/acer-wmi.c @@ -1026,7 +1026,7 @@ static void acer_rfkill_exit(void) kfree(wireless_rfkill->data); rfkill_unregister(wireless_rfkill); if (has_cap(ACER_CAP_BLUETOOTH)) { - kfree(bluetooth_rfkill->data); + kfree(wireless_rfkill->data); rfkill_unregister(bluetooth_rfkill); } return; diff --git a/trunk/drivers/platform/x86/asus-laptop.c b/trunk/drivers/platform/x86/asus-laptop.c index eeafc6c0160d..56af6cf385b0 100644 --- a/trunk/drivers/platform/x86/asus-laptop.c +++ b/trunk/drivers/platform/x86/asus-laptop.c @@ -815,7 +815,6 @@ static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) { static struct key_entry *key; - u16 count; /* TODO Find a better way to handle events count. */ if (!hotk) @@ -833,11 +832,9 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) lcd_blank(FB_BLANK_POWERDOWN); } - count = hotk->event_count[event % 128]++; - acpi_bus_generate_proc_event(hotk->device, event, count); acpi_bus_generate_netlink_event(hotk->device->pnp.device_class, dev_name(&hotk->device->dev), event, - count); + hotk->event_count[event % 128]++); if (hotk->inputdev) { key = asus_get_entry_by_scancode(event); diff --git a/trunk/drivers/platform/x86/eeepc-laptop.c b/trunk/drivers/platform/x86/eeepc-laptop.c index 6f54fd1757cd..786ed8661cb0 100644 --- a/trunk/drivers/platform/x86/eeepc-laptop.c +++ b/trunk/drivers/platform/x86/eeepc-laptop.c @@ -557,17 +557,13 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) { static struct key_entry *key; - u16 count; - if (!ehotk) return; if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) notify_brn(); - count = ehotk->event_count[event % 128]++; - acpi_bus_generate_proc_event(ehotk->device, event, count); acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, dev_name(&ehotk->device->dev), event, - count); + ehotk->event_count[event % 128]++); if (ehotk->inputdev) { key = eepc_get_entry_by_scancode(event); if (key) { diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index d2433204a40c..bcbc05107ba8 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -7532,7 +7532,7 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); * if it is not there yet. */ #define IBM_BIOS_MODULE_ALIAS(__type) \ - MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*") + MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW") /* Non-ancient thinkpads */ MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); @@ -7541,9 +7541,9 @@ MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*"); /* Ancient thinkpad BIOSes have to be identified by * BIOS type or model number, and there are far less * BIOS types than model numbers... */ -IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]"); -IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]"); -IBM_BIOS_MODULE_ALIAS("K[UX-Z]"); +IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]"); +IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]"); +IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); MODULE_DESCRIPTION(TPACPI_DESC); diff --git a/trunk/drivers/platform/x86/wmi.c b/trunk/drivers/platform/x86/wmi.c index 2f269e117b8f..8a8b377712c9 100644 --- a/trunk/drivers/platform/x86/wmi.c +++ b/trunk/drivers/platform/x86/wmi.c @@ -708,7 +708,7 @@ static int __init acpi_wmi_add(struct acpi_device *device) static int __init acpi_wmi_init(void) { - int result; + acpi_status result; INIT_LIST_HEAD(&wmi_blocks.list); diff --git a/trunk/drivers/sbus/char/openprom.c b/trunk/drivers/sbus/char/openprom.c index 124f660a0383..29dc735e1a20 100644 --- a/trunk/drivers/sbus/char/openprom.c +++ b/trunk/drivers/sbus/char/openprom.c @@ -51,7 +51,6 @@ MODULE_AUTHOR("Thomas K. Dyas (tdyas@noc.rutgers.edu) and Eddie C. Dost (ecd@sk MODULE_DESCRIPTION("OPENPROM Configuration Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0"); -MODULE_ALIAS_MISCDEV(SUN_OPENPROM_MINOR); /* Private data kept by the driver for each descriptor. */ typedef struct openprom_private_data diff --git a/trunk/drivers/scsi/fcoe/fc_transport_fcoe.c b/trunk/drivers/scsi/fcoe/fc_transport_fcoe.c index 8862758006c0..bf7fe6fc0820 100644 --- a/trunk/drivers/scsi/fcoe/fc_transport_fcoe.c +++ b/trunk/drivers/scsi/fcoe/fc_transport_fcoe.c @@ -33,19 +33,19 @@ static LIST_HEAD(fcoe_transports); static DEFINE_MUTEX(fcoe_transports_lock); /** - * fcoe_transport_default() - Returns ptr to the default transport fcoe_sw - */ + * fcoe_transport_default - returns ptr to the default transport fcoe_sw + **/ struct fcoe_transport *fcoe_transport_default(void) { return &fcoe_sw_transport; } /** - * fcoe_transport_to_pcidev() - get the pci dev from a netdev + * fcoe_transport_to_pcidev - get the pci dev from a netdev * @netdev: the netdev that pci dev will be retrived from * * Returns: NULL or the corrsponding pci_dev - */ + **/ struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev) { if (!netdev->dev.parent) @@ -54,17 +54,18 @@ struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev) } /** - * fcoe_transport_device_lookup() - Lookup a transport + * fcoe_transport_device_lookup - find out netdev is managed by the + * transport + * assign a transport to a device * @netdev: the netdev the transport to be attached to * * This will look for existing offload driver, if not found, it falls back to * the default sw hba (fcoe_sw) as its fcoe transport. * * Returns: 0 for success - */ -static struct fcoe_transport_internal * -fcoe_transport_device_lookup(struct fcoe_transport *t, - struct net_device *netdev) + **/ +static struct fcoe_transport_internal *fcoe_transport_device_lookup( + struct fcoe_transport *t, struct net_device *netdev) { struct fcoe_transport_internal *ti; @@ -80,14 +81,14 @@ fcoe_transport_device_lookup(struct fcoe_transport *t, return NULL; } /** - * fcoe_transport_device_add() - Assign a transport to a device + * fcoe_transport_device_add - assign a transport to a device * @netdev: the netdev the transport to be attached to * * This will look for existing offload driver, if not found, it falls back to * the default sw hba (fcoe_sw) as its fcoe transport. * * Returns: 0 for success - */ + **/ static int fcoe_transport_device_add(struct fcoe_transport *t, struct net_device *netdev) { @@ -122,14 +123,14 @@ static int fcoe_transport_device_add(struct fcoe_transport *t, } /** - * fcoe_transport_device_remove() - Remove a device from its transport + * fcoe_transport_device_remove - remove a device from its transport * @netdev: the netdev the transport to be attached to * - * This removes the device from the transport so the given transport will + * this removes the device from the transport so the given transport will * not manage this device any more * * Returns: 0 for success - */ + **/ static int fcoe_transport_device_remove(struct fcoe_transport *t, struct net_device *netdev) { @@ -154,13 +155,13 @@ static int fcoe_transport_device_remove(struct fcoe_transport *t, } /** - * fcoe_transport_device_remove_all() - Remove all from transport devlist + * fcoe_transport_device_remove_all - remove all from transport devlist * - * This removes the device from the transport so the given transport will + * this removes the device from the transport so the given transport will * not manage this device any more * * Returns: 0 for success - */ + **/ static void fcoe_transport_device_remove_all(struct fcoe_transport *t) { struct fcoe_transport_internal *ti, *tmp; @@ -174,18 +175,18 @@ static void fcoe_transport_device_remove_all(struct fcoe_transport *t) } /** - * fcoe_transport_match() - Use the bus device match function to match the hw - * @t: The fcoe transport to check - * @netdev: The netdev to match against + * fcoe_transport_match - use the bus device match function to match the hw + * @t: the fcoe transport + * @netdev: * - * This function is used to check if the given transport wants to manage the + * This function is used to check if the givne transport wants to manage the * input netdev. if the transports implements the match function, it will be * called, o.w. we just compare the pci vendor and device id. * * Returns: true for match up - */ + **/ static bool fcoe_transport_match(struct fcoe_transport *t, - struct net_device *netdev) + struct net_device *netdev) { /* match transport by vendor and device id */ struct pci_dev *pci; @@ -209,17 +210,17 @@ static bool fcoe_transport_match(struct fcoe_transport *t, } /** - * fcoe_transport_lookup() - Check if the transport is already registered + * fcoe_transport_lookup - check if the transport is already registered * @t: the transport to be looked up * * This compares the parent device (pci) vendor and device id * * Returns: NULL if not found * - * TODO: return default sw transport if no other transport is found - */ -static struct fcoe_transport * -fcoe_transport_lookup(struct net_device *netdev) + * TODO - return default sw transport if no other transport is found + **/ +static struct fcoe_transport *fcoe_transport_lookup( + struct net_device *netdev) { struct fcoe_transport *t; @@ -238,11 +239,11 @@ fcoe_transport_lookup(struct net_device *netdev) } /** - * fcoe_transport_register() - Adds a fcoe transport to the fcoe transports list + * fcoe_transport_register - adds a fcoe transport to the fcoe transports list * @t: ptr to the fcoe transport to be added * * Returns: 0 for success - */ + **/ int fcoe_transport_register(struct fcoe_transport *t) { struct fcoe_transport *tt; @@ -258,6 +259,9 @@ int fcoe_transport_register(struct fcoe_transport *t) list_add_tail(&t->list, &fcoe_transports); mutex_unlock(&fcoe_transports_lock); + mutex_init(&t->devlock); + INIT_LIST_HEAD(&t->devlist); + printk(KERN_DEBUG "fcoe_transport_register:%s\n", t->name); return 0; @@ -265,11 +269,11 @@ int fcoe_transport_register(struct fcoe_transport *t) EXPORT_SYMBOL_GPL(fcoe_transport_register); /** - * fcoe_transport_unregister() - Remove the tranport fro the fcoe transports list + * fcoe_transport_unregister - remove the tranport fro the fcoe transports list * @t: ptr to the fcoe transport to be removed * * Returns: 0 for success - */ + **/ int fcoe_transport_unregister(struct fcoe_transport *t) { struct fcoe_transport *tt, *tmp; @@ -290,8 +294,8 @@ int fcoe_transport_unregister(struct fcoe_transport *t) } EXPORT_SYMBOL_GPL(fcoe_transport_unregister); -/** - * fcoe_load_transport_driver() - Load an offload driver by alias name +/* + * fcoe_load_transport_driver - load an offload driver by alias name * @netdev: the target net device * * Requests for an offload driver module as the fcoe transport, if fails, it @@ -303,7 +307,7 @@ EXPORT_SYMBOL_GPL(fcoe_transport_unregister); * 3. pure hw fcoe hba may not have netdev * * Returns: 0 for success - */ + **/ int fcoe_load_transport_driver(struct net_device *netdev) { struct pci_dev *pci; @@ -331,14 +335,14 @@ int fcoe_load_transport_driver(struct net_device *netdev) EXPORT_SYMBOL_GPL(fcoe_load_transport_driver); /** - * fcoe_transport_attach() - Load transport to fcoe + * fcoe_transport_attach - load transport to fcoe * @netdev: the netdev the transport to be attached to * * This will look for existing offload driver, if not found, it falls back to * the default sw hba (fcoe_sw) as its fcoe transport. * * Returns: 0 for success - */ + **/ int fcoe_transport_attach(struct net_device *netdev) { struct fcoe_transport *t; @@ -369,11 +373,11 @@ int fcoe_transport_attach(struct net_device *netdev) EXPORT_SYMBOL_GPL(fcoe_transport_attach); /** - * fcoe_transport_release() - Unload transport from fcoe + * fcoe_transport_release - unload transport from fcoe * @netdev: the net device on which fcoe is to be released * * Returns: 0 for success - */ + **/ int fcoe_transport_release(struct net_device *netdev) { struct fcoe_transport *t; @@ -406,12 +410,12 @@ int fcoe_transport_release(struct net_device *netdev) EXPORT_SYMBOL_GPL(fcoe_transport_release); /** - * fcoe_transport_init() - Initializes fcoe transport layer + * fcoe_transport_init - initializes fcoe transport layer * * This prepares for the fcoe transport layer * * Returns: none - */ + **/ int __init fcoe_transport_init(void) { INIT_LIST_HEAD(&fcoe_transports); @@ -420,13 +424,12 @@ int __init fcoe_transport_init(void) } /** - * fcoe_transport_exit() - Cleans up the fcoe transport layer - * + * fcoe_transport_exit - cleans up the fcoe transport layer * This cleans up the fcoe transport layer. removing any transport on the list, * note that the transport destroy func is not called here. * * Returns: none - */ + **/ int __exit fcoe_transport_exit(void) { struct fcoe_transport *t, *tmp; diff --git a/trunk/drivers/scsi/fcoe/fcoe_sw.c b/trunk/drivers/scsi/fcoe/fcoe_sw.c index da210eba1941..dc4cd5e25760 100644 --- a/trunk/drivers/scsi/fcoe/fcoe_sw.c +++ b/trunk/drivers/scsi/fcoe/fcoe_sw.c @@ -104,19 +104,19 @@ static struct scsi_host_template fcoe_sw_shost_template = { .max_sectors = 0xffff, }; -/** - * fcoe_sw_lport_config() - sets up the fc_lport +/* + * fcoe_sw_lport_config - sets up the fc_lport * @lp: ptr to the fc_lport * @shost: ptr to the parent scsi host * * Returns: 0 for success + * */ static int fcoe_sw_lport_config(struct fc_lport *lp) { int i = 0; - lp->link_up = 0; - lp->qfull = 0; + lp->link_status = 0; lp->max_retry_count = 3; lp->e_d_tov = 2 * 1000; /* FC-FS default */ lp->r_a_tov = 2 * 2 * 1000; @@ -136,14 +136,16 @@ static int fcoe_sw_lport_config(struct fc_lport *lp) return 0; } -/** - * fcoe_sw_netdev_config() - Set up netdev for SW FCoE +/* + * fcoe_sw_netdev_config - sets up fcoe_softc for lport and network + * related properties * @lp : ptr to the fc_lport * @netdev : ptr to the associated netdevice struct * * Must be called after fcoe_sw_lport_config() as it will use lport mutex * * Returns : 0 for success + * */ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev) { @@ -179,8 +181,9 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev) if (fc_set_mfs(lp, mfs)) return -EINVAL; + lp->link_status = ~FC_PAUSE & ~FC_LINK_UP; if (!fcoe_link_ok(lp)) - lp->link_up = 1; + lp->link_status |= FC_LINK_UP; /* offload features support */ if (fc->real_dev->features & NETIF_F_SG) @@ -188,7 +191,6 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev) skb_queue_head_init(&fc->fcoe_pending_queue); - fc->fcoe_pending_queue_active = 0; /* setup Source Mac Address */ memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr, @@ -222,15 +224,16 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev) return 0; } -/** - * fcoe_sw_shost_config() - Sets up fc_lport->host +/* + * fcoe_sw_shost_config - sets up fc_lport->host * @lp : ptr to the fc_lport * @shost : ptr to the associated scsi host * @dev : device associated to scsi host * - * Must be called after fcoe_sw_lport_config() and fcoe_sw_netdev_config() + * Must be called after fcoe_sw_lport_config) and fcoe_sw_netdev_config() * * Returns : 0 for success + * */ static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost, struct device *dev) @@ -258,8 +261,8 @@ static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost, return 0; } -/** - * fcoe_sw_em_config() - allocates em for this lport +/* + * fcoe_sw_em_config - allocates em for this lport * @lp: the port that em is to allocated for * * Returns : 0 on success @@ -276,8 +279,8 @@ static inline int fcoe_sw_em_config(struct fc_lport *lp) return 0; } -/** - * fcoe_sw_destroy() - FCoE software HBA tear-down function +/* + * fcoe_sw_destroy - FCoE software HBA tear-down function * @netdev: ptr to the associated net_device * * Returns: 0 if link is OK for use by FCoE. @@ -298,7 +301,7 @@ static int fcoe_sw_destroy(struct net_device *netdev) if (!lp) return -ENODEV; - fc = lport_priv(lp); + fc = fcoe_softc(lp); /* Logout of the fabric */ fc_fabric_logoff(lp); @@ -350,8 +353,8 @@ static struct libfc_function_template fcoe_sw_libfc_fcn_templ = { .frame_send = fcoe_xmit, }; -/** - * fcoe_sw_create() - this function creates the fcoe interface +/* + * fcoe_sw_create - this function creates the fcoe interface * @netdev: pointer the associated netdevice * * Creates fc_lport struct and scsi_host for lport, configures lport @@ -437,8 +440,8 @@ static int fcoe_sw_create(struct net_device *netdev) return rc; } -/** - * fcoe_sw_match() - The FCoE SW transport match function +/* + * fcoe_sw_match - the fcoe sw transport match function * * Returns : false always */ @@ -458,8 +461,8 @@ struct fcoe_transport fcoe_sw_transport = { .device = 0xffff, }; -/** - * fcoe_sw_init() - Registers fcoe_sw_transport +/* + * fcoe_sw_init - registers fcoe_sw_transport * * Returns : 0 on success */ @@ -468,22 +471,17 @@ int __init fcoe_sw_init(void) /* attach to scsi transport */ scsi_transport_fcoe_sw = fc_attach_transport(&fcoe_sw_transport_function); - if (!scsi_transport_fcoe_sw) { printk(KERN_ERR "fcoe_sw_init:fc_attach_transport() failed\n"); return -ENODEV; } - - mutex_init(&fcoe_sw_transport.devlock); - INIT_LIST_HEAD(&fcoe_sw_transport.devlist); - /* register sw transport */ fcoe_transport_register(&fcoe_sw_transport); return 0; } -/** - * fcoe_sw_exit() - Unregisters fcoe_sw_transport +/* + * fcoe_sw_exit - unregisters fcoe_sw_transport * * Returns : 0 on success */ diff --git a/trunk/drivers/scsi/fcoe/libfcoe.c b/trunk/drivers/scsi/fcoe/libfcoe.c index 5548bf3bb58b..e419f486cdb3 100644 --- a/trunk/drivers/scsi/fcoe/libfcoe.c +++ b/trunk/drivers/scsi/fcoe/libfcoe.c @@ -49,7 +49,6 @@ static int debug_fcoe; #define FCOE_MAX_QUEUE_DEPTH 256 -#define FCOE_LOW_QUEUE_DEPTH 32 /* destination address mode */ #define FCOE_GW_ADDR_MODE 0x00 @@ -70,6 +69,8 @@ struct fcoe_percpu_s *fcoe_percpu[NR_CPUS]; /* Function Prototyes */ static int fcoe_check_wait_queue(struct fc_lport *); +static void fcoe_insert_wait_queue_head(struct fc_lport *, struct sk_buff *); +static void fcoe_insert_wait_queue(struct fc_lport *, struct sk_buff *); static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *); #ifdef CONFIG_HOTPLUG_CPU static int fcoe_cpu_callback(struct notifier_block *, ulong, void *); @@ -90,13 +91,13 @@ static struct notifier_block fcoe_cpu_notifier = { }; /** - * fcoe_create_percpu_data() - creates the associated cpu data + * fcoe_create_percpu_data - creates the associated cpu data * @cpu: index for the cpu where fcoe cpu data will be created * * create percpu stats block, from cpu add notifier * * Returns: none - */ + **/ static void fcoe_create_percpu_data(int cpu) { struct fc_lport *lp; @@ -114,13 +115,13 @@ static void fcoe_create_percpu_data(int cpu) } /** - * fcoe_destroy_percpu_data() - destroys the associated cpu data + * fcoe_destroy_percpu_data - destroys the associated cpu data * @cpu: index for the cpu where fcoe cpu data will destroyed * * destroy percpu stats block called by cpu add/remove notifier * * Retuns: none - */ + **/ static void fcoe_destroy_percpu_data(int cpu) { struct fc_lport *lp; @@ -136,7 +137,7 @@ static void fcoe_destroy_percpu_data(int cpu) } /** - * fcoe_cpu_callback() - fcoe cpu hotplug event callback + * fcoe_cpu_callback - fcoe cpu hotplug event callback * @nfb: callback data block * @action: event triggering the callback * @hcpu: index for the cpu of this event @@ -144,7 +145,7 @@ static void fcoe_destroy_percpu_data(int cpu) * this creates or destroys per cpu data for fcoe * * Returns NOTIFY_OK always. - */ + **/ static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -165,7 +166,7 @@ static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action, #endif /* CONFIG_HOTPLUG_CPU */ /** - * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ + * fcoe_rcv - this is the fcoe receive function called by NET_RX_SOFTIRQ * @skb: the receive skb * @dev: associated net device * @ptype: context @@ -174,7 +175,7 @@ static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action, * this function will receive the packet and build fc frame and pass it up * * Returns: 0 for success - */ + **/ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *olddev) { @@ -264,11 +265,11 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, EXPORT_SYMBOL_GPL(fcoe_rcv); /** - * fcoe_start_io() - pass to netdev to start xmit for fcoe + * fcoe_start_io - pass to netdev to start xmit for fcoe * @skb: the skb to be xmitted * * Returns: 0 for success - */ + **/ static inline int fcoe_start_io(struct sk_buff *skb) { int rc; @@ -282,12 +283,12 @@ static inline int fcoe_start_io(struct sk_buff *skb) } /** - * fcoe_get_paged_crc_eof() - in case we need alloc a page for crc_eof + * fcoe_get_paged_crc_eof - in case we need alloc a page for crc_eof * @skb: the skb to be xmitted * @tlen: total len * * Returns: 0 for success - */ + **/ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) { struct fcoe_percpu_s *fps; @@ -325,12 +326,13 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) } /** - * fcoe_fc_crc() - calculates FC CRC in this fcoe skb + * fcoe_fc_crc - calculates FC CRC in this fcoe skb * @fp: the fc_frame containg data to be checksummed * * This uses crc32() to calculate the crc for fc frame * Return : 32 bit crc - */ + * + **/ u32 fcoe_fc_crc(struct fc_frame *fp) { struct sk_buff *skb = fp_skb(fp); @@ -361,12 +363,13 @@ u32 fcoe_fc_crc(struct fc_frame *fp) EXPORT_SYMBOL_GPL(fcoe_fc_crc); /** - * fcoe_xmit() - FCoE frame transmit function + * fcoe_xmit - FCoE frame transmit function * @lp: the associated local port * @fp: the fc_frame to be transmitted * * Return : 0 for success - */ + * + **/ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) { int wlen, rc = 0; @@ -386,7 +389,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) WARN_ON((fr_len(fp) % sizeof(u32)) != 0); - fc = lport_priv(lp); + fc = fcoe_softc(lp); /* * if it is a flogi then we need to learn gw-addr * and my own fcid @@ -436,7 +439,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) if (skb_is_nonlinear(skb)) { skb_frag_t *frag; if (fcoe_get_paged_crc_eof(skb, tlen)) { - kfree_skb(skb); + kfree(skb); return -ENOMEM; } frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1]; @@ -499,22 +502,21 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) rc = fcoe_start_io(skb); if (rc) { - spin_lock_bh(&fc->fcoe_pending_queue.lock); - __skb_queue_tail(&fc->fcoe_pending_queue, skb); - spin_unlock_bh(&fc->fcoe_pending_queue.lock); + fcoe_insert_wait_queue(lp, skb); if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) - lp->qfull = 1; + fc_pause(lp); } return 0; } EXPORT_SYMBOL_GPL(fcoe_xmit); -/** - * fcoe_percpu_receive_thread() - recv thread per cpu +/* + * fcoe_percpu_receive_thread - recv thread per cpu * @arg: ptr to the fcoe per cpu struct * * Return: 0 for success + * */ int fcoe_percpu_receive_thread(void *arg) { @@ -531,7 +533,7 @@ int fcoe_percpu_receive_thread(void *arg) struct fcoe_softc *fc; struct fcoe_hdr *hp; - set_user_nice(current, -20); + set_user_nice(current, 19); while (!kthread_should_stop()) { @@ -656,7 +658,7 @@ int fcoe_percpu_receive_thread(void *arg) } /** - * fcoe_recv_flogi() - flogi receive function + * fcoe_recv_flogi - flogi receive function * @fc: associated fcoe_softc * @fp: the recieved frame * @sa: the source address of this flogi @@ -665,7 +667,7 @@ int fcoe_percpu_receive_thread(void *arg) * mac address for the initiator, eitehr OUI based or GW based. * * Returns: none - */ + **/ static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa) { struct fc_frame_header *fh; @@ -713,23 +715,32 @@ static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa) } /** - * fcoe_watchdog() - fcoe timer callback + * fcoe_watchdog - fcoe timer callback * @vp: * - * This checks the pending queue length for fcoe and set lport qfull + * This checks the pending queue length for fcoe and put fcoe to be paused state * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the * fcoe_hostlist. * * Returns: 0 for success - */ + **/ void fcoe_watchdog(ulong vp) { + struct fc_lport *lp; struct fcoe_softc *fc; + int paused = 0; read_lock(&fcoe_hostlist_lock); list_for_each_entry(fc, &fcoe_hostlist, list) { - if (fc->lp) - fcoe_check_wait_queue(fc->lp); + lp = fc->lp; + if (lp) { + if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) + paused = 1; + if (fcoe_check_wait_queue(lp) < FCOE_MAX_QUEUE_DEPTH) { + if (paused) + fc_unpause(lp); + } + } } read_unlock(&fcoe_hostlist_lock); @@ -739,64 +750,96 @@ void fcoe_watchdog(ulong vp) /** - * fcoe_check_wait_queue() - put the skb into fcoe pending xmit queue + * fcoe_check_wait_queue - put the skb into fcoe pending xmit queue * @lp: the fc_port for this skb * @skb: the associated skb to be xmitted * * This empties the wait_queue, dequeue the head of the wait_queue queue * and calls fcoe_start_io() for each packet, if all skb have been - * transmitted, return qlen or -1 if a error occurs, then restore - * wait_queue and try again later. + * transmitted, return 0 if a error occurs, then restore wait_queue and + * try again later. * * The wait_queue is used when the skb transmit fails. skb will go * in the wait_queue which will be emptied by the time function OR * by the next skb transmit. * * Returns: 0 for success - */ + **/ static int fcoe_check_wait_queue(struct fc_lport *lp) { - struct fcoe_softc *fc = lport_priv(lp); + int rc, unpause = 0; + int paused = 0; struct sk_buff *skb; - int rc = -1; + struct fcoe_softc *fc; + fc = fcoe_softc(lp); spin_lock_bh(&fc->fcoe_pending_queue.lock); - if (fc->fcoe_pending_queue_active) - goto out; - fc->fcoe_pending_queue_active = 1; - while (fc->fcoe_pending_queue.qlen) { - /* keep qlen > 0 until fcoe_start_io succeeds */ - fc->fcoe_pending_queue.qlen++; - skb = __skb_dequeue(&fc->fcoe_pending_queue); - - spin_unlock_bh(&fc->fcoe_pending_queue.lock); - rc = fcoe_start_io(skb); - spin_lock_bh(&fc->fcoe_pending_queue.lock); - - if (rc) { - __skb_queue_head(&fc->fcoe_pending_queue, skb); - /* undo temporary increment above */ - fc->fcoe_pending_queue.qlen--; - break; + /* + * is this interface paused? + */ + if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) + paused = 1; + if (fc->fcoe_pending_queue.qlen) { + while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) { + spin_unlock_bh(&fc->fcoe_pending_queue.lock); + rc = fcoe_start_io(skb); + if (rc) { + fcoe_insert_wait_queue_head(lp, skb); + return rc; + } + spin_lock_bh(&fc->fcoe_pending_queue.lock); } - /* undo temporary increment above */ - fc->fcoe_pending_queue.qlen--; + if (fc->fcoe_pending_queue.qlen < FCOE_MAX_QUEUE_DEPTH) + unpause = 1; } + spin_unlock_bh(&fc->fcoe_pending_queue.lock); + if ((unpause) && (paused)) + fc_unpause(lp); + return fc->fcoe_pending_queue.qlen; +} - if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) - lp->qfull = 0; - fc->fcoe_pending_queue_active = 0; - rc = fc->fcoe_pending_queue.qlen; -out: +/** + * fcoe_insert_wait_queue_head - puts skb to fcoe pending queue head + * @lp: the fc_port for this skb + * @skb: the associated skb to be xmitted + * + * Returns: none + **/ +static void fcoe_insert_wait_queue_head(struct fc_lport *lp, + struct sk_buff *skb) +{ + struct fcoe_softc *fc; + + fc = fcoe_softc(lp); + spin_lock_bh(&fc->fcoe_pending_queue.lock); + __skb_queue_head(&fc->fcoe_pending_queue, skb); spin_unlock_bh(&fc->fcoe_pending_queue.lock); - return rc; } /** - * fcoe_dev_setup() - setup link change notification interface - */ -static void fcoe_dev_setup() + * fcoe_insert_wait_queue - put the skb into fcoe pending queue tail + * @lp: the fc_port for this skb + * @skb: the associated skb to be xmitted + * + * Returns: none + **/ +static void fcoe_insert_wait_queue(struct fc_lport *lp, + struct sk_buff *skb) +{ + struct fcoe_softc *fc; + + fc = fcoe_softc(lp); + spin_lock_bh(&fc->fcoe_pending_queue.lock); + __skb_queue_tail(&fc->fcoe_pending_queue, skb); + spin_unlock_bh(&fc->fcoe_pending_queue.lock); +} + +/** + * fcoe_dev_setup - setup link change notification interface + * + **/ +static void fcoe_dev_setup(void) { /* * here setup a interface specific wd time to @@ -806,15 +849,15 @@ static void fcoe_dev_setup() } /** - * fcoe_dev_setup() - cleanup link change notification interface - */ + * fcoe_dev_setup - cleanup link change notification interface + **/ static void fcoe_dev_cleanup(void) { unregister_netdevice_notifier(&fcoe_notifier); } /** - * fcoe_device_notification() - netdev event notification callback + * fcoe_device_notification - netdev event notification callback * @notifier: context of the notification * @event: type of event * @ptr: fixed array for output parsed ifname @@ -822,7 +865,7 @@ static void fcoe_dev_cleanup(void) * This function is called by the ethernet driver in case of link change event * * Returns: 0 for success - */ + **/ static int fcoe_device_notification(struct notifier_block *notifier, ulong event, void *ptr) { @@ -830,7 +873,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, struct net_device *real_dev = ptr; struct fcoe_softc *fc; struct fcoe_dev_stats *stats; - u32 new_link_up; + u16 new_status; u32 mfs; int rc = NOTIFY_OK; @@ -847,15 +890,17 @@ static int fcoe_device_notification(struct notifier_block *notifier, goto out; } - new_link_up = lp->link_up; + new_status = lp->link_status; switch (event) { case NETDEV_DOWN: case NETDEV_GOING_DOWN: - new_link_up = 0; + new_status &= ~FC_LINK_UP; break; case NETDEV_UP: case NETDEV_CHANGE: - new_link_up = !fcoe_link_ok(lp); + new_status &= ~FC_LINK_UP; + if (!fcoe_link_ok(lp)) + new_status |= FC_LINK_UP; break; case NETDEV_CHANGEMTU: mfs = fc->real_dev->mtu - @@ -863,15 +908,17 @@ static int fcoe_device_notification(struct notifier_block *notifier, sizeof(struct fcoe_crc_eof)); if (mfs >= FC_MIN_MAX_FRAME) fc_set_mfs(lp, mfs); - new_link_up = !fcoe_link_ok(lp); + new_status &= ~FC_LINK_UP; + if (!fcoe_link_ok(lp)) + new_status |= FC_LINK_UP; break; case NETDEV_REGISTER: break; default: FC_DBG("unknown event %ld call", event); } - if (lp->link_up != new_link_up) { - if (new_link_up) + if (lp->link_status != new_status) { + if ((new_status & FC_LINK_UP) == FC_LINK_UP) fc_linkup(lp); else { stats = lp->dev_stats[smp_processor_id()]; @@ -886,12 +933,12 @@ static int fcoe_device_notification(struct notifier_block *notifier, } /** - * fcoe_if_to_netdev() - parse a name buffer to get netdev + * fcoe_if_to_netdev - parse a name buffer to get netdev * @ifname: fixed array for output parsed ifname * @buffer: incoming buffer to be copied * * Returns: NULL or ptr to netdeive - */ + **/ static struct net_device *fcoe_if_to_netdev(const char *buffer) { char *cp; @@ -908,13 +955,13 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer) } /** - * fcoe_netdev_to_module_owner() - finds out the nic drive moddule of the netdev + * fcoe_netdev_to_module_owner - finds out the nic drive moddule of the netdev * @netdev: the target netdev * * Returns: ptr to the struct module, NULL for failure - */ -static struct module * -fcoe_netdev_to_module_owner(const struct net_device *netdev) + **/ +static struct module *fcoe_netdev_to_module_owner( + const struct net_device *netdev) { struct device *dev; @@ -932,14 +979,12 @@ fcoe_netdev_to_module_owner(const struct net_device *netdev) } /** - * fcoe_ethdrv_get() - Hold the Ethernet driver - * @netdev: the target netdev - * - * Holds the Ethernet driver module by try_module_get() for + * fcoe_ethdrv_get - holds the nic driver module by try_module_get() for * the corresponding netdev. + * @netdev: the target netdev * * Returns: 0 for succsss - */ + **/ static int fcoe_ethdrv_get(const struct net_device *netdev) { struct module *owner; @@ -954,14 +999,12 @@ static int fcoe_ethdrv_get(const struct net_device *netdev) } /** - * fcoe_ethdrv_put() - Release the Ethernet driver - * @netdev: the target netdev - * - * Releases the Ethernet driver module by module_put for + * fcoe_ethdrv_get - releases the nic driver module by module_put for * the corresponding netdev. + * @netdev: the target netdev * * Returns: 0 for succsss - */ + **/ static int fcoe_ethdrv_put(const struct net_device *netdev) { struct module *owner; @@ -977,12 +1020,12 @@ static int fcoe_ethdrv_put(const struct net_device *netdev) } /** - * fcoe_destroy() - handles the destroy from sysfs + * fcoe_destroy- handles the destroy from sysfs * @buffer: expcted to be a eth if name * @kp: associated kernel param * * Returns: 0 for success - */ + **/ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) { int rc; @@ -1015,12 +1058,12 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) } /** - * fcoe_create() - Handles the create call from sysfs + * fcoe_create - handles the create call from sysfs * @buffer: expcted to be a eth if name * @kp: associated kernel param * * Returns: 0 for success - */ + **/ static int fcoe_create(const char *buffer, struct kernel_param *kp) { int rc; @@ -1061,8 +1104,8 @@ module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); __MODULE_PARM_TYPE(destroy, "string"); MODULE_PARM_DESC(destroy, "Destroy fcoe port"); -/** - * fcoe_link_ok() - Check if link is ok for the fc_lport +/* + * fcoe_link_ok - check if link is ok for the fc_lport * @lp: ptr to the fc_lport * * Any permanently-disqualifying conditions have been previously checked. @@ -1077,7 +1120,7 @@ MODULE_PARM_DESC(destroy, "Destroy fcoe port"); */ int fcoe_link_ok(struct fc_lport *lp) { - struct fcoe_softc *fc = lport_priv(lp); + struct fcoe_softc *fc = fcoe_softc(lp); struct net_device *dev = fc->real_dev; struct ethtool_cmd ecmd = { ETHTOOL_GSET }; int rc = 0; @@ -1106,8 +1149,9 @@ int fcoe_link_ok(struct fc_lport *lp) } EXPORT_SYMBOL_GPL(fcoe_link_ok); -/** - * fcoe_percpu_clean() - Clear the pending skbs for an lport +/* + * fcoe_percpu_clean - frees skb of the corresponding lport from the per + * cpu queue. * @lp: the fc_lport */ void fcoe_percpu_clean(struct fc_lport *lp) @@ -1141,11 +1185,11 @@ void fcoe_percpu_clean(struct fc_lport *lp) EXPORT_SYMBOL_GPL(fcoe_percpu_clean); /** - * fcoe_clean_pending_queue() - Dequeue a skb and free it + * fcoe_clean_pending_queue - dequeue skb and free it * @lp: the corresponding fc_lport * * Returns: none - */ + **/ void fcoe_clean_pending_queue(struct fc_lport *lp) { struct fcoe_softc *fc = lport_priv(lp); @@ -1162,21 +1206,21 @@ void fcoe_clean_pending_queue(struct fc_lport *lp) EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue); /** - * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport + * libfc_host_alloc - allocate a Scsi_Host with room for the fc_lport * @sht: ptr to the scsi host templ * @priv_size: size of private data after fc_lport * * Returns: ptr to Scsi_Host - * TODO: to libfc? + * TODO - to libfc? */ -static inline struct Scsi_Host * -libfc_host_alloc(struct scsi_host_template *sht, int priv_size) +static inline struct Scsi_Host *libfc_host_alloc( + struct scsi_host_template *sht, int priv_size) { return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size); } /** - * fcoe_host_alloc() - Allocate a Scsi_Host with room for the fcoe_softc + * fcoe_host_alloc - allocate a Scsi_Host with room for the fcoe_softc * @sht: ptr to the scsi host templ * @priv_size: size of private data after fc_lport * @@ -1188,8 +1232,8 @@ struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *sht, int priv_size) } EXPORT_SYMBOL_GPL(fcoe_host_alloc); -/** - * fcoe_reset() - Resets the fcoe +/* + * fcoe_reset - resets the fcoe * @shost: shost the reset is from * * Returns: always 0 @@ -1202,8 +1246,8 @@ int fcoe_reset(struct Scsi_Host *shost) } EXPORT_SYMBOL_GPL(fcoe_reset); -/** - * fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN. +/* + * fcoe_wwn_from_mac - converts 48-bit IEEE MAC address to 64-bit FC WWN. * @mac: mac address * @scheme: check port * @port: port indicator for converting @@ -1242,15 +1286,14 @@ u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], return wwn; } EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); - -/** - * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device +/* + * fcoe_hostlist_lookup_softc - find the corresponding lport by a given device * @device: this is currently ptr to net_device * * Returns: NULL or the located fcoe_softc */ -static struct fcoe_softc * -fcoe_hostlist_lookup_softc(const struct net_device *dev) +static struct fcoe_softc *fcoe_hostlist_lookup_softc( + const struct net_device *dev) { struct fcoe_softc *fc; @@ -1265,8 +1308,8 @@ fcoe_hostlist_lookup_softc(const struct net_device *dev) return NULL; } -/** - * fcoe_hostlist_lookup() - Find the corresponding lport by netdev +/* + * fcoe_hostlist_lookup - find the corresponding lport by netdev * @netdev: ptr to net_device * * Returns: 0 for success @@ -1281,8 +1324,8 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) } EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup); -/** - * fcoe_hostlist_add() - Add a lport to lports list +/* + * fcoe_hostlist_add - add a lport to lports list * @lp: ptr to the fc_lport to badded * * Returns: 0 for success @@ -1293,7 +1336,7 @@ int fcoe_hostlist_add(const struct fc_lport *lp) fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp)); if (!fc) { - fc = lport_priv(lp); + fc = fcoe_softc(lp); write_lock_bh(&fcoe_hostlist_lock); list_add_tail(&fc->list, &fcoe_hostlist); write_unlock_bh(&fcoe_hostlist_lock); @@ -1302,8 +1345,8 @@ int fcoe_hostlist_add(const struct fc_lport *lp) } EXPORT_SYMBOL_GPL(fcoe_hostlist_add); -/** - * fcoe_hostlist_remove() - remove a lport from lports list +/* + * fcoe_hostlist_remove - remove a lport from lports list * @lp: ptr to the fc_lport to badded * * Returns: 0 for success @@ -1323,12 +1366,12 @@ int fcoe_hostlist_remove(const struct fc_lport *lp) EXPORT_SYMBOL_GPL(fcoe_hostlist_remove); /** - * fcoe_libfc_config() - sets up libfc related properties for lport + * fcoe_libfc_config - sets up libfc related properties for lport * @lp: ptr to the fc_lport * @tt: libfc function template * * Returns : 0 for success - */ + **/ int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt) { /* Set the function pointers set by the LLDD */ @@ -1346,14 +1389,14 @@ int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt) EXPORT_SYMBOL_GPL(fcoe_libfc_config); /** - * fcoe_init() - fcoe module loading initialization + * fcoe_init - fcoe module loading initialization * * Initialization routine * 1. Will create fc transport software structure * 2. initialize the link list of port information structure * * Returns 0 on success, negative on failure - */ + **/ static int __init fcoe_init(void) { int cpu; @@ -1390,6 +1433,7 @@ static int __init fcoe_init(void) } else { fcoe_percpu[cpu] = NULL; kfree(p); + } } } @@ -1399,9 +1443,11 @@ static int __init fcoe_init(void) */ fcoe_dev_setup(); - setup_timer(&fcoe_timer, fcoe_watchdog, 0); - - mod_timer(&fcoe_timer, jiffies + (10 * HZ)); + init_timer(&fcoe_timer); + fcoe_timer.data = 0; + fcoe_timer.function = fcoe_watchdog; + fcoe_timer.expires = (jiffies + (10 * HZ)); + add_timer(&fcoe_timer); /* initiatlize the fcoe transport */ fcoe_transport_init(); @@ -1413,10 +1459,10 @@ static int __init fcoe_init(void) module_init(fcoe_init); /** - * fcoe_exit() - fcoe module unloading cleanup + * fcoe_exit - fcoe module unloading cleanup * * Returns 0 on success, negative on failure - */ + **/ static void __exit fcoe_exit(void) { u32 idx; @@ -1437,7 +1483,7 @@ static void __exit fcoe_exit(void) */ del_timer_sync(&fcoe_timer); - /* releases the associated fcoe transport for each lport */ + /* releases the assocaited fcoe transport for each lport */ list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) fcoe_transport_release(fc->real_dev); diff --git a/trunk/drivers/scsi/lasi700.c b/trunk/drivers/scsi/lasi700.c index f23c4ca9a2ee..4a4e6954ec79 100644 --- a/trunk/drivers/scsi/lasi700.c +++ b/trunk/drivers/scsi/lasi700.c @@ -103,7 +103,7 @@ lasi700_probe(struct parisc_device *dev) hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); if (!hostdata) { - dev_printk(KERN_ERR, &dev->dev, "Failed to allocate host data\n"); + dev_printk(KERN_ERR, dev, "Failed to allocate host data\n"); return -ENOMEM; } diff --git a/trunk/drivers/scsi/libfc/fc_disc.c b/trunk/drivers/scsi/libfc/fc_disc.c index e57556ea5b48..dd1564c9e04a 100644 --- a/trunk/drivers/scsi/libfc/fc_disc.c +++ b/trunk/drivers/scsi/libfc/fc_disc.c @@ -64,7 +64,7 @@ static void fc_disc_single(struct fc_disc *, struct fc_disc_port *); static void fc_disc_restart(struct fc_disc *); /** - * fc_disc_lookup_rport() - lookup a remote port by port_id + * fc_disc_lookup_rport - lookup a remote port by port_id * @lport: Fibre Channel host port instance * @port_id: remote port port_id to match */ @@ -92,7 +92,7 @@ struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport, } /** - * fc_disc_stop_rports() - delete all the remote ports associated with the lport + * fc_disc_stop_rports - delete all the remote ports associated with the lport * @disc: The discovery job to stop rports on * * Locking Note: This function expects that the lport mutex is locked before @@ -117,7 +117,7 @@ void fc_disc_stop_rports(struct fc_disc *disc) } /** - * fc_disc_rport_callback() - Event handler for rport events + * fc_disc_rport_callback - Event handler for rport events * @lport: The lport which is receiving the event * @rport: The rport which the event has occured on * @event: The event that occured @@ -151,7 +151,7 @@ static void fc_disc_rport_callback(struct fc_lport *lport, } /** - * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN) + * fc_disc_recv_rscn_req - Handle Registered State Change Notification (RSCN) * @sp: Current sequence of the RSCN exchange * @fp: RSCN Frame * @lport: Fibre Channel host port instance @@ -246,7 +246,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, list_del(&dp->peers); rport = lport->tt.rport_lookup(lport, dp->ids.port_id); if (rport) { - rdata = rport->dd_data; + rdata = RPORT_TO_PRIV(rport); list_del(&rdata->peers); lport->tt.rport_logoff(rport); } @@ -265,7 +265,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_disc_recv_req() - Handle incoming requests + * fc_disc_recv_req - Handle incoming requests * @sp: Current sequence of the request exchange * @fp: The frame * @lport: The FC local port @@ -294,7 +294,7 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_disc_restart() - Restart discovery + * fc_disc_restart - Restart discovery * @lport: FC discovery context * * Locking Note: This function expects that the disc mutex @@ -322,7 +322,7 @@ static void fc_disc_restart(struct fc_disc *disc) } /** - * fc_disc_start() - Fibre Channel Target discovery + * fc_disc_start - Fibre Channel Target discovery * @lport: FC local port * * Returns non-zero if discovery cannot be started. @@ -383,7 +383,7 @@ static struct fc_rport_operations fc_disc_rport_ops = { }; /** - * fc_disc_new_target() - Handle new target found by discovery + * fc_disc_new_target - Handle new target found by discovery * @lport: FC local port * @rport: The previous FC remote port (NULL if new remote port) * @ids: Identifiers for the new FC remote port @@ -396,7 +396,7 @@ static int fc_disc_new_target(struct fc_disc *disc, struct fc_rport_identifiers *ids) { struct fc_lport *lport = disc->lport; - struct fc_rport_libfc_priv *rdata; + struct fc_rport_libfc_priv *rp; int error = 0; if (rport && ids->port_name) { @@ -430,15 +430,15 @@ static int fc_disc_new_target(struct fc_disc *disc, dp.ids.port_name = ids->port_name; dp.ids.node_name = ids->node_name; dp.ids.roles = ids->roles; - rport = lport->tt.rport_create(&dp); + rport = fc_rport_rogue_create(&dp); } if (!rport) error = -ENOMEM; } if (rport) { - rdata = rport->dd_data; - rdata->ops = &fc_disc_rport_ops; - rdata->rp_state = RPORT_ST_INIT; + rp = rport->dd_data; + rp->ops = &fc_disc_rport_ops; + rp->rp_state = RPORT_ST_INIT; lport->tt.rport_login(rport); } } @@ -446,20 +446,20 @@ static int fc_disc_new_target(struct fc_disc *disc, } /** - * fc_disc_del_target() - Delete a target + * fc_disc_del_target - Delete a target * @disc: FC discovery context * @rport: The remote port to be removed */ static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport) { struct fc_lport *lport = disc->lport; - struct fc_rport_libfc_priv *rdata = rport->dd_data; + struct fc_rport_libfc_priv *rdata = RPORT_TO_PRIV(rport); list_del(&rdata->peers); lport->tt.rport_logoff(rport); } /** - * fc_disc_done() - Discovery has been completed + * fc_disc_done - Discovery has been completed * @disc: FC discovery context */ static void fc_disc_done(struct fc_disc *disc) @@ -479,7 +479,7 @@ static void fc_disc_done(struct fc_disc *disc) } /** - * fc_disc_error() - Handle error on dNS request + * fc_disc_error - Handle error on dNS request * @disc: FC discovery context * @fp: The frame pointer */ @@ -519,7 +519,7 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) } /** - * fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request + * fc_disc_gpn_ft_req - Send Get Port Names by FC-4 type (GPN_FT) request * @lport: FC discovery context * * Locking Note: This function expects that the disc_mutex is locked @@ -553,7 +553,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc) } /** - * fc_disc_gpn_ft_parse() - Parse the list of IDs and names resulting from a request + * fc_disc_gpn_ft_parse - Parse the list of IDs and names resulting from a request * @lport: Fibre Channel host port instance * @buf: GPN_FT response buffer * @len: size of response buffer @@ -617,7 +617,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) if ((dp.ids.port_id != fc_host_port_id(lport->host)) && (dp.ids.port_name != lport->wwpn)) { - rport = lport->tt.rport_create(&dp); + rport = fc_rport_rogue_create(&dp); if (rport) { rdata = rport->dd_data; rdata->ops = &fc_disc_rport_ops; @@ -658,10 +658,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) return error; } -/** - * fc_disc_timeout() - Retry handler for the disc component - * @work: Structure holding disc obj that needs retry discovery - * +/* * Handle retry of memory allocation for remote ports. */ static void fc_disc_timeout(struct work_struct *work) @@ -676,7 +673,7 @@ static void fc_disc_timeout(struct work_struct *work) } /** - * fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT) + * fc_disc_gpn_ft_resp - Handle a response frame from Get Port Names (GPN_FT) * @sp: Current sequence of GPN_FT exchange * @fp: response frame * @lp_arg: Fibre Channel host port instance @@ -715,7 +712,9 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, fr_len(fp)); } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) { - /* Accepted, parse the response. */ + /* + * Accepted. Parse response. + */ buf = cp + 1; len -= sizeof(*cp); } else if (ntohs(cp->ct_cmd) == FC_FS_RJT) { @@ -747,7 +746,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_disc_single() - Discover the directory information for a single target + * fc_disc_single - Discover the directory information for a single target * @lport: FC local port * @dp: The port to rediscover * @@ -770,7 +769,7 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) if (rport) fc_disc_del_target(disc, rport); - new_rport = lport->tt.rport_create(dp); + new_rport = fc_rport_rogue_create(dp); if (new_rport) { rdata = new_rport->dd_data; rdata->ops = &fc_disc_rport_ops; @@ -783,7 +782,7 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) } /** - * fc_disc_stop() - Stop discovery for a given lport + * fc_disc_stop - Stop discovery for a given lport * @lport: The lport that discovery should stop for */ void fc_disc_stop(struct fc_lport *lport) @@ -797,7 +796,7 @@ void fc_disc_stop(struct fc_lport *lport) } /** - * fc_disc_stop_final() - Stop discovery for a given lport + * fc_disc_stop_final - Stop discovery for a given lport * @lport: The lport that discovery should stop for * * This function will block until discovery has been @@ -810,7 +809,7 @@ void fc_disc_stop_final(struct fc_lport *lport) } /** - * fc_disc_init() - Initialize the discovery block + * fc_disc_init - Initialize the discovery block * @lport: FC local port */ int fc_disc_init(struct fc_lport *lport) diff --git a/trunk/drivers/scsi/libfc/fc_exch.c b/trunk/drivers/scsi/libfc/fc_exch.c index 505825b6124d..66db08a5f27f 100644 --- a/trunk/drivers/scsi/libfc/fc_exch.c +++ b/trunk/drivers/scsi/libfc/fc_exch.c @@ -32,6 +32,8 @@ #include #include +#define FC_DEF_R_A_TOV (10 * 1000) /* resource allocation timeout */ + /* * fc_exch_debug can be set in debugger or at compile time to get more logs. */ @@ -625,6 +627,7 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) { struct fc_exch *ep; struct fc_frame_header *fh; + u16 rxid; ep = mp->lp->tt.exch_get(mp->lp, fp); if (ep) { @@ -651,6 +654,18 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0) ep->esb_stat &= ~ESB_ST_SEQ_INIT; + /* + * Set the responder ID in the frame header. + * The old one should've been 0xffff. + * If it isn't, don't assign one. + * Incoming basic link service frames may specify + * a referenced RX_ID. + */ + if (fh->fh_type != FC_TYPE_BLS) { + rxid = ntohs(fh->fh_rx_id); + WARN_ON(rxid != FC_XID_UNKNOWN); + fh->fh_rx_id = htons(ep->rxid); + } fc_exch_hold(ep); /* hold for caller */ spin_unlock_bh(&ep->ex_lock); /* lock from exch_get */ } @@ -662,8 +677,8 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold * on the ep that should be released by the caller. */ -static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp, - struct fc_frame *fp) +static enum fc_pf_rjt_reason +fc_seq_lookup_recip(struct fc_exch_mgr *mp, struct fc_frame *fp) { struct fc_frame_header *fh = fc_frame_header_get(fp); struct fc_exch *ep = NULL; @@ -981,9 +996,9 @@ static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp) * Send BLS Reject. * This is for rejecting BA_ABTS only. */ -static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp, - enum fc_ba_rjt_reason reason, - enum fc_ba_rjt_explan explan) +static void +fc_exch_send_ba_rjt(struct fc_frame *rx_fp, enum fc_ba_rjt_reason reason, + enum fc_ba_rjt_explan explan) { struct fc_frame *fp; struct fc_frame_header *rx_fh; @@ -1081,7 +1096,7 @@ static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp) ap->ba_high_seq_cnt = fh->fh_seq_cnt; ap->ba_low_seq_cnt = htons(sp->cnt); } - sp = fc_seq_start_next_locked(sp); + sp = fc_seq_start_next(sp); spin_unlock_bh(&ep->ex_lock); fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS); fc_frame_free(rx_fp); @@ -1465,11 +1480,10 @@ static void fc_exch_reset(struct fc_exch *ep) * If sid is non-zero, reset only exchanges we source from that FID. * If did is non-zero, reset only exchanges destined to that FID. */ -void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did) +void fc_exch_mgr_reset(struct fc_exch_mgr *mp, u32 sid, u32 did) { struct fc_exch *ep; struct fc_exch *next; - struct fc_exch_mgr *mp = lp->emp; spin_lock_bh(&mp->em_lock); restart: @@ -1593,7 +1607,7 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg) if (IS_ERR(fp)) { int err = PTR_ERR(fp); - if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT) + if (err == -FC_EX_CLOSED) goto cleanup; FC_DBG("Cannot process RRQ, because of frame error %d\n", err); return; diff --git a/trunk/drivers/scsi/libfc/fc_fcp.c b/trunk/drivers/scsi/libfc/fc_fcp.c index 2a631d7dbcec..404e63ff46b8 100644 --- a/trunk/drivers/scsi/libfc/fc_fcp.c +++ b/trunk/drivers/scsi/libfc/fc_fcp.c @@ -161,7 +161,7 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lp, gfp_t gfp) } /** - * fc_fcp_pkt_release() - release hold on scsi_pkt packet + * fc_fcp_pkt_release - release hold on scsi_pkt packet * @fsp: fcp packet struct * * This is used by upper layer scsi driver. @@ -183,7 +183,8 @@ static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp) } /** - * fc_fcp_pkt_destory() - release hold on scsi_pkt packet + * fc_fcp_pkt_destory - release hold on scsi_pkt packet + * * @seq: exchange sequence * @fsp: fcp packet struct * @@ -198,7 +199,7 @@ static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp) } /** - * fc_fcp_lock_pkt() - lock a packet and get a ref to it. + * fc_fcp_lock_pkt - lock a packet and get a ref to it. * @fsp: fcp packet * * We should only return error if we return a command to scsi-ml before @@ -290,7 +291,9 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) buf = fc_frame_payload_get(fp, 0); if (offset + len > fsp->data_len) { - /* this should never happen */ + /* + * this should never happen + */ if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && fc_frame_crc_check(fp)) goto crc_err; @@ -384,8 +387,8 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) fc_fcp_complete_locked(fsp); } -/** - * fc_fcp_send_data() - Send SCSI data to target. +/* + * fc_fcp_send_data - Send SCSI data to target. * @fsp: ptr to fc_fcp_pkt * @sp: ptr to this sequence * @offset: starting offset for this data request @@ -607,8 +610,8 @@ static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) } } -/** - * fc_fcp_reduce_can_queue() - drop can_queue +/* + * fc_fcp_reduce_can_queue - drop can_queue * @lp: lport to drop queueing for * * If we are getting memory allocation failures, then we may @@ -639,11 +642,9 @@ static void fc_fcp_reduce_can_queue(struct fc_lport *lp) spin_unlock_irqrestore(lp->host->host_lock, flags); } -/** - * fc_fcp_recv() - Reveive FCP frames - * @seq: The sequence the frame is on - * @fp: The FC frame - * @arg: The related FCP packet +/* + * exch mgr calls this routine to process scsi + * exchanges. * * Return : None * Context : called from Soft IRQ context @@ -831,7 +832,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) } /** - * fc_fcp_complete_locked() - complete processing of a fcp packet + * fc_fcp_complete_locked - complete processing of a fcp packet * @fsp: fcp packet * * This function may sleep if a timer is pending. The packet lock must be @@ -899,7 +900,7 @@ static void fc_fcp_cleanup_cmd(struct fc_fcp_pkt *fsp, int error) } /** - * fc_fcp_cleanup_each_cmd() - Cleanup active commads + * fc_fcp_cleanup_each_cmd - run fn on each active command * @lp: logical port * @id: target id * @lun: lun @@ -951,7 +952,7 @@ static void fc_fcp_abort_io(struct fc_lport *lp) } /** - * fc_fcp_pkt_send() - send a fcp packet to the lower level. + * fc_fcp_pkt_send - send a fcp packet to the lower level. * @lp: fc lport * @fsp: fc packet. * @@ -1620,7 +1621,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp) { /* lock ? */ - return (lp->state == LPORT_ST_READY) && lp->link_up && !lp->qfull; + return (lp->state == LPORT_ST_READY) && (lp->link_status & FC_LINK_UP); } /** @@ -1726,7 +1727,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *)) EXPORT_SYMBOL(fc_queuecommand); /** - * fc_io_compl() - Handle responses for completed commands + * fc_io_compl - Handle responses for completed commands * @fsp: scsi packet * * Translates a error to a Linux SCSI error. @@ -1809,12 +1810,12 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) sc_cmd->result = DID_ERROR << 16; break; case FC_DATA_UNDRUN: - if ((fsp->cdb_status == 0) && !(fsp->req_flags & FC_SRB_READ)) { + if (fsp->cdb_status == 0) { /* * scsi status is good but transport level - * underrun. + * underrun. for read it should be an error?? */ - sc_cmd->result = DID_OK << 16; + sc_cmd->result = (DID_OK << 16) | fsp->cdb_status; } else { /* * scsi got underrun, this is an error @@ -1856,7 +1857,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) } /** - * fc_fcp_complete() - complete processing of a fcp packet + * fc_fcp_complete - complete processing of a fcp packet * @fsp: fcp packet * * This function may sleep if a fsp timer is pending. @@ -1873,10 +1874,9 @@ void fc_fcp_complete(struct fc_fcp_pkt *fsp) EXPORT_SYMBOL(fc_fcp_complete); /** - * fc_eh_abort() - Abort a command + * fc_eh_abort - Abort a command...from scsi host template * @sc_cmd: scsi command to abort * - * From scsi host template. * send ABTS to the target device and wait for the response * sc_cmd is the pointer to the command to be aborted. */ @@ -1890,7 +1890,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) lp = shost_priv(sc_cmd->device->host); if (lp->state != LPORT_ST_READY) return rc; - else if (!lp->link_up) + else if (!(lp->link_status & FC_LINK_UP)) return rc; spin_lock_irqsave(lp->host->host_lock, flags); @@ -1920,7 +1920,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) EXPORT_SYMBOL(fc_eh_abort); /** - * fc_eh_device_reset() Reset a single LUN + * fc_eh_device_reset: Reset a single LUN * @sc_cmd: scsi command * * Set from scsi host template to send tm cmd to the target and wait for the @@ -1973,7 +1973,7 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd) EXPORT_SYMBOL(fc_eh_device_reset); /** - * fc_eh_host_reset() - The reset function will reset the ports on the host. + * fc_eh_host_reset - The reset function will reset the ports on the host. * @sc_cmd: scsi command */ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) @@ -1999,7 +1999,7 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) EXPORT_SYMBOL(fc_eh_host_reset); /** - * fc_slave_alloc() - configure queue depth + * fc_slave_alloc - configure queue depth * @sdev: scsi device * * Configures queue depth based on host's cmd_per_len. If not set diff --git a/trunk/drivers/scsi/libfc/fc_lport.c b/trunk/drivers/scsi/libfc/fc_lport.c index 2ae50a1188e6..0b9bdb1fb807 100644 --- a/trunk/drivers/scsi/libfc/fc_lport.c +++ b/trunk/drivers/scsi/libfc/fc_lport.c @@ -139,7 +139,7 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) } /** - * fc_lport_rport_callback() - Event handler for rport events + * fc_lport_rport_callback - Event handler for rport events * @lport: The lport which is receiving the event * @rport: The rport which the event has occured on * @event: The event that occured @@ -195,7 +195,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport, } /** - * fc_lport_state() - Return a string which represents the lport's state + * fc_lport_state - Return a string which represents the lport's state * @lport: The lport whose state is to converted to a string */ static const char *fc_lport_state(struct fc_lport *lport) @@ -209,7 +209,7 @@ static const char *fc_lport_state(struct fc_lport *lport) } /** - * fc_lport_ptp_setup() - Create an rport for point-to-point mode + * fc_lport_ptp_setup - Create an rport for point-to-point mode * @lport: The lport to attach the ptp rport to * @fid: The FID of the ptp rport * @remote_wwpn: The WWPN of the ptp rport @@ -232,7 +232,7 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, lport->ptp_rp = NULL; } - lport->ptp_rp = lport->tt.rport_create(&dp); + lport->ptp_rp = fc_rport_rogue_create(&dp); lport->tt.rport_login(lport->ptp_rp); @@ -250,7 +250,7 @@ void fc_get_host_port_state(struct Scsi_Host *shost) { struct fc_lport *lp = shost_priv(shost); - if (lp->link_up) + if ((lp->link_status & FC_LINK_UP) == FC_LINK_UP) fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; else fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; @@ -351,7 +351,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type) } /** - * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report. + * fc_lport_recv_rlir_req - Handle received Registered Link Incident Report. * @lport: Fibre Channel local port recieving the RLIR * @sp: current sequence in the RLIR exchange * @fp: RLIR request frame @@ -370,7 +370,7 @@ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_lport_recv_echo_req() - Handle received ECHO request + * fc_lport_recv_echo_req - Handle received ECHO request * @lport: Fibre Channel local port recieving the ECHO * @sp: current sequence in the ECHO exchange * @fp: ECHO request frame @@ -412,7 +412,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, } /** - * fc_lport_recv_echo_req() - Handle received Request Node ID data request + * fc_lport_recv_echo_req - Handle received Request Node ID data request * @lport: Fibre Channel local port recieving the RNID * @sp: current sequence in the RNID exchange * @fp: RNID request frame @@ -479,7 +479,7 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, } /** - * fc_lport_recv_adisc_req() - Handle received Address Discovery Request + * fc_lport_recv_adisc_req - Handle received Address Discovery Request * @lport: Fibre Channel local port recieving the ADISC * @sp: current sequence in the ADISC exchange * @fp: ADISC request frame @@ -529,7 +529,7 @@ static void fc_lport_recv_adisc_req(struct fc_seq *sp, struct fc_frame *in_fp, } /** - * fc_lport_recv_logo_req() - Handle received fabric LOGO request + * fc_lport_recv_logo_req - Handle received fabric LOGO request * @lport: Fibre Channel local port recieving the LOGO * @sp: current sequence in the LOGO exchange * @fp: LOGO request frame @@ -546,7 +546,7 @@ static void fc_lport_recv_logo_req(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_fabric_login() - Start the lport state machine + * fc_fabric_login - Start the lport state machine * @lport: The lport that should log into the fabric * * Locking Note: This function should not be called @@ -568,7 +568,7 @@ int fc_fabric_login(struct fc_lport *lport) EXPORT_SYMBOL(fc_fabric_login); /** - * fc_linkup() - Handler for transport linkup events + * fc_linkup - Handler for transport linkup events * @lport: The lport whose link is up */ void fc_linkup(struct fc_lport *lport) @@ -577,8 +577,8 @@ void fc_linkup(struct fc_lport *lport) fc_host_port_id(lport->host)); mutex_lock(&lport->lp_mutex); - if (!lport->link_up) { - lport->link_up = 1; + if ((lport->link_status & FC_LINK_UP) != FC_LINK_UP) { + lport->link_status |= FC_LINK_UP; if (lport->state == LPORT_ST_RESET) fc_lport_enter_flogi(lport); @@ -588,7 +588,7 @@ void fc_linkup(struct fc_lport *lport) EXPORT_SYMBOL(fc_linkup); /** - * fc_linkdown() - Handler for transport linkdown events + * fc_linkdown - Handler for transport linkdown events * @lport: The lport whose link is down */ void fc_linkdown(struct fc_lport *lport) @@ -597,8 +597,8 @@ void fc_linkdown(struct fc_lport *lport) FC_DEBUG_LPORT("Link is down for port (%6x)\n", fc_host_port_id(lport->host)); - if (lport->link_up) { - lport->link_up = 0; + if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) { + lport->link_status &= ~(FC_LINK_UP); fc_lport_enter_reset(lport); lport->tt.fcp_cleanup(lport); } @@ -607,25 +607,48 @@ void fc_linkdown(struct fc_lport *lport) EXPORT_SYMBOL(fc_linkdown); /** - * fc_fabric_logoff() - Logout of the fabric + * fc_pause - Pause the flow of frames + * @lport: The lport to be paused + */ +void fc_pause(struct fc_lport *lport) +{ + mutex_lock(&lport->lp_mutex); + lport->link_status |= FC_PAUSE; + mutex_unlock(&lport->lp_mutex); +} +EXPORT_SYMBOL(fc_pause); + +/** + * fc_unpause - Unpause the flow of frames + * @lport: The lport to be unpaused + */ +void fc_unpause(struct fc_lport *lport) +{ + mutex_lock(&lport->lp_mutex); + lport->link_status &= ~(FC_PAUSE); + mutex_unlock(&lport->lp_mutex); +} +EXPORT_SYMBOL(fc_unpause); + +/** + * fc_fabric_logoff - Logout of the fabric * @lport: fc_lport pointer to logoff the fabric * * Return value: * 0 for success, -1 for failure - */ + **/ int fc_fabric_logoff(struct fc_lport *lport) { lport->tt.disc_stop_final(lport); mutex_lock(&lport->lp_mutex); fc_lport_enter_logo(lport); mutex_unlock(&lport->lp_mutex); - cancel_delayed_work_sync(&lport->retry_work); return 0; } EXPORT_SYMBOL(fc_fabric_logoff); /** - * fc_lport_destroy() - unregister a fc_lport + * fc_lport_destroy - unregister a fc_lport * @lport: fc_lport pointer to unregister * * Return value: @@ -635,25 +658,26 @@ EXPORT_SYMBOL(fc_fabric_logoff); * clean-up all the allocated memory * and free up other system resources. * - */ + **/ int fc_lport_destroy(struct fc_lport *lport) { lport->tt.frame_send = fc_frame_drop; lport->tt.fcp_abort_io(lport); - lport->tt.exch_mgr_reset(lport, 0, 0); + lport->tt.exch_mgr_reset(lport->emp, 0, 0); return 0; } EXPORT_SYMBOL(fc_lport_destroy); /** - * fc_set_mfs() - sets up the mfs for the corresponding fc_lport + * fc_set_mfs - sets up the mfs for the corresponding fc_lport * @lport: fc_lport pointer to unregister * @mfs: the new mfs for fc_lport * * Set mfs for the given fc_lport to the new mfs. * * Return: 0 for success - */ + * + **/ int fc_set_mfs(struct fc_lport *lport, u32 mfs) { unsigned int old_mfs; @@ -682,7 +706,7 @@ int fc_set_mfs(struct fc_lport *lport, u32 mfs) EXPORT_SYMBOL(fc_set_mfs); /** - * fc_lport_disc_callback() - Callback for discovery events + * fc_lport_disc_callback - Callback for discovery events * @lport: FC local port * @event: The discovery event */ @@ -707,7 +731,7 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) } /** - * fc_rport_enter_ready() - Enter the ready state and start discovery + * fc_rport_enter_ready - Enter the ready state and start discovery * @lport: Fibre Channel local port that is ready * * Locking Note: The lport lock is expected to be held before calling @@ -724,7 +748,7 @@ static void fc_lport_enter_ready(struct fc_lport *lport) } /** - * fc_lport_recv_flogi_req() - Receive a FLOGI request + * fc_lport_recv_flogi_req - Receive a FLOGI request * @sp_in: The sequence the FLOGI is on * @rx_fp: The frame the FLOGI is in * @lport: The lport that recieved the request @@ -814,7 +838,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, } /** - * fc_lport_recv_req() - The generic lport request handler + * fc_lport_recv_req - The generic lport request handler * @lport: The lport that received the request * @sp: The sequence the request is on * @fp: The frame the request is in @@ -910,7 +934,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, } /** - * fc_lport_reset() - Reset an lport + * fc_lport_reset - Reset an lport * @lport: The lport which should be reset * * Locking Note: This functions should not be called with the @@ -918,7 +942,6 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, */ int fc_lport_reset(struct fc_lport *lport) { - cancel_delayed_work_sync(&lport->retry_work); mutex_lock(&lport->lp_mutex); fc_lport_enter_reset(lport); mutex_unlock(&lport->lp_mutex); @@ -927,7 +950,7 @@ int fc_lport_reset(struct fc_lport *lport) EXPORT_SYMBOL(fc_lport_reset); /** - * fc_rport_enter_reset() - Reset the local port + * fc_rport_enter_reset - Reset the local port * @lport: Fibre Channel local port to be reset * * Locking Note: The lport lock is expected to be held before calling @@ -950,16 +973,16 @@ static void fc_lport_enter_reset(struct fc_lport *lport) lport->tt.disc_stop(lport); - lport->tt.exch_mgr_reset(lport, 0, 0); + lport->tt.exch_mgr_reset(lport->emp, 0, 0); fc_host_fabric_name(lport->host) = 0; fc_host_port_id(lport->host) = 0; - if (lport->link_up) + if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) fc_lport_enter_flogi(lport); } /** - * fc_lport_error() - Handler for any errors + * fc_lport_error - Handler for any errors * @lport: The fc_lport object * @fp: The frame pointer * @@ -1006,8 +1029,8 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) } /** - * fc_lport_rft_id_resp() - Handle response to Register Fibre - * Channel Types by ID (RPN_ID) request + * fc_lport_rft_id_resp - Handle response to Register Fibre + * Channel Types by ID (RPN_ID) request * @sp: current sequence in RPN_ID exchange * @fp: response frame * @lp_arg: Fibre Channel host port instance @@ -1030,17 +1053,17 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, FC_DEBUG_LPORT("Received a RFT_ID response\n"); - if (IS_ERR(fp)) { - fc_lport_error(lport, fp); - goto err; - } - if (lport->state != LPORT_ST_RFT_ID) { FC_DBG("Received a RFT_ID response, but in state %s\n", fc_lport_state(lport)); goto out; } + if (IS_ERR(fp)) { + fc_lport_error(lport, fp); + goto err; + } + fh = fc_frame_header_get(fp); ct = fc_frame_payload_get(fp, sizeof(*ct)); @@ -1058,8 +1081,8 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_lport_rpn_id_resp() - Handle response to Register Port - * Name by ID (RPN_ID) request + * fc_lport_rpn_id_resp - Handle response to Register Port + * Name by ID (RPN_ID) request * @sp: current sequence in RPN_ID exchange * @fp: response frame * @lp_arg: Fibre Channel host port instance @@ -1082,17 +1105,17 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, FC_DEBUG_LPORT("Received a RPN_ID response\n"); - if (IS_ERR(fp)) { - fc_lport_error(lport, fp); - goto err; - } - if (lport->state != LPORT_ST_RPN_ID) { FC_DBG("Received a RPN_ID response, but in state %s\n", fc_lport_state(lport)); goto out; } + if (IS_ERR(fp)) { + fc_lport_error(lport, fp); + goto err; + } + fh = fc_frame_header_get(fp); ct = fc_frame_payload_get(fp, sizeof(*ct)); if (fh && ct && fh->fh_type == FC_TYPE_CT && @@ -1110,7 +1133,7 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request + * fc_lport_scr_resp - Handle response to State Change Register (SCR) request * @sp: current sequence in SCR exchange * @fp: response frame * @lp_arg: Fibre Channel lport port instance that sent the registration request @@ -1132,17 +1155,17 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, FC_DEBUG_LPORT("Received a SCR response\n"); - if (IS_ERR(fp)) { - fc_lport_error(lport, fp); - goto err; - } - if (lport->state != LPORT_ST_SCR) { FC_DBG("Received a SCR response, but in state %s\n", fc_lport_state(lport)); goto out; } + if (IS_ERR(fp)) { + fc_lport_error(lport, fp); + goto err; + } + op = fc_frame_payload_op(fp); if (op == ELS_LS_ACC) fc_lport_enter_ready(lport); @@ -1156,7 +1179,7 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_lport_enter_scr() - Send a State Change Register (SCR) request + * fc_lport_enter_scr - Send a State Change Register (SCR) request * @lport: Fibre Channel local port to register for state changes * * Locking Note: The lport lock is expected to be held before calling @@ -1183,7 +1206,7 @@ static void fc_lport_enter_scr(struct fc_lport *lport) } /** - * fc_lport_enter_rft_id() - Register FC4-types with the name server + * fc_lport_enter_rft_id - Register FC4-types with the name server * @lport: Fibre Channel local port to register * * Locking Note: The lport lock is expected to be held before calling @@ -1225,7 +1248,7 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport) } /** - * fc_rport_enter_rft_id() - Register port name with the name server + * fc_rport_enter_rft_id - Register port name with the name server * @lport: Fibre Channel local port to register * * Locking Note: The lport lock is expected to be held before calling @@ -1258,7 +1281,7 @@ static struct fc_rport_operations fc_lport_rport_ops = { }; /** - * fc_rport_enter_dns() - Create a rport to the name server + * fc_rport_enter_dns - Create a rport to the name server * @lport: Fibre Channel local port requesting a rport for the name server * * Locking Note: The lport lock is expected to be held before calling @@ -1281,7 +1304,7 @@ static void fc_lport_enter_dns(struct fc_lport *lport) fc_lport_state_enter(lport, LPORT_ST_DNS); - rport = lport->tt.rport_create(&dp); + rport = fc_rport_rogue_create(&dp); if (!rport) goto err; @@ -1295,7 +1318,7 @@ static void fc_lport_enter_dns(struct fc_lport *lport) } /** - * fc_lport_timeout() - Handler for the retry_work timer. + * fc_lport_timeout - Handler for the retry_work timer. * @work: The work struct of the fc_lport */ static void fc_lport_timeout(struct work_struct *work) @@ -1336,7 +1359,7 @@ static void fc_lport_timeout(struct work_struct *work) } /** - * fc_lport_logo_resp() - Handle response to LOGO request + * fc_lport_logo_resp - Handle response to LOGO request * @sp: current sequence in LOGO exchange * @fp: response frame * @lp_arg: Fibre Channel lport port instance that sent the LOGO request @@ -1358,17 +1381,17 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, FC_DEBUG_LPORT("Received a LOGO response\n"); - if (IS_ERR(fp)) { - fc_lport_error(lport, fp); - goto err; - } - if (lport->state != LPORT_ST_LOGO) { FC_DBG("Received a LOGO response, but in state %s\n", fc_lport_state(lport)); goto out; } + if (IS_ERR(fp)) { + fc_lport_error(lport, fp); + goto err; + } + op = fc_frame_payload_op(fp); if (op == ELS_LS_ACC) fc_lport_enter_reset(lport); @@ -1382,7 +1405,7 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_rport_enter_logo() - Logout of the fabric + * fc_rport_enter_logo - Logout of the fabric * @lport: Fibre Channel local port to be logged out * * Locking Note: The lport lock is expected to be held before calling @@ -1414,7 +1437,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport) } /** - * fc_lport_flogi_resp() - Handle response to FLOGI request + * fc_lport_flogi_resp - Handle response to FLOGI request * @sp: current sequence in FLOGI exchange * @fp: response frame * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request @@ -1442,17 +1465,17 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, FC_DEBUG_LPORT("Received a FLOGI response\n"); - if (IS_ERR(fp)) { - fc_lport_error(lport, fp); - goto err; - } - if (lport->state != LPORT_ST_FLOGI) { FC_DBG("Received a FLOGI response, but in state %s\n", fc_lport_state(lport)); goto out; } + if (IS_ERR(fp)) { + fc_lport_error(lport, fp); + goto err; + } + fh = fc_frame_header_get(fp); did = ntoh24(fh->fh_d_id); if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { @@ -1509,7 +1532,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager + * fc_rport_enter_flogi - Send a FLOGI request to the fabric manager * @lport: Fibre Channel local port to be logged in to the fabric * * Locking Note: The lport lock is expected to be held before calling diff --git a/trunk/drivers/scsi/libfc/fc_rport.c b/trunk/drivers/scsi/libfc/fc_rport.c index dae65133a833..e780d8caf70e 100644 --- a/trunk/drivers/scsi/libfc/fc_rport.c +++ b/trunk/drivers/scsi/libfc/fc_rport.c @@ -81,7 +81,6 @@ static void fc_rport_recv_logo_req(struct fc_rport *, struct fc_seq *, struct fc_frame *); static void fc_rport_timeout(struct work_struct *); static void fc_rport_error(struct fc_rport *, struct fc_frame *); -static void fc_rport_error_retry(struct fc_rport *, struct fc_frame *); static void fc_rport_work(struct work_struct *); static const char *fc_rport_state_names[] = { @@ -146,7 +145,7 @@ struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp) } /** - * fc_rport_state() - return a string for the state the rport is in + * fc_rport_state - return a string for the state the rport is in * @rport: The rport whose state we want to get a string for */ static const char *fc_rport_state(struct fc_rport *rport) @@ -161,7 +160,7 @@ static const char *fc_rport_state(struct fc_rport *rport) } /** - * fc_set_rport_loss_tmo() - Set the remote port loss timeout in seconds. + * fc_set_rport_loss_tmo - Set the remote port loss timeout in seconds. * @rport: Pointer to Fibre Channel remote port structure * @timeout: timeout in seconds */ @@ -175,12 +174,12 @@ void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) EXPORT_SYMBOL(fc_set_rport_loss_tmo); /** - * fc_plogi_get_maxframe() - Get max payload from the common service parameters + * fc_plogi_get_maxframe - Get max payload from the common service parameters * @flp: FLOGI payload structure * @maxval: upper limit, may be less than what is in the service parameters */ -static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp, - unsigned int maxval) +static unsigned int +fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval) { unsigned int mfs; @@ -198,7 +197,7 @@ static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp, } /** - * fc_rport_state_enter() - Change the rport's state + * fc_rport_state_enter - Change the rport's state * @rport: The rport whose state should change * @new: The new state of the rport * @@ -215,7 +214,6 @@ static void fc_rport_state_enter(struct fc_rport *rport, static void fc_rport_work(struct work_struct *work) { - u32 port_id; struct fc_rport_libfc_priv *rdata = container_of(work, struct fc_rport_libfc_priv, event_work); enum fc_rport_event event; @@ -281,18 +279,14 @@ static void fc_rport_work(struct work_struct *work) rport_ops->event_callback(lport, rport, event); if (trans_state == FC_PORTSTATE_ROGUE) put_device(&rport->dev); - else { - port_id = rport->port_id; + else fc_remote_port_delete(rport); - lport->tt.exch_mgr_reset(lport, 0, port_id); - lport->tt.exch_mgr_reset(lport, port_id, 0); - } } else mutex_unlock(&rdata->rp_mutex); } /** - * fc_rport_login() - Start the remote port login state machine + * fc_rport_login - Start the remote port login state machine * @rport: Fibre Channel remote port * * Locking Note: Called without the rport lock held. This @@ -315,7 +309,7 @@ int fc_rport_login(struct fc_rport *rport) } /** - * fc_rport_logoff() - Logoff and remove an rport + * fc_rport_logoff - Logoff and remove an rport * @rport: Fibre Channel remote port to be removed * * Locking Note: Called without the rport lock held. This @@ -353,7 +347,7 @@ int fc_rport_logoff(struct fc_rport *rport) } /** - * fc_rport_enter_ready() - The rport is ready + * fc_rport_enter_ready - The rport is ready * @rport: Fibre Channel remote port that is ready * * Locking Note: The rport lock is expected to be held before calling @@ -372,7 +366,7 @@ static void fc_rport_enter_ready(struct fc_rport *rport) } /** - * fc_rport_timeout() - Handler for the retry_work timer. + * fc_rport_timeout - Handler for the retry_work timer. * @work: The work struct of the fc_rport_libfc_priv * * Locking Note: Called without the rport lock held. This @@ -411,75 +405,59 @@ static void fc_rport_timeout(struct work_struct *work) } /** - * fc_rport_error() - Error handler, called once retries have been exhausted + * fc_rport_error - Handler for any errors * @rport: The fc_rport object * @fp: The frame pointer * + * If the error was caused by a resource allocation failure + * then wait for half a second and retry, otherwise retry + * immediately. + * * Locking Note: The rport lock is expected to be held before * calling this routine */ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) { struct fc_rport_libfc_priv *rdata = rport->dd_data; + unsigned long delay = 0; FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n", PTR_ERR(fp), fc_rport_state(rport), rdata->retries); - switch (rdata->rp_state) { - case RPORT_ST_PLOGI: - case RPORT_ST_PRLI: - case RPORT_ST_LOGO: - rdata->event = RPORT_EV_FAILED; - queue_work(rport_event_queue, - &rdata->event_work); - break; - case RPORT_ST_RTV: - fc_rport_enter_ready(rport); - break; - case RPORT_ST_NONE: - case RPORT_ST_READY: - case RPORT_ST_INIT: - break; - } -} - -/** - * fc_rport_error_retry() - Error handler when retries are desired - * @rport: The fc_rport object - * @fp: The frame pointer - * - * If the error was an exchange timeout retry immediately, - * otherwise wait for E_D_TOV. - * - * Locking Note: The rport lock is expected to be held before - * calling this routine - */ -static void fc_rport_error_retry(struct fc_rport *rport, struct fc_frame *fp) -{ - struct fc_rport_libfc_priv *rdata = rport->dd_data; - unsigned long delay = FC_DEF_E_D_TOV; - - /* make sure this isn't an FC_EX_CLOSED error, never retry those */ - if (PTR_ERR(fp) == -FC_EX_CLOSED) - return fc_rport_error(rport, fp); - - if (rdata->retries < rdata->local_port->max_retry_count) { - FC_DEBUG_RPORT("Error %ld in state %s, retrying\n", - PTR_ERR(fp), fc_rport_state(rport)); - rdata->retries++; - /* no additional delay on exchange timeouts */ - if (PTR_ERR(fp) == -FC_EX_TIMEOUT) - delay = 0; - get_device(&rport->dev); - schedule_delayed_work(&rdata->retry_work, delay); - return; + if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { + /* + * Memory allocation failure, or the exchange timed out. + * Retry after delay + */ + if (rdata->retries < rdata->local_port->max_retry_count) { + rdata->retries++; + if (!fp) + delay = msecs_to_jiffies(500); + get_device(&rport->dev); + schedule_delayed_work(&rdata->retry_work, delay); + } else { + switch (rdata->rp_state) { + case RPORT_ST_PLOGI: + case RPORT_ST_PRLI: + case RPORT_ST_LOGO: + rdata->event = RPORT_EV_FAILED; + queue_work(rport_event_queue, + &rdata->event_work); + break; + case RPORT_ST_RTV: + fc_rport_enter_ready(rport); + break; + case RPORT_ST_NONE: + case RPORT_ST_READY: + case RPORT_ST_INIT: + break; + } + } } - - return fc_rport_error(rport, fp); } /** - * fc_rport_plogi_recv_resp() - Handle incoming ELS PLOGI response + * fc_rport_plogi_recv_resp - Handle incoming ELS PLOGI response * @sp: current sequence in the PLOGI exchange * @fp: response frame * @rp_arg: Fibre Channel remote port @@ -505,17 +483,17 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", rport->port_id); - if (IS_ERR(fp)) { - fc_rport_error_retry(rport, fp); - goto err; - } - if (rdata->rp_state != RPORT_ST_PLOGI) { FC_DBG("Received a PLOGI response, but in state %s\n", fc_rport_state(rport)); goto out; } + if (IS_ERR(fp)) { + fc_rport_error(rport, fp); + goto err; + } + op = fc_frame_payload_op(fp); if (op == ELS_LS_ACC && (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { @@ -544,7 +522,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, else fc_rport_enter_prli(rport); } else - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); out: fc_frame_free(fp); @@ -554,7 +532,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer + * fc_rport_enter_plogi - Send Port Login (PLOGI) request to peer * @rport: Fibre Channel remote port to send PLOGI to * * Locking Note: The rport lock is expected to be held before calling @@ -574,20 +552,20 @@ static void fc_rport_enter_plogi(struct fc_rport *rport) rport->maxframe_size = FC_MIN_MAX_PAYLOAD; fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); if (!fp) { - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); return; } rdata->e_d_tov = lport->e_d_tov; if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI, fc_rport_plogi_resp, rport, lport->e_d_tov)) - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); else get_device(&rport->dev); } /** - * fc_rport_prli_resp() - Process Login (PRLI) response handler + * fc_rport_prli_resp - Process Login (PRLI) response handler * @sp: current sequence in the PRLI exchange * @fp: response frame * @rp_arg: Fibre Channel remote port @@ -614,17 +592,17 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", rport->port_id); - if (IS_ERR(fp)) { - fc_rport_error_retry(rport, fp); - goto err; - } - if (rdata->rp_state != RPORT_ST_PRLI) { FC_DBG("Received a PRLI response, but in state %s\n", fc_rport_state(rport)); goto out; } + if (IS_ERR(fp)) { + fc_rport_error(rport, fp); + goto err; + } + op = fc_frame_payload_op(fp); if (op == ELS_LS_ACC) { pp = fc_frame_payload_get(fp, sizeof(*pp)); @@ -657,7 +635,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_rport_logo_resp() - Logout (LOGO) response handler + * fc_rport_logo_resp - Logout (LOGO) response handler * @sp: current sequence in the LOGO exchange * @fp: response frame * @rp_arg: Fibre Channel remote port @@ -679,7 +657,7 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, rport->port_id); if (IS_ERR(fp)) { - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); goto err; } @@ -706,7 +684,7 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer + * fc_rport_enter_prli - Send Process Login (PRLI) request to peer * @rport: Fibre Channel remote port to send PRLI to * * Locking Note: The rport lock is expected to be held before calling @@ -729,19 +707,19 @@ static void fc_rport_enter_prli(struct fc_rport *rport) fp = fc_frame_alloc(lport, sizeof(*pp)); if (!fp) { - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); return; } if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI, fc_rport_prli_resp, rport, lport->e_d_tov)) - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); else get_device(&rport->dev); } /** - * fc_rport_els_rtv_resp() - Request Timeout Value response handler + * fc_rport_els_rtv_resp - Request Timeout Value response handler * @sp: current sequence in the RTV exchange * @fp: response frame * @rp_arg: Fibre Channel remote port @@ -764,17 +742,17 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", rport->port_id); - if (IS_ERR(fp)) { - fc_rport_error(rport, fp); - goto err; - } - if (rdata->rp_state != RPORT_ST_RTV) { FC_DBG("Received a RTV response, but in state %s\n", fc_rport_state(rport)); goto out; } + if (IS_ERR(fp)) { + fc_rport_error(rport, fp); + goto err; + } + op = fc_frame_payload_op(fp); if (op == ELS_LS_ACC) { struct fc_els_rtv_acc *rtv; @@ -807,7 +785,7 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer + * fc_rport_enter_rtv - Send Request Timeout Value (RTV) request to peer * @rport: Fibre Channel remote port to send RTV to * * Locking Note: The rport lock is expected to be held before calling @@ -826,19 +804,19 @@ static void fc_rport_enter_rtv(struct fc_rport *rport) fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv)); if (!fp) { - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); return; } if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV, fc_rport_rtv_resp, rport, lport->e_d_tov)) - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); else get_device(&rport->dev); } /** - * fc_rport_enter_logo() - Send Logout (LOGO) request to peer + * fc_rport_enter_logo - Send Logout (LOGO) request to peer * @rport: Fibre Channel remote port to send LOGO to * * Locking Note: The rport lock is expected to be held before calling @@ -857,20 +835,20 @@ static void fc_rport_enter_logo(struct fc_rport *rport) fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo)); if (!fp) { - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); return; } if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO, fc_rport_logo_resp, rport, lport->e_d_tov)) - fc_rport_error_retry(rport, fp); + fc_rport_error(rport, fp); else get_device(&rport->dev); } /** - * fc_rport_recv_req() - Receive a request from a rport + * fc_rport_recv_req - Receive a request from a rport * @sp: current sequence in the PLOGI exchange * @fp: response frame * @rp_arg: Fibre Channel remote port @@ -931,7 +909,7 @@ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp, } /** - * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request + * fc_rport_recv_plogi_req - Handle incoming Port Login (PLOGI) request * @rport: Fibre Channel remote port that initiated PLOGI * @sp: current sequence in the PLOGI exchange * @fp: PLOGI request frame @@ -1053,7 +1031,7 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport, } /** - * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request + * fc_rport_recv_prli_req - Handle incoming Process Login (PRLI) request * @rport: Fibre Channel remote port that initiated PRLI * @sp: current sequence in the PRLI exchange * @fp: PRLI request frame @@ -1204,7 +1182,7 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, } /** - * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request + * fc_rport_recv_prlo_req - Handle incoming Process Logout (PRLO) request * @rport: Fibre Channel remote port that initiated PRLO * @sp: current sequence in the PRLO exchange * @fp: PRLO request frame @@ -1235,7 +1213,7 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, } /** - * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request + * fc_rport_recv_logo_req - Handle incoming Logout (LOGO) request * @rport: Fibre Channel remote port that initiated LOGO * @sp: current sequence in the LOGO exchange * @fp: LOGO request frame @@ -1271,9 +1249,6 @@ static void fc_rport_flush_queue(void) int fc_rport_init(struct fc_lport *lport) { - if (!lport->tt.rport_create) - lport->tt.rport_create = fc_rport_rogue_create; - if (!lport->tt.rport_login) lport->tt.rport_login = fc_rport_login; @@ -1310,7 +1285,7 @@ void fc_rport_terminate_io(struct fc_rport *rport) struct fc_rport_libfc_priv *rdata = rport->dd_data; struct fc_lport *lport = rdata->local_port; - lport->tt.exch_mgr_reset(lport, 0, rport->port_id); - lport->tt.exch_mgr_reset(lport, rport->port_id, 0); + lport->tt.exch_mgr_reset(lport->emp, 0, rport->port_id); + lport->tt.exch_mgr_reset(lport->emp, rport->port_id, 0); } EXPORT_SYMBOL(fc_rport_terminate_io); diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index ee9d40152430..f4c57227ec18 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -244,6 +244,12 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, if (ha->optrom_state != QLA_SWAITING) break; + if (start & 0xfff) { + qla_printk(KERN_WARNING, ha, + "Invalid start region 0x%x/0x%x.\n", start, size); + return -EINVAL; + } + ha->optrom_region_start = start; ha->optrom_region_size = start + size > ha->optrom_size ? ha->optrom_size - start : size; @@ -297,7 +303,8 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, else if (start == (ha->flt_region_boot * 4) || start == (ha->flt_region_fw * 4)) valid = 1; - else if (IS_QLA25XX(ha) || IS_QLA81XX(ha)) + else if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && + start == (ha->flt_region_vpd_nvram * 4)) valid = 1; if (!valid) { qla_printk(KERN_WARNING, ha, diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 87f9abc71460..986501759ad4 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -1308,12 +1308,8 @@ qla2x00_init_rings(scsi_qla_host_t *vha) DEBUG(printk("scsi(%ld): Issue init firmware.\n", vha->host_no)); - if (ha->flags.npiv_supported) { - if (ha->operating_mode == LOOP) - ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1; + if (ha->flags.npiv_supported) mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports); - } - mid_init_cb->options = __constant_cpu_to_le16(BIT_1); @@ -2614,7 +2610,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, port_id_t wrap, nxt_d_id; struct qla_hw_data *ha = vha->hw; struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev); - struct scsi_qla_host *tvp; rval = QLA_SUCCESS; @@ -2714,7 +2709,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, /* Bypass virtual ports of the same host. */ found = 0; if (ha->num_vhosts) { - list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { + list_for_each_entry(vp, &ha->vp_list, list) { if (new_fcport->d_id.b24 == vp->d_id.b24) { found = 1; break; @@ -2837,7 +2832,6 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) uint16_t first_loop_id; struct qla_hw_data *ha = vha->hw; struct scsi_qla_host *vp; - struct scsi_qla_host *tvp; rval = QLA_SUCCESS; @@ -2862,7 +2856,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) /* Check for loop ID being already in use. */ found = 0; fcport = NULL; - list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { + list_for_each_entry(vp, &ha->vp_list, list) { list_for_each_entry(fcport, &vp->vp_fcports, list) { if (fcport->loop_id == dev->loop_id && fcport != dev) { @@ -3297,7 +3291,6 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) uint8_t status = 0; struct qla_hw_data *ha = vha->hw; struct scsi_qla_host *vp; - struct scsi_qla_host *tvp; struct req_que *req = ha->req_q_map[0]; if (vha->flags.online) { @@ -3313,7 +3306,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); qla2x00_mark_all_devices_lost(vha, 0); - list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) + list_for_each_entry(vp, &ha->vp_list, list) qla2x00_mark_all_devices_lost(vp, 0); } else { if (!atomic_read(&vha->loop_down_timer)) @@ -3410,7 +3403,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) DEBUG(printk(KERN_INFO "qla2x00_abort_isp(%ld): succeeded.\n", vha->host_no)); - list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { + list_for_each_entry(vp, &ha->vp_list, list) { if (vp->vp_idx) qla2x00_vp_abort_isp(vp); } @@ -3435,7 +3428,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) static int qla2x00_restart_isp(scsi_qla_host_t *vha) { - int status = 0; + uint8_t status = 0; uint32_t wait_time; struct qla_hw_data *ha = vha->hw; struct req_que *req = ha->req_q_map[0]; diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index 4aab7acf7525..4c7504cb3990 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -2685,7 +2685,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, uint16_t stat = le16_to_cpu(rptid_entry->vp_idx); struct qla_hw_data *ha = vha->hw; scsi_qla_host_t *vp; - scsi_qla_host_t *tvp; if (rptid_entry->entry_status != 0) return; @@ -2711,7 +2710,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, if (MSB(stat) == 1) return; - list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) + list_for_each_entry(vp, &ha->vp_list, list) if (vp_idx == vp->vp_idx) break; if (!vp) diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index 785c61279e6e..3f23932210c4 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -69,10 +69,9 @@ static scsi_qla_host_t * qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name) { scsi_qla_host_t *vha; - struct scsi_qla_host *tvha; /* Locate matching device in database. */ - list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) { + list_for_each_entry(vha, &ha->vp_list, list) { if (!memcmp(port_name, vha->port_name, WWN_SIZE)) return vha; } @@ -195,11 +194,11 @@ qla24xx_configure_vp(scsi_qla_host_t *vha) void qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) { - scsi_qla_host_t *vha, *tvha; + scsi_qla_host_t *vha; struct qla_hw_data *ha = rsp->hw; int i = 0; - list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) { + list_for_each_entry(vha, &ha->vp_list, list) { if (vha->vp_idx) { switch (mb[0]) { case MBA_LIP_OCCURRED: @@ -301,7 +300,6 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha) int ret; struct qla_hw_data *ha = vha->hw; scsi_qla_host_t *vp; - struct scsi_qla_host *tvp; if (vha->vp_idx) return; @@ -310,7 +308,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha) clear_bit(VP_DPC_NEEDED, &vha->dpc_flags); - list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { + list_for_each_entry(vp, &ha->vp_list, list) { if (vp->vp_idx) ret = qla2x00_do_dpc_vp(vp); } diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 3ddfa889e949..2f5f72531e23 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -2222,6 +2222,10 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, { char name[16]; + ha->init_cb_size = sizeof(init_cb_t); + if (IS_QLA2XXX_MIDTYPE(ha)) + ha->init_cb_size = sizeof(struct mid_init_cb_24xx); + ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size, &ha->init_cb_dma, GFP_KERNEL); if (!ha->init_cb) @@ -2564,7 +2568,7 @@ qla2x00_do_work(struct scsi_qla_host *vha) void qla2x00_relogin(struct scsi_qla_host *vha) { fc_port_t *fcport; - int status; + uint8_t status; uint16_t next_loopid = 0; struct qla_hw_data *ha = vha->hw; diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index a772eab2f0ea..79f7053da99b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.00-k4" +#define QLA2XXX_VERSION "8.03.00-k3" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 4970ae4a62d6..55310dbc10a6 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -1167,19 +1167,23 @@ sd_spinup_disk(struct scsi_disk *sdkp) /* * The device does not want the automatic start to be issued. */ - if (sdkp->device->no_start_on_add) + if (sdkp->device->no_start_on_add) { break; + } - if (sense_valid && sshdr.sense_key == NOT_READY) { - if (sshdr.asc == 4 && sshdr.ascq == 3) - break; /* manual intervention required */ - if (sshdr.asc == 4 && sshdr.ascq == 0xb) - break; /* standby */ - if (sshdr.asc == 4 && sshdr.ascq == 0xc) - break; /* unavailable */ - /* - * Issue command to spin up drive when not ready - */ + /* + * If manual intervention is required, or this is an + * absent USB storage device, a spinup is meaningless. + */ + if (sense_valid && + sshdr.sense_key == NOT_READY && + sshdr.asc == 4 && sshdr.ascq == 3) { + break; /* manual intervention required */ + + /* + * Issue command to spin up drive when not ready + */ + } else if (sense_valid && sshdr.sense_key == NOT_READY) { if (!spintime) { sd_printk(KERN_NOTICE, sdkp, "Spinning up disk..."); cmd[0] = START_STOP; diff --git a/trunk/drivers/scsi/zalon.c b/trunk/drivers/scsi/zalon.c index 97f3158fa7b5..a8d61a62522e 100644 --- a/trunk/drivers/scsi/zalon.c +++ b/trunk/drivers/scsi/zalon.c @@ -137,7 +137,7 @@ zalon_probe(struct parisc_device *dev) goto fail; if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) { - dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching\n ", + dev_printk(KERN_ERR, dev, "irq problem with %d, detaching\n ", dev->irq); goto fail; } diff --git a/trunk/drivers/staging/Kconfig b/trunk/drivers/staging/Kconfig index 211af86a6c55..ce6badded47a 100644 --- a/trunk/drivers/staging/Kconfig +++ b/trunk/drivers/staging/Kconfig @@ -73,6 +73,8 @@ source "drivers/staging/rt2860/Kconfig" source "drivers/staging/rt2870/Kconfig" +source "drivers/staging/benet/Kconfig" + source "drivers/staging/comedi/Kconfig" source "drivers/staging/asus_oled/Kconfig" diff --git a/trunk/drivers/staging/Makefile b/trunk/drivers/staging/Makefile index 47a56f5ffabc..9ddcc2bb3365 100644 --- a/trunk/drivers/staging/Makefile +++ b/trunk/drivers/staging/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_AGNX) += agnx/ obj-$(CONFIG_OTUS) += otus/ obj-$(CONFIG_RT2860) += rt2860/ obj-$(CONFIG_RT2870) += rt2870/ +obj-$(CONFIG_BENET) += benet/ obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_ASUS_OLED) += asus_oled/ obj-$(CONFIG_PANEL) += panel/ diff --git a/trunk/drivers/staging/benet/Kconfig b/trunk/drivers/staging/benet/Kconfig new file mode 100644 index 000000000000..f6806074f998 --- /dev/null +++ b/trunk/drivers/staging/benet/Kconfig @@ -0,0 +1,7 @@ +config BENET + tristate "ServerEngines 10Gb NIC - BladeEngine" + depends on PCI && INET + select INET_LRO + help + This driver implements the NIC functionality for ServerEngines + 10Gb network adapter BladeEngine (EC 3210). diff --git a/trunk/drivers/staging/benet/MAINTAINERS b/trunk/drivers/staging/benet/MAINTAINERS new file mode 100644 index 000000000000..d5ce340218b3 --- /dev/null +++ b/trunk/drivers/staging/benet/MAINTAINERS @@ -0,0 +1,6 @@ +SERVER ENGINES 10Gbe NIC - BLADE-ENGINE +P: Subbu Seetharaman +M: subbus@serverengines.com +L: netdev@vger.kernel.org +W: http://www.serverengines.com +S: Supported diff --git a/trunk/drivers/staging/benet/Makefile b/trunk/drivers/staging/benet/Makefile new file mode 100644 index 000000000000..460b923b99bd --- /dev/null +++ b/trunk/drivers/staging/benet/Makefile @@ -0,0 +1,14 @@ +# +# Makefile to build the network driver for ServerEngine's BladeEngine +# +obj-$(CONFIG_BENET) += benet.o + +benet-y := be_init.o \ + be_int.o \ + be_netif.o \ + be_ethtool.o \ + funcobj.o \ + cq.o \ + eq.o \ + mpu.o \ + eth.o diff --git a/trunk/drivers/staging/benet/TODO b/trunk/drivers/staging/benet/TODO new file mode 100644 index 000000000000..a51dfb59a62f --- /dev/null +++ b/trunk/drivers/staging/benet/TODO @@ -0,0 +1,6 @@ +TODO: + - remove wrappers around common iowrite functions + - full netdev audit of common problems/issues + +Please send all patches and questions to Subbu Seetharaman + and Greg Kroah-Hartman diff --git a/trunk/drivers/staging/benet/asyncmesg.h b/trunk/drivers/staging/benet/asyncmesg.h new file mode 100644 index 000000000000..d1e779adb848 --- /dev/null +++ b/trunk/drivers/staging/benet/asyncmesg.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __asyncmesg_amap_h__ +#define __asyncmesg_amap_h__ +#include "fwcmd_common.h" + +/* --- ASYNC_EVENT_CODES --- */ +#define ASYNC_EVENT_CODE_LINK_STATE (1) +#define ASYNC_EVENT_CODE_ISCSI (2) + +/* --- ASYNC_LINK_STATES --- */ +#define ASYNC_EVENT_LINK_DOWN (0) /* Link Down on a port */ +#define ASYNC_EVENT_LINK_UP (1) /* Link Up on a port */ + +/* + * The last 4 bytes of the async events have this common format. It allows + * the driver to distinguish [link]MCC_CQ_ENTRY[/link] structs from + * asynchronous events. Both arrive on the same completion queue. This + * structure also contains the common fields used to decode the async event. + */ +struct BE_ASYNC_EVENT_TRAILER_AMAP { + u8 rsvd0[8]; /* DWORD 0 */ + u8 event_code[8]; /* DWORD 0 */ + u8 event_type[8]; /* DWORD 0 */ + u8 rsvd1[6]; /* DWORD 0 */ + u8 async_event; /* DWORD 0 */ + u8 valid; /* DWORD 0 */ +} __packed; +struct ASYNC_EVENT_TRAILER_AMAP { + u32 dw[1]; +}; + +/* + * Applicable in Initiator, Target and NIC modes. + * A link state async event is seen by all device drivers as soon they + * create an MCC ring. Thereafter, anytime the link status changes the + * drivers will receive a link state async event. Notifications continue to + * be sent until a driver destroys its MCC ring. A link down event is + * reported when either port loses link. A link up event is reported + * when either port regains link. When BE's failover mechanism is enabled, a + * link down on the active port causes traffic to be diverted to the standby + * port by the BE's ARM firmware (assuming the standby port has link). In + * this case, the standy port assumes the active status. Note: when link is + * restored on the failed port, traffic continues on the currently active + * port. The ARM firmware does not attempt to 'fail back' traffic to + * the restored port. + */ +struct BE_ASYNC_EVENT_LINK_STATE_AMAP { + u8 port0_link_status[8]; + u8 port1_link_status[8]; + u8 active_port[8]; + u8 rsvd0[8]; /* DWORD 0 */ + u8 port0_duplex[8]; + u8 port0_speed[8]; + u8 port1_duplex[8]; + u8 port1_speed[8]; + u8 port0_fault[8]; + u8 port1_fault[8]; + u8 rsvd1[2][8]; /* DWORD 2 */ + struct BE_ASYNC_EVENT_TRAILER_AMAP trailer; +} __packed; +struct ASYNC_EVENT_LINK_STATE_AMAP { + u32 dw[4]; +}; +#endif /* __asyncmesg_amap_h__ */ diff --git a/trunk/drivers/staging/benet/be_cm.h b/trunk/drivers/staging/benet/be_cm.h new file mode 100644 index 000000000000..b7a1dfd20c36 --- /dev/null +++ b/trunk/drivers/staging/benet/be_cm.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __be_cm_amap_h__ +#define __be_cm_amap_h__ +#include "be_common.h" +#include "etx_context.h" +#include "mpu_context.h" + +/* + * --- CEV_WATERMARK_ENUM --- + * CQ/EQ Watermark Encodings. Encoded as number of free entries in + * Queue when Watermark is reached. + */ +#define CEV_WMARK_0 (0) /* Watermark when Queue full */ +#define CEV_WMARK_16 (1) /* Watermark at 16 free entries */ +#define CEV_WMARK_32 (2) /* Watermark at 32 free entries */ +#define CEV_WMARK_48 (3) /* Watermark at 48 free entries */ +#define CEV_WMARK_64 (4) /* Watermark at 64 free entries */ +#define CEV_WMARK_80 (5) /* Watermark at 80 free entries */ +#define CEV_WMARK_96 (6) /* Watermark at 96 free entries */ +#define CEV_WMARK_112 (7) /* Watermark at 112 free entries */ +#define CEV_WMARK_128 (8) /* Watermark at 128 free entries */ +#define CEV_WMARK_144 (9) /* Watermark at 144 free entries */ +#define CEV_WMARK_160 (10) /* Watermark at 160 free entries */ +#define CEV_WMARK_176 (11) /* Watermark at 176 free entries */ +#define CEV_WMARK_192 (12) /* Watermark at 192 free entries */ +#define CEV_WMARK_208 (13) /* Watermark at 208 free entries */ +#define CEV_WMARK_224 (14) /* Watermark at 224 free entries */ +#define CEV_WMARK_240 (15) /* Watermark at 240 free entries */ + +/* + * --- CQ_CNT_ENUM --- + * Completion Queue Count Encodings. + */ +#define CEV_CQ_CNT_256 (0) /* CQ has 256 entries */ +#define CEV_CQ_CNT_512 (1) /* CQ has 512 entries */ +#define CEV_CQ_CNT_1024 (2) /* CQ has 1024 entries */ + +/* + * --- EQ_CNT_ENUM --- + * Event Queue Count Encodings. + */ +#define CEV_EQ_CNT_256 (0) /* EQ has 256 entries (16-byte EQEs only) */ +#define CEV_EQ_CNT_512 (1) /* EQ has 512 entries (16-byte EQEs only) */ +#define CEV_EQ_CNT_1024 (2) /* EQ has 1024 entries (4-byte or */ + /* 16-byte EQEs only) */ +#define CEV_EQ_CNT_2048 (3) /* EQ has 2048 entries (4-byte or */ + /* 16-byte EQEs only) */ +#define CEV_EQ_CNT_4096 (4) /* EQ has 4096 entries (4-byte EQEs only) */ + +/* + * --- EQ_SIZE_ENUM --- + * Event Queue Entry Size Encoding. + */ +#define CEV_EQ_SIZE_4 (0) /* EQE is 4 bytes */ +#define CEV_EQ_SIZE_16 (1) /* EQE is 16 bytes */ + +/* + * Completion Queue Context Table Entry. Contains the state of a CQ. + * Located in RAM within the CEV block. + */ +struct BE_CQ_CONTEXT_AMAP { + u8 Cidx[11]; /* DWORD 0 */ + u8 Watermark[4]; /* DWORD 0 */ + u8 NoDelay; /* DWORD 0 */ + u8 EPIdx[11]; /* DWORD 0 */ + u8 Count[2]; /* DWORD 0 */ + u8 valid; /* DWORD 0 */ + u8 SolEvent; /* DWORD 0 */ + u8 Eventable; /* DWORD 0 */ + u8 Pidx[11]; /* DWORD 1 */ + u8 PD[10]; /* DWORD 1 */ + u8 EQID[7]; /* DWORD 1 */ + u8 Func; /* DWORD 1 */ + u8 WME; /* DWORD 1 */ + u8 Stalled; /* DWORD 1 */ + u8 Armed; /* DWORD 1 */ +} __packed; +struct CQ_CONTEXT_AMAP { + u32 dw[2]; +}; + +/* + * Event Queue Context Table Entry. Contains the state of an EQ. + * Located in RAM in the CEV block. + */ +struct BE_EQ_CONTEXT_AMAP { + u8 Cidx[13]; /* DWORD 0 */ + u8 rsvd0[2]; /* DWORD 0 */ + u8 Func; /* DWORD 0 */ + u8 EPIdx[13]; /* DWORD 0 */ + u8 valid; /* DWORD 0 */ + u8 rsvd1; /* DWORD 0 */ + u8 Size; /* DWORD 0 */ + u8 Pidx[13]; /* DWORD 1 */ + u8 rsvd2[3]; /* DWORD 1 */ + u8 PD[10]; /* DWORD 1 */ + u8 Count[3]; /* DWORD 1 */ + u8 SolEvent; /* DWORD 1 */ + u8 Stalled; /* DWORD 1 */ + u8 Armed; /* DWORD 1 */ + u8 Watermark[4]; /* DWORD 2 */ + u8 WME; /* DWORD 2 */ + u8 rsvd3[3]; /* DWORD 2 */ + u8 EventVect[6]; /* DWORD 2 */ + u8 rsvd4[2]; /* DWORD 2 */ + u8 Delay[8]; /* DWORD 2 */ + u8 rsvd5[6]; /* DWORD 2 */ + u8 TMR; /* DWORD 2 */ + u8 rsvd6; /* DWORD 2 */ + u8 rsvd7[32]; /* DWORD 3 */ +} __packed; +struct EQ_CONTEXT_AMAP { + u32 dw[4]; +}; + +#endif /* __be_cm_amap_h__ */ diff --git a/trunk/drivers/staging/benet/be_common.h b/trunk/drivers/staging/benet/be_common.h new file mode 100644 index 000000000000..7e63dc5e3348 --- /dev/null +++ b/trunk/drivers/staging/benet/be_common.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __be_common_amap_h__ +#define __be_common_amap_h__ + +/* Physical Address. */ +struct BE_PHYS_ADDR_AMAP { + u8 lo[32]; /* DWORD 0 */ + u8 hi[32]; /* DWORD 1 */ +} __packed; +struct PHYS_ADDR_AMAP { + u32 dw[2]; +}; + +/* Virtual Address. */ +struct BE_VIRT_ADDR_AMAP { + u8 lo[32]; /* DWORD 0 */ + u8 hi[32]; /* DWORD 1 */ +} __packed; +struct VIRT_ADDR_AMAP { + u32 dw[2]; +}; + +/* Scatter gather element. */ +struct BE_SGE_AMAP { + u8 addr_hi[32]; /* DWORD 0 */ + u8 addr_lo[32]; /* DWORD 1 */ + u8 rsvd0[32]; /* DWORD 2 */ + u8 len[16]; /* DWORD 3 */ + u8 rsvd1[16]; /* DWORD 3 */ +} __packed; +struct SGE_AMAP { + u32 dw[4]; +}; + +#endif /* __be_common_amap_h__ */ diff --git a/trunk/drivers/staging/benet/be_ethtool.c b/trunk/drivers/staging/benet/be_ethtool.c new file mode 100644 index 000000000000..027af85707aa --- /dev/null +++ b/trunk/drivers/staging/benet/be_ethtool.c @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * be_ethtool.c + * + * This file contains various functions that ethtool can use + * to talk to the driver and the BE H/W. + */ + +#include "benet.h" + +#include + +static const char benet_gstrings_stats[][ETH_GSTRING_LEN] = { +/* net_device_stats */ + "rx_packets", + "tx_packets", + "rx_bytes", + "tx_bytes", + "rx_errors", + "tx_errors", + "rx_dropped", + "tx_dropped", + "multicast", + "collisions", + "rx_length_errors", + "rx_over_errors", + "rx_crc_errors", + "rx_frame_errors", + "rx_fifo_errors", + "rx_missed_errors", + "tx_aborted_errors", + "tx_carrier_errors", + "tx_fifo_errors", + "tx_heartbeat_errors", + "tx_window_errors", + "rx_compressed", + "tc_compressed", +/* BE driver Stats */ + "bes_tx_reqs", + "bes_tx_fails", + "bes_fwd_reqs", + "bes_tx_wrbs", + "bes_interrupts", + "bes_events", + "bes_tx_events", + "bes_rx_events", + "bes_tx_compl", + "bes_rx_compl", + "bes_ethrx_post_fail", + "bes_802_3_dropped_frames", + "bes_802_3_malformed_frames", + "bes_rx_misc_pkts", + "bes_eth_tx_rate", + "bes_eth_rx_rate", + "Num Packets collected", + "Num Times Flushed", +}; + +#define NET_DEV_STATS_LEN \ + (sizeof(struct net_device_stats)/sizeof(unsigned long)) + +#define BENET_STATS_LEN ARRAY_SIZE(benet_gstrings_stats) + +static void +be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + + strncpy(drvinfo->driver, be_driver_name, 32); + strncpy(drvinfo->version, be_drvr_ver, 32); + strncpy(drvinfo->fw_version, be_fw_ver, 32); + strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); + drvinfo->testinfo_len = 0; + drvinfo->regdump_len = 0; + drvinfo->eedump_len = 0; +} + +static int +be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + + coalesce->rx_max_coalesced_frames = adapter->max_rx_coal; + + coalesce->rx_coalesce_usecs = adapter->cur_eqd; + coalesce->rx_coalesce_usecs_high = adapter->max_eqd; + coalesce->rx_coalesce_usecs_low = adapter->min_eqd; + + coalesce->tx_coalesce_usecs = adapter->cur_eqd; + coalesce->tx_coalesce_usecs_high = adapter->max_eqd; + coalesce->tx_coalesce_usecs_low = adapter->min_eqd; + + coalesce->use_adaptive_rx_coalesce = adapter->enable_aic; + coalesce->use_adaptive_tx_coalesce = adapter->enable_aic; + + return 0; +} + +/* + * This routine is used to set interrup coalescing delay *as well as* + * the number of pkts to coalesce for LRO. + */ +static int +be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + struct be_eq_object *eq_objectp; + u32 max, min, cur; + int status; + + adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; + if (adapter->max_rx_coal >= BE_LRO_MAX_PKTS) + adapter->max_rx_coal = BE_LRO_MAX_PKTS; + + if (adapter->enable_aic == 0 && + coalesce->use_adaptive_rx_coalesce == 1) { + /* if AIC is being turned on now, start with an EQD of 0 */ + adapter->cur_eqd = 0; + } + adapter->enable_aic = coalesce->use_adaptive_rx_coalesce; + + /* round off to nearest multiple of 8 */ + max = (((coalesce->rx_coalesce_usecs_high + 4) >> 3) << 3); + min = (((coalesce->rx_coalesce_usecs_low + 4) >> 3) << 3); + cur = (((coalesce->rx_coalesce_usecs + 4) >> 3) << 3); + + if (adapter->enable_aic) { + /* accept low and high if AIC is enabled */ + if (max > MAX_EQD) + max = MAX_EQD; + if (min > max) + min = max; + adapter->max_eqd = max; + adapter->min_eqd = min; + if (adapter->cur_eqd > max) + adapter->cur_eqd = max; + if (adapter->cur_eqd < min) + adapter->cur_eqd = min; + } else { + /* accept specified coalesce_usecs only if AIC is disabled */ + if (cur > MAX_EQD) + cur = MAX_EQD; + eq_objectp = &pnob->event_q_obj; + status = + be_eq_modify_delay(&pnob->fn_obj, 1, &eq_objectp, &cur, + NULL, NULL, NULL); + if (status == BE_SUCCESS) + adapter->cur_eqd = cur; + } + return 0; +} + +static u32 be_get_rx_csum(struct net_device *netdev) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + return adapter->rx_csum; +} + +static int be_set_rx_csum(struct net_device *netdev, uint32_t data) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + + if (data) + adapter->rx_csum = 1; + else + adapter->rx_csum = 0; + + return 0; +} + +static void +be_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(data, *benet_gstrings_stats, + sizeof(benet_gstrings_stats)); + break; + } +} + +static int be_get_stats_count(struct net_device *netdev) +{ + return BENET_STATS_LEN; +} + +static void +be_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, uint64_t *data) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + int i; + + benet_get_stats(netdev); + + for (i = 0; i <= NET_DEV_STATS_LEN; i++) + data[i] = ((unsigned long *)&adapter->benet_stats)[i]; + + data[i] = adapter->be_stat.bes_tx_reqs; + data[i++] = adapter->be_stat.bes_tx_fails; + data[i++] = adapter->be_stat.bes_fwd_reqs; + data[i++] = adapter->be_stat.bes_tx_wrbs; + + data[i++] = adapter->be_stat.bes_ints; + data[i++] = adapter->be_stat.bes_events; + data[i++] = adapter->be_stat.bes_tx_events; + data[i++] = adapter->be_stat.bes_rx_events; + data[i++] = adapter->be_stat.bes_tx_compl; + data[i++] = adapter->be_stat.bes_rx_compl; + data[i++] = adapter->be_stat.bes_ethrx_post_fail; + data[i++] = adapter->be_stat.bes_802_3_dropped_frames; + data[i++] = adapter->be_stat.bes_802_3_malformed_frames; + data[i++] = adapter->be_stat.bes_rx_misc_pkts; + data[i++] = adapter->be_stat.bes_eth_tx_rate; + data[i++] = adapter->be_stat.bes_eth_rx_rate; + data[i++] = adapter->be_stat.bes_rx_coal; + data[i++] = adapter->be_stat.bes_rx_flush; + +} + +static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +{ + ecmd->speed = SPEED_10000; + ecmd->duplex = DUPLEX_FULL; + ecmd->autoneg = AUTONEG_DISABLE; + return 0; +} + +/* Get the Ring parameters from the pnob */ +static void +be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) +{ + struct be_net_object *pnob = netdev_priv(netdev); + + /* Pre Set Maxims */ + ring->rx_max_pending = pnob->rx_q_len; + ring->rx_mini_max_pending = ring->rx_mini_max_pending; + ring->rx_jumbo_max_pending = ring->rx_jumbo_max_pending; + ring->tx_max_pending = pnob->tx_q_len; + + /* Current hardware Settings */ + ring->rx_pending = atomic_read(&pnob->rx_q_posted); + ring->rx_mini_pending = ring->rx_mini_pending; + ring->rx_jumbo_pending = ring->rx_jumbo_pending; + ring->tx_pending = atomic_read(&pnob->tx_q_used); + +} + +static void +be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) +{ + struct be_net_object *pnob = netdev_priv(netdev); + bool rxfc, txfc; + int status; + + status = be_eth_get_flow_control(&pnob->fn_obj, &txfc, &rxfc); + if (status != BE_SUCCESS) { + dev_info(&netdev->dev, "Unable to get pause frame settings\n"); + /* return defaults */ + ecmd->rx_pause = 1; + ecmd->tx_pause = 0; + ecmd->autoneg = AUTONEG_ENABLE; + return; + } + + if (txfc == true) + ecmd->tx_pause = 1; + else + ecmd->tx_pause = 0; + + if (rxfc == true) + ecmd->rx_pause = 1; + else + ecmd->rx_pause = 0; + + ecmd->autoneg = AUTONEG_ENABLE; +} + +static int +be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) +{ + struct be_net_object *pnob = netdev_priv(netdev); + bool txfc, rxfc; + int status; + + if (ecmd->autoneg != AUTONEG_ENABLE) + return -EINVAL; + + if (ecmd->tx_pause) + txfc = true; + else + txfc = false; + + if (ecmd->rx_pause) + rxfc = true; + else + rxfc = false; + + status = be_eth_set_flow_control(&pnob->fn_obj, txfc, rxfc); + if (status != BE_SUCCESS) { + dev_info(&netdev->dev, "Unable to set pause frame settings\n"); + return -1; + } + return 0; +} + +struct ethtool_ops be_ethtool_ops = { + .get_settings = be_get_settings, + .get_drvinfo = be_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_coalesce = be_get_coalesce, + .set_coalesce = be_set_coalesce, + .get_ringparam = be_get_ringparam, + .get_pauseparam = be_get_pauseparam, + .set_pauseparam = be_set_pauseparam, + .get_rx_csum = be_get_rx_csum, + .set_rx_csum = be_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = ethtool_op_set_tso, + .get_strings = be_get_strings, + .get_stats_count = be_get_stats_count, + .get_ethtool_stats = be_get_ethtool_stats, +}; diff --git a/trunk/drivers/staging/benet/be_init.c b/trunk/drivers/staging/benet/be_init.c new file mode 100644 index 000000000000..12a026c3f9e1 --- /dev/null +++ b/trunk/drivers/staging/benet/be_init.c @@ -0,0 +1,1382 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#include +#include "benet.h" + +#define DRVR_VERSION "1.0.728" + +static const struct pci_device_id be_device_id_table[] = { + {PCI_DEVICE(0x19a2, 0x0201)}, + {0} +}; + +MODULE_DEVICE_TABLE(pci, be_device_id_table); + +MODULE_VERSION(DRVR_VERSION); + +#define DRV_DESCRIPTION "ServerEngines BladeEngine Network Driver Version " + +MODULE_DESCRIPTION(DRV_DESCRIPTION DRVR_VERSION); +MODULE_AUTHOR("ServerEngines"); +MODULE_LICENSE("GPL"); + +static unsigned int msix = 1; +module_param(msix, uint, S_IRUGO); +MODULE_PARM_DESC(msix, "Use MSI-x interrupts"); + +static unsigned int rxbuf_size = 2048; /* Default RX frag size */ +module_param(rxbuf_size, uint, S_IRUGO); +MODULE_PARM_DESC(rxbuf_size, "Size of buffers to hold Rx data"); + +const char be_drvr_ver[] = DRVR_VERSION; +char be_fw_ver[32]; /* F/W version filled in by be_probe */ +char be_driver_name[] = "benet"; + +/* + * Number of entries in each queue. + */ +#define EVENT_Q_LEN 1024 +#define ETH_TXQ_LEN 2048 +#define ETH_TXCQ_LEN 1024 +#define ETH_RXQ_LEN 1024 /* Does not support any other value */ +#define ETH_UC_RXCQ_LEN 1024 +#define ETH_BC_RXCQ_LEN 256 +#define MCC_Q_LEN 64 /* total size not to exceed 8 pages */ +#define MCC_CQ_LEN 256 + +/* Bit mask describing events of interest to be traced */ +unsigned int trace_level; + +static int +init_pci_be_function(struct be_adapter *adapter, struct pci_dev *pdev) +{ + u64 pa; + + /* CSR */ + pa = pci_resource_start(pdev, 2); + adapter->csr_va = ioremap_nocache(pa, pci_resource_len(pdev, 2)); + if (adapter->csr_va == NULL) + return -ENOMEM; + + /* Door Bell */ + pa = pci_resource_start(pdev, 4); + adapter->db_va = ioremap_nocache(pa, (128 * 1024)); + if (adapter->db_va == NULL) { + iounmap(adapter->csr_va); + return -ENOMEM; + } + + /* PCI */ + pa = pci_resource_start(pdev, 1); + adapter->pci_va = ioremap_nocache(pa, pci_resource_len(pdev, 1)); + if (adapter->pci_va == NULL) { + iounmap(adapter->csr_va); + iounmap(adapter->db_va); + return -ENOMEM; + } + return 0; +} + +/* + This function enables the interrupt corresponding to the Event + queue ID for the given NetObject +*/ +void be_enable_eq_intr(struct be_net_object *pnob) +{ + struct CQ_DB_AMAP cqdb; + cqdb.dw[0] = 0; + AMAP_SET_BITS_PTR(CQ_DB, event, &cqdb, 1); + AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, 1); + AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, 0); + AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, pnob->event_q_id); + PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]); +} + +/* + This function disables the interrupt corresponding to the Event + queue ID for the given NetObject +*/ +void be_disable_eq_intr(struct be_net_object *pnob) +{ + struct CQ_DB_AMAP cqdb; + cqdb.dw[0] = 0; + AMAP_SET_BITS_PTR(CQ_DB, event, &cqdb, 1); + AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, 0); + AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, 0); + AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, pnob->event_q_id); + PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]); +} + +/* + This function enables the interrupt from the network function + of the BladeEngine. Use the function be_disable_eq_intr() + to enable the interrupt from the event queue of only one specific + NetObject +*/ +void be_enable_intr(struct be_net_object *pnob) +{ + struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl; + u32 host_intr; + + ctrl.dw[0] = PCICFG1_READ(&pnob->fn_obj, host_timer_int_ctrl); + host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, + hostintr, ctrl.dw); + if (!host_intr) { + AMAP_SET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, + hostintr, ctrl.dw, 1); + PCICFG1_WRITE(&pnob->fn_obj, host_timer_int_ctrl, + ctrl.dw[0]); + } +} + +/* + This function disables the interrupt from the network function of + the BladeEngine. Use the function be_disable_eq_intr() to + disable the interrupt from the event queue of only one specific NetObject +*/ +void be_disable_intr(struct be_net_object *pnob) +{ + + struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl; + u32 host_intr; + ctrl.dw[0] = PCICFG1_READ(&pnob->fn_obj, host_timer_int_ctrl); + host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, + hostintr, ctrl.dw); + if (host_intr) { + AMAP_SET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, hostintr, + ctrl.dw, 0); + PCICFG1_WRITE(&pnob->fn_obj, host_timer_int_ctrl, + ctrl.dw[0]); + } +} + +static int be_enable_msix(struct be_adapter *adapter) +{ + int i, ret; + + if (!msix) + return -1; + + for (i = 0; i < BE_MAX_REQ_MSIX_VECTORS; i++) + adapter->msix_entries[i].entry = i; + + ret = pci_enable_msix(adapter->pdev, adapter->msix_entries, + BE_MAX_REQ_MSIX_VECTORS); + + if (ret == 0) + adapter->msix_enabled = 1; + return ret; +} + +static int be_register_isr(struct be_adapter *adapter, + struct be_net_object *pnob) +{ + struct net_device *netdev = pnob->netdev; + int intx = 0, r; + + netdev->irq = adapter->pdev->irq; + r = be_enable_msix(adapter); + + if (r == 0) { + r = request_irq(adapter->msix_entries[0].vector, + be_int, IRQF_SHARED, netdev->name, netdev); + if (r) { + printk(KERN_WARNING + "MSIX Request IRQ failed - Errno %d\n", r); + intx = 1; + pci_disable_msix(adapter->pdev); + adapter->msix_enabled = 0; + } + } else { + intx = 1; + } + + if (intx) { + r = request_irq(netdev->irq, be_int, IRQF_SHARED, + netdev->name, netdev); + if (r) { + printk(KERN_WARNING + "INTx Request IRQ failed - Errno %d\n", r); + return -1; + } + } + adapter->isr_registered = 1; + return 0; +} + +static void be_unregister_isr(struct be_adapter *adapter) +{ + struct net_device *netdev = adapter->netdevp; + if (adapter->isr_registered) { + if (adapter->msix_enabled) { + free_irq(adapter->msix_entries[0].vector, netdev); + pci_disable_msix(adapter->pdev); + adapter->msix_enabled = 0; + } else { + free_irq(netdev->irq, netdev); + } + adapter->isr_registered = 0; + } +} + +/* + This function processes the Flush Completions that are issued by the + ARM F/W, when a Recv Ring is destroyed. A flush completion is + identified when a Rx COmpl descriptor has the tcpcksum and udpcksum + set and the pktsize is 32. These completions are received on the + Rx Completion Queue. +*/ +static u32 be_process_rx_flush_cmpl(struct be_net_object *pnob) +{ + struct ETH_RX_COMPL_AMAP *rxcp; + unsigned int i = 0; + while ((rxcp = be_get_rx_cmpl(pnob)) != NULL) { + be_notify_cmpl(pnob, 1, pnob->rx_cq_id, 1); + i++; + } + return i; +} + +static void be_tx_q_clean(struct be_net_object *pnob) +{ + while (atomic_read(&pnob->tx_q_used)) + process_one_tx_compl(pnob, tx_compl_lastwrb_idx_get(pnob)); +} + +static void be_rx_q_clean(struct be_net_object *pnob) +{ + if (pnob->rx_ctxt) { + int i; + struct be_rx_page_info *rx_page_info; + for (i = 0; i < pnob->rx_q_len; i++) { + rx_page_info = &(pnob->rx_page_info[i]); + if (!pnob->rx_pg_shared || rx_page_info->page_offset) { + pci_unmap_page(pnob->adapter->pdev, + pci_unmap_addr(rx_page_info, bus), + pnob->rx_buf_size, + PCI_DMA_FROMDEVICE); + } + if (rx_page_info->page) + put_page(rx_page_info->page); + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + } + pnob->rx_pg_info_hd = 0; + } +} + +static void be_destroy_netobj(struct be_net_object *pnob) +{ + int status; + + if (pnob->tx_q_created) { + status = be_eth_sq_destroy(&pnob->tx_q_obj); + pnob->tx_q_created = 0; + } + + if (pnob->rx_q_created) { + status = be_eth_rq_destroy(&pnob->rx_q_obj); + if (status != 0) { + status = be_eth_rq_destroy_options(&pnob->rx_q_obj, 0, + NULL, NULL); + BUG_ON(status); + } + pnob->rx_q_created = 0; + } + + be_process_rx_flush_cmpl(pnob); + + if (pnob->tx_cq_created) { + status = be_cq_destroy(&pnob->tx_cq_obj); + pnob->tx_cq_created = 0; + } + + if (pnob->rx_cq_created) { + status = be_cq_destroy(&pnob->rx_cq_obj); + pnob->rx_cq_created = 0; + } + + if (pnob->mcc_q_created) { + status = be_mcc_ring_destroy(&pnob->mcc_q_obj); + pnob->mcc_q_created = 0; + } + if (pnob->mcc_cq_created) { + status = be_cq_destroy(&pnob->mcc_cq_obj); + pnob->mcc_cq_created = 0; + } + + if (pnob->event_q_created) { + status = be_eq_destroy(&pnob->event_q_obj); + pnob->event_q_created = 0; + } + be_function_cleanup(&pnob->fn_obj); +} + +/* + * free all resources associated with a pnob + * Called at the time of module cleanup as well a any error during + * module init. Some resources may be partially allocated in a NetObj. + */ +static void netobject_cleanup(struct be_adapter *adapter, + struct be_net_object *pnob) +{ + struct net_device *netdev = adapter->netdevp; + + if (netif_running(netdev)) { + netif_stop_queue(netdev); + be_wait_nic_tx_cmplx_cmpl(pnob); + be_disable_eq_intr(pnob); + } + + be_unregister_isr(adapter); + + if (adapter->tasklet_started) { + tasklet_kill(&(adapter->sts_handler)); + adapter->tasklet_started = 0; + } + if (pnob->fn_obj_created) + be_disable_intr(pnob); + + if (adapter->dev_state != BE_DEV_STATE_NONE) + unregister_netdev(netdev); + + if (pnob->fn_obj_created) + be_destroy_netobj(pnob); + + adapter->net_obj = NULL; + adapter->netdevp = NULL; + + be_rx_q_clean(pnob); + if (pnob->rx_ctxt) { + kfree(pnob->rx_page_info); + kfree(pnob->rx_ctxt); + } + + be_tx_q_clean(pnob); + kfree(pnob->tx_ctxt); + + if (pnob->mcc_q) + pci_free_consistent(adapter->pdev, pnob->mcc_q_size, + pnob->mcc_q, pnob->mcc_q_bus); + + if (pnob->mcc_wrb_ctxt) + free_pages((unsigned long)pnob->mcc_wrb_ctxt, + get_order(pnob->mcc_wrb_ctxt_size)); + + if (pnob->mcc_cq) + pci_free_consistent(adapter->pdev, pnob->mcc_cq_size, + pnob->mcc_cq, pnob->mcc_cq_bus); + + if (pnob->event_q) + pci_free_consistent(adapter->pdev, pnob->event_q_size, + pnob->event_q, pnob->event_q_bus); + + if (pnob->tx_cq) + pci_free_consistent(adapter->pdev, pnob->tx_cq_size, + pnob->tx_cq, pnob->tx_cq_bus); + + if (pnob->tx_q) + pci_free_consistent(adapter->pdev, pnob->tx_q_size, + pnob->tx_q, pnob->tx_q_bus); + + if (pnob->rx_q) + pci_free_consistent(adapter->pdev, pnob->rx_q_size, + pnob->rx_q, pnob->rx_q_bus); + + if (pnob->rx_cq) + pci_free_consistent(adapter->pdev, pnob->rx_cq_size, + pnob->rx_cq, pnob->rx_cq_bus); + + + if (pnob->mb_ptr) + pci_free_consistent(adapter->pdev, pnob->mb_size, pnob->mb_ptr, + pnob->mb_bus); + + free_netdev(netdev); +} + + +static int be_nob_ring_alloc(struct be_adapter *adapter, + struct be_net_object *pnob) +{ + u32 size; + + /* Mail box rd; mailbox pointer needs to be 16 byte aligned */ + pnob->mb_size = sizeof(struct MCC_MAILBOX_AMAP) + 16; + pnob->mb_ptr = pci_alloc_consistent(adapter->pdev, pnob->mb_size, + &pnob->mb_bus); + if (!pnob->mb_bus) + return -1; + memset(pnob->mb_ptr, 0, pnob->mb_size); + pnob->mb_rd.va = PTR_ALIGN(pnob->mb_ptr, 16); + pnob->mb_rd.pa = PTR_ALIGN(pnob->mb_bus, 16); + pnob->mb_rd.length = sizeof(struct MCC_MAILBOX_AMAP); + /* + * Event queue + */ + pnob->event_q_len = EVENT_Q_LEN; + pnob->event_q_size = pnob->event_q_len * sizeof(struct EQ_ENTRY_AMAP); + pnob->event_q = pci_alloc_consistent(adapter->pdev, pnob->event_q_size, + &pnob->event_q_bus); + if (!pnob->event_q_bus) + return -1; + memset(pnob->event_q, 0, pnob->event_q_size); + /* + * Eth TX queue + */ + pnob->tx_q_len = ETH_TXQ_LEN; + pnob->tx_q_port = 0; + pnob->tx_q_size = pnob->tx_q_len * sizeof(struct ETH_WRB_AMAP); + pnob->tx_q = pci_alloc_consistent(adapter->pdev, pnob->tx_q_size, + &pnob->tx_q_bus); + if (!pnob->tx_q_bus) + return -1; + memset(pnob->tx_q, 0, pnob->tx_q_size); + /* + * Eth TX Compl queue + */ + pnob->txcq_len = ETH_TXCQ_LEN; + pnob->tx_cq_size = pnob->txcq_len * sizeof(struct ETH_TX_COMPL_AMAP); + pnob->tx_cq = pci_alloc_consistent(adapter->pdev, pnob->tx_cq_size, + &pnob->tx_cq_bus); + if (!pnob->tx_cq_bus) + return -1; + memset(pnob->tx_cq, 0, pnob->tx_cq_size); + /* + * Eth RX queue + */ + pnob->rx_q_len = ETH_RXQ_LEN; + pnob->rx_q_size = pnob->rx_q_len * sizeof(struct ETH_RX_D_AMAP); + pnob->rx_q = pci_alloc_consistent(adapter->pdev, pnob->rx_q_size, + &pnob->rx_q_bus); + if (!pnob->rx_q_bus) + return -1; + memset(pnob->rx_q, 0, pnob->rx_q_size); + /* + * Eth Unicast RX Compl queue + */ + pnob->rx_cq_len = ETH_UC_RXCQ_LEN; + pnob->rx_cq_size = pnob->rx_cq_len * + sizeof(struct ETH_RX_COMPL_AMAP); + pnob->rx_cq = pci_alloc_consistent(adapter->pdev, pnob->rx_cq_size, + &pnob->rx_cq_bus); + if (!pnob->rx_cq_bus) + return -1; + memset(pnob->rx_cq, 0, pnob->rx_cq_size); + + /* TX resources */ + size = pnob->tx_q_len * sizeof(void **); + pnob->tx_ctxt = kzalloc(size, GFP_KERNEL); + if (pnob->tx_ctxt == NULL) + return -1; + + /* RX resources */ + size = pnob->rx_q_len * sizeof(void *); + pnob->rx_ctxt = kzalloc(size, GFP_KERNEL); + if (pnob->rx_ctxt == NULL) + return -1; + + size = (pnob->rx_q_len * sizeof(struct be_rx_page_info)); + pnob->rx_page_info = kzalloc(size, GFP_KERNEL); + if (pnob->rx_page_info == NULL) + return -1; + + adapter->eth_statsp = kzalloc(sizeof(struct FWCMD_ETH_GET_STATISTICS), + GFP_KERNEL); + if (adapter->eth_statsp == NULL) + return -1; + pnob->rx_buf_size = rxbuf_size; + return 0; +} + +/* + This function initializes the be_net_object for subsequent + network operations. + + Before calling this function, the driver must have allocated + space for the NetObject structure, initialized the structure, + allocated DMAable memory for all the network queues that form + part of the NetObject and populated the start address (virtual) + and number of entries allocated for each queue in the NetObject structure. + + The driver must also have allocated memory to hold the + mailbox structure (MCC_MAILBOX) and post the physical address, + virtual addresses and the size of the mailbox memory in the + NetObj.mb_rd. This structure is used by BECLIB for + initial communication with the embedded MCC processor. BECLIB + uses the mailbox until MCC rings are created for more efficient + communication with the MCC processor. + + If the driver wants to create multiple network interface for more + than one protection domain, it can call be_create_netobj() + multiple times once for each protection domain. A Maximum of + 32 protection domains are supported. + +*/ +static int +be_create_netobj(struct be_net_object *pnob, u8 __iomem *csr_va, + u8 __iomem *db_va, u8 __iomem *pci_va) +{ + int status = 0; + bool eventable = false, tx_no_delay = false, rx_no_delay = false; + struct be_eq_object *eq_objectp = NULL; + struct be_function_object *pfob = &pnob->fn_obj; + struct ring_desc rd; + u32 set_rxbuf_size; + u32 tx_cmpl_wm = CEV_WMARK_96; /* 0xffffffff to disable */ + u32 rx_cmpl_wm = CEV_WMARK_160; /* 0xffffffff to disable */ + u32 eq_delay = 0; /* delay in 8usec units. 0xffffffff to disable */ + + memset(&rd, 0, sizeof(struct ring_desc)); + + status = be_function_object_create(csr_va, db_va, pci_va, + BE_FUNCTION_TYPE_NETWORK, &pnob->mb_rd, pfob); + if (status != BE_SUCCESS) + return status; + pnob->fn_obj_created = true; + + if (tx_cmpl_wm == 0xffffffff) + tx_no_delay = true; + if (rx_cmpl_wm == 0xffffffff) + rx_no_delay = true; + /* + * now create the necessary rings + * Event Queue first. + */ + if (pnob->event_q_len) { + rd.va = pnob->event_q; + rd.pa = pnob->event_q_bus; + rd.length = pnob->event_q_size; + + status = be_eq_create(pfob, &rd, 4, pnob->event_q_len, + (u32) -1, /* CEV_WMARK_* or -1 */ + eq_delay, /* in 8us units, or -1 */ + &pnob->event_q_obj); + if (status != BE_SUCCESS) + goto error_ret; + pnob->event_q_id = pnob->event_q_obj.eq_id; + pnob->event_q_created = 1; + eventable = true; + eq_objectp = &pnob->event_q_obj; + } + /* + * Now Eth Tx Compl. queue. + */ + if (pnob->txcq_len) { + rd.va = pnob->tx_cq; + rd.pa = pnob->tx_cq_bus; + rd.length = pnob->tx_cq_size; + + status = be_cq_create(pfob, &rd, + pnob->txcq_len * sizeof(struct ETH_TX_COMPL_AMAP), + false, /* solicted events, */ + tx_no_delay, /* nodelay */ + tx_cmpl_wm, /* Watermark encodings */ + eq_objectp, &pnob->tx_cq_obj); + if (status != BE_SUCCESS) + goto error_ret; + + pnob->tx_cq_id = pnob->tx_cq_obj.cq_id; + pnob->tx_cq_created = 1; + } + /* + * Eth Tx queue + */ + if (pnob->tx_q_len) { + struct be_eth_sq_parameters ex_params = { 0 }; + u32 type; + + if (pnob->tx_q_port) { + /* TXQ to be bound to a specific port */ + type = BE_ETH_TX_RING_TYPE_BOUND; + ex_params.port = pnob->tx_q_port - 1; + } else + type = BE_ETH_TX_RING_TYPE_STANDARD; + + rd.va = pnob->tx_q; + rd.pa = pnob->tx_q_bus; + rd.length = pnob->tx_q_size; + + status = be_eth_sq_create_ex(pfob, &rd, + pnob->tx_q_len * sizeof(struct ETH_WRB_AMAP), + type, 2, &pnob->tx_cq_obj, + &ex_params, &pnob->tx_q_obj); + + if (status != BE_SUCCESS) + goto error_ret; + + pnob->tx_q_id = pnob->tx_q_obj.bid; + pnob->tx_q_created = 1; + } + /* + * Now Eth Rx compl. queue. Always needed. + */ + rd.va = pnob->rx_cq; + rd.pa = pnob->rx_cq_bus; + rd.length = pnob->rx_cq_size; + + status = be_cq_create(pfob, &rd, + pnob->rx_cq_len * sizeof(struct ETH_RX_COMPL_AMAP), + false, /* solicted events, */ + rx_no_delay, /* nodelay */ + rx_cmpl_wm, /* Watermark encodings */ + eq_objectp, &pnob->rx_cq_obj); + if (status != BE_SUCCESS) + goto error_ret; + + pnob->rx_cq_id = pnob->rx_cq_obj.cq_id; + pnob->rx_cq_created = 1; + + status = be_eth_rq_set_frag_size(pfob, pnob->rx_buf_size, + (u32 *) &set_rxbuf_size); + if (status != BE_SUCCESS) { + be_eth_rq_get_frag_size(pfob, (u32 *) &pnob->rx_buf_size); + if ((pnob->rx_buf_size != 2048) && (pnob->rx_buf_size != 4096) + && (pnob->rx_buf_size != 8192)) + goto error_ret; + } else { + if (pnob->rx_buf_size != set_rxbuf_size) + pnob->rx_buf_size = set_rxbuf_size; + } + /* + * Eth RX queue. be_eth_rq_create() always assumes 2 pages size + */ + rd.va = pnob->rx_q; + rd.pa = pnob->rx_q_bus; + rd.length = pnob->rx_q_size; + + status = be_eth_rq_create(pfob, &rd, &pnob->rx_cq_obj, + &pnob->rx_cq_obj, &pnob->rx_q_obj); + + if (status != BE_SUCCESS) + goto error_ret; + + pnob->rx_q_id = pnob->rx_q_obj.rid; + pnob->rx_q_created = 1; + + return BE_SUCCESS; /* All required queues created. */ + +error_ret: + be_destroy_netobj(pnob); + return status; +} + +static int be_nob_ring_init(struct be_adapter *adapter, + struct be_net_object *pnob) +{ + int status; + + pnob->event_q_tl = 0; + + pnob->tx_q_hd = 0; + pnob->tx_q_tl = 0; + + pnob->tx_cq_tl = 0; + + pnob->rx_cq_tl = 0; + + memset(pnob->event_q, 0, pnob->event_q_size); + memset(pnob->tx_cq, 0, pnob->tx_cq_size); + memset(pnob->tx_ctxt, 0, pnob->tx_q_len * sizeof(void **)); + memset(pnob->rx_ctxt, 0, pnob->rx_q_len * sizeof(void *)); + pnob->rx_pg_info_hd = 0; + pnob->rx_q_hd = 0; + atomic_set(&pnob->rx_q_posted, 0); + + status = be_create_netobj(pnob, adapter->csr_va, adapter->db_va, + adapter->pci_va); + if (status != BE_SUCCESS) + return -1; + + be_post_eth_rx_buffs(pnob); + return 0; +} + +/* This function handles async callback for link status */ +static void +be_link_status_async_callback(void *context, u32 event_code, void *event) +{ + struct ASYNC_EVENT_LINK_STATE_AMAP *link_status = event; + struct be_adapter *adapter = context; + bool link_enable = false; + struct be_net_object *pnob; + struct ASYNC_EVENT_TRAILER_AMAP *async_trailer; + struct net_device *netdev; + u32 async_event_code, async_event_type, active_port; + u32 port0_link_status, port1_link_status, port0_duplex, port1_duplex; + u32 port0_speed, port1_speed; + + if (event_code != ASYNC_EVENT_CODE_LINK_STATE) { + /* Not our event to handle */ + return; + } + async_trailer = (struct ASYNC_EVENT_TRAILER_AMAP *) + ((u8 *) event + sizeof(struct MCC_CQ_ENTRY_AMAP) - + sizeof(struct ASYNC_EVENT_TRAILER_AMAP)); + + async_event_code = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, event_code, + async_trailer); + BUG_ON(async_event_code != ASYNC_EVENT_CODE_LINK_STATE); + + pnob = adapter->net_obj; + netdev = pnob->netdev; + + /* Determine if this event is a switch VLD or a physical link event */ + async_event_type = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, event_type, + async_trailer); + active_port = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, + active_port, link_status); + port0_link_status = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, + port0_link_status, link_status); + port1_link_status = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, + port1_link_status, link_status); + port0_duplex = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, + port0_duplex, link_status); + port1_duplex = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, + port1_duplex, link_status); + port0_speed = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, + port0_speed, link_status); + port1_speed = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, + port1_speed, link_status); + if (async_event_type == NTWK_LINK_TYPE_VIRTUAL) { + adapter->be_stat.bes_link_change_virtual++; + if (adapter->be_link_sts->active_port != active_port) { + dev_notice(&netdev->dev, + "Active port changed due to VLD on switch\n"); + } else { + dev_notice(&netdev->dev, "Link status update\n"); + } + + } else { + adapter->be_stat.bes_link_change_physical++; + if (adapter->be_link_sts->active_port != active_port) { + dev_notice(&netdev->dev, + "Active port changed due to port link" + " status change\n"); + } else { + dev_notice(&netdev->dev, "Link status update\n"); + } + } + + memset(adapter->be_link_sts, 0, sizeof(adapter->be_link_sts)); + + if ((port0_link_status == ASYNC_EVENT_LINK_UP) || + (port1_link_status == ASYNC_EVENT_LINK_UP)) { + if ((adapter->port0_link_sts == BE_PORT_LINK_DOWN) && + (adapter->port1_link_sts == BE_PORT_LINK_DOWN)) { + /* Earlier both the ports are down So link is up */ + link_enable = true; + } + + if (port0_link_status == ASYNC_EVENT_LINK_UP) { + adapter->port0_link_sts = BE_PORT_LINK_UP; + adapter->be_link_sts->mac0_duplex = port0_duplex; + adapter->be_link_sts->mac0_speed = port0_speed; + if (active_port == NTWK_PORT_A) + adapter->be_link_sts->active_port = 0; + } else + adapter->port0_link_sts = BE_PORT_LINK_DOWN; + + if (port1_link_status == ASYNC_EVENT_LINK_UP) { + adapter->port1_link_sts = BE_PORT_LINK_UP; + adapter->be_link_sts->mac1_duplex = port1_duplex; + adapter->be_link_sts->mac1_speed = port1_speed; + if (active_port == NTWK_PORT_B) + adapter->be_link_sts->active_port = 1; + } else + adapter->port1_link_sts = BE_PORT_LINK_DOWN; + + printk(KERN_INFO "Link Properties for %s:\n", netdev->name); + dev_info(&netdev->dev, "Link Properties:\n"); + be_print_link_info(adapter->be_link_sts); + + if (!link_enable) + return; + /* + * Both ports were down previously, but atleast one of + * them has come up if this netdevice's carrier is not up, + * then indicate to stack + */ + if (!netif_carrier_ok(netdev)) { + netif_start_queue(netdev); + netif_carrier_on(netdev); + } + return; + } + + /* Now both the ports are down. Tell the stack about it */ + dev_info(&netdev->dev, "Both ports are down\n"); + adapter->port0_link_sts = BE_PORT_LINK_DOWN; + adapter->port1_link_sts = BE_PORT_LINK_DOWN; + if (netif_carrier_ok(netdev)) { + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + return; +} + +static int be_mcc_create(struct be_adapter *adapter) +{ + struct be_net_object *pnob; + + pnob = adapter->net_obj; + /* + * Create the MCC ring so that all further communication with + * MCC can go thru the ring. we do this at the end since + * we do not want to be dealing with interrupts until the + * initialization is complete. + */ + pnob->mcc_q_len = MCC_Q_LEN; + pnob->mcc_q_size = pnob->mcc_q_len * sizeof(struct MCC_WRB_AMAP); + pnob->mcc_q = pci_alloc_consistent(adapter->pdev, pnob->mcc_q_size, + &pnob->mcc_q_bus); + if (!pnob->mcc_q_bus) + return -1; + /* + * space for MCC WRB context + */ + pnob->mcc_wrb_ctxtLen = MCC_Q_LEN; + pnob->mcc_wrb_ctxt_size = pnob->mcc_wrb_ctxtLen * + sizeof(struct be_mcc_wrb_context); + pnob->mcc_wrb_ctxt = (void *)__get_free_pages(GFP_KERNEL, + get_order(pnob->mcc_wrb_ctxt_size)); + if (pnob->mcc_wrb_ctxt == NULL) + return -1; + /* + * Space for MCC compl. ring + */ + pnob->mcc_cq_len = MCC_CQ_LEN; + pnob->mcc_cq_size = pnob->mcc_cq_len * sizeof(struct MCC_CQ_ENTRY_AMAP); + pnob->mcc_cq = pci_alloc_consistent(adapter->pdev, pnob->mcc_cq_size, + &pnob->mcc_cq_bus); + if (!pnob->mcc_cq_bus) + return -1; + return 0; +} + +/* + This function creates the MCC request and completion ring required + for communicating with the ARM processor. The caller must have + allocated required amount of memory for the MCC ring and MCC + completion ring and posted the virtual address and number of + entries in the corresponding members (mcc_q and mcc_cq) in the + NetObject struture. + + When this call is completed, all further communication with + ARM will switch from mailbox to this ring. + + pnob - Pointer to the NetObject structure. This NetObject should + have been created using a previous call to be_create_netobj() +*/ +int be_create_mcc_rings(struct be_net_object *pnob) +{ + int status = 0; + struct ring_desc rd; + struct be_function_object *pfob = &pnob->fn_obj; + + memset(&rd, 0, sizeof(struct ring_desc)); + if (pnob->mcc_cq_len) { + rd.va = pnob->mcc_cq; + rd.pa = pnob->mcc_cq_bus; + rd.length = pnob->mcc_cq_size; + + status = be_cq_create(pfob, &rd, + pnob->mcc_cq_len * sizeof(struct MCC_CQ_ENTRY_AMAP), + false, /* solicted events, */ + true, /* nodelay */ + 0, /* 0 Watermark since Nodelay is true */ + &pnob->event_q_obj, + &pnob->mcc_cq_obj); + + if (status != BE_SUCCESS) + return status; + + pnob->mcc_cq_id = pnob->mcc_cq_obj.cq_id; + pnob->mcc_cq_created = 1; + } + if (pnob->mcc_q_len) { + rd.va = pnob->mcc_q; + rd.pa = pnob->mcc_q_bus; + rd.length = pnob->mcc_q_size; + + status = be_mcc_ring_create(pfob, &rd, + pnob->mcc_q_len * sizeof(struct MCC_WRB_AMAP), + pnob->mcc_wrb_ctxt, pnob->mcc_wrb_ctxtLen, + &pnob->mcc_cq_obj, &pnob->mcc_q_obj); + + if (status != BE_SUCCESS) + return status; + + pnob->mcc_q_created = 1; + } + return BE_SUCCESS; +} + +static int be_mcc_init(struct be_adapter *adapter) +{ + u32 r; + struct be_net_object *pnob; + + pnob = adapter->net_obj; + memset(pnob->mcc_q, 0, pnob->mcc_q_size); + pnob->mcc_q_hd = 0; + + memset(pnob->mcc_wrb_ctxt, 0, pnob->mcc_wrb_ctxt_size); + + memset(pnob->mcc_cq, 0, pnob->mcc_cq_size); + pnob->mcc_cq_tl = 0; + + r = be_create_mcc_rings(adapter->net_obj); + if (r != BE_SUCCESS) + return -1; + + return 0; +} + +static void be_remove(struct pci_dev *pdev) +{ + struct be_net_object *pnob; + struct be_adapter *adapter; + + adapter = pci_get_drvdata(pdev); + if (!adapter) + return; + + pci_set_drvdata(pdev, NULL); + pnob = (struct be_net_object *)adapter->net_obj; + + flush_scheduled_work(); + + if (pnob) { + /* Unregister async callback function for link status updates */ + if (pnob->mcc_q_created) + be_mcc_add_async_event_callback(&pnob->mcc_q_obj, + NULL, NULL); + netobject_cleanup(adapter, pnob); + } + + if (adapter->csr_va) + iounmap(adapter->csr_va); + if (adapter->db_va) + iounmap(adapter->db_va); + if (adapter->pci_va) + iounmap(adapter->pci_va); + + pci_release_regions(adapter->pdev); + pci_disable_device(adapter->pdev); + + kfree(adapter->be_link_sts); + kfree(adapter->eth_statsp); + + if (adapter->timer_ctxt.get_stats_timer.function) + del_timer_sync(&adapter->timer_ctxt.get_stats_timer); + kfree(adapter); +} + +/* + * This function is called by the PCI sub-system when it finds a PCI + * device with dev/vendor IDs that match with one of our devices. + * All of the driver initialization is done in this function. + */ +static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) +{ + int status = 0; + struct be_adapter *adapter; + struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD get_fwv; + struct be_net_object *pnob; + struct net_device *netdev; + + status = pci_enable_device(pdev); + if (status) + goto error; + + status = pci_request_regions(pdev, be_driver_name); + if (status) + goto error_pci_req; + + pci_set_master(pdev); + adapter = kzalloc(sizeof(struct be_adapter), GFP_KERNEL); + if (adapter == NULL) { + status = -ENOMEM; + goto error_adapter; + } + adapter->dev_state = BE_DEV_STATE_NONE; + adapter->pdev = pdev; + pci_set_drvdata(pdev, adapter); + + adapter->enable_aic = 1; + adapter->max_eqd = MAX_EQD; + adapter->min_eqd = 0; + adapter->cur_eqd = 0; + + status = pci_set_dma_mask(pdev, DMA_64BIT_MASK); + if (!status) { + adapter->dma_64bit_cap = true; + } else { + adapter->dma_64bit_cap = false; + status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (status != 0) { + printk(KERN_ERR "Could not set PCI DMA Mask\n"); + goto cleanup; + } + } + + status = init_pci_be_function(adapter, pdev); + if (status != 0) { + printk(KERN_ERR "Failed to map PCI BARS\n"); + status = -ENOMEM; + goto cleanup; + } + + be_trace_set_level(DL_ALWAYS | DL_ERR); + + adapter->be_link_sts = kmalloc(sizeof(struct BE_LINK_STATUS), + GFP_KERNEL); + if (adapter->be_link_sts == NULL) { + printk(KERN_ERR "Memory allocation for link status " + "buffer failed\n"); + goto cleanup; + } + spin_lock_init(&adapter->txq_lock); + + netdev = alloc_etherdev(sizeof(struct be_net_object)); + if (netdev == NULL) { + status = -ENOMEM; + goto cleanup; + } + pnob = netdev_priv(netdev); + adapter->net_obj = pnob; + adapter->netdevp = netdev; + pnob->adapter = adapter; + pnob->netdev = netdev; + + status = be_nob_ring_alloc(adapter, pnob); + if (status != 0) + goto cleanup; + + status = be_nob_ring_init(adapter, pnob); + if (status != 0) + goto cleanup; + + be_rxf_mac_address_read_write(&pnob->fn_obj, false, false, false, + false, false, netdev->dev_addr, NULL, NULL); + + netdev->init = &benet_init; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + + SET_NETDEV_DEV(netdev, &(adapter->pdev->dev)); + + netif_napi_add(netdev, &pnob->napi, be_poll, 64); + + /* if the rx_frag size if 2K, one page is shared as two RX frags */ + pnob->rx_pg_shared = + (pnob->rx_buf_size <= PAGE_SIZE / 2) ? true : false; + if (pnob->rx_buf_size != rxbuf_size) { + printk(KERN_WARNING + "Could not set Rx buffer size to %d. Using %d\n", + rxbuf_size, pnob->rx_buf_size); + rxbuf_size = pnob->rx_buf_size; + } + + tasklet_init(&(adapter->sts_handler), be_process_intr, + (unsigned long)adapter); + adapter->tasklet_started = 1; + spin_lock_init(&(adapter->int_lock)); + + status = be_register_isr(adapter, pnob); + if (status != 0) + goto cleanup; + + adapter->rx_csum = 1; + adapter->max_rx_coal = BE_LRO_MAX_PKTS; + + memset(&get_fwv, 0, + sizeof(struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD)); + printk(KERN_INFO "BladeEngine Driver version:%s. " + "Copyright ServerEngines, Corporation 2005 - 2008\n", + be_drvr_ver); + status = be_function_get_fw_version(&pnob->fn_obj, &get_fwv, NULL, + NULL); + if (status == BE_SUCCESS) { + strncpy(be_fw_ver, get_fwv.firmware_version_string, 32); + printk(KERN_INFO "BladeEngine Firmware Version:%s\n", + get_fwv.firmware_version_string); + } else { + printk(KERN_WARNING "Unable to get BE Firmware Version\n"); + } + + sema_init(&adapter->get_eth_stat_sem, 0); + init_timer(&adapter->timer_ctxt.get_stats_timer); + atomic_set(&adapter->timer_ctxt.get_stat_flag, 0); + adapter->timer_ctxt.get_stats_timer.function = + &be_get_stats_timer_handler; + + status = be_mcc_create(adapter); + if (status < 0) + goto cleanup; + status = be_mcc_init(adapter); + if (status < 0) + goto cleanup; + + + status = be_mcc_add_async_event_callback(&adapter->net_obj->mcc_q_obj, + be_link_status_async_callback, (void *)adapter); + if (status != BE_SUCCESS) { + printk(KERN_WARNING "add_async_event_callback failed"); + printk(KERN_WARNING + "Link status changes may not be reflected\n"); + } + + status = register_netdev(netdev); + if (status != 0) + goto cleanup; + be_update_link_status(adapter); + adapter->dev_state = BE_DEV_STATE_INIT; + return 0; + +cleanup: + be_remove(pdev); + return status; +error_adapter: + pci_release_regions(pdev); +error_pci_req: + pci_disable_device(pdev); +error: + printk(KERN_ERR "BladeEngine initalization failed\n"); + return status; +} + +/* + * Get the current link status and print the status on console + */ +void be_update_link_status(struct be_adapter *adapter) +{ + int status; + struct be_net_object *pnob = adapter->net_obj; + + status = be_rxf_link_status(&pnob->fn_obj, adapter->be_link_sts, NULL, + NULL, NULL); + if (status == BE_SUCCESS) { + if (adapter->be_link_sts->mac0_speed && + adapter->be_link_sts->mac0_duplex) + adapter->port0_link_sts = BE_PORT_LINK_UP; + else + adapter->port0_link_sts = BE_PORT_LINK_DOWN; + + if (adapter->be_link_sts->mac1_speed && + adapter->be_link_sts->mac1_duplex) + adapter->port1_link_sts = BE_PORT_LINK_UP; + else + adapter->port1_link_sts = BE_PORT_LINK_DOWN; + + dev_info(&pnob->netdev->dev, "Link Properties:\n"); + be_print_link_info(adapter->be_link_sts); + return; + } + dev_info(&pnob->netdev->dev, "Could not get link status\n"); + return; +} + + +#ifdef CONFIG_PM +static void +be_pm_cleanup(struct be_adapter *adapter, + struct be_net_object *pnob, struct net_device *netdev) +{ + netif_carrier_off(netdev); + netif_stop_queue(netdev); + + be_wait_nic_tx_cmplx_cmpl(pnob); + be_disable_eq_intr(pnob); + + if (adapter->tasklet_started) { + tasklet_kill(&adapter->sts_handler); + adapter->tasklet_started = 0; + } + + be_unregister_isr(adapter); + be_disable_intr(pnob); + + be_tx_q_clean(pnob); + be_rx_q_clean(pnob); + + be_destroy_netobj(pnob); +} + +static int be_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct be_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdevp; + struct be_net_object *pnob = netdev_priv(netdev); + + adapter->dev_pm_state = adapter->dev_state; + adapter->dev_state = BE_DEV_STATE_SUSPEND; + + netif_device_detach(netdev); + if (netif_running(netdev)) + be_pm_cleanup(adapter, pnob, netdev); + + pci_enable_wake(pdev, 3, 1); + pci_enable_wake(pdev, 4, 1); /* D3 Cold = 4 */ + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + return 0; +} + +static void be_up(struct be_adapter *adapter) +{ + struct be_net_object *pnob = adapter->net_obj; + + if (pnob->num_vlans != 0) + be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans, + pnob->vlan_tag, NULL, NULL, NULL); + +} + +static int be_resume(struct pci_dev *pdev) +{ + int status = 0; + struct be_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdevp; + struct be_net_object *pnob = netdev_priv(netdev); + + netif_device_detach(netdev); + + status = pci_enable_device(pdev); + if (status) + return status; + + pci_set_power_state(pdev, 0); + pci_restore_state(pdev); + pci_enable_wake(pdev, 3, 0); + pci_enable_wake(pdev, 4, 0); /* 4 is D3 cold */ + + netif_carrier_on(netdev); + netif_start_queue(netdev); + + if (netif_running(netdev)) { + be_rxf_mac_address_read_write(&pnob->fn_obj, false, false, + false, true, false, netdev->dev_addr, NULL, NULL); + + status = be_nob_ring_init(adapter, pnob); + if (status < 0) + return status; + + tasklet_init(&(adapter->sts_handler), be_process_intr, + (unsigned long)adapter); + adapter->tasklet_started = 1; + + if (be_register_isr(adapter, pnob) != 0) { + printk(KERN_ERR "be_register_isr failed\n"); + return status; + } + + + status = be_mcc_init(adapter); + if (status < 0) { + printk(KERN_ERR "be_mcc_init failed\n"); + return status; + } + be_update_link_status(adapter); + /* + * Register async call back function to handle link + * status updates + */ + status = be_mcc_add_async_event_callback( + &adapter->net_obj->mcc_q_obj, + be_link_status_async_callback, (void *)adapter); + if (status != BE_SUCCESS) { + printk(KERN_WARNING "add_async_event_callback failed"); + printk(KERN_WARNING + "Link status changes may not be reflected\n"); + } + be_enable_intr(pnob); + be_enable_eq_intr(pnob); + be_up(adapter); + } + netif_device_attach(netdev); + adapter->dev_state = adapter->dev_pm_state; + return 0; + +} + +#endif + +/* Wait until no more pending transmits */ +void be_wait_nic_tx_cmplx_cmpl(struct be_net_object *pnob) +{ + int i; + + /* Wait for 20us * 50000 (= 1s) and no more */ + i = 0; + while ((pnob->tx_q_tl != pnob->tx_q_hd) && (i < 50000)) { + ++i; + udelay(20); + } + + /* Check for no more pending transmits */ + if (i >= 50000) { + printk(KERN_WARNING + "Did not receive completions for all TX requests\n"); + } +} + +static struct pci_driver be_driver = { + .name = be_driver_name, + .id_table = be_device_id_table, + .probe = be_probe, +#ifdef CONFIG_PM + .suspend = be_suspend, + .resume = be_resume, +#endif + .remove = be_remove +}; + +/* + * Module init entry point. Registers our our device and return. + * Our probe will be called if the device is found. + */ +static int __init be_init_module(void) +{ + int ret; + + if (rxbuf_size != 8192 && rxbuf_size != 4096 && rxbuf_size != 2048) { + printk(KERN_WARNING + "Unsupported receive buffer size (%d) requested\n", + rxbuf_size); + printk(KERN_WARNING + "Must be 2048, 4096 or 8192. Defaulting to 2048\n"); + rxbuf_size = 2048; + } + + ret = pci_register_driver(&be_driver); + + return ret; +} + +module_init(be_init_module); + +/* + * be_exit_module - Driver Exit Cleanup Routine + */ +static void __exit be_exit_module(void) +{ + pci_unregister_driver(&be_driver); +} + +module_exit(be_exit_module); diff --git a/trunk/drivers/staging/benet/be_int.c b/trunk/drivers/staging/benet/be_int.c new file mode 100644 index 000000000000..cba95d09a8b6 --- /dev/null +++ b/trunk/drivers/staging/benet/be_int.c @@ -0,0 +1,863 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#include +#include + +#include "benet.h" + +/* number of bytes of RX frame that are copied to skb->data */ +#define BE_HDR_LEN 64 + +#define NETIF_RX(skb) netif_receive_skb(skb) +#define VLAN_ACCEL_RX(skb, pnob, vt) \ + vlan_hwaccel_rx(skb, pnob->vlan_grp, vt) + +/* + This function notifies BladeEngine of the number of completion + entries processed from the specified completion queue by writing + the number of popped entries to the door bell. + + pnob - Pointer to the NetObject structure + n - Number of completion entries processed + cq_id - Queue ID of the completion queue for which notification + is being done. + re_arm - 1 - rearm the completion ring to generate an event. + - 0 - dont rearm the completion ring to generate an event +*/ +void be_notify_cmpl(struct be_net_object *pnob, int n, int cq_id, int re_arm) +{ + struct CQ_DB_AMAP cqdb; + + cqdb.dw[0] = 0; + AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, cq_id); + AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, re_arm); + AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, n); + PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]); +} + +/* + * adds additional receive frags indicated by BE starting from given + * frag index (fi) to specified skb's frag list + */ +static void +add_skb_frags(struct be_net_object *pnob, struct sk_buff *skb, + u32 nresid, u32 fi) +{ + struct be_adapter *adapter = pnob->adapter; + u32 sk_frag_idx, n; + struct be_rx_page_info *rx_page_info; + u32 frag_sz = pnob->rx_buf_size; + + sk_frag_idx = skb_shinfo(skb)->nr_frags; + while (nresid) { + index_inc(&fi, pnob->rx_q_len); + + rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi]; + pnob->rx_ctxt[fi] = NULL; + if ((rx_page_info->page_offset) || + (pnob->rx_pg_shared == false)) { + pci_unmap_page(adapter->pdev, + pci_unmap_addr(rx_page_info, bus), + frag_sz, PCI_DMA_FROMDEVICE); + } + + n = min(nresid, frag_sz); + skb_shinfo(skb)->frags[sk_frag_idx].page = rx_page_info->page; + skb_shinfo(skb)->frags[sk_frag_idx].page_offset + = rx_page_info->page_offset; + skb_shinfo(skb)->frags[sk_frag_idx].size = n; + + sk_frag_idx++; + skb->len += n; + skb->data_len += n; + skb_shinfo(skb)->nr_frags++; + nresid -= n; + + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + atomic_dec(&pnob->rx_q_posted); + } +} + +/* + * This function processes incoming nic packets over various Rx queues. + * This function takes the adapter, the current Rx status descriptor + * entry and the Rx completion queue ID as argument. + */ +static inline int process_nic_rx_completion(struct be_net_object *pnob, + struct ETH_RX_COMPL_AMAP *rxcp) +{ + struct be_adapter *adapter = pnob->adapter; + struct sk_buff *skb; + int udpcksm, tcpcksm; + int n; + u32 nresid, fi; + u32 frag_sz = pnob->rx_buf_size; + u8 *va; + struct be_rx_page_info *rx_page_info; + u32 numfrags, vtp, vtm, vlan_tag, pktsize; + + fi = AMAP_GET_BITS_PTR(ETH_RX_COMPL, fragndx, rxcp); + BUG_ON(fi >= (int)pnob->rx_q_len); + BUG_ON(fi < 0); + + rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi]; + BUG_ON(!rx_page_info->page); + pnob->rx_ctxt[fi] = NULL; + + /* + * If one page is used per fragment or if this is the second half of + * of the page, unmap the page here + */ + if ((rx_page_info->page_offset) || (pnob->rx_pg_shared == false)) { + pci_unmap_page(adapter->pdev, + pci_unmap_addr(rx_page_info, bus), frag_sz, + PCI_DMA_FROMDEVICE); + } + + atomic_dec(&pnob->rx_q_posted); + udpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, udpcksm, rxcp); + tcpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, tcpcksm, rxcp); + pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp); + /* + * get rid of RX flush completions first. + */ + if ((tcpcksm) && (udpcksm) && (pktsize == 32)) { + put_page(rx_page_info->page); + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + return 0; + } + skb = netdev_alloc_skb(pnob->netdev, BE_HDR_LEN + NET_IP_ALIGN); + if (skb == NULL) { + dev_info(&pnob->netdev->dev, "alloc_skb() failed\n"); + put_page(rx_page_info->page); + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + goto free_frags; + } + skb_reserve(skb, NET_IP_ALIGN); + + skb->dev = pnob->netdev; + + n = min(pktsize, frag_sz); + + va = page_address(rx_page_info->page) + rx_page_info->page_offset; + prefetch(va); + + skb->len = n; + skb->data_len = n; + if (n <= BE_HDR_LEN) { + memcpy(skb->data, va, n); + put_page(rx_page_info->page); + skb->data_len -= n; + skb->tail += n; + } else { + + /* Setup the SKB with page buffer information */ + skb_shinfo(skb)->frags[0].page = rx_page_info->page; + skb_shinfo(skb)->nr_frags++; + + /* Copy the header into the skb_data */ + memcpy(skb->data, va, BE_HDR_LEN); + skb_shinfo(skb)->frags[0].page_offset = + rx_page_info->page_offset + BE_HDR_LEN; + skb_shinfo(skb)->frags[0].size = n - BE_HDR_LEN; + skb->data_len -= BE_HDR_LEN; + skb->tail += BE_HDR_LEN; + } + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + nresid = pktsize - n; + + skb->protocol = eth_type_trans(skb, pnob->netdev); + + if ((tcpcksm || udpcksm) && adapter->rx_csum) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + /* + * if we have more bytes left, the frame has been + * given to us in multiple fragments. This happens + * with Jumbo frames. Add the remaining fragments to + * skb->frags[] array. + */ + if (nresid) + add_skb_frags(pnob, skb, nresid, fi); + + /* update the the true size of the skb. */ + skb->truesize = skb->len + sizeof(struct sk_buff); + + /* + * If a 802.3 frame or 802.2 LLC frame + * (i.e) contains length field in MAC Hdr + * and frame len is greater than 64 bytes + */ + if (((skb->protocol == ntohs(ETH_P_802_2)) || + (skb->protocol == ntohs(ETH_P_802_3))) + && (pktsize > BE_HDR_LEN)) { + /* + * If the length given in Mac Hdr is less than frame size + * Erraneous frame, Drop it + */ + if ((ntohs(*(u16 *) (va + 12)) + ETH_HLEN) < pktsize) { + /* Increment Non Ether type II frames dropped */ + adapter->be_stat.bes_802_3_dropped_frames++; + + kfree_skb(skb); + return 0; + } + /* + * else if the length given in Mac Hdr is greater than + * frame size, should not be seeing this sort of frames + * dump the pkt and pass to stack + */ + else if ((ntohs(*(u16 *) (va + 12)) + ETH_HLEN) > pktsize) { + /* Increment Non Ether type II frames malformed */ + adapter->be_stat.bes_802_3_malformed_frames++; + } + } + + vtp = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtp, rxcp); + vtm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtm, rxcp); + if (vtp && vtm) { + /* Vlan tag present in pkt and BE found + * that the tag matched an entry in VLAN table + */ + if (!pnob->vlan_grp || pnob->num_vlans == 0) { + /* But we have no VLANs configured. + * This should never happen. Drop the packet. + */ + dev_info(&pnob->netdev->dev, + "BladeEngine: Unexpected vlan tagged packet\n"); + kfree_skb(skb); + return 0; + } + /* pass the VLAN packet to stack */ + vlan_tag = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vlan_tag, rxcp); + VLAN_ACCEL_RX(skb, pnob, be16_to_cpu(vlan_tag)); + + } else { + NETIF_RX(skb); + } + return 0; + +free_frags: + /* free all frags associated with the current rxcp */ + numfrags = AMAP_GET_BITS_PTR(ETH_RX_COMPL, numfrags, rxcp); + while (numfrags-- > 1) { + index_inc(&fi, pnob->rx_q_len); + + rx_page_info = (struct be_rx_page_info *) + pnob->rx_ctxt[fi]; + pnob->rx_ctxt[fi] = (void *)NULL; + if (rx_page_info->page_offset || !pnob->rx_pg_shared) { + pci_unmap_page(adapter->pdev, + pci_unmap_addr(rx_page_info, bus), + frag_sz, PCI_DMA_FROMDEVICE); + } + + put_page(rx_page_info->page); + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + atomic_dec(&pnob->rx_q_posted); + } + return -ENOMEM; +} + +static void process_nic_rx_completion_lro(struct be_net_object *pnob, + struct ETH_RX_COMPL_AMAP *rxcp) +{ + struct be_adapter *adapter = pnob->adapter; + struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; + unsigned int udpcksm, tcpcksm; + u32 numfrags, vlanf, vtm, vlan_tag, nresid; + u16 vlant; + unsigned int fi, idx, n; + struct be_rx_page_info *rx_page_info; + u32 frag_sz = pnob->rx_buf_size, pktsize; + bool rx_coal = (adapter->max_rx_coal <= 1) ? 0 : 1; + u8 err, *va; + __wsum csum = 0; + + if (AMAP_GET_BITS_PTR(ETH_RX_COMPL, ipsec, rxcp)) { + /* Drop the pkt and move to the next completion. */ + adapter->be_stat.bes_rx_misc_pkts++; + return; + } + err = AMAP_GET_BITS_PTR(ETH_RX_COMPL, err, rxcp); + if (err || !rx_coal) { + /* We won't coalesce Rx pkts if the err bit set. + * take the path of normal completion processing */ + process_nic_rx_completion(pnob, rxcp); + return; + } + + fi = AMAP_GET_BITS_PTR(ETH_RX_COMPL, fragndx, rxcp); + BUG_ON(fi >= (int)pnob->rx_q_len); + BUG_ON(fi < 0); + rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi]; + BUG_ON(!rx_page_info->page); + pnob->rx_ctxt[fi] = (void *)NULL; + /* If one page is used per fragment or if this is the + * second half of the page, unmap the page here + */ + if (rx_page_info->page_offset || !pnob->rx_pg_shared) { + pci_unmap_page(adapter->pdev, + pci_unmap_addr(rx_page_info, bus), + frag_sz, PCI_DMA_FROMDEVICE); + } + + numfrags = AMAP_GET_BITS_PTR(ETH_RX_COMPL, numfrags, rxcp); + udpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, udpcksm, rxcp); + tcpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, tcpcksm, rxcp); + vlan_tag = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vlan_tag, rxcp); + vlant = be16_to_cpu(vlan_tag); + vlanf = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtp, rxcp); + vtm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtm, rxcp); + pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp); + + atomic_dec(&pnob->rx_q_posted); + + if (tcpcksm && udpcksm && pktsize == 32) { + /* flush completion entries */ + put_page(rx_page_info->page); + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + return; + } + /* Only one of udpcksum and tcpcksum can be set */ + BUG_ON(udpcksm && tcpcksm); + + /* jumbo frames could come in multiple fragments */ + BUG_ON(numfrags != ((pktsize + (frag_sz - 1)) / frag_sz)); + n = min(pktsize, frag_sz); + nresid = pktsize - n; /* will be useful for jumbo pkts */ + idx = 0; + + va = page_address(rx_page_info->page) + rx_page_info->page_offset; + prefetch(va); + rx_frags[idx].page = rx_page_info->page; + rx_frags[idx].page_offset = (rx_page_info->page_offset); + rx_frags[idx].size = n; + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + + /* If we got multiple fragments, we have more data. */ + while (nresid) { + idx++; + index_inc(&fi, pnob->rx_q_len); + + rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi]; + pnob->rx_ctxt[fi] = (void *)NULL; + if (rx_page_info->page_offset || !pnob->rx_pg_shared) { + pci_unmap_page(adapter->pdev, + pci_unmap_addr(rx_page_info, bus), + frag_sz, PCI_DMA_FROMDEVICE); + } + + n = min(nresid, frag_sz); + rx_frags[idx].page = rx_page_info->page; + rx_frags[idx].page_offset = (rx_page_info->page_offset); + rx_frags[idx].size = n; + + nresid -= n; + memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); + atomic_dec(&pnob->rx_q_posted); + } + + if (likely(!(vlanf && vtm))) { + lro_receive_frags(&pnob->lro_mgr, rx_frags, + pktsize, pktsize, + (void *)(unsigned long)csum, csum); + } else { + /* Vlan tag present in pkt and BE found + * that the tag matched an entry in VLAN table + */ + if (unlikely(!pnob->vlan_grp || pnob->num_vlans == 0)) { + /* But we have no VLANs configured. + * This should never happen. Drop the packet. + */ + dev_info(&pnob->netdev->dev, + "BladeEngine: Unexpected vlan tagged packet\n"); + return; + } + /* pass the VLAN packet to stack */ + lro_vlan_hwaccel_receive_frags(&pnob->lro_mgr, + rx_frags, pktsize, pktsize, + pnob->vlan_grp, vlant, + (void *)(unsigned long)csum, + csum); + } + + adapter->be_stat.bes_rx_coal++; +} + +struct ETH_RX_COMPL_AMAP *be_get_rx_cmpl(struct be_net_object *pnob) +{ + struct ETH_RX_COMPL_AMAP *rxcp = &pnob->rx_cq[pnob->rx_cq_tl]; + u32 valid, ct; + + valid = AMAP_GET_BITS_PTR(ETH_RX_COMPL, valid, rxcp); + if (valid == 0) + return NULL; + + ct = AMAP_GET_BITS_PTR(ETH_RX_COMPL, ct, rxcp); + if (ct != 0) { + /* Invalid chute #. treat as error */ + AMAP_SET_BITS_PTR(ETH_RX_COMPL, err, rxcp, 1); + } + + be_adv_rxcq_tl(pnob); + AMAP_SET_BITS_PTR(ETH_RX_COMPL, valid, rxcp, 0); + return rxcp; +} + +static void update_rx_rate(struct be_adapter *adapter) +{ + /* update the rate once in two seconds */ + if ((jiffies - adapter->eth_rx_jiffies) > 2 * (HZ)) { + u32 r; + r = adapter->eth_rx_bytes / + ((jiffies - adapter->eth_rx_jiffies) / (HZ)); + r = (r / 1000000); /* MB/Sec */ + + /* Mega Bits/Sec */ + adapter->be_stat.bes_eth_rx_rate = (r * 8); + adapter->eth_rx_jiffies = jiffies; + adapter->eth_rx_bytes = 0; + } +} + +static int process_rx_completions(struct be_net_object *pnob, int max_work) +{ + struct be_adapter *adapter = pnob->adapter; + struct ETH_RX_COMPL_AMAP *rxcp; + u32 nc = 0; + unsigned int pktsize; + + while (max_work && (rxcp = be_get_rx_cmpl(pnob))) { + prefetch(rxcp); + pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp); + process_nic_rx_completion_lro(pnob, rxcp); + adapter->eth_rx_bytes += pktsize; + update_rx_rate(adapter); + nc++; + max_work--; + adapter->be_stat.bes_rx_compl++; + } + if (likely(adapter->max_rx_coal > 1)) { + adapter->be_stat.bes_rx_flush++; + lro_flush_all(&pnob->lro_mgr); + } + + /* Refill the queue */ + if (atomic_read(&pnob->rx_q_posted) < 900) + be_post_eth_rx_buffs(pnob); + + return nc; +} + +static struct ETH_TX_COMPL_AMAP *be_get_tx_cmpl(struct be_net_object *pnob) +{ + struct ETH_TX_COMPL_AMAP *txcp = &pnob->tx_cq[pnob->tx_cq_tl]; + u32 valid; + + valid = AMAP_GET_BITS_PTR(ETH_TX_COMPL, valid, txcp); + if (valid == 0) + return NULL; + + AMAP_SET_BITS_PTR(ETH_TX_COMPL, valid, txcp, 0); + be_adv_txcq_tl(pnob); + return txcp; + +} + +void process_one_tx_compl(struct be_net_object *pnob, u32 end_idx) +{ + struct be_adapter *adapter = pnob->adapter; + int cur_index, tx_wrbs_completed = 0; + struct sk_buff *skb; + u64 busaddr, pa, pa_lo, pa_hi; + struct ETH_WRB_AMAP *wrb; + u32 frag_len, last_index, j; + + last_index = tx_compl_lastwrb_idx_get(pnob); + BUG_ON(last_index != end_idx); + pnob->tx_ctxt[pnob->tx_q_tl] = NULL; + do { + cur_index = pnob->tx_q_tl; + wrb = &pnob->tx_q[cur_index]; + pa_hi = AMAP_GET_BITS_PTR(ETH_WRB, frag_pa_hi, wrb); + pa_lo = AMAP_GET_BITS_PTR(ETH_WRB, frag_pa_lo, wrb); + frag_len = AMAP_GET_BITS_PTR(ETH_WRB, frag_len, wrb); + busaddr = (pa_hi << 32) | pa_lo; + if (busaddr != 0) { + pa = le64_to_cpu(busaddr); + pci_unmap_single(adapter->pdev, pa, + frag_len, PCI_DMA_TODEVICE); + } + if (cur_index == last_index) { + skb = (struct sk_buff *)pnob->tx_ctxt[cur_index]; + BUG_ON(!skb); + for (j = 0; j < skb_shinfo(skb)->nr_frags; j++) { + struct skb_frag_struct *frag; + frag = &skb_shinfo(skb)->frags[j]; + pci_unmap_page(adapter->pdev, + (ulong) frag->page, frag->size, + PCI_DMA_TODEVICE); + } + kfree_skb(skb); + pnob->tx_ctxt[cur_index] = NULL; + } else { + BUG_ON(pnob->tx_ctxt[cur_index]); + } + tx_wrbs_completed++; + be_adv_txq_tl(pnob); + } while (cur_index != last_index); + atomic_sub(tx_wrbs_completed, &pnob->tx_q_used); +} + +/* there is no need to take an SMP lock here since currently + * we have only one instance of the tasklet that does completion + * processing. + */ +static void process_nic_tx_completions(struct be_net_object *pnob) +{ + struct be_adapter *adapter = pnob->adapter; + struct ETH_TX_COMPL_AMAP *txcp; + struct net_device *netdev = pnob->netdev; + u32 end_idx, num_processed = 0; + + adapter->be_stat.bes_tx_events++; + + while ((txcp = be_get_tx_cmpl(pnob))) { + end_idx = AMAP_GET_BITS_PTR(ETH_TX_COMPL, wrb_index, txcp); + process_one_tx_compl(pnob, end_idx); + num_processed++; + adapter->be_stat.bes_tx_compl++; + } + be_notify_cmpl(pnob, num_processed, pnob->tx_cq_id, 1); + /* + * We got Tx completions and have usable WRBs. + * If the netdev's queue has been stopped + * because we had run out of WRBs, wake it now. + */ + spin_lock(&adapter->txq_lock); + if (netif_queue_stopped(netdev) + && atomic_read(&pnob->tx_q_used) < pnob->tx_q_len / 2) { + netif_wake_queue(netdev); + } + spin_unlock(&adapter->txq_lock); +} + +static u32 post_rx_buffs(struct be_net_object *pnob, struct list_head *rxbl) +{ + u32 nposted = 0; + struct ETH_RX_D_AMAP *rxd = NULL; + struct be_recv_buffer *rxbp; + void **rx_ctxp; + struct RQ_DB_AMAP rqdb; + + rx_ctxp = pnob->rx_ctxt; + + while (!list_empty(rxbl) && + (rx_ctxp[pnob->rx_q_hd] == NULL) && nposted < 255) { + + rxbp = list_first_entry(rxbl, struct be_recv_buffer, rxb_list); + list_del(&rxbp->rxb_list); + rxd = pnob->rx_q + pnob->rx_q_hd; + AMAP_SET_BITS_PTR(ETH_RX_D, fragpa_lo, rxd, rxbp->rxb_pa_lo); + AMAP_SET_BITS_PTR(ETH_RX_D, fragpa_hi, rxd, rxbp->rxb_pa_hi); + + rx_ctxp[pnob->rx_q_hd] = rxbp->rxb_ctxt; + be_adv_rxq_hd(pnob); + nposted++; + } + + if (nposted) { + /* Now press the door bell to notify BladeEngine. */ + rqdb.dw[0] = 0; + AMAP_SET_BITS_PTR(RQ_DB, numPosted, &rqdb, nposted); + AMAP_SET_BITS_PTR(RQ_DB, rq, &rqdb, pnob->rx_q_id); + PD_WRITE(&pnob->fn_obj, erx_rq_db, rqdb.dw[0]); + } + atomic_add(nposted, &pnob->rx_q_posted); + return nposted; +} + +void be_post_eth_rx_buffs(struct be_net_object *pnob) +{ + struct be_adapter *adapter = pnob->adapter; + u32 num_bufs, r; + u64 busaddr = 0, tmp_pa; + u32 max_bufs, pg_hd; + u32 frag_size; + struct be_recv_buffer *rxbp; + struct list_head rxbl; + struct be_rx_page_info *rx_page_info; + struct page *page = NULL; + u32 page_order = 0; + gfp_t alloc_flags = GFP_ATOMIC; + + BUG_ON(!adapter); + + max_bufs = 64; /* should be even # <= 255. */ + + frag_size = pnob->rx_buf_size; + page_order = get_order(frag_size); + + if (frag_size == 8192) + alloc_flags |= (gfp_t) __GFP_COMP; + /* + * Form a linked list of RECV_BUFFFER structure to be be posted. + * We will post even number of buffer so that pages can be + * shared. + */ + INIT_LIST_HEAD(&rxbl); + + for (num_bufs = 0; num_bufs < max_bufs && + !pnob->rx_page_info[pnob->rx_pg_info_hd].page; ++num_bufs) { + + rxbp = &pnob->eth_rx_bufs[num_bufs]; + pg_hd = pnob->rx_pg_info_hd; + rx_page_info = &pnob->rx_page_info[pg_hd]; + + if (!page) { + page = alloc_pages(alloc_flags, page_order); + if (unlikely(page == NULL)) { + adapter->be_stat.bes_ethrx_post_fail++; + pnob->rxbuf_post_fail++; + break; + } + pnob->rxbuf_post_fail = 0; + busaddr = pci_map_page(adapter->pdev, page, 0, + frag_size, PCI_DMA_FROMDEVICE); + rx_page_info->page_offset = 0; + rx_page_info->page = page; + /* + * If we are sharing a page among two skbs, + * alloc a new one on the next iteration + */ + if (pnob->rx_pg_shared == false) + page = NULL; + } else { + get_page(page); + rx_page_info->page_offset += frag_size; + rx_page_info->page = page; + /* + * We are finished with the alloced page, + * Alloc a new one on the next iteration + */ + page = NULL; + } + rxbp->rxb_ctxt = (void *)rx_page_info; + index_inc(&pnob->rx_pg_info_hd, pnob->rx_q_len); + + pci_unmap_addr_set(rx_page_info, bus, busaddr); + tmp_pa = busaddr + rx_page_info->page_offset; + rxbp->rxb_pa_lo = (tmp_pa & 0xFFFFFFFF); + rxbp->rxb_pa_hi = (tmp_pa >> 32); + rxbp->rxb_len = frag_size; + list_add_tail(&rxbp->rxb_list, &rxbl); + } /* End of for */ + + r = post_rx_buffs(pnob, &rxbl); + BUG_ON(r != num_bufs); + return; +} + +/* + * Interrupt service for network function. We just schedule the + * tasklet which does all completion processing. + */ +irqreturn_t be_int(int irq, void *dev) +{ + struct net_device *netdev = dev; + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + u32 isr; + + isr = CSR_READ(&pnob->fn_obj, cev.isr1); + if (unlikely(!isr)) + return IRQ_NONE; + + spin_lock(&adapter->int_lock); + adapter->isr |= isr; + spin_unlock(&adapter->int_lock); + + adapter->be_stat.bes_ints++; + + tasklet_schedule(&adapter->sts_handler); + return IRQ_HANDLED; +} + +/* + * Poll function called by NAPI with a work budget. + * We process as many UC. BC and MC receive completions + * as the budget allows and return the actual number of + * RX ststutses processed. + */ +int be_poll(struct napi_struct *napi, int budget) +{ + struct be_net_object *pnob = + container_of(napi, struct be_net_object, napi); + u32 work_done; + + pnob->adapter->be_stat.bes_polls++; + work_done = process_rx_completions(pnob, budget); + BUG_ON(work_done > budget); + + /* All consumed */ + if (work_done < budget) { + netif_rx_complete(napi); + /* enable intr */ + be_notify_cmpl(pnob, work_done, pnob->rx_cq_id, 1); + } else { + /* More to be consumed; continue with interrupts disabled */ + be_notify_cmpl(pnob, work_done, pnob->rx_cq_id, 0); + } + return work_done; +} + +static struct EQ_ENTRY_AMAP *get_event(struct be_net_object *pnob) +{ + struct EQ_ENTRY_AMAP *eqp = &(pnob->event_q[pnob->event_q_tl]); + if (!AMAP_GET_BITS_PTR(EQ_ENTRY, Valid, eqp)) + return NULL; + be_adv_eq_tl(pnob); + return eqp; +} + +/* + * Processes all valid events in the event ring associated with given + * NetObject. Also, notifies BE the number of events processed. + */ +static inline u32 process_events(struct be_net_object *pnob) +{ + struct be_adapter *adapter = pnob->adapter; + struct EQ_ENTRY_AMAP *eqp; + u32 rid, num_events = 0; + struct net_device *netdev = pnob->netdev; + + while ((eqp = get_event(pnob)) != NULL) { + adapter->be_stat.bes_events++; + rid = AMAP_GET_BITS_PTR(EQ_ENTRY, ResourceID, eqp); + if (rid == pnob->rx_cq_id) { + adapter->be_stat.bes_rx_events++; + netif_rx_schedule(&pnob->napi); + } else if (rid == pnob->tx_cq_id) { + process_nic_tx_completions(pnob); + } else if (rid == pnob->mcc_cq_id) { + be_mcc_process_cq(&pnob->mcc_q_obj, 1); + } else { + dev_info(&netdev->dev, + "Invalid EQ ResourceID %d\n", rid); + } + AMAP_SET_BITS_PTR(EQ_ENTRY, Valid, eqp, 0); + AMAP_SET_BITS_PTR(EQ_ENTRY, ResourceID, eqp, 0); + num_events++; + } + return num_events; +} + +static void update_eqd(struct be_adapter *adapter, struct be_net_object *pnob) +{ + int status; + struct be_eq_object *eq_objectp; + + /* update once a second */ + if ((jiffies - adapter->ips_jiffies) > 1 * (HZ)) { + /* One second elapsed since last update */ + u32 r, new_eqd = -1; + r = adapter->be_stat.bes_ints - adapter->be_stat.bes_prev_ints; + r = r / ((jiffies - adapter->ips_jiffies) / (HZ)); + adapter->be_stat.bes_ips = r; + adapter->ips_jiffies = jiffies; + adapter->be_stat.bes_prev_ints = adapter->be_stat.bes_ints; + if (r > IPS_HI_WM && adapter->cur_eqd < adapter->max_eqd) + new_eqd = (adapter->cur_eqd + 8); + if (r < IPS_LO_WM && adapter->cur_eqd > adapter->min_eqd) + new_eqd = (adapter->cur_eqd - 8); + if (adapter->enable_aic && new_eqd != -1) { + eq_objectp = &pnob->event_q_obj; + status = be_eq_modify_delay(&pnob->fn_obj, 1, + &eq_objectp, &new_eqd, NULL, + NULL, NULL); + if (status == BE_SUCCESS) + adapter->cur_eqd = new_eqd; + } + } +} + +/* + This function notifies BladeEngine of how many events were processed + from the event queue by ringing the corresponding door bell and + optionally re-arms the event queue. + n - number of events processed + re_arm - 1 - re-arm the EQ, 0 - do not re-arm the EQ + +*/ +static void be_notify_event(struct be_net_object *pnob, int n, int re_arm) +{ + struct CQ_DB_AMAP eqdb; + eqdb.dw[0] = 0; + + AMAP_SET_BITS_PTR(CQ_DB, qid, &eqdb, pnob->event_q_id); + AMAP_SET_BITS_PTR(CQ_DB, rearm, &eqdb, re_arm); + AMAP_SET_BITS_PTR(CQ_DB, event, &eqdb, 1); + AMAP_SET_BITS_PTR(CQ_DB, num_popped, &eqdb, n); + /* + * Under some situations we see an interrupt and no valid + * EQ entry. To keep going, we need to ring the DB even if + * numPOsted is 0. + */ + PD_WRITE(&pnob->fn_obj, cq_db, eqdb.dw[0]); + return; +} + +/* + * Called from the tasklet scheduled by ISR. All real interrupt processing + * is done here. + */ +void be_process_intr(unsigned long context) +{ + struct be_adapter *adapter = (struct be_adapter *)context; + struct be_net_object *pnob = adapter->net_obj; + u32 isr, n; + ulong flags = 0; + + isr = adapter->isr; + + /* + * we create only one NIC event queue in Linux. Event is + * expected only in the first event queue + */ + BUG_ON(isr & 0xfffffffe); + if ((isr & 1) == 0) + return; /* not our interrupt */ + n = process_events(pnob); + /* + * Clear the event bit. adapter->isr is set by + * hard interrupt. Prevent race with lock. + */ + spin_lock_irqsave(&adapter->int_lock, flags); + adapter->isr &= ~1; + spin_unlock_irqrestore(&adapter->int_lock, flags); + be_notify_event(pnob, n, 1); + /* + * If previous allocation attempts had failed and + * BE has used up all posted buffers, post RX buffers here + */ + if (pnob->rxbuf_post_fail && atomic_read(&pnob->rx_q_posted) == 0) + be_post_eth_rx_buffs(pnob); + update_eqd(adapter, pnob); + return; +} diff --git a/trunk/drivers/staging/benet/be_netif.c b/trunk/drivers/staging/benet/be_netif.c new file mode 100644 index 000000000000..2b8daf63dc7d --- /dev/null +++ b/trunk/drivers/staging/benet/be_netif.c @@ -0,0 +1,705 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * be_netif.c + * + * This file contains various entry points of drivers seen by tcp/ip stack. + */ + +#include +#include +#include "benet.h" +#include +#include + +/* Strings to print Link properties */ +static const char *link_speed[] = { + "Invalid link Speed Value", + "10 Mbps", + "100 Mbps", + "1 Gbps", + "10 Gbps" +}; + +static const char *link_duplex[] = { + "Invalid Duplex Value", + "Half Duplex", + "Full Duplex" +}; + +static const char *link_state[] = { + "", + "(active)" +}; + +void be_print_link_info(struct BE_LINK_STATUS *lnk_status) +{ + u16 si, di, ai; + + /* Port 0 */ + if (lnk_status->mac0_speed && lnk_status->mac0_duplex) { + /* Port is up and running */ + si = (lnk_status->mac0_speed < 5) ? lnk_status->mac0_speed : 0; + di = (lnk_status->mac0_duplex < 3) ? + lnk_status->mac0_duplex : 0; + ai = (lnk_status->active_port == 0) ? 1 : 0; + printk(KERN_INFO "PortNo. 0: Speed - %s %s %s\n", + link_speed[si], link_duplex[di], link_state[ai]); + } else + printk(KERN_INFO "PortNo. 0: Down\n"); + + /* Port 1 */ + if (lnk_status->mac1_speed && lnk_status->mac1_duplex) { + /* Port is up and running */ + si = (lnk_status->mac1_speed < 5) ? lnk_status->mac1_speed : 0; + di = (lnk_status->mac1_duplex < 3) ? + lnk_status->mac1_duplex : 0; + ai = (lnk_status->active_port == 0) ? 1 : 0; + printk(KERN_INFO "PortNo. 1: Speed - %s %s %s\n", + link_speed[si], link_duplex[di], link_state[ai]); + } else + printk(KERN_INFO "PortNo. 1: Down\n"); + + return; +} + +static int +be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr, + void **ip_hdr, void **tcpudp_hdr, + u64 *hdr_flags, void *priv) +{ + struct ethhdr *eh; + struct vlan_ethhdr *veh; + struct iphdr *iph; + u8 *va = page_address(frag->page) + frag->page_offset; + unsigned long ll_hlen; + + /* find the mac header, abort if not IPv4 */ + + prefetch(va); + eh = (struct ethhdr *)va; + *mac_hdr = eh; + ll_hlen = ETH_HLEN; + if (eh->h_proto != htons(ETH_P_IP)) { + if (eh->h_proto == htons(ETH_P_8021Q)) { + veh = (struct vlan_ethhdr *)va; + if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP)) + return -1; + + ll_hlen += VLAN_HLEN; + + } else { + return -1; + } + } + *hdr_flags = LRO_IPV4; + + iph = (struct iphdr *)(va + ll_hlen); + *ip_hdr = iph; + if (iph->protocol != IPPROTO_TCP) + return -1; + *hdr_flags |= LRO_TCP; + *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2); + + return 0; +} + +static int benet_open(struct net_device *netdev) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + struct net_lro_mgr *lro_mgr; + + if (adapter->dev_state < BE_DEV_STATE_INIT) + return -EAGAIN; + + lro_mgr = &pnob->lro_mgr; + lro_mgr->dev = netdev; + + lro_mgr->features = LRO_F_NAPI; + lro_mgr->ip_summed = CHECKSUM_UNNECESSARY; + lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; + lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS; + lro_mgr->lro_arr = pnob->lro_desc; + lro_mgr->get_frag_header = be_get_frag_header; + lro_mgr->max_aggr = adapter->max_rx_coal; + lro_mgr->frag_align_pad = 2; + if (lro_mgr->max_aggr > MAX_SKB_FRAGS) + lro_mgr->max_aggr = MAX_SKB_FRAGS; + + adapter->max_rx_coal = BE_LRO_MAX_PKTS; + + be_update_link_status(adapter); + + /* + * Set carrier on only if Physical Link up + * Either of the port link status up signifies this + */ + if ((adapter->port0_link_sts == BE_PORT_LINK_UP) || + (adapter->port1_link_sts == BE_PORT_LINK_UP)) { + netif_start_queue(netdev); + netif_carrier_on(netdev); + } + + adapter->dev_state = BE_DEV_STATE_OPEN; + napi_enable(&pnob->napi); + be_enable_intr(pnob); + be_enable_eq_intr(pnob); + /* + * RX completion queue may be in dis-armed state. Arm it. + */ + be_notify_cmpl(pnob, 0, pnob->rx_cq_id, 1); + + return 0; +} + +static int benet_close(struct net_device *netdev) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + + netif_stop_queue(netdev); + synchronize_irq(netdev->irq); + + be_wait_nic_tx_cmplx_cmpl(pnob); + adapter->dev_state = BE_DEV_STATE_INIT; + netif_carrier_off(netdev); + + adapter->port0_link_sts = BE_PORT_LINK_DOWN; + adapter->port1_link_sts = BE_PORT_LINK_DOWN; + be_disable_intr(pnob); + be_disable_eq_intr(pnob); + napi_disable(&pnob->napi); + + return 0; +} + +/* + * Setting a Mac Address for BE + * Takes netdev and a void pointer as arguments. + * The pointer holds the new addres to be used. + */ +static int benet_set_mac_addr(struct net_device *netdev, void *p) +{ + struct sockaddr *addr = p; + struct be_net_object *pnob = netdev_priv(netdev); + + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); + be_rxf_mac_address_read_write(&pnob->fn_obj, 0, 0, false, true, false, + netdev->dev_addr, NULL, NULL); + /* + * Since we are doing Active-Passive failover, both + * ports should have matching MAC addresses everytime. + */ + be_rxf_mac_address_read_write(&pnob->fn_obj, 1, 0, false, true, false, + netdev->dev_addr, NULL, NULL); + + return 0; +} + +void be_get_stats_timer_handler(unsigned long context) +{ + struct be_timer_ctxt *ctxt = (struct be_timer_ctxt *)context; + + if (atomic_read(&ctxt->get_stat_flag)) { + atomic_dec(&ctxt->get_stat_flag); + up((void *)ctxt->get_stat_sem_addr); + } + del_timer(&ctxt->get_stats_timer); + return; +} + +void be_get_stat_cb(void *context, int status, + struct MCC_WRB_AMAP *optional_wrb) +{ + struct be_timer_ctxt *ctxt = (struct be_timer_ctxt *)context; + /* + * just up the semaphore if the get_stat_flag + * reads 1. so that the waiter can continue. + * If it is 0, then it was handled by the timer handler. + */ + del_timer(&ctxt->get_stats_timer); + if (atomic_read(&ctxt->get_stat_flag)) { + atomic_dec(&ctxt->get_stat_flag); + up((void *)ctxt->get_stat_sem_addr); + } +} + +struct net_device_stats *benet_get_stats(struct net_device *dev) +{ + struct be_net_object *pnob = netdev_priv(dev); + struct be_adapter *adapter = pnob->adapter; + u64 pa; + struct be_timer_ctxt *ctxt = &adapter->timer_ctxt; + + if (adapter->dev_state != BE_DEV_STATE_OPEN) { + /* Return previously read stats */ + return &(adapter->benet_stats); + } + /* Get Physical Addr */ + pa = pci_map_single(adapter->pdev, adapter->eth_statsp, + sizeof(struct FWCMD_ETH_GET_STATISTICS), + PCI_DMA_FROMDEVICE); + ctxt->get_stat_sem_addr = (unsigned long)&adapter->get_eth_stat_sem; + atomic_inc(&ctxt->get_stat_flag); + + be_rxf_query_eth_statistics(&pnob->fn_obj, adapter->eth_statsp, + cpu_to_le64(pa), be_get_stat_cb, ctxt, + NULL); + + ctxt->get_stats_timer.data = (unsigned long)ctxt; + mod_timer(&ctxt->get_stats_timer, (jiffies + (HZ * 2))); + down((void *)ctxt->get_stat_sem_addr); /* callback will unblock us */ + + /* Adding port0 and port1 stats. */ + adapter->benet_stats.rx_packets = + adapter->eth_statsp->params.response.p0recvdtotalframes + + adapter->eth_statsp->params.response.p1recvdtotalframes; + adapter->benet_stats.tx_packets = + adapter->eth_statsp->params.response.p0xmitunicastframes + + adapter->eth_statsp->params.response.p1xmitunicastframes; + adapter->benet_stats.tx_bytes = + adapter->eth_statsp->params.response.p0xmitbyteslsd + + adapter->eth_statsp->params.response.p1xmitbyteslsd; + adapter->benet_stats.rx_errors = + adapter->eth_statsp->params.response.p0crcerrors + + adapter->eth_statsp->params.response.p1crcerrors; + adapter->benet_stats.rx_errors += + adapter->eth_statsp->params.response.p0alignmentsymerrs + + adapter->eth_statsp->params.response.p1alignmentsymerrs; + adapter->benet_stats.rx_errors += + adapter->eth_statsp->params.response.p0inrangelenerrors + + adapter->eth_statsp->params.response.p1inrangelenerrors; + adapter->benet_stats.rx_bytes = + adapter->eth_statsp->params.response.p0recvdtotalbytesLSD + + adapter->eth_statsp->params.response.p1recvdtotalbytesLSD; + adapter->benet_stats.rx_crc_errors = + adapter->eth_statsp->params.response.p0crcerrors + + adapter->eth_statsp->params.response.p1crcerrors; + + adapter->benet_stats.tx_packets += + adapter->eth_statsp->params.response.p0xmitmulticastframes + + adapter->eth_statsp->params.response.p1xmitmulticastframes; + adapter->benet_stats.tx_packets += + adapter->eth_statsp->params.response.p0xmitbroadcastframes + + adapter->eth_statsp->params.response.p1xmitbroadcastframes; + adapter->benet_stats.tx_errors = 0; + + adapter->benet_stats.multicast = + adapter->eth_statsp->params.response.p0xmitmulticastframes + + adapter->eth_statsp->params.response.p1xmitmulticastframes; + + adapter->benet_stats.rx_fifo_errors = + adapter->eth_statsp->params.response.p0rxfifooverflowdropped + + adapter->eth_statsp->params.response.p1rxfifooverflowdropped; + adapter->benet_stats.rx_frame_errors = + adapter->eth_statsp->params.response.p0alignmentsymerrs + + adapter->eth_statsp->params.response.p1alignmentsymerrs; + adapter->benet_stats.rx_length_errors = + adapter->eth_statsp->params.response.p0inrangelenerrors + + adapter->eth_statsp->params.response.p1inrangelenerrors; + adapter->benet_stats.rx_length_errors += + adapter->eth_statsp->params.response.p0outrangeerrors + + adapter->eth_statsp->params.response.p1outrangeerrors; + adapter->benet_stats.rx_length_errors += + adapter->eth_statsp->params.response.p0frametoolongerrors + + adapter->eth_statsp->params.response.p1frametoolongerrors; + + pci_unmap_single(adapter->pdev, (ulong) adapter->eth_statsp, + sizeof(struct FWCMD_ETH_GET_STATISTICS), + PCI_DMA_FROMDEVICE); + return &(adapter->benet_stats); + +} + +static void be_start_tx(struct be_net_object *pnob, u32 nposted) +{ +#define CSR_ETH_MAX_SQPOSTS 255 + struct SQ_DB_AMAP sqdb; + + sqdb.dw[0] = 0; + + AMAP_SET_BITS_PTR(SQ_DB, cid, &sqdb, pnob->tx_q_id); + while (nposted) { + if (nposted > CSR_ETH_MAX_SQPOSTS) { + AMAP_SET_BITS_PTR(SQ_DB, numPosted, &sqdb, + CSR_ETH_MAX_SQPOSTS); + nposted -= CSR_ETH_MAX_SQPOSTS; + } else { + AMAP_SET_BITS_PTR(SQ_DB, numPosted, &sqdb, nposted); + nposted = 0; + } + PD_WRITE(&pnob->fn_obj, etx_sq_db, sqdb.dw[0]); + } + + return; +} + +static void update_tx_rate(struct be_adapter *adapter) +{ + /* update the rate once in two seconds */ + if ((jiffies - adapter->eth_tx_jiffies) > 2 * (HZ)) { + u32 r; + r = adapter->eth_tx_bytes / + ((jiffies - adapter->eth_tx_jiffies) / (HZ)); + r = (r / 1000000); /* M bytes/s */ + adapter->be_stat.bes_eth_tx_rate = (r * 8); /* M bits/s */ + adapter->eth_tx_jiffies = jiffies; + adapter->eth_tx_bytes = 0; + } +} + +static int wrb_cnt_in_skb(struct sk_buff *skb) +{ + int cnt = 0; + while (skb) { + if (skb->len > skb->data_len) + cnt++; + cnt += skb_shinfo(skb)->nr_frags; + skb = skb_shinfo(skb)->frag_list; + } + BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT); + return cnt; +} + +static void wrb_fill(struct ETH_WRB_AMAP *wrb, u64 addr, int len) +{ + AMAP_SET_BITS_PTR(ETH_WRB, frag_pa_hi, wrb, addr >> 32); + AMAP_SET_BITS_PTR(ETH_WRB, frag_pa_lo, wrb, addr & 0xFFFFFFFF); + AMAP_SET_BITS_PTR(ETH_WRB, frag_len, wrb, len); +} + +static void wrb_fill_extra(struct ETH_WRB_AMAP *wrb, struct sk_buff *skb, + struct be_net_object *pnob) +{ + wrb->dw[2] = 0; + wrb->dw[3] = 0; + AMAP_SET_BITS_PTR(ETH_WRB, crc, wrb, 1); + if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) { + AMAP_SET_BITS_PTR(ETH_WRB, lso, wrb, 1); + AMAP_SET_BITS_PTR(ETH_WRB, lso_mss, wrb, + skb_shinfo(skb)->gso_size); + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + u8 proto = ((struct iphdr *)ip_hdr(skb))->protocol; + if (proto == IPPROTO_TCP) + AMAP_SET_BITS_PTR(ETH_WRB, tcpcs, wrb, 1); + else if (proto == IPPROTO_UDP) + AMAP_SET_BITS_PTR(ETH_WRB, udpcs, wrb, 1); + } + if (pnob->vlan_grp && vlan_tx_tag_present(skb)) { + AMAP_SET_BITS_PTR(ETH_WRB, vlan, wrb, 1); + AMAP_SET_BITS_PTR(ETH_WRB, vlan_tag, wrb, vlan_tx_tag_get(skb)); + } +} + +static inline void wrb_copy_extra(struct ETH_WRB_AMAP *to, + struct ETH_WRB_AMAP *from) +{ + + to->dw[2] = from->dw[2]; + to->dw[3] = from->dw[3]; +} + +/* Returns the actual count of wrbs used including a possible dummy */ +static int copy_skb_to_txq(struct be_net_object *pnob, struct sk_buff *skb, + u32 wrb_cnt, u32 *copied) +{ + u64 busaddr; + struct ETH_WRB_AMAP *wrb = NULL, *first = NULL; + u32 i; + bool dummy = true; + struct pci_dev *pdev = pnob->adapter->pdev; + + if (wrb_cnt & 1) + wrb_cnt++; + else + dummy = false; + + atomic_add(wrb_cnt, &pnob->tx_q_used); + + while (skb) { + if (skb->len > skb->data_len) { + int len = skb->len - skb->data_len; + busaddr = pci_map_single(pdev, skb->data, len, + PCI_DMA_TODEVICE); + busaddr = cpu_to_le64(busaddr); + wrb = &pnob->tx_q[pnob->tx_q_hd]; + if (first == NULL) { + wrb_fill_extra(wrb, skb, pnob); + first = wrb; + } else { + wrb_copy_extra(wrb, first); + } + wrb_fill(wrb, busaddr, len); + be_adv_txq_hd(pnob); + *copied += len; + } + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + struct skb_frag_struct *frag = + &skb_shinfo(skb)->frags[i]; + busaddr = pci_map_page(pdev, frag->page, + frag->page_offset, frag->size, + PCI_DMA_TODEVICE); + busaddr = cpu_to_le64(busaddr); + wrb = &pnob->tx_q[pnob->tx_q_hd]; + if (first == NULL) { + wrb_fill_extra(wrb, skb, pnob); + first = wrb; + } else { + wrb_copy_extra(wrb, first); + } + wrb_fill(wrb, busaddr, frag->size); + be_adv_txq_hd(pnob); + *copied += frag->size; + } + skb = skb_shinfo(skb)->frag_list; + } + + if (dummy) { + wrb = &pnob->tx_q[pnob->tx_q_hd]; + BUG_ON(first == NULL); + wrb_copy_extra(wrb, first); + wrb_fill(wrb, 0, 0); + be_adv_txq_hd(pnob); + } + AMAP_SET_BITS_PTR(ETH_WRB, complete, wrb, 1); + AMAP_SET_BITS_PTR(ETH_WRB, last, wrb, 1); + return wrb_cnt; +} + +/* For each skb transmitted, tx_ctxt stores the num of wrbs in the + * start index and skb pointer in the end index + */ +static inline void be_tx_wrb_info_remember(struct be_net_object *pnob, + struct sk_buff *skb, int wrb_cnt, + u32 start) +{ + *(u32 *) (&pnob->tx_ctxt[start]) = wrb_cnt; + index_adv(&start, wrb_cnt - 1, pnob->tx_q_len); + pnob->tx_ctxt[start] = skb; +} + +static int benet_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + u32 wrb_cnt, copied = 0; + u32 start = pnob->tx_q_hd; + + adapter->be_stat.bes_tx_reqs++; + + wrb_cnt = wrb_cnt_in_skb(skb); + spin_lock_bh(&adapter->txq_lock); + if ((pnob->tx_q_len - 2 - atomic_read(&pnob->tx_q_used)) <= wrb_cnt) { + netif_stop_queue(pnob->netdev); + spin_unlock_bh(&adapter->txq_lock); + adapter->be_stat.bes_tx_fails++; + return NETDEV_TX_BUSY; + } + spin_unlock_bh(&adapter->txq_lock); + + wrb_cnt = copy_skb_to_txq(pnob, skb, wrb_cnt, &copied); + be_tx_wrb_info_remember(pnob, skb, wrb_cnt, start); + + be_start_tx(pnob, wrb_cnt); + + adapter->eth_tx_bytes += copied; + adapter->be_stat.bes_tx_wrbs += wrb_cnt; + update_tx_rate(adapter); + netdev->trans_start = jiffies; + + return NETDEV_TX_OK; +} + +/* + * This is the driver entry point to change the mtu of the device + * Returns 0 for success and errno for failure. + */ +static int benet_change_mtu(struct net_device *netdev, int new_mtu) +{ + /* + * BE supports jumbo frame size upto 9000 bytes including the link layer + * header. Considering the different variants of frame formats possible + * like VLAN, SNAP/LLC, the maximum possible value for MTU is 8974 bytes + */ + + if (new_mtu < (ETH_ZLEN + ETH_FCS_LEN) || (new_mtu > BE_MAX_MTU)) { + dev_info(&netdev->dev, "Invalid MTU requested. " + "Must be between %d and %d bytes\n", + (ETH_ZLEN + ETH_FCS_LEN), BE_MAX_MTU); + return -EINVAL; + } + dev_info(&netdev->dev, "MTU changed from %d to %d\n", + netdev->mtu, new_mtu); + netdev->mtu = new_mtu; + return 0; +} + +/* + * This is the driver entry point to register a vlan with the device + */ +static void benet_vlan_register(struct net_device *netdev, + struct vlan_group *grp) +{ + struct be_net_object *pnob = netdev_priv(netdev); + + be_disable_eq_intr(pnob); + pnob->vlan_grp = grp; + pnob->num_vlans = 0; + be_enable_eq_intr(pnob); +} + +/* + * This is the driver entry point to add a vlan vlan_id + * with the device netdev + */ +static void benet_vlan_add_vid(struct net_device *netdev, u16 vlan_id) +{ + struct be_net_object *pnob = netdev_priv(netdev); + + if (pnob->num_vlans == (BE_NUM_VLAN_SUPPORTED - 1)) { + /* no way to return an error */ + dev_info(&netdev->dev, + "BladeEngine: Cannot configure more than %d Vlans\n", + BE_NUM_VLAN_SUPPORTED); + return; + } + /* The new vlan tag will be in the slot indicated by num_vlans. */ + pnob->vlan_tag[pnob->num_vlans++] = vlan_id; + be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans, + pnob->vlan_tag, NULL, NULL, NULL); +} + +/* + * This is the driver entry point to remove a vlan vlan_id + * with the device netdev + */ +static void benet_vlan_rem_vid(struct net_device *netdev, u16 vlan_id) +{ + struct be_net_object *pnob = netdev_priv(netdev); + + u32 i, value; + + /* + * In Blade Engine, we support 32 vlan tag filters across both ports. + * To program a vlan tag, the RXF_RTPR_CSR register is used. + * Each 32-bit value of RXF_RTDR_CSR can address 2 vlan tag entries. + * The Vlan table is of depth 16. thus we support 32 tags. + */ + + value = vlan_id | VLAN_VALID_BIT; + for (i = 0; i < BE_NUM_VLAN_SUPPORTED; i++) { + if (pnob->vlan_tag[i] == vlan_id) + break; + } + + if (i == BE_NUM_VLAN_SUPPORTED) + return; + /* Now compact the vlan tag array by removing hole created. */ + while ((i + 1) < BE_NUM_VLAN_SUPPORTED) { + pnob->vlan_tag[i] = pnob->vlan_tag[i + 1]; + i++; + } + if ((i + 1) == BE_NUM_VLAN_SUPPORTED) + pnob->vlan_tag[i] = (u16) 0x0; + pnob->num_vlans--; + be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans, + pnob->vlan_tag, NULL, NULL, NULL); +} + +/* + * This function is called to program multicast + * address in the multicast filter of the ASIC. + */ +static void be_set_multicast_filter(struct net_device *netdev) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct dev_mc_list *mc_ptr; + u8 mac_addr[32][ETH_ALEN]; + int i; + + if (netdev->flags & IFF_ALLMULTI) { + /* set BE in Multicast promiscuous */ + be_rxf_multicast_config(&pnob->fn_obj, true, 0, NULL, NULL, + NULL, NULL); + return; + } + + for (mc_ptr = netdev->mc_list, i = 0; mc_ptr; + mc_ptr = mc_ptr->next, i++) { + memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN); + } + + /* reset the promiscuous mode also. */ + be_rxf_multicast_config(&pnob->fn_obj, false, i, + &mac_addr[0][0], NULL, NULL, NULL); +} + +/* + * This is the driver entry point to set multicast list + * with the device netdev. This function will be used to + * set promiscuous mode or multicast promiscuous mode + * or multicast mode.... + */ +static void benet_set_multicast_list(struct net_device *netdev) +{ + struct be_net_object *pnob = netdev_priv(netdev); + + if (netdev->flags & IFF_PROMISC) { + be_rxf_promiscuous(&pnob->fn_obj, 1, 1, NULL, NULL, NULL); + } else { + be_rxf_promiscuous(&pnob->fn_obj, 0, 0, NULL, NULL, NULL); + be_set_multicast_filter(netdev); + } +} + +int benet_init(struct net_device *netdev) +{ + struct be_net_object *pnob = netdev_priv(netdev); + struct be_adapter *adapter = pnob->adapter; + + ether_setup(netdev); + + netdev->open = &benet_open; + netdev->stop = &benet_close; + netdev->hard_start_xmit = &benet_xmit; + + netdev->get_stats = &benet_get_stats; + + netdev->set_multicast_list = &benet_set_multicast_list; + + netdev->change_mtu = &benet_change_mtu; + netdev->set_mac_address = &benet_set_mac_addr; + + netdev->vlan_rx_register = benet_vlan_register; + netdev->vlan_rx_add_vid = benet_vlan_add_vid; + netdev->vlan_rx_kill_vid = benet_vlan_rem_vid; + + netdev->features = + NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM; + + netdev->flags |= IFF_MULTICAST; + + /* If device is DAC Capable, set the HIGHDMA flag for netdevice. */ + if (adapter->dma_64bit_cap) + netdev->features |= NETIF_F_HIGHDMA; + + SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); + return 0; +} diff --git a/trunk/drivers/staging/benet/benet.h b/trunk/drivers/staging/benet/benet.h new file mode 100644 index 000000000000..09a1f0817722 --- /dev/null +++ b/trunk/drivers/staging/benet/benet.h @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#ifndef _BENET_H_ +#define _BENET_H_ + +#include +#include +#include +#include "hwlib.h" + +#define _SA_MODULE_NAME "net-driver" + +#define VLAN_VALID_BIT 0x8000 +#define BE_NUM_VLAN_SUPPORTED 32 +#define BE_PORT_LINK_DOWN 0000 +#define BE_PORT_LINK_UP 0001 +#define BE_MAX_TX_FRAG_COUNT (30) + +/* Flag bits for send operation */ +#define IPCS (1 << 0) /* Enable IP checksum offload */ +#define UDPCS (1 << 1) /* Enable UDP checksum offload */ +#define TCPCS (1 << 2) /* Enable TCP checksum offload */ +#define LSO (1 << 3) /* Enable Large Segment offload */ +#define ETHVLAN (1 << 4) /* Enable VLAN insert */ +#define ETHEVENT (1 << 5) /* Generate event on completion */ +#define ETHCOMPLETE (1 << 6) /* Generate completion when done */ +#define IPSEC (1 << 7) /* Enable IPSEC */ +#define FORWARD (1 << 8) /* Send the packet in forwarding path */ +#define FIN (1 << 9) /* Issue FIN segment */ + +#define BE_MAX_MTU 8974 + +#define BE_MAX_LRO_DESCRIPTORS 8 +#define BE_LRO_MAX_PKTS 64 +#define BE_MAX_FRAGS_PER_FRAME 6 + +extern const char be_drvr_ver[]; +extern char be_fw_ver[]; +extern char be_driver_name[]; + +extern struct ethtool_ops be_ethtool_ops; + +#define BE_DEV_STATE_NONE 0 +#define BE_DEV_STATE_INIT 1 +#define BE_DEV_STATE_OPEN 2 +#define BE_DEV_STATE_SUSPEND 3 + +/* This structure is used to describe physical fragments to use + * for DMAing data from NIC. + */ +struct be_recv_buffer { + struct list_head rxb_list; /* for maintaining a linked list */ + void *rxb_va; /* buffer virtual address */ + u32 rxb_pa_lo; /* low part of physical address */ + u32 rxb_pa_hi; /* high part of physical address */ + u32 rxb_len; /* length of recv buffer */ + void *rxb_ctxt; /* context for OSM driver to use */ +}; + +/* + * fragment list to describe scattered data. + */ +struct be_tx_frag_list { + u32 txb_len; /* Size of this fragment */ + u32 txb_pa_lo; /* Lower 32 bits of 64 bit physical addr */ + u32 txb_pa_hi; /* Higher 32 bits of 64 bit physical addr */ +}; + +struct be_rx_page_info { + struct page *page; + dma_addr_t bus; + u16 page_offset; +}; + +/* + * This structure is the main tracking structure for a NIC interface. + */ +struct be_net_object { + /* MCC Ring - used to send fwcmds to embedded ARM processor */ + struct MCC_WRB_AMAP *mcc_q; /* VA of the start of the ring */ + u32 mcc_q_len; /* # of WRB entries in this ring */ + u32 mcc_q_size; + u32 mcc_q_hd; /* MCC ring head */ + u8 mcc_q_created; /* flag to help cleanup */ + struct be_mcc_object mcc_q_obj; /* BECLIB's MCC ring Object */ + dma_addr_t mcc_q_bus; /* DMA'ble bus address */ + + /* MCC Completion Ring - FW responses to fwcmds sent from MCC ring */ + struct MCC_CQ_ENTRY_AMAP *mcc_cq; /* VA of the start of the ring */ + u32 mcc_cq_len; /* # of compl. entries in this ring */ + u32 mcc_cq_size; + u32 mcc_cq_tl; /* compl. ring tail */ + u8 mcc_cq_created; /* flag to help cleanup */ + struct be_cq_object mcc_cq_obj; /* BECLIB's MCC compl. ring object */ + u32 mcc_cq_id; /* MCC ring ID */ + dma_addr_t mcc_cq_bus; /* DMA'ble bus address */ + + struct ring_desc mb_rd; /* RD for MCC_MAIL_BOX */ + void *mb_ptr; /* mailbox ptr to be freed */ + dma_addr_t mb_bus; /* DMA'ble bus address */ + u32 mb_size; + + /* BEClib uses an array of context objects to track outstanding + * requests to the MCC. We need allocate the same number of + * conext entries as the number of entries in the MCC WRB ring + */ + u32 mcc_wrb_ctxt_size; + void *mcc_wrb_ctxt; /* pointer to the context area */ + u32 mcc_wrb_ctxtLen; /* Number of entries in the context */ + /* + * NIC send request ring - used for xmitting raw ether frames. + */ + struct ETH_WRB_AMAP *tx_q; /* VA of the start of the ring */ + u32 tx_q_len; /* # if entries in the send ring */ + u32 tx_q_size; + u32 tx_q_hd; /* Head index. Next req. goes here */ + u32 tx_q_tl; /* Tail indx. oldest outstanding req. */ + u8 tx_q_created; /* flag to help cleanup */ + struct be_ethsq_object tx_q_obj;/* BECLIB's send Q handle */ + dma_addr_t tx_q_bus; /* DMA'ble bus address */ + u32 tx_q_id; /* send queue ring ID */ + u32 tx_q_port; /* 0 no binding, 1 port A, 2 port B */ + atomic_t tx_q_used; /* # of WRBs used */ + /* ptr to an array in which we store context info for each send req. */ + void **tx_ctxt; + /* + * NIC Send compl. ring - completion status for all NIC frames xmitted. + */ + struct ETH_TX_COMPL_AMAP *tx_cq;/* VA of start of the ring */ + u32 txcq_len; /* # of entries in the ring */ + u32 tx_cq_size; + /* + * index into compl ring where the host expects next completion entry + */ + u32 tx_cq_tl; + u32 tx_cq_id; /* completion queue id */ + u8 tx_cq_created; /* flag to help cleanup */ + struct be_cq_object tx_cq_obj; + dma_addr_t tx_cq_bus; /* DMA'ble bus address */ + /* + * Event Queue - all completion entries post events here. + */ + struct EQ_ENTRY_AMAP *event_q; /* VA of start of event queue */ + u32 event_q_len; /* # of entries */ + u32 event_q_size; + u32 event_q_tl; /* Tail of the event queue */ + u32 event_q_id; /* Event queue ID */ + u8 event_q_created; /* flag to help cleanup */ + struct be_eq_object event_q_obj; /* Queue handle */ + dma_addr_t event_q_bus; /* DMA'ble bus address */ + /* + * NIC receive queue - Data buffers to be used for receiving unicast, + * broadcast and multi-cast frames are posted here. + */ + struct ETH_RX_D_AMAP *rx_q; /* VA of start of the queue */ + u32 rx_q_len; /* # of entries */ + u32 rx_q_size; + u32 rx_q_hd; /* Head of the queue */ + atomic_t rx_q_posted; /* number of posted buffers */ + u32 rx_q_id; /* queue ID */ + u8 rx_q_created; /* flag to help cleanup */ + struct be_ethrq_object rx_q_obj; /* NIC RX queue handle */ + dma_addr_t rx_q_bus; /* DMA'ble bus address */ + /* + * Pointer to an array of opaque context object for use by OSM driver + */ + void **rx_ctxt; + /* + * NIC unicast RX completion queue - all unicast ether frame completion + * statuses from BE come here. + */ + struct ETH_RX_COMPL_AMAP *rx_cq; /* VA of start of the queue */ + u32 rx_cq_len; /* # of entries */ + u32 rx_cq_size; + u32 rx_cq_tl; /* Tail of the queue */ + u32 rx_cq_id; /* queue ID */ + u8 rx_cq_created; /* flag to help cleanup */ + struct be_cq_object rx_cq_obj; /* queue handle */ + dma_addr_t rx_cq_bus; /* DMA'ble bus address */ + struct be_function_object fn_obj; /* function object */ + bool fn_obj_created; + u32 rx_buf_size; /* Size of the RX buffers */ + + struct net_device *netdev; + struct be_recv_buffer eth_rx_bufs[256]; /* to pass Rx buffer + addresses */ + struct be_adapter *adapter; /* Pointer to OSM adapter */ + u32 devno; /* OSM, network dev no. */ + u32 use_port; /* Current active port */ + struct be_rx_page_info *rx_page_info; /* Array of Rx buf pages */ + u32 rx_pg_info_hd; /* Head of queue */ + int rxbuf_post_fail; /* RxBuff posting fail count */ + bool rx_pg_shared; /* Is an allocsted page shared as two frags ? */ + struct vlan_group *vlan_grp; + u32 num_vlans; /* Number of vlans in BE's filter */ + u16 vlan_tag[BE_NUM_VLAN_SUPPORTED]; /* vlans currently configured */ + struct napi_struct napi; + struct net_lro_mgr lro_mgr; + struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS]; +}; + +#define NET_FH(np) (&(np)->fn_obj) + +/* + * BE driver statistics. + */ +struct be_drvr_stat { + u32 bes_tx_reqs; /* number of TX requests initiated */ + u32 bes_tx_fails; /* number of TX requests that failed */ + u32 bes_fwd_reqs; /* number of send reqs through forwarding i/f */ + u32 bes_tx_wrbs; /* number of tx WRBs used */ + + u32 bes_ints; /* number of interrupts */ + u32 bes_polls; /* number of times NAPI called poll function */ + u32 bes_events; /* total evet entries processed */ + u32 bes_tx_events; /* number of tx completion events */ + u32 bes_rx_events; /* number of ucast rx completion events */ + u32 bes_tx_compl; /* number of tx completion entries processed */ + u32 bes_rx_compl; /* number of rx completion entries + processed */ + u32 bes_ethrx_post_fail; /* number of ethrx buffer alloc + failures */ + /* + * number of non ether type II frames dropped where + * frame len > length field of Mac Hdr + */ + u32 bes_802_3_dropped_frames; + /* + * number of non ether type II frames malformed where + * in frame len < length field of Mac Hdr + */ + u32 bes_802_3_malformed_frames; + u32 bes_ips; /* interrupts / sec */ + u32 bes_prev_ints; /* bes_ints at last IPS calculation */ + u16 bes_eth_tx_rate; /* ETH TX rate - Mb/sec */ + u16 bes_eth_rx_rate; /* ETH RX rate - Mb/sec */ + u32 bes_rx_coal; /* Num pkts coalasced */ + u32 bes_rx_flush; /* Num times coalasced */ + u32 bes_link_change_physical; /*Num of times physical link changed */ + u32 bes_link_change_virtual; /*Num of times virtual link changed */ + u32 bes_rx_misc_pkts; /* Misc pkts received */ +}; + +/* Maximum interrupt delay (in microseconds) allowed */ +#define MAX_EQD 120 + +/* + * timer to prevent system shutdown hang for ever if h/w stops responding + */ +struct be_timer_ctxt { + atomic_t get_stat_flag; + struct timer_list get_stats_timer; + unsigned long get_stat_sem_addr; +} ; + +/* This structure is the main BladeEngine driver context. */ +struct be_adapter { + struct net_device *netdevp; + struct be_drvr_stat be_stat; + struct net_device_stats benet_stats; + + /* PCI BAR mapped addresses */ + u8 __iomem *csr_va; /* CSR */ + u8 __iomem *db_va; /* Door Bell */ + u8 __iomem *pci_va; /* PCI Config */ + + struct tasklet_struct sts_handler; + struct timer_list cq_timer; + spinlock_t int_lock; /* to protect the isr field in adapter */ + + struct FWCMD_ETH_GET_STATISTICS *eth_statsp; + /* + * This will enable the use of ethtool to enable or disable + * Checksum on Rx pkts to be obeyed or disobeyed. + * If this is true = 1, then whatever is the checksum on the + * Received pkt as per BE, it will be given to the stack. + * Else the stack will re calculate it. + */ + bool rx_csum; + /* + * This will enable the use of ethtool to enable or disable + * Coalese on Rx pkts to be obeyed or disobeyed. + * If this is grater than 0 and less than 16 then coalascing + * is enabled else it is disabled + */ + u32 max_rx_coal; + struct pci_dev *pdev; /* Pointer to OS's PCI dvice */ + + spinlock_t txq_lock; /* to stop/wake queue based on tx_q_used */ + + u32 isr; /* copy of Intr status reg. */ + + u32 port0_link_sts; /* Port 0 link status */ + u32 port1_link_sts; /* port 1 list status */ + struct BE_LINK_STATUS *be_link_sts; + + /* pointer to the first netobject of this adapter */ + struct be_net_object *net_obj; + + /* Flags to indicate what to clean up */ + bool tasklet_started; + bool isr_registered; + /* + * adaptive interrupt coalescing (AIC) related + */ + bool enable_aic; /* 1 if AIC is enabled */ + u16 min_eqd; /* minimum EQ delay in usec */ + u16 max_eqd; /* minimum EQ delay in usec */ + u16 cur_eqd; /* current EQ delay in usec */ + /* + * book keeping for interrupt / sec and TX/RX rate calculation + */ + ulong ips_jiffies; /* jiffies at last IPS calc */ + u32 eth_tx_bytes; + ulong eth_tx_jiffies; + u32 eth_rx_bytes; + ulong eth_rx_jiffies; + + struct semaphore get_eth_stat_sem; + + /* timer ctxt to prevent shutdown hanging due to un-responsive BE */ + struct be_timer_ctxt timer_ctxt; + +#define BE_MAX_MSIX_VECTORS 32 +#define BE_MAX_REQ_MSIX_VECTORS 1 /* only one EQ in Linux driver */ + struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS]; + bool msix_enabled; + bool dma_64bit_cap; /* the Device DAC capable or not */ + u8 dev_state; /* The current state of the device */ + u8 dev_pm_state; /* The State of device before going to suspend */ +}; + +/* + * Every second we look at the ints/sec and adjust eq_delay + * between adapter->min_eqd and adapter->max_eqd to keep the ints/sec between + * IPS_HI_WM and IPS_LO_WM. + */ +#define IPS_HI_WM 18000 +#define IPS_LO_WM 8000 + + +static inline void index_adv(u32 *index, u32 val, u32 limit) +{ + BUG_ON(limit & (limit-1)); + *index = (*index + val) & (limit - 1); +} + +static inline void index_inc(u32 *index, u32 limit) +{ + BUG_ON(limit & (limit-1)); + *index = (*index + 1) & (limit - 1); +} + +static inline void be_adv_eq_tl(struct be_net_object *pnob) +{ + index_inc(&pnob->event_q_tl, pnob->event_q_len); +} + +static inline void be_adv_txq_hd(struct be_net_object *pnob) +{ + index_inc(&pnob->tx_q_hd, pnob->tx_q_len); +} + +static inline void be_adv_txq_tl(struct be_net_object *pnob) +{ + index_inc(&pnob->tx_q_tl, pnob->tx_q_len); +} + +static inline void be_adv_txcq_tl(struct be_net_object *pnob) +{ + index_inc(&pnob->tx_cq_tl, pnob->txcq_len); +} + +static inline void be_adv_rxq_hd(struct be_net_object *pnob) +{ + index_inc(&pnob->rx_q_hd, pnob->rx_q_len); +} + +static inline void be_adv_rxcq_tl(struct be_net_object *pnob) +{ + index_inc(&pnob->rx_cq_tl, pnob->rx_cq_len); +} + +static inline u32 tx_compl_lastwrb_idx_get(struct be_net_object *pnob) +{ + return (pnob->tx_q_tl + *(u32 *)&pnob->tx_ctxt[pnob->tx_q_tl] - 1) + & (pnob->tx_q_len - 1); +} + +int benet_init(struct net_device *); +int be_ethtool_ioctl(struct net_device *, struct ifreq *); +struct net_device_stats *benet_get_stats(struct net_device *); +void be_process_intr(unsigned long context); +irqreturn_t be_int(int irq, void *dev); +void be_post_eth_rx_buffs(struct be_net_object *); +void be_get_stat_cb(void *, int, struct MCC_WRB_AMAP *); +void be_get_stats_timer_handler(unsigned long); +void be_wait_nic_tx_cmplx_cmpl(struct be_net_object *); +void be_print_link_info(struct BE_LINK_STATUS *); +void be_update_link_status(struct be_adapter *); +void be_init_procfs(struct be_adapter *); +void be_cleanup_procfs(struct be_adapter *); +int be_poll(struct napi_struct *, int); +struct ETH_RX_COMPL_AMAP *be_get_rx_cmpl(struct be_net_object *); +void be_notify_cmpl(struct be_net_object *, int, int, int); +void be_enable_intr(struct be_net_object *); +void be_enable_eq_intr(struct be_net_object *); +void be_disable_intr(struct be_net_object *); +void be_disable_eq_intr(struct be_net_object *); +int be_set_uc_mac_adr(struct be_net_object *, u8, u8, u8, + u8 *, mcc_wrb_cqe_callback, void *); +int be_get_flow_ctl(struct be_function_object *pFnObj, bool *, bool *); +void process_one_tx_compl(struct be_net_object *pnob, u32 end_idx); + +#endif /* _BENET_H_ */ diff --git a/trunk/drivers/staging/benet/bestatus.h b/trunk/drivers/staging/benet/bestatus.h new file mode 100644 index 000000000000..59c7a4b62223 --- /dev/null +++ b/trunk/drivers/staging/benet/bestatus.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#ifndef _BESTATUS_H_ +#define _BESTATUS_H_ + +#define BE_SUCCESS (0x00000000L) +/* + * MessageId: BE_PENDING + * The BladeEngine Driver call succeeded, and pended operation. + */ +#define BE_PENDING (0x20070001L) +#define BE_STATUS_PENDING (BE_PENDING) +/* + * MessageId: BE_NOT_OK + * An error occurred. + */ +#define BE_NOT_OK (0xE0070002L) +/* + * MessageId: BE_STATUS_SYSTEM_RESOURCES + * Insufficient host system resources exist to complete the API. + */ +#define BE_STATUS_SYSTEM_RESOURCES (0xE0070003L) +/* + * MessageId: BE_STATUS_CHIP_RESOURCES + * Insufficient chip resources exist to complete the API. + */ +#define BE_STATUS_CHIP_RESOURCES (0xE0070004L) +/* + * MessageId: BE_STATUS_NO_RESOURCE + * Insufficient resources to complete request. + */ +#define BE_STATUS_NO_RESOURCE (0xE0070005L) +/* + * MessageId: BE_STATUS_BUSY + * Resource is currently busy. + */ +#define BE_STATUS_BUSY (0xE0070006L) +/* + * MessageId: BE_STATUS_INVALID_PARAMETER + * Invalid Parameter in request. + */ +#define BE_STATUS_INVALID_PARAMETER (0xE0000007L) +/* + * MessageId: BE_STATUS_NOT_SUPPORTED + * Requested operation is not supported. + */ +#define BE_STATUS_NOT_SUPPORTED (0xE000000DL) + +/* + * *************************************************************************** + * E T H E R N E T S T A T U S + * *************************************************************************** + */ + +/* + * MessageId: BE_ETH_TX_ERROR + * The Ethernet device driver failed to transmit a packet. + */ +#define BE_ETH_TX_ERROR (0xE0070101L) + +/* + * *************************************************************************** + * S H A R E D S T A T U S + * *************************************************************************** + */ + +/* + * MessageId: BE_STATUS_VBD_INVALID_VERSION + * The device driver is not compatible with this version of the VBD. + */ +#define BE_STATUS_INVALID_VERSION (0xE0070402L) +/* + * MessageId: BE_STATUS_DOMAIN_DENIED + * The operation failed to complete due to insufficient access + * rights for the requesting domain. + */ +#define BE_STATUS_DOMAIN_DENIED (0xE0070403L) +/* + * MessageId: BE_STATUS_TCP_NOT_STARTED + * The embedded TCP/IP stack has not been started. + */ +#define BE_STATUS_TCP_NOT_STARTED (0xE0070409L) +/* + * MessageId: BE_STATUS_NO_MCC_WRB + * No free MCC WRB are available for posting the request. + */ +#define BE_STATUS_NO_MCC_WRB (0xE0070414L) + +#endif /* _BESTATUS_ */ diff --git a/trunk/drivers/staging/benet/cev.h b/trunk/drivers/staging/benet/cev.h new file mode 100644 index 000000000000..30996920a544 --- /dev/null +++ b/trunk/drivers/staging/benet/cev.h @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __cev_amap_h__ +#define __cev_amap_h__ +#include "ep.h" + +/* + * Host Interrupt Status Register 0. The first of four application + * interrupt status registers. This register contains the interrupts + * for Event Queues EQ0 through EQ31. + */ +struct BE_CEV_ISR0_CSR_AMAP { + u8 interrupt0; /* DWORD 0 */ + u8 interrupt1; /* DWORD 0 */ + u8 interrupt2; /* DWORD 0 */ + u8 interrupt3; /* DWORD 0 */ + u8 interrupt4; /* DWORD 0 */ + u8 interrupt5; /* DWORD 0 */ + u8 interrupt6; /* DWORD 0 */ + u8 interrupt7; /* DWORD 0 */ + u8 interrupt8; /* DWORD 0 */ + u8 interrupt9; /* DWORD 0 */ + u8 interrupt10; /* DWORD 0 */ + u8 interrupt11; /* DWORD 0 */ + u8 interrupt12; /* DWORD 0 */ + u8 interrupt13; /* DWORD 0 */ + u8 interrupt14; /* DWORD 0 */ + u8 interrupt15; /* DWORD 0 */ + u8 interrupt16; /* DWORD 0 */ + u8 interrupt17; /* DWORD 0 */ + u8 interrupt18; /* DWORD 0 */ + u8 interrupt19; /* DWORD 0 */ + u8 interrupt20; /* DWORD 0 */ + u8 interrupt21; /* DWORD 0 */ + u8 interrupt22; /* DWORD 0 */ + u8 interrupt23; /* DWORD 0 */ + u8 interrupt24; /* DWORD 0 */ + u8 interrupt25; /* DWORD 0 */ + u8 interrupt26; /* DWORD 0 */ + u8 interrupt27; /* DWORD 0 */ + u8 interrupt28; /* DWORD 0 */ + u8 interrupt29; /* DWORD 0 */ + u8 interrupt30; /* DWORD 0 */ + u8 interrupt31; /* DWORD 0 */ +} __packed; +struct CEV_ISR0_CSR_AMAP { + u32 dw[1]; +}; + +/* + * Host Interrupt Status Register 1. The second of four application + * interrupt status registers. This register contains the interrupts + * for Event Queues EQ32 through EQ63. + */ +struct BE_CEV_ISR1_CSR_AMAP { + u8 interrupt32; /* DWORD 0 */ + u8 interrupt33; /* DWORD 0 */ + u8 interrupt34; /* DWORD 0 */ + u8 interrupt35; /* DWORD 0 */ + u8 interrupt36; /* DWORD 0 */ + u8 interrupt37; /* DWORD 0 */ + u8 interrupt38; /* DWORD 0 */ + u8 interrupt39; /* DWORD 0 */ + u8 interrupt40; /* DWORD 0 */ + u8 interrupt41; /* DWORD 0 */ + u8 interrupt42; /* DWORD 0 */ + u8 interrupt43; /* DWORD 0 */ + u8 interrupt44; /* DWORD 0 */ + u8 interrupt45; /* DWORD 0 */ + u8 interrupt46; /* DWORD 0 */ + u8 interrupt47; /* DWORD 0 */ + u8 interrupt48; /* DWORD 0 */ + u8 interrupt49; /* DWORD 0 */ + u8 interrupt50; /* DWORD 0 */ + u8 interrupt51; /* DWORD 0 */ + u8 interrupt52; /* DWORD 0 */ + u8 interrupt53; /* DWORD 0 */ + u8 interrupt54; /* DWORD 0 */ + u8 interrupt55; /* DWORD 0 */ + u8 interrupt56; /* DWORD 0 */ + u8 interrupt57; /* DWORD 0 */ + u8 interrupt58; /* DWORD 0 */ + u8 interrupt59; /* DWORD 0 */ + u8 interrupt60; /* DWORD 0 */ + u8 interrupt61; /* DWORD 0 */ + u8 interrupt62; /* DWORD 0 */ + u8 interrupt63; /* DWORD 0 */ +} __packed; +struct CEV_ISR1_CSR_AMAP { + u32 dw[1]; +}; +/* + * Host Interrupt Status Register 2. The third of four application + * interrupt status registers. This register contains the interrupts + * for Event Queues EQ64 through EQ95. + */ +struct BE_CEV_ISR2_CSR_AMAP { + u8 interrupt64; /* DWORD 0 */ + u8 interrupt65; /* DWORD 0 */ + u8 interrupt66; /* DWORD 0 */ + u8 interrupt67; /* DWORD 0 */ + u8 interrupt68; /* DWORD 0 */ + u8 interrupt69; /* DWORD 0 */ + u8 interrupt70; /* DWORD 0 */ + u8 interrupt71; /* DWORD 0 */ + u8 interrupt72; /* DWORD 0 */ + u8 interrupt73; /* DWORD 0 */ + u8 interrupt74; /* DWORD 0 */ + u8 interrupt75; /* DWORD 0 */ + u8 interrupt76; /* DWORD 0 */ + u8 interrupt77; /* DWORD 0 */ + u8 interrupt78; /* DWORD 0 */ + u8 interrupt79; /* DWORD 0 */ + u8 interrupt80; /* DWORD 0 */ + u8 interrupt81; /* DWORD 0 */ + u8 interrupt82; /* DWORD 0 */ + u8 interrupt83; /* DWORD 0 */ + u8 interrupt84; /* DWORD 0 */ + u8 interrupt85; /* DWORD 0 */ + u8 interrupt86; /* DWORD 0 */ + u8 interrupt87; /* DWORD 0 */ + u8 interrupt88; /* DWORD 0 */ + u8 interrupt89; /* DWORD 0 */ + u8 interrupt90; /* DWORD 0 */ + u8 interrupt91; /* DWORD 0 */ + u8 interrupt92; /* DWORD 0 */ + u8 interrupt93; /* DWORD 0 */ + u8 interrupt94; /* DWORD 0 */ + u8 interrupt95; /* DWORD 0 */ +} __packed; +struct CEV_ISR2_CSR_AMAP { + u32 dw[1]; +}; + +/* + * Host Interrupt Status Register 3. The fourth of four application + * interrupt status registers. This register contains the interrupts + * for Event Queues EQ96 through EQ127. + */ +struct BE_CEV_ISR3_CSR_AMAP { + u8 interrupt96; /* DWORD 0 */ + u8 interrupt97; /* DWORD 0 */ + u8 interrupt98; /* DWORD 0 */ + u8 interrupt99; /* DWORD 0 */ + u8 interrupt100; /* DWORD 0 */ + u8 interrupt101; /* DWORD 0 */ + u8 interrupt102; /* DWORD 0 */ + u8 interrupt103; /* DWORD 0 */ + u8 interrupt104; /* DWORD 0 */ + u8 interrupt105; /* DWORD 0 */ + u8 interrupt106; /* DWORD 0 */ + u8 interrupt107; /* DWORD 0 */ + u8 interrupt108; /* DWORD 0 */ + u8 interrupt109; /* DWORD 0 */ + u8 interrupt110; /* DWORD 0 */ + u8 interrupt111; /* DWORD 0 */ + u8 interrupt112; /* DWORD 0 */ + u8 interrupt113; /* DWORD 0 */ + u8 interrupt114; /* DWORD 0 */ + u8 interrupt115; /* DWORD 0 */ + u8 interrupt116; /* DWORD 0 */ + u8 interrupt117; /* DWORD 0 */ + u8 interrupt118; /* DWORD 0 */ + u8 interrupt119; /* DWORD 0 */ + u8 interrupt120; /* DWORD 0 */ + u8 interrupt121; /* DWORD 0 */ + u8 interrupt122; /* DWORD 0 */ + u8 interrupt123; /* DWORD 0 */ + u8 interrupt124; /* DWORD 0 */ + u8 interrupt125; /* DWORD 0 */ + u8 interrupt126; /* DWORD 0 */ + u8 interrupt127; /* DWORD 0 */ +} __packed; +struct CEV_ISR3_CSR_AMAP { + u32 dw[1]; +}; + +/* Completions and Events block Registers. */ +struct BE_CEV_CSRMAP_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[32]; /* DWORD 1 */ + u8 rsvd2[32]; /* DWORD 2 */ + u8 rsvd3[32]; /* DWORD 3 */ + struct BE_CEV_ISR0_CSR_AMAP isr0; + struct BE_CEV_ISR1_CSR_AMAP isr1; + struct BE_CEV_ISR2_CSR_AMAP isr2; + struct BE_CEV_ISR3_CSR_AMAP isr3; + u8 rsvd4[32]; /* DWORD 8 */ + u8 rsvd5[32]; /* DWORD 9 */ + u8 rsvd6[32]; /* DWORD 10 */ + u8 rsvd7[32]; /* DWORD 11 */ + u8 rsvd8[32]; /* DWORD 12 */ + u8 rsvd9[32]; /* DWORD 13 */ + u8 rsvd10[32]; /* DWORD 14 */ + u8 rsvd11[32]; /* DWORD 15 */ + u8 rsvd12[32]; /* DWORD 16 */ + u8 rsvd13[32]; /* DWORD 17 */ + u8 rsvd14[32]; /* DWORD 18 */ + u8 rsvd15[32]; /* DWORD 19 */ + u8 rsvd16[32]; /* DWORD 20 */ + u8 rsvd17[32]; /* DWORD 21 */ + u8 rsvd18[32]; /* DWORD 22 */ + u8 rsvd19[32]; /* DWORD 23 */ + u8 rsvd20[32]; /* DWORD 24 */ + u8 rsvd21[32]; /* DWORD 25 */ + u8 rsvd22[32]; /* DWORD 26 */ + u8 rsvd23[32]; /* DWORD 27 */ + u8 rsvd24[32]; /* DWORD 28 */ + u8 rsvd25[32]; /* DWORD 29 */ + u8 rsvd26[32]; /* DWORD 30 */ + u8 rsvd27[32]; /* DWORD 31 */ + u8 rsvd28[32]; /* DWORD 32 */ + u8 rsvd29[32]; /* DWORD 33 */ + u8 rsvd30[192]; /* DWORD 34 */ + u8 rsvd31[192]; /* DWORD 40 */ + u8 rsvd32[160]; /* DWORD 46 */ + u8 rsvd33[160]; /* DWORD 51 */ + u8 rsvd34[160]; /* DWORD 56 */ + u8 rsvd35[96]; /* DWORD 61 */ + u8 rsvd36[192][32]; /* DWORD 64 */ +} __packed; +struct CEV_CSRMAP_AMAP { + u32 dw[256]; +}; + +#endif /* __cev_amap_h__ */ diff --git a/trunk/drivers/staging/benet/cq.c b/trunk/drivers/staging/benet/cq.c new file mode 100644 index 000000000000..650458645433 --- /dev/null +++ b/trunk/drivers/staging/benet/cq.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#include "hwlib.h" +#include "bestatus.h" + +/* + * Completion Queue Objects + */ +/* + *============================================================================ + * P U B L I C R O U T I N E S + *============================================================================ + */ + +/* + This routine creates a completion queue based on the client completion + queue configuration information. + + + FunctionObject - Handle to a function object + CqBaseVa - Base VA for a the CQ ring + NumEntries - CEV_CQ_CNT_* values + solEventEnable - 0 = All CQEs can generate Events if CQ is eventable + 1 = only CQEs with solicited bit set are eventable + eventable - Eventable CQ, generates interrupts. + nodelay - 1 = Force interrupt, relevent if CQ eventable. + Interrupt is asserted immediately after EQE + write is confirmed, regardless of EQ Timer + or watermark settings. + wme - Enable watermark based coalescing + wmThresh - High watermark(CQ fullness at which event + or interrupt should be asserted). These are the + CEV_WATERMARK encoded values. + EqObject - EQ Handle to assign to this CQ + ppCqObject - Internal CQ Handle returned. + + Returns BE_SUCCESS if successfull, otherwise a useful error code is + returned. + + IRQL < DISPATCH_LEVEL + +*/ +int be_cq_create(struct be_function_object *pfob, + struct ring_desc *rd, u32 length, bool solicited_eventable, + bool no_delay, u32 wm_thresh, + struct be_eq_object *eq_object, struct be_cq_object *cq_object) +{ + int status = BE_SUCCESS; + u32 num_entries_encoding; + u32 num_entries = length / sizeof(struct MCC_CQ_ENTRY_AMAP); + struct FWCMD_COMMON_CQ_CREATE *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + u32 n; + unsigned long irql; + + ASSERT(rd); + ASSERT(cq_object); + ASSERT(length % sizeof(struct MCC_CQ_ENTRY_AMAP) == 0); + + switch (num_entries) { + case 256: + num_entries_encoding = CEV_CQ_CNT_256; + break; + case 512: + num_entries_encoding = CEV_CQ_CNT_512; + break; + case 1024: + num_entries_encoding = CEV_CQ_CNT_1024; + break; + default: + ASSERT(0); + return BE_STATUS_INVALID_PARAMETER; + } + + /* + * All cq entries all the same size. Use iSCSI version + * as a test for the proper rd length. + */ + memset(cq_object, 0, sizeof(*cq_object)); + + atomic_set(&cq_object->ref_count, 0); + cq_object->parent_function = pfob; + cq_object->eq_object = eq_object; + cq_object->num_entries = num_entries; + /* save for MCC cq processing */ + cq_object->va = rd->va; + + /* map into UT. */ + length = num_entries * sizeof(struct MCC_CQ_ENTRY_AMAP); + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + ASSERT(wrb); + TRACE(DL_ERR, "No free MCC WRBs in create EQ."); + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_CQ_CREATE); + + fwcmd->params.request.num_pages = PAGES_SPANNED(OFFSET_IN_PAGE(rd->va), + length); + + AMAP_SET_BITS_PTR(CQ_CONTEXT, valid, &fwcmd->params.request.context, 1); + n = pfob->pci_function_number; + AMAP_SET_BITS_PTR(CQ_CONTEXT, Func, &fwcmd->params.request.context, n); + + n = (eq_object != NULL); + AMAP_SET_BITS_PTR(CQ_CONTEXT, Eventable, + &fwcmd->params.request.context, n); + AMAP_SET_BITS_PTR(CQ_CONTEXT, Armed, &fwcmd->params.request.context, 1); + + n = eq_object ? eq_object->eq_id : 0; + AMAP_SET_BITS_PTR(CQ_CONTEXT, EQID, &fwcmd->params.request.context, n); + AMAP_SET_BITS_PTR(CQ_CONTEXT, Count, + &fwcmd->params.request.context, num_entries_encoding); + + n = 0; /* Protection Domain is always 0 in Linux driver */ + AMAP_SET_BITS_PTR(CQ_CONTEXT, PD, &fwcmd->params.request.context, n); + AMAP_SET_BITS_PTR(CQ_CONTEXT, NoDelay, + &fwcmd->params.request.context, no_delay); + AMAP_SET_BITS_PTR(CQ_CONTEXT, SolEvent, + &fwcmd->params.request.context, solicited_eventable); + + n = (wm_thresh != 0xFFFFFFFF); + AMAP_SET_BITS_PTR(CQ_CONTEXT, WME, &fwcmd->params.request.context, n); + + n = (n ? wm_thresh : 0); + AMAP_SET_BITS_PTR(CQ_CONTEXT, Watermark, + &fwcmd->params.request.context, n); + /* Create a page list for the FWCMD. */ + be_rd_to_pa_list(rd, fwcmd->params.request.pages, + ARRAY_SIZE(fwcmd->params.request.pages)); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "MCC to create CQ failed."); + goto Error; + } + /* Remember the CQ id. */ + cq_object->cq_id = fwcmd->params.response.cq_id; + + /* insert this cq into eq_object reference */ + if (eq_object) { + atomic_inc(&eq_object->ref_count); + list_add_tail(&cq_object->cqlist_for_eq, + &eq_object->cq_list_head); + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + + Deferences the given object. Once the object's reference count drops to + zero, the object is destroyed and all resources that are held by this object + are released. The on-chip context is also destroyed along with the queue + ID, and any mappings made into the UT. + + cq_object - CQ handle returned from cq_object_create. + + returns the current reference count on the object + + IRQL: IRQL < DISPATCH_LEVEL +*/ +int be_cq_destroy(struct be_cq_object *cq_object) +{ + int status = 0; + + /* Nothing should reference this CQ at this point. */ + ASSERT(atomic_read(&cq_object->ref_count) == 0); + + /* Send fwcmd to destroy the CQ. */ + status = be_function_ring_destroy(cq_object->parent_function, + cq_object->cq_id, FWCMD_RING_TYPE_CQ, + NULL, NULL, NULL, NULL); + ASSERT(status == 0); + + /* Remove reference if this is an eventable CQ. */ + if (cq_object->eq_object) { + atomic_dec(&cq_object->eq_object->ref_count); + list_del(&cq_object->cqlist_for_eq); + } + return BE_SUCCESS; +} + diff --git a/trunk/drivers/staging/benet/descriptors.h b/trunk/drivers/staging/benet/descriptors.h new file mode 100644 index 000000000000..8da438c407d2 --- /dev/null +++ b/trunk/drivers/staging/benet/descriptors.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __descriptors_amap_h__ +#define __descriptors_amap_h__ + +/* + * --- IPC_NODE_ID_ENUM --- + * IPC processor id values + */ +#define TPOST_NODE_ID (0) /* TPOST ID */ +#define TPRE_NODE_ID (1) /* TPRE ID */ +#define TXULP0_NODE_ID (2) /* TXULP0 ID */ +#define TXULP1_NODE_ID (3) /* TXULP1 ID */ +#define TXULP2_NODE_ID (4) /* TXULP2 ID */ +#define RXULP0_NODE_ID (5) /* RXULP0 ID */ +#define RXULP1_NODE_ID (6) /* RXULP1 ID */ +#define RXULP2_NODE_ID (7) /* RXULP2 ID */ +#define MPU_NODE_ID (15) /* MPU ID */ + +/* + * --- MAC_ID_ENUM --- + * Meaning of the mac_id field in rxpp_eth_d + */ +#define PORT0_HOST_MAC0 (0) /* PD 0, Port 0, host networking, MAC 0. */ +#define PORT0_HOST_MAC1 (1) /* PD 0, Port 0, host networking, MAC 1. */ +#define PORT0_STORAGE_MAC0 (2) /* PD 0, Port 0, host storage, MAC 0. */ +#define PORT0_STORAGE_MAC1 (3) /* PD 0, Port 0, host storage, MAC 1. */ +#define PORT1_HOST_MAC0 (4) /* PD 0, Port 1 host networking, MAC 0. */ +#define PORT1_HOST_MAC1 (5) /* PD 0, Port 1 host networking, MAC 1. */ +#define PORT1_STORAGE_MAC0 (6) /* PD 0, Port 1 host storage, MAC 0. */ +#define PORT1_STORAGE_MAC1 (7) /* PD 0, Port 1 host storage, MAC 1. */ +#define FIRST_VM_MAC (8) /* PD 1 MAC. Protection domains have IDs */ + /* from 0x8-0x26, one per PD. */ +#define LAST_VM_MAC (38) /* PD 31 MAC. */ +#define MGMT_MAC (39) /* Management port MAC. */ +#define MARBLE_MAC0 (59) /* Used for flushing function 0 receive */ + /* + * queues before re-using a torn-down + * receive ring. the DA = + * 00-00-00-00-00-00, and the MSB of the + * SA = 00 + */ +#define MARBLE_MAC1 (60) /* Used for flushing function 1 receive */ + /* + * queues before re-using a torn-down + * receive ring. the DA = + * 00-00-00-00-00-00, and the MSB of the + * SA != 00 + */ +#define NULL_MAC (61) /* Promiscuous mode, indicates no match */ +#define MCAST_MAC (62) /* Multicast match. */ +#define BCAST_MATCH (63) /* Broadcast match. */ + +#endif /* __descriptors_amap_h__ */ diff --git a/trunk/drivers/staging/benet/doorbells.h b/trunk/drivers/staging/benet/doorbells.h new file mode 100644 index 000000000000..550cc4d5d6f7 --- /dev/null +++ b/trunk/drivers/staging/benet/doorbells.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __doorbells_amap_h__ +#define __doorbells_amap_h__ + +/* The TX/RDMA send queue doorbell. */ +struct BE_SQ_DB_AMAP { + u8 cid[11]; /* DWORD 0 */ + u8 rsvd0[5]; /* DWORD 0 */ + u8 numPosted[14]; /* DWORD 0 */ + u8 rsvd1[2]; /* DWORD 0 */ +} __packed; +struct SQ_DB_AMAP { + u32 dw[1]; +}; + +/* The receive queue doorbell. */ +struct BE_RQ_DB_AMAP { + u8 rq[10]; /* DWORD 0 */ + u8 rsvd0[13]; /* DWORD 0 */ + u8 Invalidate; /* DWORD 0 */ + u8 numPosted[8]; /* DWORD 0 */ +} __packed; +struct RQ_DB_AMAP { + u32 dw[1]; +}; + +/* + * The CQ/EQ doorbell. Software MUST set reserved fields in this + * descriptor to zero, otherwise (CEV) hardware will not execute the + * doorbell (flagging a bad_db_qid error instead). + */ +struct BE_CQ_DB_AMAP { + u8 qid[10]; /* DWORD 0 */ + u8 rsvd0[4]; /* DWORD 0 */ + u8 rearm; /* DWORD 0 */ + u8 event; /* DWORD 0 */ + u8 num_popped[13]; /* DWORD 0 */ + u8 rsvd1[3]; /* DWORD 0 */ +} __packed; +struct CQ_DB_AMAP { + u32 dw[1]; +}; + +struct BE_TPM_RQ_DB_AMAP { + u8 qid[10]; /* DWORD 0 */ + u8 rsvd0[6]; /* DWORD 0 */ + u8 numPosted[11]; /* DWORD 0 */ + u8 mss_cnt[5]; /* DWORD 0 */ +} __packed; +struct TPM_RQ_DB_AMAP { + u32 dw[1]; +}; + +/* + * Post WRB Queue Doorbell Register used by the host Storage stack + * to notify the controller of a posted Work Request Block + */ +struct BE_WRB_POST_DB_AMAP { + u8 wrb_cid[10]; /* DWORD 0 */ + u8 rsvd0[6]; /* DWORD 0 */ + u8 wrb_index[8]; /* DWORD 0 */ + u8 numberPosted[8]; /* DWORD 0 */ +} __packed; +struct WRB_POST_DB_AMAP { + u32 dw[1]; +}; + +/* + * Update Default PDU Queue Doorbell Register used to communicate + * to the controller that the driver has stopped processing the queue + * and where in the queue it stopped, this is + * a CQ Entry Type. Used by storage driver. + */ +struct BE_DEFAULT_PDU_DB_AMAP { + u8 qid[10]; /* DWORD 0 */ + u8 rsvd0[4]; /* DWORD 0 */ + u8 rearm; /* DWORD 0 */ + u8 event; /* DWORD 0 */ + u8 cqproc[14]; /* DWORD 0 */ + u8 rsvd1[2]; /* DWORD 0 */ +} __packed; +struct DEFAULT_PDU_DB_AMAP { + u32 dw[1]; +}; + +/* Management Command and Controller default fragment ring */ +struct BE_MCC_DB_AMAP { + u8 rid[11]; /* DWORD 0 */ + u8 rsvd0[5]; /* DWORD 0 */ + u8 numPosted[14]; /* DWORD 0 */ + u8 rsvd1[2]; /* DWORD 0 */ +} __packed; +struct MCC_DB_AMAP { + u32 dw[1]; +}; + +/* + * Used for bootstrapping the Host interface. This register is + * used for driver communication with the MPU when no MCC Rings exist. + * The software must write this register twice to post any MCC + * command. First, it writes the register with hi=1 and the upper bits of + * the physical address for the MCC_MAILBOX structure. Software must poll + * the ready bit until this is acknowledged. Then, sotware writes the + * register with hi=0 with the lower bits in the address. It must + * poll the ready bit until the MCC command is complete. Upon completion, + * the MCC_MAILBOX will contain a valid completion queue entry. + */ +struct BE_MPU_MAILBOX_DB_AMAP { + u8 ready; /* DWORD 0 */ + u8 hi; /* DWORD 0 */ + u8 address[30]; /* DWORD 0 */ +} __packed; +struct MPU_MAILBOX_DB_AMAP { + u32 dw[1]; +}; + +/* + * This is the protection domain doorbell register map. Note that + * while this map shows doorbells for all Blade Engine supported + * protocols, not all of these may be valid in a given function or + * protection domain. It is the responsibility of the application + * accessing the doorbells to know which are valid. Each doorbell + * occupies 32 bytes of space, but unless otherwise specified, + * only the first 4 bytes should be written. There are 32 instances + * of these doorbells for the host and 31 virtual machines respectively. + * The host and VMs will only map the doorbell pages belonging to its + * protection domain. It will not be able to touch the doorbells for + * another VM. The doorbells are the only registers directly accessible + * by a virtual machine. Similarly, there are 511 additional + * doorbells for RDMA protection domains. PD 0 for RDMA shares + * the same physical protection domain doorbell page as ETH/iSCSI. + * + */ +struct BE_PROTECTION_DOMAIN_DBMAP_AMAP { + u8 rsvd0[512]; /* DWORD 0 */ + struct BE_SQ_DB_AMAP rdma_sq_db; + u8 rsvd1[7][32]; /* DWORD 17 */ + struct BE_WRB_POST_DB_AMAP iscsi_wrb_post_db; + u8 rsvd2[7][32]; /* DWORD 25 */ + struct BE_SQ_DB_AMAP etx_sq_db; + u8 rsvd3[7][32]; /* DWORD 33 */ + struct BE_RQ_DB_AMAP rdma_rq_db; + u8 rsvd4[7][32]; /* DWORD 41 */ + struct BE_DEFAULT_PDU_DB_AMAP iscsi_default_pdu_db; + u8 rsvd5[7][32]; /* DWORD 49 */ + struct BE_TPM_RQ_DB_AMAP tpm_rq_db; + u8 rsvd6[7][32]; /* DWORD 57 */ + struct BE_RQ_DB_AMAP erx_rq_db; + u8 rsvd7[7][32]; /* DWORD 65 */ + struct BE_CQ_DB_AMAP cq_db; + u8 rsvd8[7][32]; /* DWORD 73 */ + struct BE_MCC_DB_AMAP mpu_mcc_db; + u8 rsvd9[7][32]; /* DWORD 81 */ + struct BE_MPU_MAILBOX_DB_AMAP mcc_bootstrap_db; + u8 rsvd10[935][32]; /* DWORD 89 */ +} __packed; +struct PROTECTION_DOMAIN_DBMAP_AMAP { + u32 dw[1024]; +}; + +#endif /* __doorbells_amap_h__ */ diff --git a/trunk/drivers/staging/benet/ep.h b/trunk/drivers/staging/benet/ep.h new file mode 100644 index 000000000000..72fcf64a9ffb --- /dev/null +++ b/trunk/drivers/staging/benet/ep.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __ep_amap_h__ +#define __ep_amap_h__ + +/* General Control and Status Register. */ +struct BE_EP_CONTROL_CSR_AMAP { + u8 m0_RxPbuf; /* DWORD 0 */ + u8 m1_RxPbuf; /* DWORD 0 */ + u8 m2_RxPbuf; /* DWORD 0 */ + u8 ff_en; /* DWORD 0 */ + u8 rsvd0[27]; /* DWORD 0 */ + u8 CPU_reset; /* DWORD 0 */ +} __packed; +struct EP_CONTROL_CSR_AMAP { + u32 dw[1]; +}; + +/* Semaphore Register. */ +struct BE_EP_SEMAPHORE_CSR_AMAP { + u8 value[32]; /* DWORD 0 */ +} __packed; +struct EP_SEMAPHORE_CSR_AMAP { + u32 dw[1]; +}; + +/* Embedded Processor Specific Registers. */ +struct BE_EP_CSRMAP_AMAP { + struct BE_EP_CONTROL_CSR_AMAP ep_control; + u8 rsvd0[32]; /* DWORD 1 */ + u8 rsvd1[32]; /* DWORD 2 */ + u8 rsvd2[32]; /* DWORD 3 */ + u8 rsvd3[32]; /* DWORD 4 */ + u8 rsvd4[32]; /* DWORD 5 */ + u8 rsvd5[8][128]; /* DWORD 6 */ + u8 rsvd6[32]; /* DWORD 38 */ + u8 rsvd7[32]; /* DWORD 39 */ + u8 rsvd8[32]; /* DWORD 40 */ + u8 rsvd9[32]; /* DWORD 41 */ + u8 rsvd10[32]; /* DWORD 42 */ + struct BE_EP_SEMAPHORE_CSR_AMAP ep_semaphore; + u8 rsvd11[32]; /* DWORD 44 */ + u8 rsvd12[19][32]; /* DWORD 45 */ +} __packed; +struct EP_CSRMAP_AMAP { + u32 dw[64]; +}; + +#endif /* __ep_amap_h__ */ diff --git a/trunk/drivers/staging/benet/eq.c b/trunk/drivers/staging/benet/eq.c new file mode 100644 index 000000000000..db92ccd8fed8 --- /dev/null +++ b/trunk/drivers/staging/benet/eq.c @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#include "hwlib.h" +#include "bestatus.h" +/* + This routine creates an event queue based on the client completion + queue configuration information. + + FunctionObject - Handle to a function object + EqBaseVa - Base VA for a the EQ ring + SizeEncoding - The encoded size for the EQ entries. This value is + either CEV_EQ_SIZE_4 or CEV_EQ_SIZE_16 + NumEntries - CEV_CQ_CNT_* values. + Watermark - Enables watermark based coalescing. This parameter + must be of the type CEV_WMARK_* if watermarks + are enabled. If watermarks to to be disabled + this value should be-1. + TimerDelay - If a timer delay is enabled this value should be the + time of the delay in 8 microsecond units. If + delays are not used this parameter should be + set to -1. + ppEqObject - Internal EQ Handle returned. + + Returns BE_SUCCESS if successfull,, otherwise a useful error code + is returned. + + IRQL < DISPATCH_LEVEL +*/ +int +be_eq_create(struct be_function_object *pfob, + struct ring_desc *rd, u32 eqe_size, u32 num_entries, + u32 watermark, /* CEV_WMARK_* or -1 */ + u32 timer_delay, /* in 8us units, or -1 */ + struct be_eq_object *eq_object) +{ + int status = BE_SUCCESS; + u32 num_entries_encoding, eqe_size_encoding, length; + struct FWCMD_COMMON_EQ_CREATE *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + u32 n; + unsigned long irql; + + ASSERT(rd); + ASSERT(eq_object); + + switch (num_entries) { + case 256: + num_entries_encoding = CEV_EQ_CNT_256; + break; + case 512: + num_entries_encoding = CEV_EQ_CNT_512; + break; + case 1024: + num_entries_encoding = CEV_EQ_CNT_1024; + break; + case 2048: + num_entries_encoding = CEV_EQ_CNT_2048; + break; + case 4096: + num_entries_encoding = CEV_EQ_CNT_4096; + break; + default: + ASSERT(0); + return BE_STATUS_INVALID_PARAMETER; + } + + switch (eqe_size) { + case 4: + eqe_size_encoding = CEV_EQ_SIZE_4; + break; + case 16: + eqe_size_encoding = CEV_EQ_SIZE_16; + break; + default: + ASSERT(0); + return BE_STATUS_INVALID_PARAMETER; + } + + if ((eqe_size == 4 && num_entries < 1024) || + (eqe_size == 16 && num_entries == 4096)) { + TRACE(DL_ERR, "Bad EQ size. eqe_size:%d num_entries:%d", + eqe_size, num_entries); + ASSERT(0); + return BE_STATUS_INVALID_PARAMETER; + } + + memset(eq_object, 0, sizeof(*eq_object)); + + atomic_set(&eq_object->ref_count, 0); + eq_object->parent_function = pfob; + eq_object->eq_id = 0xFFFFFFFF; + + INIT_LIST_HEAD(&eq_object->cq_list_head); + + length = num_entries * eqe_size; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + ASSERT(wrb); + TRACE(DL_ERR, "No free MCC WRBs in create EQ."); + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_EQ_CREATE); + + fwcmd->params.request.num_pages = PAGES_SPANNED(OFFSET_IN_PAGE(rd->va), + length); + n = pfob->pci_function_number; + AMAP_SET_BITS_PTR(EQ_CONTEXT, Func, &fwcmd->params.request.context, n); + + AMAP_SET_BITS_PTR(EQ_CONTEXT, valid, &fwcmd->params.request.context, 1); + + AMAP_SET_BITS_PTR(EQ_CONTEXT, Size, + &fwcmd->params.request.context, eqe_size_encoding); + + n = 0; /* Protection Domain is always 0 in Linux driver */ + AMAP_SET_BITS_PTR(EQ_CONTEXT, PD, &fwcmd->params.request.context, n); + + /* Let the caller ARM the EQ with the doorbell. */ + AMAP_SET_BITS_PTR(EQ_CONTEXT, Armed, &fwcmd->params.request.context, 0); + + AMAP_SET_BITS_PTR(EQ_CONTEXT, Count, &fwcmd->params.request.context, + num_entries_encoding); + + n = pfob->pci_function_number * 32; + AMAP_SET_BITS_PTR(EQ_CONTEXT, EventVect, + &fwcmd->params.request.context, n); + if (watermark != -1) { + AMAP_SET_BITS_PTR(EQ_CONTEXT, WME, + &fwcmd->params.request.context, 1); + AMAP_SET_BITS_PTR(EQ_CONTEXT, Watermark, + &fwcmd->params.request.context, watermark); + ASSERT(watermark <= CEV_WMARK_240); + } else + AMAP_SET_BITS_PTR(EQ_CONTEXT, WME, + &fwcmd->params.request.context, 0); + if (timer_delay != -1) { + AMAP_SET_BITS_PTR(EQ_CONTEXT, TMR, + &fwcmd->params.request.context, 1); + + ASSERT(timer_delay <= 250); /* max value according to EAS */ + timer_delay = min(timer_delay, (u32)250); + + AMAP_SET_BITS_PTR(EQ_CONTEXT, Delay, + &fwcmd->params.request.context, timer_delay); + } else { + AMAP_SET_BITS_PTR(EQ_CONTEXT, TMR, + &fwcmd->params.request.context, 0); + } + /* Create a page list for the FWCMD. */ + be_rd_to_pa_list(rd, fwcmd->params.request.pages, + ARRAY_SIZE(fwcmd->params.request.pages)); + + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "MCC to create EQ failed."); + goto Error; + } + /* Get the EQ id. The MPU allocates the IDs. */ + eq_object->eq_id = fwcmd->params.response.eq_id; + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + Deferences the given object. Once the object's reference count drops to + zero, the object is destroyed and all resources that are held by this + object are released. The on-chip context is also destroyed along with + the queue ID, and any mappings made into the UT. + + eq_object - EQ handle returned from eq_object_create. + + Returns BE_SUCCESS if successfull, otherwise a useful error code + is returned. + + IRQL: IRQL < DISPATCH_LEVEL +*/ +int be_eq_destroy(struct be_eq_object *eq_object) +{ + int status = 0; + + ASSERT(atomic_read(&eq_object->ref_count) == 0); + /* no CQs should reference this EQ now */ + ASSERT(list_empty(&eq_object->cq_list_head)); + + /* Send fwcmd to destroy the EQ. */ + status = be_function_ring_destroy(eq_object->parent_function, + eq_object->eq_id, FWCMD_RING_TYPE_EQ, + NULL, NULL, NULL, NULL); + ASSERT(status == 0); + + return BE_SUCCESS; +} +/* + *--------------------------------------------------------------------------- + * Function: be_eq_modify_delay + * Changes the EQ delay for a group of EQs. + * num_eq - The number of EQs in the eq_array to adjust. + * This also is the number of delay values in + * the eq_delay_array. + * eq_array - Array of struct be_eq_object pointers to adjust. + * eq_delay_array - Array of "num_eq" timer delays in units + * of microseconds. The be_eq_query_delay_range + * fwcmd returns the resolution and range of + * legal EQ delays. + * cb - + * cb_context - + * q_ctxt - Optional. Pointer to a previously allocated + * struct. If the MCC WRB ring is full, this + * structure is used to queue the operation. It + * will be posted to the MCC ring when space + * becomes available. All queued commands will + * be posted to the ring in the order they are + * received. It is always valid to pass a pointer to + * a generic be_generic_q_cntxt. However, + * the specific context structs + * are generally smaller than the generic struct. + * return pend_status - BE_SUCCESS (0) on success. + * BE_PENDING (postive value) if the FWCMD + * completion is pending. Negative error code on failure. + *------------------------------------------------------------------------- + */ +int +be_eq_modify_delay(struct be_function_object *pfob, + u32 num_eq, struct be_eq_object **eq_array, + u32 *eq_delay_array, mcc_wrb_cqe_callback cb, + void *cb_context, struct be_eq_modify_delay_q_ctxt *q_ctxt) +{ + struct FWCMD_COMMON_MODIFY_EQ_DELAY *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + struct be_generic_q_ctxt *gen_ctxt = NULL; + u32 i; + unsigned long irql; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + if (q_ctxt && cb) { + wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; + gen_ctxt = (struct be_generic_q_ctxt *) q_ctxt; + gen_ctxt->context.bytes = sizeof(*q_ctxt); + } else { + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_MODIFY_EQ_DELAY); + + ASSERT(num_eq > 0); + ASSERT(num_eq <= ARRAY_SIZE(fwcmd->params.request.delay)); + fwcmd->params.request.num_eq = num_eq; + for (i = 0; i < num_eq; i++) { + fwcmd->params.request.delay[i].eq_id = eq_array[i]->eq_id; + fwcmd->params.request.delay[i].delay_in_microseconds = + eq_delay_array[i]; + } + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, gen_ctxt, + cb, cb_context, NULL, NULL, fwcmd, NULL); + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + diff --git a/trunk/drivers/staging/benet/eth.c b/trunk/drivers/staging/benet/eth.c new file mode 100644 index 000000000000..f641b6260d07 --- /dev/null +++ b/trunk/drivers/staging/benet/eth.c @@ -0,0 +1,1273 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#include +#include "hwlib.h" +#include "bestatus.h" + +/* + *--------------------------------------------------------- + * Function: be_eth_sq_create_ex + * Creates an ethernet send ring - extended version with + * additional parameters. + * pfob - + * rd - ring address + * length_in_bytes - + * type - The type of ring to create. + * ulp - The requested ULP number for the ring. + * This should be zero based, i.e. 0,1,2. This must + * be valid NIC ULP based on the firmware config. + * All doorbells for this ring must be sent to + * this ULP. The first network ring allocated for + * each ULP are higher performance than subsequent rings. + * cq_object - cq object for completions + * ex_parameters - Additional parameters (that may increase in + * future revisions). These parameters are only used + * for certain ring types -- see + * struct be_eth_sq_parameters for details. + * eth_sq - + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *--------------------------------------------------------- + */ +int +be_eth_sq_create_ex(struct be_function_object *pfob, struct ring_desc *rd, + u32 length, u32 type, u32 ulp, struct be_cq_object *cq_object, + struct be_eth_sq_parameters *ex_parameters, + struct be_ethsq_object *eth_sq) +{ + struct FWCMD_COMMON_ETH_TX_CREATE *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + u32 n; + unsigned long irql; + + ASSERT(rd); + ASSERT(eth_sq); + ASSERT(ex_parameters); + + spin_lock_irqsave(&pfob->post_lock, irql); + + memset(eth_sq, 0, sizeof(*eth_sq)); + + eth_sq->parent_function = pfob; + eth_sq->bid = 0xFFFFFFFF; + eth_sq->cq_object = cq_object; + + /* Translate hwlib interface to arm interface. */ + switch (type) { + case BE_ETH_TX_RING_TYPE_FORWARDING: + type = ETH_TX_RING_TYPE_FORWARDING; + break; + case BE_ETH_TX_RING_TYPE_STANDARD: + type = ETH_TX_RING_TYPE_STANDARD; + break; + case BE_ETH_TX_RING_TYPE_BOUND: + ASSERT(ex_parameters->port < 2); + type = ETH_TX_RING_TYPE_BOUND; + break; + default: + TRACE(DL_ERR, "Invalid eth tx ring type:%d", type); + return BE_NOT_OK; + break; + } + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + ASSERT(wrb); + TRACE(DL_ERR, "No free MCC WRBs in create EQ."); + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + /* NIC must be supported by the current config. */ + ASSERT(pfob->fw_config.nic_ulp_mask); + + /* + * The ulp parameter must select a valid NIC ULP + * for the current config. + */ + ASSERT((1 << ulp) & pfob->fw_config.nic_ulp_mask); + + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_TX_CREATE); + fwcmd->header.request.port_number = ex_parameters->port; + + AMAP_SET_BITS_PTR(ETX_CONTEXT, pd_id, + &fwcmd->params.request.context, 0); + + n = be_ring_length_to_encoding(length, sizeof(struct ETH_WRB_AMAP)); + AMAP_SET_BITS_PTR(ETX_CONTEXT, tx_ring_size, + &fwcmd->params.request.context, n); + + AMAP_SET_BITS_PTR(ETX_CONTEXT, cq_id_send, + &fwcmd->params.request.context, cq_object->cq_id); + + n = pfob->pci_function_number; + AMAP_SET_BITS_PTR(ETX_CONTEXT, func, &fwcmd->params.request.context, n); + + fwcmd->params.request.type = type; + fwcmd->params.request.ulp_num = (1 << ulp); + fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE); + ASSERT(PAGES_SPANNED(rd->va, rd->length) >= + fwcmd->params.request.num_pages); + + /* Create a page list for the FWCMD. */ + be_rd_to_pa_list(rd, fwcmd->params.request.pages, + ARRAY_SIZE(fwcmd->params.request.pages)); + + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "MCC to create etx queue failed."); + goto Error; + } + /* save the butler ID */ + eth_sq->bid = fwcmd->params.response.cid; + + /* add a reference to the corresponding CQ */ + atomic_inc(&cq_object->ref_count); + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + + +/* + This routine destroys an ethernet send queue + + EthSq - EthSq Handle returned from EthSqCreate + + This function always return BE_SUCCESS. + + This function frees memory allocated by EthSqCreate for the EthSq Object. + +*/ +int be_eth_sq_destroy(struct be_ethsq_object *eth_sq) +{ + int status = 0; + + /* Send fwcmd to destroy the queue. */ + status = be_function_ring_destroy(eth_sq->parent_function, eth_sq->bid, + FWCMD_RING_TYPE_ETH_TX, NULL, NULL, NULL, NULL); + ASSERT(status == 0); + + /* Derefence any associated CQs. */ + atomic_dec(ð_sq->cq_object->ref_count); + return status; +} +/* + This routine attempts to set the transmit flow control parameters. + + FunctionObject - Handle to a function object + + txfc_enable - transmit flow control enable - true for + enable, false for disable + + rxfc_enable - receive flow control enable - true for + enable, false for disable + + Returns BE_SUCCESS if successfull, otherwise a useful int error + code is returned. + + IRQL: < DISPATCH_LEVEL + + This function always fails in non-privileged machine context. +*/ +int +be_eth_set_flow_control(struct be_function_object *pfob, + bool txfc_enable, bool rxfc_enable) +{ + struct FWCMD_COMMON_SET_FLOW_CONTROL *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FLOW_CONTROL); + + fwcmd->params.request.rx_flow_control = rxfc_enable; + fwcmd->params.request.tx_flow_control = txfc_enable; + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + + if (status != 0) { + TRACE(DL_ERR, "set flow control fwcmd failed."); + goto error; + } + +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + This routine attempts to get the transmit flow control parameters. + + pfob - Handle to a function object + + txfc_enable - transmit flow control enable - true for + enable, false for disable + + rxfc_enable - receive flow control enable - true for enable, + false for disable + + Returns BE_SUCCESS if successfull, otherwise a useful int error code + is returned. + + IRQL: < DISPATCH_LEVEL + + This function always fails in non-privileged machine context. +*/ +int +be_eth_get_flow_control(struct be_function_object *pfob, + bool *txfc_enable, bool *rxfc_enable) +{ + struct FWCMD_COMMON_GET_FLOW_CONTROL *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FLOW_CONTROL); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + + if (status != 0) { + TRACE(DL_ERR, "get flow control fwcmd failed."); + goto error; + } + + *txfc_enable = fwcmd->params.response.tx_flow_control; + *rxfc_enable = fwcmd->params.response.rx_flow_control; + +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + *--------------------------------------------------------- + * Function: be_eth_set_qos + * This function sets the ethernet transmit Quality of Service (QoS) + * characteristics of BladeEngine for the domain. All ethernet + * transmit rings of the domain will evenly share the bandwidth. + * The exeception to sharing is the host primary (super) ethernet + * transmit ring as well as the host ethernet forwarding ring + * for missed offload data. + * pfob - + * max_bps - the maximum bits per second in units of + * 10 Mbps (valid 0-100) + * max_pps - the maximum packets per second in units + * of 1 Kpps (0 indicates no limit) + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *--------------------------------------------------------- + */ +int +be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps) +{ + struct FWCMD_COMMON_SET_QOS *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_QOS); + + /* Set fields in fwcmd */ + fwcmd->params.request.max_bits_per_second_NIC = max_bps; + fwcmd->params.request.max_packets_per_second_NIC = max_pps; + fwcmd->params.request.valid_flags = QOS_BITS_NIC | QOS_PKTS_NIC; + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + + if (status != 0) + TRACE(DL_ERR, "network set qos fwcmd failed."); + +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + *--------------------------------------------------------- + * Function: be_eth_get_qos + * This function retrieves the ethernet transmit Quality of Service (QoS) + * characteristics for the domain. + * max_bps - the maximum bits per second in units of + * 10 Mbps (valid 0-100) + * max_pps - the maximum packets per second in units of + * 1 Kpps (0 indicates no limit) + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *--------------------------------------------------------- + */ +int +be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps) +{ + struct FWCMD_COMMON_GET_QOS *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_QOS); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + + if (status != 0) { + TRACE(DL_ERR, "network get qos fwcmd failed."); + goto error; + } + + *max_bps = fwcmd->params.response.max_bits_per_second_NIC; + *max_pps = fwcmd->params.response.max_packets_per_second_NIC; + +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + *--------------------------------------------------------- + * Function: be_eth_set_frame_size + * This function sets the ethernet maximum frame size. The previous + * values are returned. + * pfob - + * tx_frame_size - maximum transmit frame size in bytes + * rx_frame_size - maximum receive frame size in bytes + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *--------------------------------------------------------- + */ +int +be_eth_set_frame_size(struct be_function_object *pfob, + u32 *tx_frame_size, u32 *rx_frame_size) +{ + struct FWCMD_COMMON_SET_FRAME_SIZE *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FRAME_SIZE); + fwcmd->params.request.max_tx_frame_size = *tx_frame_size; + fwcmd->params.request.max_rx_frame_size = *rx_frame_size; + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + + if (status != 0) { + TRACE(DL_ERR, "network set frame size fwcmd failed."); + goto error; + } + + *tx_frame_size = fwcmd->params.response.chip_max_tx_frame_size; + *rx_frame_size = fwcmd->params.response.chip_max_rx_frame_size; + +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + + +/* + This routine creates a Ethernet receive ring. + + pfob - handle to a function object + rq_base_va - base VA for the default receive ring. this must be + exactly 8K in length and continguous physical memory. + cq_object - handle to a previously created CQ to be associated + with the RQ. + pp_eth_rq - pointer to an opqaue handle where an eth + receive object is returned. + Returns BE_SUCCESS if successfull, , otherwise a useful + int error code is returned. + + IRQL: < DISPATCH_LEVEL + this function allocates a struct be_ethrq_object *object. + there must be no more than 1 of these per function object, unless the + function object supports RSS (is networking and on the host). + the rq_base_va must point to a buffer of exactly 8K. + the erx::host_cqid (or host_stor_cqid) register and erx::ring_page registers + will be updated as appropriate on return +*/ +int +be_eth_rq_create(struct be_function_object *pfob, + struct ring_desc *rd, struct be_cq_object *cq_object, + struct be_cq_object *bcmc_cq_object, + struct be_ethrq_object *eth_rq) +{ + int status = 0; + struct MCC_WRB_AMAP *wrb = NULL; + struct FWCMD_COMMON_ETH_RX_CREATE *fwcmd = NULL; + unsigned long irql; + + /* MPU will set the */ + ASSERT(rd); + ASSERT(eth_rq); + + spin_lock_irqsave(&pfob->post_lock, irql); + + eth_rq->parent_function = pfob; + eth_rq->cq_object = cq_object; + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_RX_CREATE); + + fwcmd->params.request.num_pages = 2; /* required length */ + fwcmd->params.request.cq_id = cq_object->cq_id; + + if (bcmc_cq_object) + fwcmd->params.request.bcmc_cq_id = bcmc_cq_object->cq_id; + else + fwcmd->params.request.bcmc_cq_id = 0xFFFF; + + /* Create a page list for the FWCMD. */ + be_rd_to_pa_list(rd, fwcmd->params.request.pages, + ARRAY_SIZE(fwcmd->params.request.pages)); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "fwcmd to map eth rxq frags failed."); + goto Error; + } + /* Save the ring ID for cleanup. */ + eth_rq->rid = fwcmd->params.response.id; + + atomic_inc(&cq_object->ref_count); + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + This routine destroys an Ethernet receive queue + + eth_rq - ethernet receive queue handle returned from eth_rq_create + + Returns BE_SUCCESS on success and an appropriate int on failure. + + This function frees resourcs allocated by EthRqCreate. + The erx::host_cqid (or host_stor_cqid) register and erx::ring_page + registers will be updated as appropriate on return + IRQL: < DISPATCH_LEVEL +*/ + +static void be_eth_rq_destroy_internal_cb(void *context, int status, + struct MCC_WRB_AMAP *wrb) +{ + struct be_ethrq_object *eth_rq = (struct be_ethrq_object *) context; + + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "Destroy eth rq failed in internal callback.\n"); + } else { + /* Dereference any CQs associated with this queue. */ + atomic_dec(ð_rq->cq_object->ref_count); + } + + return; +} + +int be_eth_rq_destroy(struct be_ethrq_object *eth_rq) +{ + int status = BE_SUCCESS; + + /* Send fwcmd to destroy the RQ. */ + status = be_function_ring_destroy(eth_rq->parent_function, + eth_rq->rid, FWCMD_RING_TYPE_ETH_RX, NULL, NULL, + be_eth_rq_destroy_internal_cb, eth_rq); + + return status; +} + +/* + *--------------------------------------------------------------------------- + * Function: be_eth_rq_destroy_options + * Destroys an ethernet receive ring with finer granularity options + * than the standard be_eth_rq_destroy() API function. + * eth_rq - + * flush - Set to 1 to flush the ring, set to 0 to bypass the flush + * cb - Callback function on completion + * cb_context - Callback context + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *---------------------------------------------------------------------------- + */ +int +be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush, + mcc_wrb_cqe_callback cb, void *cb_context) +{ + struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = BE_SUCCESS; + struct be_function_object *pfob = NULL; + unsigned long irql; + + pfob = eth_rq->parent_function; + + spin_lock_irqsave(&pfob->post_lock, irql); + + TRACE(DL_INFO, "Destroy eth_rq ring id:%d, flush:%d", eth_rq->rid, + flush); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + ASSERT(wrb); + TRACE(DL_ERR, "No free MCC WRBs in destroy eth_rq ring."); + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY); + + fwcmd->params.request.id = eth_rq->rid; + fwcmd->params.request.ring_type = FWCMD_RING_TYPE_ETH_RX; + fwcmd->params.request.bypass_flush = ((0 == flush) ? 1 : 0); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context, + be_eth_rq_destroy_internal_cb, eth_rq, fwcmd, NULL); + + if (status != BE_SUCCESS && status != BE_PENDING) { + TRACE(DL_ERR, "eth_rq ring destroy failed. id:%d, flush:%d", + eth_rq->rid, flush); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + This routine queries the frag size for erx. + + pfob - handle to a function object + + frag_size_bytes - erx frag size in bytes that is/was set. + + Returns BE_SUCCESS if successfull, otherwise a useful int error + code is returned. + + IRQL: < DISPATCH_LEVEL + +*/ +int +be_eth_rq_get_frag_size(struct be_function_object *pfob, u32 *frag_size_bytes) +{ + struct FWCMD_ETH_GET_RX_FRAG_SIZE *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + + ASSERT(frag_size_bytes); + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + return BE_STATUS_NO_MCC_WRB; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_GET_RX_FRAG_SIZE); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + + if (status != 0) { + TRACE(DL_ERR, "get frag size fwcmd failed."); + goto error; + } + + *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2; + +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + This routine attempts to set the frag size for erx. If the frag size is + already set, the attempt fails and the current frag size is returned. + + pfob - Handle to a function object + + frag_size - Erx frag size in bytes that is/was set. + + current_frag_size_bytes - Pointer to location where currrent frag + is to be rturned + + Returns BE_SUCCESS if successfull, otherwise a useful int error + code is returned. + + IRQL: < DISPATCH_LEVEL + + This function always fails in non-privileged machine context. +*/ +int +be_eth_rq_set_frag_size(struct be_function_object *pfob, + u32 frag_size, u32 *frag_size_bytes) +{ + struct FWCMD_ETH_SET_RX_FRAG_SIZE *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + + ASSERT(frag_size_bytes); + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_SET_RX_FRAG_SIZE); + + ASSERT(frag_size >= 128 && frag_size <= 16 * 1024); + + /* This is the log2 of the fragsize. This is not the exact + * ERX encoding. */ + fwcmd->params.request.new_fragsize_log2 = __ilog2_u32(frag_size); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + + if (status != 0) { + TRACE(DL_ERR, "set frag size fwcmd failed."); + goto error; + } + + *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2; +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + + +/* + This routine gets or sets a mac address for a domain + given the port and mac. + + FunctionObject - Function object handle. + port1 - Set to TRUE if this function will set/get the Port 1 + address. Only the host may set this to TRUE. + mac1 - Set to TRUE if this function will set/get the + MAC 1 address. Only the host may set this to TRUE. + write - Set to TRUE if this function should write the mac address. + mac_address - Buffer of the mac address to read or write. + + Returns BE_SUCCESS if successfull, otherwise a useful int is returned. + + IRQL: < DISPATCH_LEVEL +*/ +int be_rxf_mac_address_read_write(struct be_function_object *pfob, + bool port1, /* VM must always set to false */ + bool mac1, /* VM must always set to false */ + bool mgmt, bool write, + bool permanent, u8 *mac_address, + mcc_wrb_cqe_callback cb, /* optional */ + void *cb_context) /* optional */ +{ + int status = BE_SUCCESS; + union { + struct FWCMD_COMMON_NTWK_MAC_QUERY *query; + struct FWCMD_COMMON_NTWK_MAC_SET *set; + } fwcmd = {NULL}; + struct MCC_WRB_AMAP *wrb = NULL; + u32 type = 0; + unsigned long irql; + struct be_mcc_wrb_response_copy rc; + + spin_lock_irqsave(&pfob->post_lock, irql); + + ASSERT(mac_address); + + ASSERT(port1 == false); + ASSERT(mac1 == false); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + + if (mgmt) { + type = MAC_ADDRESS_TYPE_MANAGEMENT; + } else { + if (pfob->type == BE_FUNCTION_TYPE_NETWORK) + type = MAC_ADDRESS_TYPE_NETWORK; + else + type = MAC_ADDRESS_TYPE_STORAGE; + } + + if (write) { + /* Prepares an embedded fwcmd, including + * request/response sizes. + */ + fwcmd.set = BE_PREPARE_EMBEDDED_FWCMD(pfob, + wrb, COMMON_NTWK_MAC_SET); + + fwcmd.set->params.request.invalidate = 0; + fwcmd.set->params.request.mac1 = (mac1 ? 1 : 0); + fwcmd.set->params.request.port = (port1 ? 1 : 0); + fwcmd.set->params.request.type = type; + + /* Copy the mac address to set. */ + fwcmd.set->params.request.mac.SizeOfStructure = + sizeof(fwcmd.set->params.request.mac); + memcpy(fwcmd.set->params.request.mac.MACAddress, + mac_address, ETH_ALEN); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, + cb, cb_context, NULL, NULL, fwcmd.set, NULL); + + } else { + + /* + * Prepares an embedded fwcmd, including + * request/response sizes. + */ + fwcmd.query = BE_PREPARE_EMBEDDED_FWCMD(pfob, + wrb, COMMON_NTWK_MAC_QUERY); + + fwcmd.query->params.request.mac1 = (mac1 ? 1 : 0); + fwcmd.query->params.request.port = (port1 ? 1 : 0); + fwcmd.query->params.request.type = type; + fwcmd.query->params.request.permanent = permanent; + + rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_MAC_QUERY, + params.response.mac.MACAddress); + rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_MAC_QUERY, + params.response.mac.MACAddress); + rc.va = mac_address; + /* Post the f/w command (with a copy for the response) */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, + cb_context, NULL, NULL, fwcmd.query, &rc); + } + + if (status < 0) { + TRACE(DL_ERR, "mac set/query failed."); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + This routine writes data to context memory. + + pfob - Function object handle. + mac_table - Set to the 128-bit multicast address hash table. + + Returns BE_SUCCESS if successfull, otherwise a useful int is returned. + + IRQL: < DISPATCH_LEVEL +*/ + +int be_rxf_multicast_config(struct be_function_object *pfob, + bool promiscuous, u32 num, u8 *mac_table, + mcc_wrb_cqe_callback cb, /* optional */ + void *cb_context, + struct be_multicast_q_ctxt *q_ctxt) +{ + int status = BE_SUCCESS; + struct FWCMD_COMMON_NTWK_MULTICAST_SET *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + struct be_generic_q_ctxt *generic_ctxt = NULL; + unsigned long irql; + + ASSERT(num <= ARRAY_SIZE(fwcmd->params.request.mac)); + + if (num > ARRAY_SIZE(fwcmd->params.request.mac)) { + TRACE(DL_ERR, "Too many multicast addresses. BE supports %d.", + (int) ARRAY_SIZE(fwcmd->params.request.mac)); + return BE_NOT_OK; + } + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + if (q_ctxt && cb) { + wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; + generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; + generic_ctxt->context.bytes = sizeof(*q_ctxt); + } else { + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_MULTICAST_SET); + + fwcmd->params.request.promiscuous = promiscuous; + if (!promiscuous) { + fwcmd->params.request.num_mac = num; + if (num > 0) { + ASSERT(mac_table); + memcpy(fwcmd->params.request.mac, + mac_table, ETH_ALEN * num); + } + } + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, + cb, cb_context, NULL, NULL, fwcmd, NULL); + if (status < 0) { + TRACE(DL_ERR, "multicast fwcmd failed."); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + This routine adds or removes a vlan tag from the rxf table. + + FunctionObject - Function object handle. + VLanTag - VLan tag to add or remove. + Add - Set to TRUE if this will add a vlan tag + + Returns BE_SUCCESS if successfull, otherwise a useful int is returned. + + IRQL: < DISPATCH_LEVEL +*/ +int be_rxf_vlan_config(struct be_function_object *pfob, + bool promiscuous, u32 num, u16 *vlan_tag_array, + mcc_wrb_cqe_callback cb, /* optional */ + void *cb_context, + struct be_vlan_q_ctxt *q_ctxt) /* optional */ +{ + int status = BE_SUCCESS; + struct FWCMD_COMMON_NTWK_VLAN_CONFIG *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + struct be_generic_q_ctxt *generic_ctxt = NULL; + unsigned long irql; + + if (num > ARRAY_SIZE(fwcmd->params.request.vlan_tag)) { + TRACE(DL_ERR, "Too many VLAN tags."); + return BE_NOT_OK; + } + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + if (q_ctxt && cb) { + wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; + generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; + generic_ctxt->context.bytes = sizeof(*q_ctxt); + } else { + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_VLAN_CONFIG); + + fwcmd->params.request.promiscuous = promiscuous; + if (!promiscuous) { + fwcmd->params.request.num_vlan = num; + + if (num > 0) { + ASSERT(vlan_tag_array); + memcpy(fwcmd->params.request.vlan_tag, vlan_tag_array, + num * sizeof(vlan_tag_array[0])); + } + } + + /* Post the commadn */ + status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, + cb, cb_context, NULL, NULL, fwcmd, NULL); + if (status < 0) { + TRACE(DL_ERR, "vlan fwcmd failed."); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + + +int be_rxf_link_status(struct be_function_object *pfob, + struct BE_LINK_STATUS *link_status, + mcc_wrb_cqe_callback cb, + void *cb_context, + struct be_link_status_q_ctxt *q_ctxt) +{ + struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + struct be_generic_q_ctxt *generic_ctxt = NULL; + unsigned long irql; + struct be_mcc_wrb_response_copy rc; + + ASSERT(link_status); + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + + if (!wrb) { + if (q_ctxt && cb) { + wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; + generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; + generic_ctxt->context.bytes = sizeof(*q_ctxt); + } else { + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, + COMMON_NTWK_LINK_STATUS_QUERY); + + rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY, + params.response); + rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY, + params.response); + rc.va = link_status; + /* Post or queue the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, + cb, cb_context, NULL, NULL, fwcmd, &rc); + + if (status < 0) { + TRACE(DL_ERR, "link status fwcmd failed."); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +int +be_rxf_query_eth_statistics(struct be_function_object *pfob, + struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd, + u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb, + void *cb_context, + struct be_nonembedded_q_ctxt *q_ctxt) +{ + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + struct be_generic_q_ctxt *generic_ctxt = NULL; + unsigned long irql; + + ASSERT(va_for_fwcmd); + ASSERT(pa_for_fwcmd); + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + + if (!wrb) { + if (q_ctxt && cb) { + wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; + generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; + generic_ctxt->context.bytes = sizeof(*q_ctxt); + } else { + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + } + + TRACE(DL_INFO, "Query eth stats. fwcmd va:%p pa:0x%08x_%08x", + va_for_fwcmd, upper_32_bits(pa_for_fwcmd), (u32)pa_for_fwcmd); + + /* Prepares an embedded fwcmd, including request/response sizes. */ + va_for_fwcmd = BE_PREPARE_NONEMBEDDED_FWCMD(pfob, wrb, + va_for_fwcmd, pa_for_fwcmd, ETH_GET_STATISTICS); + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, + cb, cb_context, NULL, NULL, va_for_fwcmd, NULL); + if (status < 0) { + TRACE(DL_ERR, "eth stats fwcmd failed."); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +int +be_rxf_promiscuous(struct be_function_object *pfob, + bool enable_port0, bool enable_port1, + mcc_wrb_cqe_callback cb, void *cb_context, + struct be_promiscuous_q_ctxt *q_ctxt) +{ + struct FWCMD_ETH_PROMISCUOUS *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + struct be_generic_q_ctxt *generic_ctxt = NULL; + unsigned long irql; + + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + + if (!wrb) { + if (q_ctxt && cb) { + wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; + generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; + generic_ctxt->context.bytes = sizeof(*q_ctxt); + } else { + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_PROMISCUOUS); + + fwcmd->params.request.port0_promiscuous = enable_port0; + fwcmd->params.request.port1_promiscuous = enable_port1; + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, + cb, cb_context, NULL, NULL, fwcmd, NULL); + + if (status < 0) { + TRACE(DL_ERR, "promiscuous fwcmd failed."); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + + +/* + *------------------------------------------------------------------------- + * Function: be_rxf_filter_config + * Configures BladeEngine ethernet receive filter settings. + * pfob - + * settings - Pointer to the requested filter settings. + * The response from BladeEngine will be placed back + * in this structure. + * cb - optional + * cb_context - optional + * q_ctxt - Optional. Pointer to a previously allocated struct. + * If the MCC WRB ring is full, this structure is + * used to queue the operation. It will be posted + * to the MCC ring when space becomes available. All + * queued commands will be posted to the ring in + * the order they are received. It is always valid + * to pass a pointer to a generic + * be_generic_q_ctxt. However, the specific + * context structs are generally smaller than + * the generic struct. + * return pend_status - BE_SUCCESS (0) on success. + * BE_PENDING (postive value) if the FWCMD + * completion is pending. Negative error code on failure. + *--------------------------------------------------------------------------- + */ +int +be_rxf_filter_config(struct be_function_object *pfob, + struct NTWK_RX_FILTER_SETTINGS *settings, + mcc_wrb_cqe_callback cb, void *cb_context, + struct be_rxf_filter_q_ctxt *q_ctxt) +{ + struct FWCMD_COMMON_NTWK_RX_FILTER *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + struct be_generic_q_ctxt *generic_ctxt = NULL; + unsigned long irql; + struct be_mcc_wrb_response_copy rc; + + ASSERT(settings); + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + + if (!wrb) { + if (q_ctxt && cb) { + wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; + generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; + generic_ctxt->context.bytes = sizeof(*q_ctxt); + } else { + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_RX_FILTER); + memcpy(&fwcmd->params.request, settings, sizeof(*settings)); + + rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_RX_FILTER, + params.response); + rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_RX_FILTER, + params.response); + rc.va = settings; + /* Post or queue the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, + cb, cb_context, NULL, NULL, fwcmd, &rc); + + if (status < 0) { + TRACE(DL_ERR, "RXF/ERX filter config fwcmd failed."); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} diff --git a/trunk/drivers/staging/benet/etx_context.h b/trunk/drivers/staging/benet/etx_context.h new file mode 100644 index 000000000000..554fbe5d127b --- /dev/null +++ b/trunk/drivers/staging/benet/etx_context.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __etx_context_amap_h__ +#define __etx_context_amap_h__ + +/* ETX ring context structure. */ +struct BE_ETX_CONTEXT_AMAP { + u8 tx_cidx[11]; /* DWORD 0 */ + u8 rsvd0[5]; /* DWORD 0 */ + u8 rsvd1[16]; /* DWORD 0 */ + u8 tx_pidx[11]; /* DWORD 1 */ + u8 rsvd2; /* DWORD 1 */ + u8 tx_ring_size[4]; /* DWORD 1 */ + u8 pd_id[5]; /* DWORD 1 */ + u8 pd_id_not_valid; /* DWORD 1 */ + u8 cq_id_send[10]; /* DWORD 1 */ + u8 rsvd3[32]; /* DWORD 2 */ + u8 rsvd4[32]; /* DWORD 3 */ + u8 cur_bytes[32]; /* DWORD 4 */ + u8 max_bytes[32]; /* DWORD 5 */ + u8 time_stamp[32]; /* DWORD 6 */ + u8 rsvd5[11]; /* DWORD 7 */ + u8 func; /* DWORD 7 */ + u8 rsvd6[20]; /* DWORD 7 */ + u8 cur_txd_count[32]; /* DWORD 8 */ + u8 max_txd_count[32]; /* DWORD 9 */ + u8 rsvd7[32]; /* DWORD 10 */ + u8 rsvd8[32]; /* DWORD 11 */ + u8 rsvd9[32]; /* DWORD 12 */ + u8 rsvd10[32]; /* DWORD 13 */ + u8 rsvd11[32]; /* DWORD 14 */ + u8 rsvd12[32]; /* DWORD 15 */ +} __packed; +struct ETX_CONTEXT_AMAP { + u32 dw[16]; +}; + +#endif /* __etx_context_amap_h__ */ diff --git a/trunk/drivers/staging/benet/funcobj.c b/trunk/drivers/staging/benet/funcobj.c new file mode 100644 index 000000000000..0f57eb58daef --- /dev/null +++ b/trunk/drivers/staging/benet/funcobj.c @@ -0,0 +1,565 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#include "hwlib.h" +#include "bestatus.h" + + +int +be_function_internal_query_firmware_config(struct be_function_object *pfob, + struct BE_FIRMWARE_CONFIG *config) +{ + struct FWCMD_COMMON_FIRMWARE_CONFIG *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + struct be_mcc_wrb_response_copy rc; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_FIRMWARE_CONFIG); + + rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_FIRMWARE_CONFIG, + params.response); + rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_FIRMWARE_CONFIG, + params.response); + rc.va = config; + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, + NULL, NULL, NULL, fwcmd, &rc); +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + This allocates and initializes a function object based on the information + provided by upper layer drivers. + + Returns BE_SUCCESS on success and an appropriate int on failure. + + A function object represents a single BladeEngine (logical) PCI function. + That is a function object either represents + the networking side of BladeEngine or the iSCSI side of BladeEngine. + + This routine will also detect and create an appropriate PD object for the + PCI function as needed. +*/ +int +be_function_object_create(u8 __iomem *csr_va, u8 __iomem *db_va, + u8 __iomem *pci_va, u32 function_type, + struct ring_desc *mailbox, struct be_function_object *pfob) +{ + int status; + + ASSERT(pfob); /* not a magic assert */ + ASSERT(function_type <= 2); + + TRACE(DL_INFO, "Create function object. type:%s object:0x%p", + (function_type == BE_FUNCTION_TYPE_ISCSI ? "iSCSI" : + (function_type == BE_FUNCTION_TYPE_NETWORK ? "Network" : + "Arm")), pfob); + + memset(pfob, 0, sizeof(*pfob)); + + pfob->type = function_type; + pfob->csr_va = csr_va; + pfob->db_va = db_va; + pfob->pci_va = pci_va; + + spin_lock_init(&pfob->cq_lock); + spin_lock_init(&pfob->post_lock); + spin_lock_init(&pfob->mcc_context_lock); + + + pfob->pci_function_number = 1; + + + pfob->emulate = false; + TRACE(DL_NOTE, "Non-emulation mode"); + status = be_drive_POST(pfob); + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "BladeEngine POST failed."); + goto error; + } + + /* Initialize the mailbox */ + status = be_mpu_init_mailbox(pfob, mailbox); + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "Failed to initialize mailbox."); + goto error; + } + /* + * Cache the firmware config for ASSERTs in hwclib and later + * driver queries. + */ + status = be_function_internal_query_firmware_config(pfob, + &pfob->fw_config); + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "Failed to query firmware config."); + goto error; + } + +error: + if (status != BE_SUCCESS) { + /* No cleanup necessary */ + TRACE(DL_ERR, "Failed to create function."); + memset(pfob, 0, sizeof(*pfob)); + } + return status; +} + +/* + This routine drops the reference count on a given function object. Once + the reference count falls to zero, the function object is destroyed and all + resources held are freed. + + FunctionObject - The function object to drop the reference to. +*/ +int be_function_object_destroy(struct be_function_object *pfob) +{ + TRACE(DL_INFO, "Destroy pfob. Object:0x%p", + pfob); + + + ASSERT(pfob->mcc == NULL); + + return BE_SUCCESS; +} + +int be_function_cleanup(struct be_function_object *pfob) +{ + int status = 0; + u32 isr; + u32 host_intr; + struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl; + + + if (pfob->type == BE_FUNCTION_TYPE_NETWORK) { + status = be_rxf_multicast_config(pfob, false, 0, + NULL, NULL, NULL, NULL); + ASSERT(status == BE_SUCCESS); + } + /* VLAN */ + status = be_rxf_vlan_config(pfob, false, 0, NULL, NULL, NULL, NULL); + ASSERT(status == BE_SUCCESS); + /* + * MCC Queue -- Switches to mailbox mode. May want to destroy + * all but the MCC CQ before this call if polling CQ is much better + * performance than polling mailbox register. + */ + if (pfob->mcc) + status = be_mcc_ring_destroy(pfob->mcc); + /* + * If interrupts are disabled, clear any CEV interrupt assertions that + * fired after we stopped processing EQs. + */ + ctrl.dw[0] = PCICFG1_READ(pfob, host_timer_int_ctrl); + host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, + hostintr, ctrl.dw); + if (!host_intr) + if (pfob->type == BE_FUNCTION_TYPE_NETWORK) + isr = CSR_READ(pfob, cev.isr1); + else + isr = CSR_READ(pfob, cev.isr0); + else + /* This should never happen... */ + TRACE(DL_ERR, "function_cleanup called with interrupt enabled"); + /* Function object destroy */ + status = be_function_object_destroy(pfob); + ASSERT(status == BE_SUCCESS); + + return status; +} + + +void * +be_function_prepare_embedded_fwcmd(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, u32 payld_len, u32 request_length, + u32 response_length, u32 opcode, u32 subsystem) +{ + struct FWCMD_REQUEST_HEADER *header = NULL; + u32 n; + + ASSERT(wrb); + + n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8; + AMAP_SET_BITS_PTR(MCC_WRB, embedded, wrb, 1); + AMAP_SET_BITS_PTR(MCC_WRB, payload_length, wrb, min(payld_len, n)); + header = (struct FWCMD_REQUEST_HEADER *)((u8 *)wrb + n); + + header->timeout = 0; + header->domain = 0; + header->request_length = max(request_length, response_length); + header->opcode = opcode; + header->subsystem = subsystem; + + return header; +} + +void * +be_function_prepare_nonembedded_fwcmd(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, + void *fwcmd_va, u64 fwcmd_pa, + u32 payld_len, + u32 request_length, + u32 response_length, + u32 opcode, u32 subsystem) +{ + struct FWCMD_REQUEST_HEADER *header = NULL; + u32 n; + struct MCC_WRB_PAYLOAD_AMAP *plp; + + ASSERT(wrb); + ASSERT(fwcmd_va); + + header = (struct FWCMD_REQUEST_HEADER *) fwcmd_va; + + AMAP_SET_BITS_PTR(MCC_WRB, embedded, wrb, 0); + AMAP_SET_BITS_PTR(MCC_WRB, payload_length, wrb, payld_len); + + /* + * Assume one fragment. The caller may override the SGL by + * rewriting the 0th length and adding more entries. They + * will also need to update the sge_count. + */ + AMAP_SET_BITS_PTR(MCC_WRB, sge_count, wrb, 1); + + n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8; + plp = (struct MCC_WRB_PAYLOAD_AMAP *)((u8 *)wrb + n); + AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].length, plp, payld_len); + AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].pa_lo, plp, (u32)fwcmd_pa); + AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].pa_hi, plp, + upper_32_bits(fwcmd_pa)); + + header->timeout = 0; + header->domain = 0; + header->request_length = max(request_length, response_length); + header->opcode = opcode; + header->subsystem = subsystem; + + return header; +} + +struct MCC_WRB_AMAP * +be_function_peek_mcc_wrb(struct be_function_object *pfob) +{ + struct MCC_WRB_AMAP *wrb = NULL; + u32 offset; + + if (pfob->mcc) + wrb = _be_mpu_peek_ring_wrb(pfob->mcc, false); + else { + offset = offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8; + wrb = (struct MCC_WRB_AMAP *) ((u8 *) pfob->mailbox.va + + offset); + } + + if (wrb) + memset(wrb, 0, sizeof(struct MCC_WRB_AMAP)); + + return wrb; +} + +#if defined(BE_DEBUG) +void be_function_debug_print_wrb(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, void *optional_fwcmd_va, + struct be_mcc_wrb_context *wrb_context) +{ + + struct FWCMD_REQUEST_HEADER *header = NULL; + u8 embedded; + u32 n; + + embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, wrb); + + if (embedded) { + n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8; + header = (struct FWCMD_REQUEST_HEADER *)((u8 *)wrb + n); + } else { + header = (struct FWCMD_REQUEST_HEADER *) optional_fwcmd_va; + } + + /* Save the completed count before posting for a debug assert. */ + + if (header) { + wrb_context->opcode = header->opcode; + wrb_context->subsystem = header->subsystem; + + } else { + wrb_context->opcode = 0; + wrb_context->subsystem = 0; + } +} +#else +#define be_function_debug_print_wrb(a_, b_, c_, d_) +#endif + +int +be_function_post_mcc_wrb(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, + struct be_generic_q_ctxt *q_ctxt, + mcc_wrb_cqe_callback cb, void *cb_context, + mcc_wrb_cqe_callback internal_cb, + void *internal_cb_context, void *optional_fwcmd_va, + struct be_mcc_wrb_response_copy *rc) +{ + int status; + struct be_mcc_wrb_context *wrb_context = NULL; + u64 *p; + + if (q_ctxt) { + /* Initialize context. */ + q_ctxt->context.internal_cb = internal_cb; + q_ctxt->context.internal_cb_context = internal_cb_context; + q_ctxt->context.cb = cb; + q_ctxt->context.cb_context = cb_context; + if (rc) { + q_ctxt->context.copy.length = rc->length; + q_ctxt->context.copy.fwcmd_offset = rc->fwcmd_offset; + q_ctxt->context.copy.va = rc->va; + } else + q_ctxt->context.copy.length = 0; + + q_ctxt->context.optional_fwcmd_va = optional_fwcmd_va; + + /* Queue this request */ + status = be_function_queue_mcc_wrb(pfob, q_ctxt); + + goto Error; + } + /* + * Allocate a WRB context struct to hold the callback pointers, + * status, etc. This is required if commands complete out of order. + */ + wrb_context = _be_mcc_allocate_wrb_context(pfob); + if (!wrb_context) { + TRACE(DL_WARN, "Failed to allocate MCC WRB context."); + status = BE_STATUS_SYSTEM_RESOURCES; + goto Error; + } + /* Initialize context. */ + memset(wrb_context, 0, sizeof(*wrb_context)); + wrb_context->internal_cb = internal_cb; + wrb_context->internal_cb_context = internal_cb_context; + wrb_context->cb = cb; + wrb_context->cb_context = cb_context; + if (rc) { + wrb_context->copy.length = rc->length; + wrb_context->copy.fwcmd_offset = rc->fwcmd_offset; + wrb_context->copy.va = rc->va; + } else + wrb_context->copy.length = 0; + wrb_context->wrb = wrb; + + /* + * Copy the context pointer into the WRB opaque tag field. + * Verify assumption of 64-bit tag with a compile time assert. + */ + p = (u64 *) ((u8 *)wrb + offsetof(struct BE_MCC_WRB_AMAP, tag)/8); + *p = (u64)(size_t)wrb_context; + + /* Print info about this FWCMD for debug builds. */ + be_function_debug_print_wrb(pfob, wrb, optional_fwcmd_va, wrb_context); + + /* + * issue the WRB to the MPU as appropriate + */ + if (pfob->mcc) { + /* + * we're in WRB mode, pass to the mcc layer + */ + status = _be_mpu_post_wrb_ring(pfob->mcc, wrb, wrb_context); + } else { + /* + * we're in mailbox mode + */ + status = _be_mpu_post_wrb_mailbox(pfob, wrb, wrb_context); + + /* mailbox mode always completes synchronously */ + ASSERT(status != BE_STATUS_PENDING); + } + +Error: + + return status; +} + +int +be_function_ring_destroy(struct be_function_object *pfob, + u32 id, u32 ring_type, mcc_wrb_cqe_callback cb, + void *cb_context, mcc_wrb_cqe_callback internal_cb, + void *internal_cb_context) +{ + + struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + int status = 0; + unsigned long irql; + + spin_lock_irqsave(&pfob->post_lock, irql); + + TRACE(DL_INFO, "Destroy ring id:%d type:%d", id, ring_type); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + ASSERT(wrb); + TRACE(DL_ERR, "No free MCC WRBs in destroy ring."); + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY); + + fwcmd->params.request.id = id; + fwcmd->params.request.ring_type = ring_type; + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context, + internal_cb, internal_cb_context, fwcmd, NULL); + if (status != BE_SUCCESS && status != BE_PENDING) { + TRACE(DL_ERR, "Ring destroy fwcmd failed. id:%d ring_type:%d", + id, ring_type); + goto Error; + } + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +void +be_rd_to_pa_list(struct ring_desc *rd, struct PHYS_ADDR *pa_list, u32 max_num) +{ + u32 num_pages = PAGES_SPANNED(rd->va, rd->length); + u32 i = 0; + u64 pa = rd->pa; + __le64 lepa; + + ASSERT(pa_list); + ASSERT(pa); + + for (i = 0; i < min(num_pages, max_num); i++) { + lepa = cpu_to_le64(pa); + pa_list[i].lo = (u32)lepa; + pa_list[i].hi = upper_32_bits(lepa); + pa += PAGE_SIZE; + } +} + + + +/*----------------------------------------------------------------------------- + * Function: be_function_get_fw_version + * Retrieves the firmware version on the adpater. If the callback is + * NULL this call executes synchronously. If the callback is not NULL, + * the returned status will be BE_PENDING if the command was issued + * successfully. + * pfob - + * fwv - Pointer to response buffer if callback is NULL. + * cb - Callback function invoked when the FWCMD completes. + * cb_context - Passed to the callback function. + * return pend_status - BE_SUCCESS (0) on success. + * BE_PENDING (postive value) if the FWCMD + * completion is pending. Negative error code on failure. + *--------------------------------------------------------------------------- + */ +int +be_function_get_fw_version(struct be_function_object *pfob, + struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD *fwv, + mcc_wrb_cqe_callback cb, void *cb_context) +{ + int status = BE_SUCCESS; + struct MCC_WRB_AMAP *wrb = NULL; + struct FWCMD_COMMON_GET_FW_VERSION *fwcmd = NULL; + unsigned long irql; + struct be_mcc_wrb_response_copy rc; + + spin_lock_irqsave(&pfob->post_lock, irql); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + TRACE(DL_ERR, "MCC wrb peek failed."); + status = BE_STATUS_NO_MCC_WRB; + goto Error; + } + + if (!cb && !fwv) { + TRACE(DL_ERR, "callback and response buffer NULL!"); + status = BE_NOT_OK; + goto Error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FW_VERSION); + + rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_GET_FW_VERSION, + params.response); + rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_GET_FW_VERSION, + params.response); + rc.va = fwv; + + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, + cb_context, NULL, NULL, fwcmd, &rc); + +Error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +int +be_function_queue_mcc_wrb(struct be_function_object *pfob, + struct be_generic_q_ctxt *q_ctxt) +{ + int status; + + ASSERT(q_ctxt); + + /* + * issue the WRB to the MPU as appropriate + */ + if (pfob->mcc) { + + /* We're in ring mode. Queue this item. */ + pfob->mcc->backlog_length++; + list_add_tail(&q_ctxt->context.list, &pfob->mcc->backlog); + status = BE_PENDING; + } else { + status = BE_NOT_OK; + } + return status; +} + diff --git a/trunk/drivers/staging/benet/fwcmd_common.h b/trunk/drivers/staging/benet/fwcmd_common.h new file mode 100644 index 000000000000..406e0d6fa985 --- /dev/null +++ b/trunk/drivers/staging/benet/fwcmd_common.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __fwcmd_common_amap_h__ +#define __fwcmd_common_amap_h__ +#include "host_struct.h" + +/* --- PHY_LINK_DUPLEX_ENUM --- */ +#define PHY_LINK_DUPLEX_NONE (0) +#define PHY_LINK_DUPLEX_HALF (1) +#define PHY_LINK_DUPLEX_FULL (2) + +/* --- PHY_LINK_SPEED_ENUM --- */ +#define PHY_LINK_SPEED_ZERO (0) /* No link. */ +#define PHY_LINK_SPEED_10MBPS (1) /* 10 Mbps */ +#define PHY_LINK_SPEED_100MBPS (2) /* 100 Mbps */ +#define PHY_LINK_SPEED_1GBPS (3) /* 1 Gbps */ +#define PHY_LINK_SPEED_10GBPS (4) /* 10 Gbps */ + +/* --- PHY_LINK_FAULT_ENUM --- */ +#define PHY_LINK_FAULT_NONE (0) /* No fault status + available or detected */ +#define PHY_LINK_FAULT_LOCAL (1) /* Local fault detected */ +#define PHY_LINK_FAULT_REMOTE (2) /* Remote fault detected */ + +/* --- BE_ULP_MASK --- */ +#define BE_ULP0_MASK (1) +#define BE_ULP1_MASK (2) +#define BE_ULP2_MASK (4) + +/* --- NTWK_ACTIVE_PORT --- */ +#define NTWK_PORT_A (0) /* Port A is currently active */ +#define NTWK_PORT_B (1) /* Port B is currently active */ +#define NTWK_NO_ACTIVE_PORT (15) /* Both ports have lost link */ + +/* --- NTWK_LINK_TYPE --- */ +#define NTWK_LINK_TYPE_PHYSICAL (0) /* link up/down event + applies to BladeEngine's + Physical Ports + */ +#define NTWK_LINK_TYPE_VIRTUAL (1) /* Virtual link up/down event + reported by BladeExchange. + This applies only when the + VLD feature is enabled + */ + +/* + * --- FWCMD_MAC_TYPE_ENUM --- + * This enum defines the types of MAC addresses in the RXF MAC Address Table. + */ +#define MAC_ADDRESS_TYPE_STORAGE (0) /* Storage MAC Address */ +#define MAC_ADDRESS_TYPE_NETWORK (1) /* Network MAC Address */ +#define MAC_ADDRESS_TYPE_PD (2) /* Protection Domain MAC Addr */ +#define MAC_ADDRESS_TYPE_MANAGEMENT (3) /* Managment MAC Address */ + + +/* --- FWCMD_RING_TYPE_ENUM --- */ +#define FWCMD_RING_TYPE_ETH_RX (1) /* Ring created with */ + /* FWCMD_COMMON_ETH_RX_CREATE. */ +#define FWCMD_RING_TYPE_ETH_TX (2) /* Ring created with */ + /* FWCMD_COMMON_ETH_TX_CREATE. */ +#define FWCMD_RING_TYPE_ISCSI_WRBQ (3) /* Ring created with */ + /* FWCMD_COMMON_ISCSI_WRBQ_CREATE. */ +#define FWCMD_RING_TYPE_ISCSI_DEFQ (4) /* Ring created with */ + /* FWCMD_COMMON_ISCSI_DEFQ_CREATE. */ +#define FWCMD_RING_TYPE_TPM_WRBQ (5) /* Ring created with */ + /* FWCMD_COMMON_TPM_WRBQ_CREATE. */ +#define FWCMD_RING_TYPE_TPM_DEFQ (6) /* Ring created with */ + /* FWCMD_COMMONTPM_TDEFQ_CREATE. */ +#define FWCMD_RING_TYPE_TPM_RQ (7) /* Ring created with */ + /* FWCMD_COMMON_TPM_RQ_CREATE. */ +#define FWCMD_RING_TYPE_MCC (8) /* Ring created with */ + /* FWCMD_COMMON_MCC_CREATE. */ +#define FWCMD_RING_TYPE_CQ (9) /* Ring created with */ + /* FWCMD_COMMON_CQ_CREATE. */ +#define FWCMD_RING_TYPE_EQ (10) /* Ring created with */ + /* FWCMD_COMMON_EQ_CREATE. */ +#define FWCMD_RING_TYPE_QP (11) /* Ring created with */ + /* FWCMD_RDMA_QP_CREATE. */ + + +/* --- ETH_TX_RING_TYPE_ENUM --- */ +#define ETH_TX_RING_TYPE_FORWARDING (1) /* Ethernet ring for + forwarding packets */ +#define ETH_TX_RING_TYPE_STANDARD (2) /* Ethernet ring for sending + network packets. */ +#define ETH_TX_RING_TYPE_BOUND (3) /* Ethernet ring bound to the + port specified in the command + header.port_number field. + Rings of this type are + NOT subject to the + failover logic implemented + in the BladeEngine. + */ + +/* --- FWCMD_COMMON_QOS_TYPE_ENUM --- */ +#define QOS_BITS_NIC (1) /* max_bits_per_second_NIC */ + /* field is valid. */ +#define QOS_PKTS_NIC (2) /* max_packets_per_second_NIC */ + /* field is valid. */ +#define QOS_IOPS_ISCSI (4) /* max_ios_per_second_iSCSI */ + /*field is valid. */ +#define QOS_VLAN_TAG (8) /* domain_VLAN_tag field + is valid. */ +#define QOS_FABRIC_ID (16) /* fabric_domain_ID field + is valid. */ +#define QOS_OEM_PARAMS (32) /* qos_params_oem field + is valid. */ +#define QOS_TPUT_ISCSI (64) /* max_bytes_per_second_iSCSI + field is valid. */ + + +/* + * --- FAILOVER_CONFIG_ENUM --- + * Failover configuration setting used in FWCMD_COMMON_FORCE_FAILOVER + */ +#define FAILOVER_CONFIG_NO_CHANGE (0) /* No change to automatic */ + /* port failover setting. */ +#define FAILOVER_CONFIG_ON (1) /* Automatic port failover + on link down is enabled. */ +#define FAILOVER_CONFIG_OFF (2) /* Automatic port failover + on link down is disabled. */ + +/* + * --- FAILOVER_PORT_ENUM --- + * Failover port setting used in FWCMD_COMMON_FORCE_FAILOVER + */ +#define FAILOVER_PORT_A (0) /* Selects port A. */ +#define FAILOVER_PORT_B (1) /* Selects port B. */ +#define FAILOVER_PORT_NONE (15) /* No port change requested. */ + + +/* + * --- MGMT_FLASHROM_OPCODE --- + * Flash ROM operation code + */ +#define MGMT_FLASHROM_OPCODE_FLASH (1) /* Commit downloaded data + to Flash ROM */ +#define MGMT_FLASHROM_OPCODE_SAVE (2) /* Save downloaded data to + ARM's DDR - do not flash */ +#define MGMT_FLASHROM_OPCODE_CLEAR (3) /* Erase specified component + from FlashROM */ +#define MGMT_FLASHROM_OPCODE_REPORT (4) /* Read specified component + from Flash ROM */ +#define MGMT_FLASHROM_OPCODE_IMAGE_INFO (5) /* Returns size of a + component */ + +/* + * --- MGMT_FLASHROM_OPTYPE --- + * Flash ROM operation type + */ +#define MGMT_FLASHROM_OPTYPE_CODE_FIRMWARE (0) /* Includes ARM firmware, + IPSec (optional) and EP + firmware */ +#define MGMT_FLASHROM_OPTYPE_CODE_REDBOOT (1) +#define MGMT_FLASHROM_OPTYPE_CODE_BIOS (2) +#define MGMT_FLASHROM_OPTYPE_CODE_PXE_BIOS (3) +#define MGMT_FLASHROM_OPTYPE_CODE_CTRLS (4) +#define MGMT_FLASHROM_OPTYPE_CFG_IPSEC (5) +#define MGMT_FLASHROM_OPTYPE_CFG_INI (6) +#define MGMT_FLASHROM_OPTYPE_ROM_OFFSET_SPECIFIED (7) + +/* + * --- FLASHROM_TYPE --- + * Flash ROM manufacturers supported in the f/w + */ +#define INTEL (0) +#define SPANSION (1) +#define MICRON (2) + +/* --- DDR_CAS_TYPE --- */ +#define CAS_3 (0) +#define CAS_4 (1) +#define CAS_5 (2) + +/* --- DDR_SIZE_TYPE --- */ +#define SIZE_256MB (0) +#define SIZE_512MB (1) + +/* --- DDR_MODE_TYPE --- */ +#define DDR_NO_ECC (0) +#define DDR_ECC (1) + +/* --- INTERFACE_10GB_TYPE --- */ +#define CX4_TYPE (0) +#define XFP_TYPE (1) + +/* --- BE_CHIP_MAX_MTU --- */ +#define CHIP_MAX_MTU (9000) + +/* --- XAUI_STATE_ENUM --- */ +#define XAUI_STATE_ENABLE (0) /* This MUST be the default + value for all requests + which set/change + equalization parameter. */ +#define XAUI_STATE_DISABLE (255) /* The XAUI for both ports + may be disabled for EMI + tests. There is no + provision for turning off + individual ports. + */ +/* --- BE_ASIC_REVISION --- */ +#define BE_ASIC_REV_A0 (1) +#define BE_ASIC_REV_A1 (2) + +#endif /* __fwcmd_common_amap_h__ */ diff --git a/trunk/drivers/staging/benet/fwcmd_common_bmap.h b/trunk/drivers/staging/benet/fwcmd_common_bmap.h new file mode 100644 index 000000000000..a007cf276500 --- /dev/null +++ b/trunk/drivers/staging/benet/fwcmd_common_bmap.h @@ -0,0 +1,717 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __fwcmd_common_bmap_h__ +#define __fwcmd_common_bmap_h__ +#include "fwcmd_types_bmap.h" +#include "fwcmd_hdr_bmap.h" + +#if defined(__BIG_ENDIAN) + /* Physical Address. */ +struct PHYS_ADDR { + union { + struct { + u32 lo; /* DWORD 0 */ + u32 hi; /* DWORD 1 */ + } __packed; /* unnamed struct */ + u32 dw[2]; /* dword union */ + }; /* unnamed union */ +} __packed ; + + +#else + /* Physical Address. */ +struct PHYS_ADDR { + union { + struct { + u32 lo; /* DWORD 0 */ + u32 hi; /* DWORD 1 */ + } __packed; /* unnamed struct */ + u32 dw[2]; /* dword union */ + }; /* unnamed union */ +} __packed ; + +struct BE_LINK_STATUS { + u8 mac0_duplex; + u8 mac0_speed; + u8 mac1_duplex; + u8 mac1_speed; + u8 mgmt_mac_duplex; + u8 mgmt_mac_speed; + u8 active_port; + u8 rsvd0; + u8 mac0_fault; + u8 mac1_fault; + u16 rsvd1; +} __packed; +#endif + +struct FWCMD_COMMON_ANON_170_REQUEST { + u32 rsvd0; +} __packed; + +union LINK_STATUS_QUERY_PARAMS { + struct BE_LINK_STATUS response; + struct FWCMD_COMMON_ANON_170_REQUEST request; +} __packed; + +/* + * Queries the the link status for all ports. The valid values below + * DO NOT indicate that a particular duplex or speed is supported by + * BladeEngine. These enumerations simply list all possible duplexes + * and speeds for any port. Consult BladeEngine product documentation + * for the supported parameters. + */ +struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY { + union FWCMD_HEADER header; + union LINK_STATUS_QUERY_PARAMS params; +} __packed; + +struct FWCMD_COMMON_ANON_171_REQUEST { + u8 type; + u8 port; + u8 mac1; + u8 permanent; +} __packed; + +struct FWCMD_COMMON_ANON_172_RESPONSE { + struct MAC_ADDRESS_FORMAT mac; +} __packed; + +union NTWK_MAC_QUERY_PARAMS { + struct FWCMD_COMMON_ANON_171_REQUEST request; + struct FWCMD_COMMON_ANON_172_RESPONSE response; +} __packed; + +/* Queries one MAC address. */ +struct FWCMD_COMMON_NTWK_MAC_QUERY { + union FWCMD_HEADER header; + union NTWK_MAC_QUERY_PARAMS params; +} __packed; + +struct MAC_SET_PARAMS_IN { + u8 type; + u8 port; + u8 mac1; + u8 invalidate; + struct MAC_ADDRESS_FORMAT mac; +} __packed; + +struct MAC_SET_PARAMS_OUT { + u32 rsvd0; +} __packed; + +union MAC_SET_PARAMS { + struct MAC_SET_PARAMS_IN request; + struct MAC_SET_PARAMS_OUT response; +} __packed; + +/* Sets a MAC address. */ +struct FWCMD_COMMON_NTWK_MAC_SET { + union FWCMD_HEADER header; + union MAC_SET_PARAMS params; +} __packed; + +/* MAC address list. */ +struct NTWK_MULTICAST_MAC_LIST { + u8 byte[6]; +} __packed; + +struct FWCMD_COMMON_NTWK_MULTICAST_SET_REQUEST_PAYLOAD { + u16 num_mac; + u8 promiscuous; + u8 rsvd0; + struct NTWK_MULTICAST_MAC_LIST mac[32]; +} __packed; + +struct FWCMD_COMMON_ANON_174_RESPONSE { + u32 rsvd0; +} __packed; + +union FWCMD_COMMON_ANON_173_PARAMS { + struct FWCMD_COMMON_NTWK_MULTICAST_SET_REQUEST_PAYLOAD request; + struct FWCMD_COMMON_ANON_174_RESPONSE response; +} __packed; + +/* + * Sets multicast address hash. The MPU will merge the MAC address lists + * from all clients, including the networking and storage functions. + * This command may fail if the final merged list of MAC addresses exceeds + * 32 entries. + */ +struct FWCMD_COMMON_NTWK_MULTICAST_SET { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_173_PARAMS params; +} __packed; + +struct FWCMD_COMMON_NTWK_VLAN_CONFIG_REQUEST_PAYLOAD { + u16 num_vlan; + u8 promiscuous; + u8 rsvd0; + u16 vlan_tag[32]; +} __packed; + +struct FWCMD_COMMON_ANON_176_RESPONSE { + u32 rsvd0; +} __packed; + +union FWCMD_COMMON_ANON_175_PARAMS { + struct FWCMD_COMMON_NTWK_VLAN_CONFIG_REQUEST_PAYLOAD request; + struct FWCMD_COMMON_ANON_176_RESPONSE response; +} __packed; + +/* + * Sets VLAN tag filter. The MPU will merge the VLAN tag list from all + * clients, including the networking and storage functions. This command + * may fail if the final vlan_tag array (from all functions) is longer + * than 32 entries. + */ +struct FWCMD_COMMON_NTWK_VLAN_CONFIG { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_175_PARAMS params; +} __packed; + +struct RING_DESTROY_REQUEST { + u16 ring_type; + u16 id; + u8 bypass_flush; + u8 rsvd0; + u16 rsvd1; +} __packed; + +struct FWCMD_COMMON_ANON_190_RESPONSE { + u32 rsvd0; +} __packed; + +union FWCMD_COMMON_ANON_189_PARAMS { + struct RING_DESTROY_REQUEST request; + struct FWCMD_COMMON_ANON_190_RESPONSE response; +} __packed; +/* + * Command for destroying any ring. The connection(s) using the ring should + * be quiesced before destroying the ring. + */ +struct FWCMD_COMMON_RING_DESTROY { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_189_PARAMS params; +} __packed; + +struct FWCMD_COMMON_ANON_192_REQUEST { + u16 num_pages; + u16 rsvd0; + struct CQ_CONTEXT_AMAP context; + struct PHYS_ADDR pages[4]; +} __packed ; + +struct FWCMD_COMMON_ANON_193_RESPONSE { + u16 cq_id; +} __packed ; + +union FWCMD_COMMON_ANON_191_PARAMS { + struct FWCMD_COMMON_ANON_192_REQUEST request; + struct FWCMD_COMMON_ANON_193_RESPONSE response; +} __packed ; + +/* + * Command for creating a completion queue. A Completion Queue must span + * at least 1 page and at most 4 pages. Each completion queue entry + * is 16 bytes regardless of CQ entry format. Thus the ring must be + * at least 256 entries deep (corresponding to 1 page) and can be at + * most 1024 entries deep (corresponding to 4 pages). The number of + * pages posted must contain the CQ ring size as encoded in the context. + * + */ +struct FWCMD_COMMON_CQ_CREATE { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_191_PARAMS params; +} __packed ; + +struct FWCMD_COMMON_ANON_198_REQUEST { + u16 num_pages; + u16 rsvd0; + struct EQ_CONTEXT_AMAP context; + struct PHYS_ADDR pages[8]; +} __packed ; + +struct FWCMD_COMMON_ANON_199_RESPONSE { + u16 eq_id; +} __packed ; + +union FWCMD_COMMON_ANON_197_PARAMS { + struct FWCMD_COMMON_ANON_198_REQUEST request; + struct FWCMD_COMMON_ANON_199_RESPONSE response; +} __packed ; + +/* + * Command for creating a event queue. An Event Queue must span at least + * 1 page and at most 8 pages. The number of pages posted must contain + * the EQ ring. The ring is defined by the size of the EQ entries (encoded + * in the context) and the number of EQ entries (also encoded in the + * context). + */ +struct FWCMD_COMMON_EQ_CREATE { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_197_PARAMS params; +} __packed ; + +struct FWCMD_COMMON_ANON_201_REQUEST { + u16 cq_id; + u16 bcmc_cq_id; + u16 num_pages; + u16 rsvd0; + struct PHYS_ADDR pages[2]; +} __packed; + +struct FWCMD_COMMON_ANON_202_RESPONSE { + u16 id; +} __packed; + +union FWCMD_COMMON_ANON_200_PARAMS { + struct FWCMD_COMMON_ANON_201_REQUEST request; + struct FWCMD_COMMON_ANON_202_RESPONSE response; +} __packed; + +/* + * Command for creating Ethernet receive ring. An ERX ring contains ETH_RX_D + * entries (8 bytes each). An ERX ring must be 1024 entries deep + * (corresponding to 2 pages). + */ +struct FWCMD_COMMON_ETH_RX_CREATE { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_200_PARAMS params; +} __packed; + +struct FWCMD_COMMON_ANON_204_REQUEST { + u16 num_pages; + u8 ulp_num; + u8 type; + struct ETX_CONTEXT_AMAP context; + struct PHYS_ADDR pages[8]; +} __packed ; + +struct FWCMD_COMMON_ANON_205_RESPONSE { + u16 cid; + u8 ulp_num; + u8 rsvd0; +} __packed ; + +union FWCMD_COMMON_ANON_203_PARAMS { + struct FWCMD_COMMON_ANON_204_REQUEST request; + struct FWCMD_COMMON_ANON_205_RESPONSE response; +} __packed ; + +/* + * Command for creating an Ethernet transmit ring. An ETX ring contains + * ETH_WRB entries (16 bytes each). An ETX ring must be at least 256 + * entries deep (corresponding to 1 page) and at most 2k entries deep + * (corresponding to 8 pages). + */ +struct FWCMD_COMMON_ETH_TX_CREATE { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_203_PARAMS params; +} __packed ; + +struct FWCMD_COMMON_ANON_222_REQUEST { + u16 num_pages; + u16 rsvd0; + struct MCC_RING_CONTEXT_AMAP context; + struct PHYS_ADDR pages[8]; +} __packed ; + +struct FWCMD_COMMON_ANON_223_RESPONSE { + u16 id; +} __packed ; + +union FWCMD_COMMON_ANON_221_PARAMS { + struct FWCMD_COMMON_ANON_222_REQUEST request; + struct FWCMD_COMMON_ANON_223_RESPONSE response; +} __packed ; + +/* + * Command for creating the MCC ring. An MCC ring must be at least 16 + * entries deep (corresponding to 1 page) and at most 128 entries deep + * (corresponding to 8 pages). + */ +struct FWCMD_COMMON_MCC_CREATE { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_221_PARAMS params; +} __packed ; + +struct GET_QOS_IN { + u32 qos_params_rsvd; +} __packed; + +struct GET_QOS_OUT { + u32 max_bits_per_second_NIC; + u32 max_packets_per_second_NIC; + u32 max_ios_per_second_iSCSI; + u32 max_bytes_per_second_iSCSI; + u16 domain_VLAN_tag; + u16 fabric_domain_ID; + u32 qos_params_oem[4]; +} __packed; + +union GET_QOS_PARAMS { + struct GET_QOS_IN request; + struct GET_QOS_OUT response; +} __packed; + +/* QOS/Bandwidth settings per domain. Applicable only in VMs. */ +struct FWCMD_COMMON_GET_QOS { + union FWCMD_HEADER header; + union GET_QOS_PARAMS params; +} __packed; + +struct SET_QOS_IN { + u32 valid_flags; + u32 max_bits_per_second_NIC; + u32 max_packets_per_second_NIC; + u32 max_ios_per_second_iSCSI; + u32 max_bytes_per_second_iSCSI; + u16 domain_VLAN_tag; + u16 fabric_domain_ID; + u32 qos_params_oem[4]; +} __packed; + +struct SET_QOS_OUT { + u32 qos_params_rsvd; +} __packed; + +union SET_QOS_PARAMS { + struct SET_QOS_IN request; + struct SET_QOS_OUT response; +} __packed; + +/* QOS/Bandwidth settings per domain. Applicable only in VMs. */ +struct FWCMD_COMMON_SET_QOS { + union FWCMD_HEADER header; + union SET_QOS_PARAMS params; +} __packed; + +struct SET_FRAME_SIZE_IN { + u32 max_tx_frame_size; + u32 max_rx_frame_size; +} __packed; + +struct SET_FRAME_SIZE_OUT { + u32 chip_max_tx_frame_size; + u32 chip_max_rx_frame_size; +} __packed; + +union SET_FRAME_SIZE_PARAMS { + struct SET_FRAME_SIZE_IN request; + struct SET_FRAME_SIZE_OUT response; +} __packed; + +/* Set frame size command. Only host domain may issue this command. */ +struct FWCMD_COMMON_SET_FRAME_SIZE { + union FWCMD_HEADER header; + union SET_FRAME_SIZE_PARAMS params; +} __packed; + +struct FORCE_FAILOVER_IN { + u32 move_to_port; + u32 failover_config; +} __packed; + +struct FWCMD_COMMON_ANON_231_RESPONSE { + u32 rsvd0; +} __packed; + +union FWCMD_COMMON_ANON_230_PARAMS { + struct FORCE_FAILOVER_IN request; + struct FWCMD_COMMON_ANON_231_RESPONSE response; +} __packed; + +/* + * Use this command to control failover in BladeEngine. It may be used + * to failback to a restored port or to forcibly move traffic from + * one port to another. It may also be used to enable or disable the + * automatic failover feature. This command can only be issued by domain + * 0. + */ +struct FWCMD_COMMON_FORCE_FAILOVER { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_230_PARAMS params; +} __packed; + +struct FWCMD_COMMON_ANON_240_REQUEST { + u64 context; +} __packed; + +struct FWCMD_COMMON_ANON_241_RESPONSE { + u64 context; +} __packed; + +union FWCMD_COMMON_ANON_239_PARAMS { + struct FWCMD_COMMON_ANON_240_REQUEST request; + struct FWCMD_COMMON_ANON_241_RESPONSE response; +} __packed; + +/* + * This command can be used by clients as a no-operation request. Typical + * uses for drivers are as a heartbeat mechanism, or deferred processing + * catalyst. The ARM will always complete this command with a good completion. + * The 64-bit parameter is not touched by the ARM processor. + */ +struct FWCMD_COMMON_NOP { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_239_PARAMS params; +} __packed; + +struct NTWK_RX_FILTER_SETTINGS { + u8 promiscuous; + u8 ip_cksum; + u8 tcp_cksum; + u8 udp_cksum; + u8 pass_err; + u8 pass_ckerr; + u8 strip_crc; + u8 mcast_en; + u8 bcast_en; + u8 mcast_promiscuous_en; + u8 unicast_en; + u8 vlan_promiscuous; +} __packed; + +union FWCMD_COMMON_ANON_242_PARAMS { + struct NTWK_RX_FILTER_SETTINGS request; + struct NTWK_RX_FILTER_SETTINGS response; +} __packed; + +/* + * This command is used to modify the ethernet receive filter configuration. + * Only domain 0 network function drivers may issue this command. The + * applied configuration is returned in the response payload. Note: + * Some receive packet filter settings are global on BladeEngine and + * can affect both the storage and network function clients that the + * BladeEngine hardware and firmware serve. Additionaly, depending + * on the revision of BladeEngine, some ethernet receive filter settings + * are dependent on others. If a dependency exists between settings + * for the BladeEngine revision, and the command request settings do + * not meet the dependency requirement, the invalid settings will not + * be applied despite the comand succeeding. For example: a driver may + * request to enable broadcast packets, but not enable multicast packets. + * On early revisions of BladeEngine, there may be no distinction between + * broadcast and multicast filters, so broadcast could not be enabled + * without enabling multicast. In this scenario, the comand would still + * succeed, but the response payload would indicate the previously + * configured broadcast and multicast setting. + */ +struct FWCMD_COMMON_NTWK_RX_FILTER { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_242_PARAMS params; +} __packed; + + +struct FWCMD_COMMON_ANON_244_REQUEST { + u32 rsvd0; +} __packed; + +struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD { + u8 firmware_version_string[32]; + u8 fw_on_flash_version_string[32]; +} __packed; + +union FWCMD_COMMON_ANON_243_PARAMS { + struct FWCMD_COMMON_ANON_244_REQUEST request; + struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD response; +} __packed; + +/* This comand retrieves the firmware version. */ +struct FWCMD_COMMON_GET_FW_VERSION { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_243_PARAMS params; +} __packed; + +struct FWCMD_COMMON_ANON_246_REQUEST { + u16 tx_flow_control; + u16 rx_flow_control; +} __packed; + +struct FWCMD_COMMON_ANON_247_RESPONSE { + u32 rsvd0; +} __packed; + +union FWCMD_COMMON_ANON_245_PARAMS { + struct FWCMD_COMMON_ANON_246_REQUEST request; + struct FWCMD_COMMON_ANON_247_RESPONSE response; +} __packed; + +/* + * This comand is used to program BladeEngine flow control behavior. + * Only the host networking driver is allowed to use this comand. + */ +struct FWCMD_COMMON_SET_FLOW_CONTROL { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_245_PARAMS params; +} __packed; + +struct FWCMD_COMMON_ANON_249_REQUEST { + u32 rsvd0; +} __packed; + +struct FWCMD_COMMON_ANON_250_RESPONSE { + u16 tx_flow_control; + u16 rx_flow_control; +} __packed; + +union FWCMD_COMMON_ANON_248_PARAMS { + struct FWCMD_COMMON_ANON_249_REQUEST request; + struct FWCMD_COMMON_ANON_250_RESPONSE response; +} __packed; + +/* This comand is used to read BladeEngine flow control settings. */ +struct FWCMD_COMMON_GET_FLOW_CONTROL { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_248_PARAMS params; +} __packed; + +struct EQ_DELAY_PARAMS { + u32 eq_id; + u32 delay_in_microseconds; +} __packed; + +struct FWCMD_COMMON_ANON_257_REQUEST { + u32 num_eq; + u32 rsvd0; + struct EQ_DELAY_PARAMS delay[16]; +} __packed; + +struct FWCMD_COMMON_ANON_258_RESPONSE { + u32 delay_resolution_in_microseconds; + u32 delay_max_in_microseconds; +} __packed; + +union MODIFY_EQ_DELAY_PARAMS { + struct FWCMD_COMMON_ANON_257_REQUEST request; + struct FWCMD_COMMON_ANON_258_RESPONSE response; +} __packed; + +/* This comand changes the EQ delay for a given set of EQs. */ +struct FWCMD_COMMON_MODIFY_EQ_DELAY { + union FWCMD_HEADER header; + union MODIFY_EQ_DELAY_PARAMS params; +} __packed; + +struct FWCMD_COMMON_ANON_260_REQUEST { + u32 rsvd0; +} __packed; + +struct BE_FIRMWARE_CONFIG { + u16 be_config_number; + u16 asic_revision; + u32 nic_ulp_mask; + u32 tulp_mask; + u32 iscsi_ulp_mask; + u32 rdma_ulp_mask; + u32 rsvd0[4]; + u32 eth_tx_id_start; + u32 eth_tx_id_count; + u32 eth_rx_id_start; + u32 eth_rx_id_count; + u32 tpm_wrbq_id_start; + u32 tpm_wrbq_id_count; + u32 tpm_defq_id_start; + u32 tpm_defq_id_count; + u32 iscsi_wrbq_id_start; + u32 iscsi_wrbq_id_count; + u32 iscsi_defq_id_start; + u32 iscsi_defq_id_count; + u32 rdma_qp_id_start; + u32 rdma_qp_id_count; + u32 rsvd1[8]; +} __packed; + +union FWCMD_COMMON_ANON_259_PARAMS { + struct FWCMD_COMMON_ANON_260_REQUEST request; + struct BE_FIRMWARE_CONFIG response; +} __packed; + +/* + * This comand queries the current firmware configuration parameters. + * The static configuration type is defined by be_config_number. This + * differentiates different BladeEngine builds, such as iSCSI Initiator + * versus iSCSI Target. For a given static configuration, the Upper + * Layer Protocol (ULP) processors may be reconfigured to support different + * protocols. Each ULP processor supports one or more protocols. The + * masks indicate which processors are configured for each protocol. + * For a given static configuration, the number of TCP connections + * supported for each protocol may vary. The *_id_start and *_id_count + * variables define a linear range of IDs that are available for each + * supported protocol. The *_id_count may be used by the driver to allocate + * the appropriate number of connection resources. The *_id_start may + * be used to map the arbitrary range of IDs to a zero-based range + * of indices. + */ +struct FWCMD_COMMON_FIRMWARE_CONFIG { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_259_PARAMS params; +} __packed; + +struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS { + u32 emph_lev_sel_port0; + u32 emph_lev_sel_port1; + u8 xaui_vo_sel; + u8 xaui_state; + u16 rsvd0; + u32 xaui_eq_vector; +} __packed; + +struct FWCMD_COMMON_ANON_262_REQUEST { + u32 rsvd0; +} __packed; + +union FWCMD_COMMON_ANON_261_PARAMS { + struct FWCMD_COMMON_ANON_262_REQUEST request; + struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS response; +} __packed; + +/* + * This comand can be used to read XAUI equalization parameters. The + * ARM firmware applies default equalization parameters during initialization. + * These parameters may be customer-specific when derived from the + * SEEPROM. See SEEPROM_DATA for equalization specific fields. + */ +struct FWCMD_COMMON_GET_PORT_EQUALIZATION { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_261_PARAMS params; +} __packed; + +struct FWCMD_COMMON_ANON_264_RESPONSE { + u32 rsvd0; +} __packed; + +union FWCMD_COMMON_ANON_263_PARAMS { + struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS request; + struct FWCMD_COMMON_ANON_264_RESPONSE response; +} __packed; + +/* + * This comand can be used to set XAUI equalization parameters. The ARM + * firmware applies default equalization parameters during initialization. + * These parameters may be customer-specific when derived from the + * SEEPROM. See SEEPROM_DATA for equalization specific fields. + */ +struct FWCMD_COMMON_SET_PORT_EQUALIZATION { + union FWCMD_HEADER header; + union FWCMD_COMMON_ANON_263_PARAMS params; +} __packed; + +#endif /* __fwcmd_common_bmap_h__ */ diff --git a/trunk/drivers/staging/benet/fwcmd_eth_bmap.h b/trunk/drivers/staging/benet/fwcmd_eth_bmap.h new file mode 100644 index 000000000000..234b179eace6 --- /dev/null +++ b/trunk/drivers/staging/benet/fwcmd_eth_bmap.h @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __fwcmd_eth_bmap_h__ +#define __fwcmd_eth_bmap_h__ +#include "fwcmd_hdr_bmap.h" +#include "fwcmd_types_bmap.h" + +struct MIB_ETH_STATISTICS_PARAMS_IN { + u32 rsvd0; +} __packed; + +struct BE_RXF_STATS { + u32 p0recvdtotalbytesLSD; /* DWORD 0 */ + u32 p0recvdtotalbytesMSD; /* DWORD 1 */ + u32 p0recvdtotalframes; /* DWORD 2 */ + u32 p0recvdunicastframes; /* DWORD 3 */ + u32 p0recvdmulticastframes; /* DWORD 4 */ + u32 p0recvdbroadcastframes; /* DWORD 5 */ + u32 p0crcerrors; /* DWORD 6 */ + u32 p0alignmentsymerrs; /* DWORD 7 */ + u32 p0pauseframesrecvd; /* DWORD 8 */ + u32 p0controlframesrecvd; /* DWORD 9 */ + u32 p0inrangelenerrors; /* DWORD 10 */ + u32 p0outrangeerrors; /* DWORD 11 */ + u32 p0frametoolongerrors; /* DWORD 12 */ + u32 p0droppedaddressmatch; /* DWORD 13 */ + u32 p0droppedvlanmismatch; /* DWORD 14 */ + u32 p0ipdroppedtoosmall; /* DWORD 15 */ + u32 p0ipdroppedtooshort; /* DWORD 16 */ + u32 p0ipdroppedhdrtoosmall; /* DWORD 17 */ + u32 p0tcpdroppedlen; /* DWORD 18 */ + u32 p0droppedrunt; /* DWORD 19 */ + u32 p0recvd64; /* DWORD 20 */ + u32 p0recvd65_127; /* DWORD 21 */ + u32 p0recvd128_256; /* DWORD 22 */ + u32 p0recvd256_511; /* DWORD 23 */ + u32 p0recvd512_1023; /* DWORD 24 */ + u32 p0recvd1518_1522; /* DWORD 25 */ + u32 p0recvd1522_2047; /* DWORD 26 */ + u32 p0recvd2048_4095; /* DWORD 27 */ + u32 p0recvd4096_8191; /* DWORD 28 */ + u32 p0recvd8192_9216; /* DWORD 29 */ + u32 p0rcvdipcksmerrs; /* DWORD 30 */ + u32 p0recvdtcpcksmerrs; /* DWORD 31 */ + u32 p0recvdudpcksmerrs; /* DWORD 32 */ + u32 p0recvdnonrsspackets; /* DWORD 33 */ + u32 p0recvdippackets; /* DWORD 34 */ + u32 p0recvdchute1packets; /* DWORD 35 */ + u32 p0recvdchute2packets; /* DWORD 36 */ + u32 p0recvdchute3packets; /* DWORD 37 */ + u32 p0recvdipsecpackets; /* DWORD 38 */ + u32 p0recvdmanagementpackets; /* DWORD 39 */ + u32 p0xmitbyteslsd; /* DWORD 40 */ + u32 p0xmitbytesmsd; /* DWORD 41 */ + u32 p0xmitunicastframes; /* DWORD 42 */ + u32 p0xmitmulticastframes; /* DWORD 43 */ + u32 p0xmitbroadcastframes; /* DWORD 44 */ + u32 p0xmitpauseframes; /* DWORD 45 */ + u32 p0xmitcontrolframes; /* DWORD 46 */ + u32 p0xmit64; /* DWORD 47 */ + u32 p0xmit65_127; /* DWORD 48 */ + u32 p0xmit128_256; /* DWORD 49 */ + u32 p0xmit256_511; /* DWORD 50 */ + u32 p0xmit512_1023; /* DWORD 51 */ + u32 p0xmit1518_1522; /* DWORD 52 */ + u32 p0xmit1522_2047; /* DWORD 53 */ + u32 p0xmit2048_4095; /* DWORD 54 */ + u32 p0xmit4096_8191; /* DWORD 55 */ + u32 p0xmit8192_9216; /* DWORD 56 */ + u32 p0rxfifooverflowdropped; /* DWORD 57 */ + u32 p0ipseclookupfaileddropped; /* DWORD 58 */ + u32 p1recvdtotalbytesLSD; /* DWORD 59 */ + u32 p1recvdtotalbytesMSD; /* DWORD 60 */ + u32 p1recvdtotalframes; /* DWORD 61 */ + u32 p1recvdunicastframes; /* DWORD 62 */ + u32 p1recvdmulticastframes; /* DWORD 63 */ + u32 p1recvdbroadcastframes; /* DWORD 64 */ + u32 p1crcerrors; /* DWORD 65 */ + u32 p1alignmentsymerrs; /* DWORD 66 */ + u32 p1pauseframesrecvd; /* DWORD 67 */ + u32 p1controlframesrecvd; /* DWORD 68 */ + u32 p1inrangelenerrors; /* DWORD 69 */ + u32 p1outrangeerrors; /* DWORD 70 */ + u32 p1frametoolongerrors; /* DWORD 71 */ + u32 p1droppedaddressmatch; /* DWORD 72 */ + u32 p1droppedvlanmismatch; /* DWORD 73 */ + u32 p1ipdroppedtoosmall; /* DWORD 74 */ + u32 p1ipdroppedtooshort; /* DWORD 75 */ + u32 p1ipdroppedhdrtoosmall; /* DWORD 76 */ + u32 p1tcpdroppedlen; /* DWORD 77 */ + u32 p1droppedrunt; /* DWORD 78 */ + u32 p1recvd64; /* DWORD 79 */ + u32 p1recvd65_127; /* DWORD 80 */ + u32 p1recvd128_256; /* DWORD 81 */ + u32 p1recvd256_511; /* DWORD 82 */ + u32 p1recvd512_1023; /* DWORD 83 */ + u32 p1recvd1518_1522; /* DWORD 84 */ + u32 p1recvd1522_2047; /* DWORD 85 */ + u32 p1recvd2048_4095; /* DWORD 86 */ + u32 p1recvd4096_8191; /* DWORD 87 */ + u32 p1recvd8192_9216; /* DWORD 88 */ + u32 p1rcvdipcksmerrs; /* DWORD 89 */ + u32 p1recvdtcpcksmerrs; /* DWORD 90 */ + u32 p1recvdudpcksmerrs; /* DWORD 91 */ + u32 p1recvdnonrsspackets; /* DWORD 92 */ + u32 p1recvdippackets; /* DWORD 93 */ + u32 p1recvdchute1packets; /* DWORD 94 */ + u32 p1recvdchute2packets; /* DWORD 95 */ + u32 p1recvdchute3packets; /* DWORD 96 */ + u32 p1recvdipsecpackets; /* DWORD 97 */ + u32 p1recvdmanagementpackets; /* DWORD 98 */ + u32 p1xmitbyteslsd; /* DWORD 99 */ + u32 p1xmitbytesmsd; /* DWORD 100 */ + u32 p1xmitunicastframes; /* DWORD 101 */ + u32 p1xmitmulticastframes; /* DWORD 102 */ + u32 p1xmitbroadcastframes; /* DWORD 103 */ + u32 p1xmitpauseframes; /* DWORD 104 */ + u32 p1xmitcontrolframes; /* DWORD 105 */ + u32 p1xmit64; /* DWORD 106 */ + u32 p1xmit65_127; /* DWORD 107 */ + u32 p1xmit128_256; /* DWORD 108 */ + u32 p1xmit256_511; /* DWORD 109 */ + u32 p1xmit512_1023; /* DWORD 110 */ + u32 p1xmit1518_1522; /* DWORD 111 */ + u32 p1xmit1522_2047; /* DWORD 112 */ + u32 p1xmit2048_4095; /* DWORD 113 */ + u32 p1xmit4096_8191; /* DWORD 114 */ + u32 p1xmit8192_9216; /* DWORD 115 */ + u32 p1rxfifooverflowdropped; /* DWORD 116 */ + u32 p1ipseclookupfaileddropped; /* DWORD 117 */ + u32 pxdroppednopbuf; /* DWORD 118 */ + u32 pxdroppednotxpb; /* DWORD 119 */ + u32 pxdroppednoipsecbuf; /* DWORD 120 */ + u32 pxdroppednoerxdescr; /* DWORD 121 */ + u32 pxdroppednotpredescr; /* DWORD 122 */ + u32 pxrecvdmanagementportpackets; /* DWORD 123 */ + u32 pxrecvdmanagementportbytes; /* DWORD 124 */ + u32 pxrecvdmanagementportpauseframes; /* DWORD 125 */ + u32 pxrecvdmanagementporterrors; /* DWORD 126 */ + u32 pxxmitmanagementportpackets; /* DWORD 127 */ + u32 pxxmitmanagementportbytes; /* DWORD 128 */ + u32 pxxmitmanagementportpause; /* DWORD 129 */ + u32 pxxmitmanagementportrxfifooverflow; /* DWORD 130 */ + u32 pxrecvdipsecipcksmerrs; /* DWORD 131 */ + u32 pxrecvdtcpsecipcksmerrs; /* DWORD 132 */ + u32 pxrecvdudpsecipcksmerrs; /* DWORD 133 */ + u32 pxipsecrunt; /* DWORD 134 */ + u32 pxipsecaddressmismatchdropped; /* DWORD 135 */ + u32 pxipsecrxfifooverflowdropped; /* DWORD 136 */ + u32 pxipsecframestoolong; /* DWORD 137 */ + u32 pxipsectotalipframes; /* DWORD 138 */ + u32 pxipseciptoosmall; /* DWORD 139 */ + u32 pxipseciptooshort; /* DWORD 140 */ + u32 pxipseciphdrtoosmall; /* DWORD 141 */ + u32 pxipsectcphdrbad; /* DWORD 142 */ + u32 pxrecvdipsecchute1; /* DWORD 143 */ + u32 pxrecvdipsecchute2; /* DWORD 144 */ + u32 pxrecvdipsecchute3; /* DWORD 145 */ + u32 pxdropped7frags; /* DWORD 146 */ + u32 pxdroppedfrags; /* DWORD 147 */ + u32 pxdroppedinvalidfragring; /* DWORD 148 */ + u32 pxnumforwardedpackets; /* DWORD 149 */ +} __packed; + +union MIB_ETH_STATISTICS_PARAMS { + struct MIB_ETH_STATISTICS_PARAMS_IN request; + struct BE_RXF_STATS response; +} __packed; + +/* + * Query ethernet statistics. All domains may issue this command. The + * host domain drivers may optionally reset internal statistic counters + * with a query. + */ +struct FWCMD_ETH_GET_STATISTICS { + union FWCMD_HEADER header; + union MIB_ETH_STATISTICS_PARAMS params; +} __packed; + + +struct FWCMD_ETH_ANON_175_REQUEST { + u8 port0_promiscuous; + u8 port1_promiscuous; + u16 rsvd0; +} __packed; + +struct FWCMD_ETH_ANON_176_RESPONSE { + u32 rsvd0; +} __packed; + +union FWCMD_ETH_ANON_174_PARAMS { + struct FWCMD_ETH_ANON_175_REQUEST request; + struct FWCMD_ETH_ANON_176_RESPONSE response; +} __packed; + +/* Enables/Disables promiscuous ethernet receive mode. */ +struct FWCMD_ETH_PROMISCUOUS { + union FWCMD_HEADER header; + union FWCMD_ETH_ANON_174_PARAMS params; +} __packed; + +struct FWCMD_ETH_ANON_178_REQUEST { + u32 new_fragsize_log2; +} __packed; + +struct FWCMD_ETH_ANON_179_RESPONSE { + u32 actual_fragsize_log2; +} __packed; + +union FWCMD_ETH_ANON_177_PARAMS { + struct FWCMD_ETH_ANON_178_REQUEST request; + struct FWCMD_ETH_ANON_179_RESPONSE response; +} __packed; + +/* + * Sets the Ethernet RX fragment size. Only host (domain 0) networking + * drivers may issue this command. This call will fail for non-host + * protection domains. In this situation the MCC CQ status will indicate + * a failure due to insufficient priviledges. The response should be + * ignored, and the driver should use the FWCMD_ETH_GET_FRAG_SIZE to + * query the existing ethernet receive fragment size. It must use this + * fragment size for all fragments in the ethernet receive ring. If + * the command succeeds, the driver must use the frag size indicated + * in the command response since the requested frag size may not be applied + * until the next reboot. When the requested fragsize matches the response + * fragsize, this indicates the request was applied immediately. + */ +struct FWCMD_ETH_SET_RX_FRAG_SIZE { + union FWCMD_HEADER header; + union FWCMD_ETH_ANON_177_PARAMS params; +} __packed; + +struct FWCMD_ETH_ANON_181_REQUEST { + u32 rsvd0; +} __packed; + +struct FWCMD_ETH_ANON_182_RESPONSE { + u32 actual_fragsize_log2; +} __packed; + +union FWCMD_ETH_ANON_180_PARAMS { + struct FWCMD_ETH_ANON_181_REQUEST request; + struct FWCMD_ETH_ANON_182_RESPONSE response; +} __packed; + +/* + * Queries the Ethernet RX fragment size. All domains may issue this + * command. The driver should call this command to determine the minimum + * required fragment size for the ethernet RX ring buffers. Drivers + * may choose to use a larger size for each fragment buffer, but BladeEngine + * will use up to the configured minimum required fragsize in each ethernet + * receive fragment buffer. For example, if the ethernet receive fragment + * size is configured to 4kB, and a driver uses 8kB fragments, a 6kB + * ethernet packet received by BladeEngine will be split accross two + * of the driver's receive framgents (4kB in one fragment buffer, and + * 2kB in the subsequent fragment buffer). + */ +struct FWCMD_ETH_GET_RX_FRAG_SIZE { + union FWCMD_HEADER header; + union FWCMD_ETH_ANON_180_PARAMS params; +} __packed; + +#endif /* __fwcmd_eth_bmap_h__ */ diff --git a/trunk/drivers/staging/benet/fwcmd_hdr_bmap.h b/trunk/drivers/staging/benet/fwcmd_hdr_bmap.h new file mode 100644 index 000000000000..28b45328fe7b --- /dev/null +++ b/trunk/drivers/staging/benet/fwcmd_hdr_bmap.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __fwcmd_hdr_bmap_h__ +#define __fwcmd_hdr_bmap_h__ + +struct FWCMD_REQUEST_HEADER { + u8 opcode; + u8 subsystem; + u8 port_number; + u8 domain; + u32 timeout; + u32 request_length; + u32 rsvd0; +} __packed; + +struct FWCMD_RESPONSE_HEADER { + u8 opcode; + u8 subsystem; + u8 rsvd0; + u8 domain; + u8 status; + u8 additional_status; + u16 rsvd1; + u32 response_length; + u32 actual_response_length; +} __packed; + +/* + * The firmware/driver overwrites the input FWCMD_REQUEST_HEADER with + * the output FWCMD_RESPONSE_HEADER. + */ +union FWCMD_HEADER { + struct FWCMD_REQUEST_HEADER request; + struct FWCMD_RESPONSE_HEADER response; +} __packed; + +#endif /* __fwcmd_hdr_bmap_h__ */ diff --git a/trunk/drivers/staging/benet/fwcmd_mcc.h b/trunk/drivers/staging/benet/fwcmd_mcc.h new file mode 100644 index 000000000000..9eeca878c1fb --- /dev/null +++ b/trunk/drivers/staging/benet/fwcmd_mcc.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __fwcmd_mcc_amap_h__ +#define __fwcmd_mcc_amap_h__ +#include "fwcmd_opcodes.h" +/* + * Where applicable, a WRB, may contain a list of Scatter-gather elements. + * Each element supports a 64 bit address and a 32bit length field. + */ +struct BE_MCC_SGE_AMAP { + u8 pa_lo[32]; /* DWORD 0 */ + u8 pa_hi[32]; /* DWORD 1 */ + u8 length[32]; /* DWORD 2 */ +} __packed; +struct MCC_SGE_AMAP { + u32 dw[3]; +}; +/* + * The design of an MCC_SGE allows up to 19 elements to be embedded + * in a WRB, supporting 64KB data transfers (assuming a 4KB page size). + */ +struct BE_MCC_WRB_PAYLOAD_AMAP { + union { + struct BE_MCC_SGE_AMAP sgl[19]; + u8 embedded[59][32]; /* DWORD 0 */ + }; +} __packed; +struct MCC_WRB_PAYLOAD_AMAP { + u32 dw[59]; +}; + +/* + * This is the structure of the MCC Command WRB for commands + * sent to the Management Processing Unit (MPU). See section + * for usage in embedded and non-embedded modes. + */ +struct BE_MCC_WRB_AMAP { + u8 embedded; /* DWORD 0 */ + u8 rsvd0[2]; /* DWORD 0 */ + u8 sge_count[5]; /* DWORD 0 */ + u8 rsvd1[16]; /* DWORD 0 */ + u8 special[8]; /* DWORD 0 */ + u8 payload_length[32]; /* DWORD 1 */ + u8 tag[2][32]; /* DWORD 2 */ + u8 rsvd2[32]; /* DWORD 4 */ + struct BE_MCC_WRB_PAYLOAD_AMAP payload; +} __packed; +struct MCC_WRB_AMAP { + u32 dw[64]; +}; + +/* This is the structure of the MCC Completion queue entry */ +struct BE_MCC_CQ_ENTRY_AMAP { + u8 completion_status[16]; /* DWORD 0 */ + u8 extended_status[16]; /* DWORD 0 */ + u8 mcc_tag[2][32]; /* DWORD 1 */ + u8 rsvd0[27]; /* DWORD 3 */ + u8 consumed; /* DWORD 3 */ + u8 completed; /* DWORD 3 */ + u8 hpi_buffer_completion; /* DWORD 3 */ + u8 async_event; /* DWORD 3 */ + u8 valid; /* DWORD 3 */ +} __packed; +struct MCC_CQ_ENTRY_AMAP { + u32 dw[4]; +}; + +/* Mailbox structures used by the MPU during bootstrap */ +struct BE_MCC_MAILBOX_AMAP { + struct BE_MCC_WRB_AMAP wrb; + struct BE_MCC_CQ_ENTRY_AMAP cq; +} __packed; +struct MCC_MAILBOX_AMAP { + u32 dw[68]; +}; + +#endif /* __fwcmd_mcc_amap_h__ */ diff --git a/trunk/drivers/staging/benet/fwcmd_opcodes.h b/trunk/drivers/staging/benet/fwcmd_opcodes.h new file mode 100644 index 000000000000..23d569386b46 --- /dev/null +++ b/trunk/drivers/staging/benet/fwcmd_opcodes.h @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __fwcmd_opcodes_amap_h__ +#define __fwcmd_opcodes_amap_h__ + +/* + * --- FWCMD_SUBSYSTEMS --- + * The commands are grouped into the following subsystems. The subsystem + * code along with the opcode uniquely identify a particular fwcmd. + */ +#define FWCMD_SUBSYSTEM_RSVD (0) /* This subsystem is reserved. It is */ + /* never used. */ +#define FWCMD_SUBSYSTEM_COMMON (1) /* CMDs in this group are common to + * all subsystems. See + * COMMON_SUBSYSTEM_OPCODES for opcodes + * and Common Host Configuration CMDs + * for the FWCMD descriptions. + */ +#define FWCMD_SUBSYSTEM_COMMON_ISCSI (2) /* CMDs in this group are */ + /* + * common to Initiator and Target. See + * COMMON_ISCSI_SUBSYSTEM_OPCODES and + * Common iSCSI Initiator and Target + * CMDs for the command descriptions. + */ +#define FWCMD_SUBSYSTEM_ETH (3) /* This subsystem is used to + execute Ethernet commands. */ + +#define FWCMD_SUBSYSTEM_TPM (4) /* This subsystem is used + to execute TPM commands. */ +#define FWCMD_SUBSYSTEM_PXE_UNDI (5) /* This subsystem is used + * to execute PXE + * and UNDI specific commands. + */ + +#define FWCMD_SUBSYSTEM_ISCSI_INI (6) /* This subsystem is used to + execute ISCSI Initiator + specific commands. + */ +#define FWCMD_SUBSYSTEM_ISCSI_TGT (7) /* This subsystem is used + to execute iSCSI Target + specific commands.between + PTL and ARM firmware. + */ +#define FWCMD_SUBSYSTEM_MILI_PTL (8) /* This subsystem is used to + execute iSCSI Target specific + commands.between MILI + and PTL. */ +#define FWCMD_SUBSYSTEM_MILI_TMD (9) /* This subsystem is used to + execute iSCSI Target specific + commands between MILI + and TMD. */ +#define FWCMD_SUBSYSTEM_PROXY (11) /* This subsystem is used + to execute proxied commands + within the host at the + explicit request of a + non priviledged domain. + This 'subsystem' is entirely + virtual from the controller + and firmware perspective as + it is implemented in host + drivers. + */ + +/* + * --- COMMON_SUBSYSTEM_OPCODES --- + * These opcodes are common to both networking and storage PCI + * functions. They are used to reserve resources and configure + * BladeEngine. These opcodes all use the FWCMD_SUBSYSTEM_COMMON + * subsystem code. + */ +#define OPCODE_COMMON_NTWK_MAC_QUERY (1) +#define SUBSYSTEM_COMMON_NTWK_MAC_QUERY (1) +#define SUBSYSTEM_COMMON_NTWK_MAC_SET (1) +#define SUBSYSTEM_COMMON_NTWK_MULTICAST_SET (1) +#define SUBSYSTEM_COMMON_NTWK_VLAN_CONFIG (1) +#define SUBSYSTEM_COMMON_NTWK_LINK_STATUS_QUERY (1) +#define SUBSYSTEM_COMMON_READ_FLASHROM (1) +#define SUBSYSTEM_COMMON_WRITE_FLASHROM (1) +#define SUBSYSTEM_COMMON_QUERY_MAX_FWCMD_BUFFER_SIZE (1) +#define SUBSYSTEM_COMMON_ADD_PAGE_TABLES (1) +#define SUBSYSTEM_COMMON_REMOVE_PAGE_TABLES (1) +#define SUBSYSTEM_COMMON_RING_DESTROY (1) +#define SUBSYSTEM_COMMON_CQ_CREATE (1) +#define SUBSYSTEM_COMMON_EQ_CREATE (1) +#define SUBSYSTEM_COMMON_ETH_RX_CREATE (1) +#define SUBSYSTEM_COMMON_ETH_TX_CREATE (1) +#define SUBSYSTEM_COMMON_ISCSI_DEFQ_CREATE (1) +#define SUBSYSTEM_COMMON_ISCSI_WRBQ_CREATE (1) +#define SUBSYSTEM_COMMON_MCC_CREATE (1) +#define SUBSYSTEM_COMMON_JELL_CONFIG (1) +#define SUBSYSTEM_COMMON_FORCE_FAILOVER (1) +#define SUBSYSTEM_COMMON_ADD_TEMPLATE_HEADER_BUFFERS (1) +#define SUBSYSTEM_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS (1) +#define SUBSYSTEM_COMMON_POST_ZERO_BUFFER (1) +#define SUBSYSTEM_COMMON_GET_QOS (1) +#define SUBSYSTEM_COMMON_SET_QOS (1) +#define SUBSYSTEM_COMMON_TCP_GET_STATISTICS (1) +#define SUBSYSTEM_COMMON_SEEPROM_READ (1) +#define SUBSYSTEM_COMMON_TCP_STATE_QUERY (1) +#define SUBSYSTEM_COMMON_GET_CNTL_ATTRIBUTES (1) +#define SUBSYSTEM_COMMON_NOP (1) +#define SUBSYSTEM_COMMON_NTWK_RX_FILTER (1) +#define SUBSYSTEM_COMMON_GET_FW_VERSION (1) +#define SUBSYSTEM_COMMON_SET_FLOW_CONTROL (1) +#define SUBSYSTEM_COMMON_GET_FLOW_CONTROL (1) +#define SUBSYSTEM_COMMON_SET_TCP_PARAMETERS (1) +#define SUBSYSTEM_COMMON_SET_FRAME_SIZE (1) +#define SUBSYSTEM_COMMON_GET_FAT (1) +#define SUBSYSTEM_COMMON_MODIFY_EQ_DELAY (1) +#define SUBSYSTEM_COMMON_FIRMWARE_CONFIG (1) +#define SUBSYSTEM_COMMON_ENABLE_DISABLE_DOMAINS (1) +#define SUBSYSTEM_COMMON_GET_DOMAIN_CONFIG (1) +#define SUBSYSTEM_COMMON_SET_VLD_CONFIG (1) +#define SUBSYSTEM_COMMON_GET_VLD_CONFIG (1) +#define SUBSYSTEM_COMMON_GET_PORT_EQUALIZATION (1) +#define SUBSYSTEM_COMMON_SET_PORT_EQUALIZATION (1) +#define SUBSYSTEM_COMMON_RED_CONFIG (1) +#define OPCODE_COMMON_NTWK_MAC_SET (2) +#define OPCODE_COMMON_NTWK_MULTICAST_SET (3) +#define OPCODE_COMMON_NTWK_VLAN_CONFIG (4) +#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY (5) +#define OPCODE_COMMON_READ_FLASHROM (6) +#define OPCODE_COMMON_WRITE_FLASHROM (7) +#define OPCODE_COMMON_QUERY_MAX_FWCMD_BUFFER_SIZE (8) +#define OPCODE_COMMON_ADD_PAGE_TABLES (9) +#define OPCODE_COMMON_REMOVE_PAGE_TABLES (10) +#define OPCODE_COMMON_RING_DESTROY (11) +#define OPCODE_COMMON_CQ_CREATE (12) +#define OPCODE_COMMON_EQ_CREATE (13) +#define OPCODE_COMMON_ETH_RX_CREATE (14) +#define OPCODE_COMMON_ETH_TX_CREATE (15) +#define OPCODE_COMMON_NET_RESERVED0 (16) /* Reserved */ +#define OPCODE_COMMON_NET_RESERVED1 (17) /* Reserved */ +#define OPCODE_COMMON_NET_RESERVED2 (18) /* Reserved */ +#define OPCODE_COMMON_ISCSI_DEFQ_CREATE (19) +#define OPCODE_COMMON_ISCSI_WRBQ_CREATE (20) +#define OPCODE_COMMON_MCC_CREATE (21) +#define OPCODE_COMMON_JELL_CONFIG (22) +#define OPCODE_COMMON_FORCE_FAILOVER (23) +#define OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS (24) +#define OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS (25) +#define OPCODE_COMMON_POST_ZERO_BUFFER (26) +#define OPCODE_COMMON_GET_QOS (27) +#define OPCODE_COMMON_SET_QOS (28) +#define OPCODE_COMMON_TCP_GET_STATISTICS (29) +#define OPCODE_COMMON_SEEPROM_READ (30) +#define OPCODE_COMMON_TCP_STATE_QUERY (31) +#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES (32) +#define OPCODE_COMMON_NOP (33) +#define OPCODE_COMMON_NTWK_RX_FILTER (34) +#define OPCODE_COMMON_GET_FW_VERSION (35) +#define OPCODE_COMMON_SET_FLOW_CONTROL (36) +#define OPCODE_COMMON_GET_FLOW_CONTROL (37) +#define OPCODE_COMMON_SET_TCP_PARAMETERS (38) +#define OPCODE_COMMON_SET_FRAME_SIZE (39) +#define OPCODE_COMMON_GET_FAT (40) +#define OPCODE_COMMON_MODIFY_EQ_DELAY (41) +#define OPCODE_COMMON_FIRMWARE_CONFIG (42) +#define OPCODE_COMMON_ENABLE_DISABLE_DOMAINS (43) +#define OPCODE_COMMON_GET_DOMAIN_CONFIG (44) +#define OPCODE_COMMON_SET_VLD_CONFIG (45) +#define OPCODE_COMMON_GET_VLD_CONFIG (46) +#define OPCODE_COMMON_GET_PORT_EQUALIZATION (47) +#define OPCODE_COMMON_SET_PORT_EQUALIZATION (48) +#define OPCODE_COMMON_RED_CONFIG (49) + + + +/* + * --- ETH_SUBSYSTEM_OPCODES --- + * These opcodes are used for configuring the Ethernet interfaces. These + * opcodes all use the FWCMD_SUBSYSTEM_ETH subsystem code. + */ +#define OPCODE_ETH_RSS_CONFIG (1) +#define OPCODE_ETH_ACPI_CONFIG (2) +#define SUBSYSTEM_ETH_RSS_CONFIG (3) +#define SUBSYSTEM_ETH_ACPI_CONFIG (3) +#define OPCODE_ETH_PROMISCUOUS (3) +#define SUBSYSTEM_ETH_PROMISCUOUS (3) +#define SUBSYSTEM_ETH_GET_STATISTICS (3) +#define SUBSYSTEM_ETH_GET_RX_FRAG_SIZE (3) +#define SUBSYSTEM_ETH_SET_RX_FRAG_SIZE (3) +#define OPCODE_ETH_GET_STATISTICS (4) +#define OPCODE_ETH_GET_RX_FRAG_SIZE (5) +#define OPCODE_ETH_SET_RX_FRAG_SIZE (6) + + + + + +/* + * --- MCC_STATUS_CODE --- + * These are the global status codes used by all subsystems + */ +#define MCC_STATUS_SUCCESS (0) /* Indicates a successful + completion of the command */ +#define MCC_STATUS_INSUFFICIENT_PRIVILEGES (1) /* The client does not have + sufficient privileges to + execute the command */ +#define MCC_STATUS_INVALID_PARAMETER (2) /* A parameter in the command + was invalid. The extended + status contains the index + of the parameter */ +#define MCC_STATUS_INSUFFICIENT_RESOURCES (3) /* There are insufficient + chip resources to execute + the command */ +#define MCC_STATUS_QUEUE_FLUSHING (4) /* The command is completing + because the queue was + getting flushed */ +#define MCC_STATUS_DMA_FAILED (5) /* The command is completing + with a DMA error */ + +/* + * --- MGMT_ERROR_CODES --- + * Error Codes returned in the status field of the FWCMD response header + */ +#define MGMT_STATUS_SUCCESS (0) /* The FWCMD completed + without errors */ +#define MGMT_STATUS_FAILED (1) /* Error status in the Status + field of the + struct FWCMD_RESPONSE_HEADER */ +#define MGMT_STATUS_ILLEGAL_REQUEST (2) /* Invalid FWCMD opcode */ +#define MGMT_STATUS_ILLEGAL_FIELD (3) /* Invalid parameter in + the FWCMD payload */ + +#endif /* __fwcmd_opcodes_amap_h__ */ diff --git a/trunk/drivers/staging/benet/fwcmd_types_bmap.h b/trunk/drivers/staging/benet/fwcmd_types_bmap.h new file mode 100644 index 000000000000..92217aff3a16 --- /dev/null +++ b/trunk/drivers/staging/benet/fwcmd_types_bmap.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __fwcmd_types_bmap_h__ +#define __fwcmd_types_bmap_h__ + +/* MAC address format */ +struct MAC_ADDRESS_FORMAT { + u16 SizeOfStructure; + u8 MACAddress[6]; +} __packed; + +#endif /* __fwcmd_types_bmap_h__ */ diff --git a/trunk/drivers/staging/benet/host_struct.h b/trunk/drivers/staging/benet/host_struct.h new file mode 100644 index 000000000000..3de6722b980f --- /dev/null +++ b/trunk/drivers/staging/benet/host_struct.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __host_struct_amap_h__ +#define __host_struct_amap_h__ +#include "be_cm.h" +#include "be_common.h" +#include "descriptors.h" + +/* --- EQ_COMPLETION_MAJOR_CODE_ENUM --- */ +#define EQ_MAJOR_CODE_COMPLETION (0) /* Completion event on a */ + /* qcompletion ueue. */ +#define EQ_MAJOR_CODE_ETH (1) /* Affiliated Ethernet Event. */ +#define EQ_MAJOR_CODE_RESERVED (2) /* Reserved */ +#define EQ_MAJOR_CODE_RDMA (3) /* Affiliated RDMA Event. */ +#define EQ_MAJOR_CODE_ISCSI (4) /* Affiliated ISCSI Event */ +#define EQ_MAJOR_CODE_UNAFFILIATED (5) /* Unaffiliated Event */ + +/* --- EQ_COMPLETION_MINOR_CODE_ENUM --- */ +#define EQ_MINOR_CODE_COMPLETION (0) /* Completion event on a */ + /* completion queue. */ +#define EQ_MINOR_CODE_OTHER (1) /* Other Event (TBD). */ + +/* Queue Entry Definition for all 4 byte event queue types. */ +struct BE_EQ_ENTRY_AMAP { + u8 Valid; /* DWORD 0 */ + u8 MajorCode[3]; /* DWORD 0 */ + u8 MinorCode[12]; /* DWORD 0 */ + u8 ResourceID[16]; /* DWORD 0 */ +} __packed; +struct EQ_ENTRY_AMAP { + u32 dw[1]; +}; + +/* + * --- ETH_EVENT_CODE --- + * These codes are returned by the MPU when one of these events has occurred, + * and the event is configured to report to an Event Queue when an event + * is detected. + */ +#define ETH_EQ_LINK_STATUS (0) /* Link status change event */ + /* detected. */ +#define ETH_EQ_WATERMARK (1) /* watermark event detected. */ +#define ETH_EQ_MAGIC_PKT (2) /* magic pkt event detected. */ +#define ETH_EQ_ACPI_PKT0 (3) /* ACPI interesting packet */ + /* detected. */ +#define ETH_EQ_ACPI_PKT1 (3) /* ACPI interesting packet */ + /* detected. */ +#define ETH_EQ_ACPI_PKT2 (3) /* ACPI interesting packet */ + /* detected. */ +#define ETH_EQ_ACPI_PKT3 (3) /* ACPI interesting packet */ + /* detected. */ + +/* + * --- ETH_TX_COMPL_STATUS_ENUM --- + * Status codes contained in Ethernet TX completion descriptors. + */ +#define ETH_COMP_VALID (0) +#define ETH_COMP_ERROR (1) +#define ETH_COMP_INVALID (15) + +/* + * --- ETH_TX_COMPL_PORT_ENUM --- + * Port indicator contained in Ethernet TX completion descriptors. + */ +#define ETH_COMP_PORT0 (0) +#define ETH_COMP_PORT1 (1) +#define ETH_COMP_MGMT (2) + +/* + * --- ETH_TX_COMPL_CT_ENUM --- + * Completion type indicator contained in Ethernet TX completion descriptors. + */ +#define ETH_COMP_ETH (0) + +/* + * Work request block that the driver issues to the chip for + * Ethernet transmissions. All control fields must be valid in each WRB for + * a message. The controller, as specified by the flags, optionally writes + * an entry to the Completion Ring and generate an event. + */ +struct BE_ETH_WRB_AMAP { + u8 frag_pa_hi[32]; /* DWORD 0 */ + u8 frag_pa_lo[32]; /* DWORD 1 */ + u8 complete; /* DWORD 2 */ + u8 event; /* DWORD 2 */ + u8 crc; /* DWORD 2 */ + u8 forward; /* DWORD 2 */ + u8 ipsec; /* DWORD 2 */ + u8 mgmt; /* DWORD 2 */ + u8 ipcs; /* DWORD 2 */ + u8 udpcs; /* DWORD 2 */ + u8 tcpcs; /* DWORD 2 */ + u8 lso; /* DWORD 2 */ + u8 last; /* DWORD 2 */ + u8 vlan; /* DWORD 2 */ + u8 dbg[3]; /* DWORD 2 */ + u8 hash_val[3]; /* DWORD 2 */ + u8 lso_mss[14]; /* DWORD 2 */ + u8 frag_len[16]; /* DWORD 3 */ + u8 vlan_tag[16]; /* DWORD 3 */ +} __packed; +struct ETH_WRB_AMAP { + u32 dw[4]; +}; + +/* This is an Ethernet transmit completion descriptor */ +struct BE_ETH_TX_COMPL_AMAP { + u8 user_bytes[16]; /* DWORD 0 */ + u8 nwh_bytes[8]; /* DWORD 0 */ + u8 lso; /* DWORD 0 */ + u8 rsvd0[7]; /* DWORD 0 */ + u8 wrb_index[16]; /* DWORD 1 */ + u8 ct[2]; /* DWORD 1 */ + u8 port[2]; /* DWORD 1 */ + u8 rsvd1[8]; /* DWORD 1 */ + u8 status[4]; /* DWORD 1 */ + u8 rsvd2[16]; /* DWORD 2 */ + u8 ringid[11]; /* DWORD 2 */ + u8 hash_val[4]; /* DWORD 2 */ + u8 valid; /* DWORD 2 */ + u8 rsvd3[32]; /* DWORD 3 */ +} __packed; +struct ETH_TX_COMPL_AMAP { + u32 dw[4]; +}; + +/* Ethernet Receive Buffer descriptor */ +struct BE_ETH_RX_D_AMAP { + u8 fragpa_hi[32]; /* DWORD 0 */ + u8 fragpa_lo[32]; /* DWORD 1 */ +} __packed; +struct ETH_RX_D_AMAP { + u32 dw[2]; +}; + +/* This is an Ethernet Receive Completion Descriptor */ +struct BE_ETH_RX_COMPL_AMAP { + u8 vlan_tag[16]; /* DWORD 0 */ + u8 pktsize[14]; /* DWORD 0 */ + u8 port; /* DWORD 0 */ + u8 rsvd0; /* DWORD 0 */ + u8 err; /* DWORD 1 */ + u8 rsshp; /* DWORD 1 */ + u8 ipf; /* DWORD 1 */ + u8 tcpf; /* DWORD 1 */ + u8 udpf; /* DWORD 1 */ + u8 ipcksm; /* DWORD 1 */ + u8 tcpcksm; /* DWORD 1 */ + u8 udpcksm; /* DWORD 1 */ + u8 macdst[6]; /* DWORD 1 */ + u8 vtp; /* DWORD 1 */ + u8 vtm; /* DWORD 1 */ + u8 fragndx[10]; /* DWORD 1 */ + u8 ct[2]; /* DWORD 1 */ + u8 ipsec; /* DWORD 1 */ + u8 numfrags[3]; /* DWORD 1 */ + u8 rsvd1[31]; /* DWORD 2 */ + u8 valid; /* DWORD 2 */ + u8 rsshash[32]; /* DWORD 3 */ +} __packed; +struct ETH_RX_COMPL_AMAP { + u32 dw[4]; +}; + +#endif /* __host_struct_amap_h__ */ diff --git a/trunk/drivers/staging/benet/hwlib.h b/trunk/drivers/staging/benet/hwlib.h new file mode 100644 index 000000000000..afedf4dc5903 --- /dev/null +++ b/trunk/drivers/staging/benet/hwlib.h @@ -0,0 +1,830 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#ifndef __hwlib_h__ +#define __hwlib_h__ + +#include +#include +#include +#include + +#include "regmap.h" /* srcgen array map output */ + +#include "asyncmesg.h" +#include "fwcmd_opcodes.h" +#include "post_codes.h" +#include "fwcmd_mcc.h" + +#include "fwcmd_types_bmap.h" +#include "fwcmd_common_bmap.h" +#include "fwcmd_eth_bmap.h" +#include "bestatus.h" +/* + * + * Macros for reading/writing a protection domain or CSR registers + * in BladeEngine. + */ +#define PD_READ(fo, field) ioread32((fo)->db_va + \ + offsetof(struct BE_PROTECTION_DOMAIN_DBMAP_AMAP, field)/8) + +#define PD_WRITE(fo, field, val) iowrite32(val, (fo)->db_va + \ + offsetof(struct BE_PROTECTION_DOMAIN_DBMAP_AMAP, field)/8) + +#define CSR_READ(fo, field) ioread32((fo)->csr_va + \ + offsetof(struct BE_BLADE_ENGINE_CSRMAP_AMAP, field)/8) + +#define CSR_WRITE(fo, field, val) iowrite32(val, (fo)->csr_va + \ + offsetof(struct BE_BLADE_ENGINE_CSRMAP_AMAP, field)/8) + +#define PCICFG0_READ(fo, field) ioread32((fo)->pci_va + \ + offsetof(struct BE_PCICFG0_CSRMAP_AMAP, field)/8) + +#define PCICFG0_WRITE(fo, field, val) iowrite32(val, (fo)->pci_va + \ + offsetof(struct BE_PCICFG0_CSRMAP_AMAP, field)/8) + +#define PCICFG1_READ(fo, field) ioread32((fo)->pci_va + \ + offsetof(struct BE_PCICFG1_CSRMAP_AMAP, field)/8) + +#define PCICFG1_WRITE(fo, field, val) iowrite32(val, (fo)->pci_va + \ + offsetof(struct BE_PCICFG1_CSRMAP_AMAP, field)/8) + +#ifdef BE_DEBUG +#define ASSERT(c) BUG_ON(!(c)); +#else +#define ASSERT(c) +#endif + +/* debug levels */ +enum BE_DEBUG_LEVELS { + DL_ALWAYS = 0, /* cannot be masked */ + DL_ERR = 0x1, /* errors that should never happen */ + DL_WARN = 0x2, /* something questionable. + recoverable errors */ + DL_NOTE = 0x4, /* infrequent, important debug info */ + DL_INFO = 0x8, /* debug information */ + DL_VERBOSE = 0x10, /* detailed info, such as buffer traces */ + BE_DL_MIN_VALUE = 0x1, /* this is the min value used */ + BE_DL_MAX_VALUE = 0x80 /* this is the higheset value used */ +} ; + +extern unsigned int trace_level; + +#define TRACE(lm, fmt, args...) { \ + if (trace_level & lm) { \ + printk(KERN_NOTICE "BE: %s:%d \n" fmt, \ + __FILE__ , __LINE__ , ## args); \ + } \ + } + +static inline unsigned int be_trace_set_level(unsigned int level) +{ + unsigned int old_level = trace_level; + trace_level = level; + return old_level; +} + +#define be_trace_get_level() trace_level +/* + * Returns number of pages spanned by the size of data + * starting at the given address. + */ +#define PAGES_SPANNED(_address, _size) \ + ((u32)((((size_t)(_address) & (PAGE_SIZE - 1)) + \ + (_size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) +/* Byte offset into the page corresponding to given address */ +#define OFFSET_IN_PAGE(_addr_) ((size_t)(_addr_) & (PAGE_SIZE-1)) + +/* + * circular subtract. + * Returns a - b assuming a circular number system, where a and b are + * in range (0, maxValue-1). If a==b, zero is returned so the + * highest value possible with this subtraction is maxValue-1. + */ +static inline u32 be_subc(u32 a, u32 b, u32 max) +{ + ASSERT(a <= max && b <= max); + ASSERT(max > 0); + return a >= b ? (a - b) : (max - b + a); +} + +static inline u32 be_addc(u32 a, u32 b, u32 max) +{ + ASSERT(a < max); + ASSERT(max > 0); + return (max - a > b) ? (a + b) : (b + a - max); +} + +/* descriptor for a physically contiguous memory used for ring */ +struct ring_desc { + u32 length; /* length in bytes */ + void *va; /* virtual address */ + u64 pa; /* bus address */ +} ; + +/* + * This structure stores information about a ring shared between hardware + * and software. Each ring is allocated by the driver in the uncached + * extension and mapped into BladeEngine's unified table. + */ +struct mp_ring { + u32 pages; /* queue size in pages */ + u32 id; /* queue id assigned by beklib */ + u32 num; /* number of elements in queue */ + u32 cidx; /* consumer index */ + u32 pidx; /* producer index -- not used by most rings */ + u32 itemSize; /* size in bytes of one object */ + + void *va; /* The virtual address of the ring. + This should be last to allow 32 & 64 + bit debugger extensions to work. */ +} ; + +/*----------- amap bit filed get / set macros and functions -----*/ +/* + * Structures defined in the map header files (under fw/amap/) with names + * in the format BE__AMAP are pseudo structures with members + * of type u8. These structures are templates that are used in + * conjuntion with the structures with names in the format + * _AMAP to calculate the bit masks and bit offsets to get or set + * bit fields in structures. The structures _AMAP are arrays + * of 32 bits words and have the correct size. The following macros + * provide convenient ways to get and set the various members + * in the structures without using strucctures with bit fields. + * Always use the macros AMAP_GET_BITS_PTR and AMAP_SET_BITS_PTR + * macros to extract and set various members. + */ + +/* + * Returns the a bit mask for the register that is NOT shifted into location. + * That means return values always look like: 0x1, 0xFF, 0x7FF, etc... + */ +static inline u32 amap_mask(u32 bit_size) +{ + return bit_size == 32 ? 0xFFFFFFFF : (1 << bit_size) - 1; +} + +#define AMAP_BIT_MASK(_struct_, field) \ + amap_mask(AMAP_BIT_SIZE(_struct_, field)) + +/* + * non-optimized set bits function. First clears the bits and then assigns them. + * This does not require knowledge of the particular DWORD you are setting. + * e.g. AMAP_SET_BITS_PTR (struct, field1, &contextMemory, 123); + */ +static inline void +amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value) +{ + u32 *dw = (u32 *)ptr; + *(dw + dw_offset) &= ~(mask << offset); + *(dw + dw_offset) |= (mask & value) << offset; +} + +#define AMAP_SET_BITS_PTR(_struct_, field, _structPtr_, val) \ + amap_set(_structPtr_, AMAP_WORD_OFFSET(_struct_, field),\ + AMAP_BIT_MASK(_struct_, field), \ + AMAP_BIT_OFFSET(_struct_, field), val) +/* + * Non-optimized routine that gets the bits without knowing the correct DWORD. + * e.g. fieldValue = AMAP_GET_BITS_PTR (struct, field1, &contextMemory); + */ +static inline u32 +amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset) +{ + u32 *dw = (u32 *)ptr; + return mask & (*(dw + dw_offset) >> offset); +} +#define AMAP_GET_BITS_PTR(_struct_, field, _structPtr_) \ + amap_get(_structPtr_, AMAP_WORD_OFFSET(_struct_, field), \ + AMAP_BIT_MASK(_struct_, field), \ + AMAP_BIT_OFFSET(_struct_, field)) + +/* Returns 0-31 representing bit offset within a DWORD of a bitfield. */ +#define AMAP_BIT_OFFSET(_struct_, field) \ + (offsetof(struct BE_ ## _struct_ ## _AMAP, field) % 32) + +/* Returns 0-n representing DWORD offset of bitfield within the structure. */ +#define AMAP_WORD_OFFSET(_struct_, field) \ + (offsetof(struct BE_ ## _struct_ ## _AMAP, field)/32) + +/* Returns size of bitfield in bits. */ +#define AMAP_BIT_SIZE(_struct_, field) \ + sizeof(((struct BE_ ## _struct_ ## _AMAP*)0)->field) + +struct be_mcc_wrb_response_copy { + u16 length; /* bytes in response */ + u16 fwcmd_offset; /* offset within the wrb of the response */ + void *va; /* user's va to copy response into */ + +} ; +typedef void (*mcc_wrb_cqe_callback) (void *context, int status, + struct MCC_WRB_AMAP *optional_wrb); +struct be_mcc_wrb_context { + + mcc_wrb_cqe_callback internal_cb; /* Function to call on + completion */ + void *internal_cb_context; /* Parameter to pass + to completion function */ + + mcc_wrb_cqe_callback cb; /* Function to call on completion */ + void *cb_context; /* Parameter to pass to completion function */ + + int *users_final_status; /* pointer to a local + variable for synchronous + commands */ + struct MCC_WRB_AMAP *wrb; /* pointer to original wrb for embedded + commands only */ + struct list_head next; /* links context structs together in + free list */ + + struct be_mcc_wrb_response_copy copy; /* Optional parameters to copy + embedded response to user's va */ + +#if defined(BE_DEBUG) + u16 subsystem, opcode; /* Track this FWCMD for debug builds. */ + struct MCC_WRB_AMAP *ring_wrb; + u32 consumed_count; +#endif +} ; + +/* + Represents a function object for network or storage. This + is used to manage per-function resources like MCC CQs, etc. +*/ +struct be_function_object { + + u32 magic; /*!< magic for detecting memory corruption. */ + + /* PCI BAR mapped addresses */ + u8 __iomem *csr_va; /* CSR */ + u8 __iomem *db_va; /* Door Bell */ + u8 __iomem *pci_va; /* PCI config space */ + u32 emulate; /* if set, MPU is not available. + Emulate everything. */ + u32 pend_queue_driving; /* if set, drive the queued WRBs + after releasing the WRB lock */ + + spinlock_t post_lock; /* lock for verifying one thread posting wrbs */ + spinlock_t cq_lock; /* lock for verifying one thread + processing cq */ + spinlock_t mcc_context_lock; /* lock for protecting mcc + context free list */ + unsigned long post_irq; + unsigned long cq_irq; + + u32 type; + u32 pci_function_number; + + struct be_mcc_object *mcc; /* mcc rings. */ + + struct { + struct MCC_MAILBOX_AMAP *va; /* VA to the mailbox */ + u64 pa; /* PA to the mailbox */ + u32 length; /* byte length of mailbox */ + + /* One default context struct used for posting at + * least one MCC_WRB + */ + struct be_mcc_wrb_context default_context; + bool default_context_allocated; + } mailbox; + + struct { + + /* Wake on lans configured. */ + u32 wol_bitmask; /* bits 0,1,2,3 are set if + corresponding index is enabled */ + } config; + + + struct BE_FIRMWARE_CONFIG fw_config; +} ; + +/* + Represents an Event Queue +*/ +struct be_eq_object { + u32 magic; + atomic_t ref_count; + + struct be_function_object *parent_function; + + struct list_head eq_list; + struct list_head cq_list_head; + + u32 eq_id; + void *cb_context; + +} ; + +/* + Manages a completion queue +*/ +struct be_cq_object { + u32 magic; + atomic_t ref_count; + + struct be_function_object *parent_function; + struct be_eq_object *eq_object; + + struct list_head cq_list; + struct list_head cqlist_for_eq; + + void *va; + u32 num_entries; + + void *cb_context; + + u32 cq_id; + +} ; + +/* + Manages an ethernet send queue +*/ +struct be_ethsq_object { + u32 magic; + + struct list_head list; + + struct be_function_object *parent_function; + struct be_cq_object *cq_object; + u32 bid; + +} ; + +/* +@brief + Manages an ethernet receive queue +*/ +struct be_ethrq_object { + u32 magic; + struct list_head list; + struct be_function_object *parent_function; + u32 rid; + struct be_cq_object *cq_object; + struct be_cq_object *rss_cq_object[4]; + +} ; + +/* + Manages an MCC +*/ +typedef void (*mcc_async_event_callback) (void *context, u32 event_code, + void *event); +struct be_mcc_object { + u32 magic; + + struct be_function_object *parent_function; + struct list_head mcc_list; + + struct be_cq_object *cq_object; + + /* Async event callback for MCC CQ. */ + mcc_async_event_callback async_cb; + void *async_context; + + struct { + struct be_mcc_wrb_context *base; + u32 num; + struct list_head list_head; + } wrb_context; + + struct { + struct ring_desc *rd; + struct mp_ring ring; + } sq; + + struct { + struct mp_ring ring; + } cq; + + u32 processing; /* flag indicating that one thread + is processing CQ */ + u32 rearm; /* doorbell rearm setting to make + sure the active processing thread */ + /* rearms the CQ if any of the threads requested it. */ + + struct list_head backlog; + u32 backlog_length; + u32 driving_backlog; + u32 consumed_index; + +} ; + + +/* Queue context header -- the required software information for + * queueing a WRB. + */ +struct be_queue_driver_context { + mcc_wrb_cqe_callback internal_cb; /* Function to call on + completion */ + void *internal_cb_context; /* Parameter to pass + to completion function */ + + mcc_wrb_cqe_callback cb; /* Function to call on completion */ + void *cb_context; /* Parameter to pass to completion function */ + + struct be_mcc_wrb_response_copy copy; /* Optional parameters to copy + embedded response to user's va */ + void *optional_fwcmd_va; + struct list_head list; + u32 bytes; +} ; + +/* + * Common MCC WRB header that all commands require. + */ +struct be_mcc_wrb_header { + u8 rsvd[offsetof(struct BE_MCC_WRB_AMAP, payload)/8]; +} ; + +/* + * All non embedded commands supported by hwlib functions only allow + * 1 SGE. This queue context handles them all. + */ +struct be_nonembedded_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct MCC_SGE_AMAP sge[1]; +} ; + +/* + * ------------------------------------------------------------------------ + * This section contains the specific queue struct for each command. + * The user could always provide a be_generic_q_ctxt but this is a + * rather large struct. By using the specific struct, memory consumption + * can be reduced. + * ------------------------------------------------------------------------ + */ + +struct be_link_status_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY fwcmd; +} ; + +struct be_multicast_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct FWCMD_COMMON_NTWK_MULTICAST_SET fwcmd; +} ; + + +struct be_vlan_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct FWCMD_COMMON_NTWK_VLAN_CONFIG fwcmd; +} ; + +struct be_promiscuous_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct FWCMD_ETH_PROMISCUOUS fwcmd; +} ; + +struct be_force_failover_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct FWCMD_COMMON_FORCE_FAILOVER fwcmd; +} ; + + +struct be_rxf_filter_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct FWCMD_COMMON_NTWK_RX_FILTER fwcmd; +} ; + +struct be_eq_modify_delay_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct FWCMD_COMMON_MODIFY_EQ_DELAY fwcmd; +} ; + +/* + * The generic context is the largest size that would be required. + * It is the software context plus an entire WRB. + */ +struct be_generic_q_ctxt { + struct be_queue_driver_context context; + struct be_mcc_wrb_header wrb_header; + struct MCC_WRB_PAYLOAD_AMAP payload; +} ; + +/* + * Types for the BE_QUEUE_CONTEXT object. + */ +#define BE_QUEUE_INVALID (0) +#define BE_QUEUE_LINK_STATUS (0xA006) +#define BE_QUEUE_ETH_STATS (0xA007) +#define BE_QUEUE_TPM_STATS (0xA008) +#define BE_QUEUE_TCP_STATS (0xA009) +#define BE_QUEUE_MULTICAST (0xA00A) +#define BE_QUEUE_VLAN (0xA00B) +#define BE_QUEUE_RSS (0xA00C) +#define BE_QUEUE_FORCE_FAILOVER (0xA00D) +#define BE_QUEUE_PROMISCUOUS (0xA00E) +#define BE_QUEUE_WAKE_ON_LAN (0xA00F) +#define BE_QUEUE_NOP (0xA010) + +/* --- BE_FUNCTION_ENUM --- */ +#define BE_FUNCTION_TYPE_ISCSI (0) +#define BE_FUNCTION_TYPE_NETWORK (1) +#define BE_FUNCTION_TYPE_ARM (2) + +/* --- BE_ETH_TX_RING_TYPE_ENUM --- */ +#define BE_ETH_TX_RING_TYPE_FORWARDING (1) /* Ether ring for forwarding */ +#define BE_ETH_TX_RING_TYPE_STANDARD (2) /* Ether ring for sending */ + /* network packets. */ +#define BE_ETH_TX_RING_TYPE_BOUND (3) /* Ethernet ring for sending */ + /* network packets, bound */ + /* to a physical port. */ +/* + * ---------------------------------------------------------------------- + * API MACROS + * ---------------------------------------------------------------------- + */ +#define BE_FWCMD_NAME(_short_name_) struct FWCMD_##_short_name_ +#define BE_OPCODE_NAME(_short_name_) OPCODE_##_short_name_ +#define BE_SUBSYSTEM_NAME(_short_name_) SUBSYSTEM_##_short_name_ + + +#define BE_PREPARE_EMBEDDED_FWCMD(_pfob_, _wrb_, _short_name_) \ + ((BE_FWCMD_NAME(_short_name_) *) \ + be_function_prepare_embedded_fwcmd(_pfob_, _wrb_, \ + sizeof(BE_FWCMD_NAME(_short_name_)), \ + FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.request), \ + FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.response), \ + BE_OPCODE_NAME(_short_name_), \ + BE_SUBSYSTEM_NAME(_short_name_))); + +#define BE_PREPARE_NONEMBEDDED_FWCMD(_pfob_, _wrb_, _iva_, _ipa_, _short_name_)\ + ((BE_FWCMD_NAME(_short_name_) *) \ + be_function_prepare_nonembedded_fwcmd(_pfob_, _wrb_, (_iva_), (_ipa_), \ + sizeof(BE_FWCMD_NAME(_short_name_)), \ + FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.request), \ + FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.response), \ + BE_OPCODE_NAME(_short_name_), \ + BE_SUBSYSTEM_NAME(_short_name_))); + +int be_function_object_create(u8 __iomem *csr_va, u8 __iomem *db_va, + u8 __iomem *pci_va, u32 function_type, struct ring_desc *mailbox_rd, + struct be_function_object *pfob); + +int be_function_object_destroy(struct be_function_object *pfob); +int be_function_cleanup(struct be_function_object *pfob); + + +int be_function_get_fw_version(struct be_function_object *pfob, + struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD *fw_version, + mcc_wrb_cqe_callback cb, void *cb_context); + + +int be_eq_modify_delay(struct be_function_object *pfob, + u32 num_eq, struct be_eq_object **eq_array, + u32 *eq_delay_array, mcc_wrb_cqe_callback cb, + void *cb_context, + struct be_eq_modify_delay_q_ctxt *q_ctxt); + + + +int be_eq_create(struct be_function_object *pfob, + struct ring_desc *rd, u32 eqe_size, u32 num_entries, + u32 watermark, u32 timer_delay, struct be_eq_object *eq_object); + +int be_eq_destroy(struct be_eq_object *eq); + +int be_cq_create(struct be_function_object *pfob, + struct ring_desc *rd, u32 length, + bool solicited_eventable, bool no_delay, + u32 wm_thresh, struct be_eq_object *eq_object, + struct be_cq_object *cq_object); + +int be_cq_destroy(struct be_cq_object *cq); + +int be_mcc_ring_create(struct be_function_object *pfob, + struct ring_desc *rd, u32 length, + struct be_mcc_wrb_context *context_array, + u32 num_context_entries, + struct be_cq_object *cq, struct be_mcc_object *mcc); +int be_mcc_ring_destroy(struct be_mcc_object *mcc_object); + +int be_mcc_process_cq(struct be_mcc_object *mcc_object, bool rearm); + +int be_mcc_add_async_event_callback(struct be_mcc_object *mcc_object, + mcc_async_event_callback cb, void *cb_context); + +int be_pci_soft_reset(struct be_function_object *pfob); + + +int be_drive_POST(struct be_function_object *pfob); + + +int be_eth_sq_create(struct be_function_object *pfob, + struct ring_desc *rd, u32 length_in_bytes, + u32 type, u32 ulp, struct be_cq_object *cq_object, + struct be_ethsq_object *eth_sq); + +struct be_eth_sq_parameters { + u32 port; + u32 rsvd0[2]; +} ; + +int be_eth_sq_create_ex(struct be_function_object *pfob, + struct ring_desc *rd, u32 length_in_bytes, + u32 type, u32 ulp, struct be_cq_object *cq_object, + struct be_eth_sq_parameters *ex_parameters, + struct be_ethsq_object *eth_sq); +int be_eth_sq_destroy(struct be_ethsq_object *eth_sq); + +int be_eth_set_flow_control(struct be_function_object *pfob, + bool txfc_enable, bool rxfc_enable); + +int be_eth_get_flow_control(struct be_function_object *pfob, + bool *txfc_enable, bool *rxfc_enable); +int be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps); + +int be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps); + +int be_eth_set_frame_size(struct be_function_object *pfob, + u32 *tx_frame_size, u32 *rx_frame_size); + +int be_eth_rq_create(struct be_function_object *pfob, + struct ring_desc *rd, struct be_cq_object *cq_object, + struct be_cq_object *bcmc_cq_object, + struct be_ethrq_object *eth_rq); + +int be_eth_rq_destroy(struct be_ethrq_object *eth_rq); + +int be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush, + mcc_wrb_cqe_callback cb, void *cb_context); +int be_eth_rq_set_frag_size(struct be_function_object *pfob, + u32 new_frag_size_bytes, u32 *actual_frag_size_bytes); +int be_eth_rq_get_frag_size(struct be_function_object *pfob, + u32 *frag_size_bytes); + +void *be_function_prepare_embedded_fwcmd(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, + u32 payload_length, u32 request_length, + u32 response_length, u32 opcode, u32 subsystem); +void *be_function_prepare_nonembedded_fwcmd(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, void *fwcmd_header_va, u64 fwcmd_header_pa, + u32 payload_length, u32 request_length, u32 response_length, + u32 opcode, u32 subsystem); + + +struct MCC_WRB_AMAP * +be_function_peek_mcc_wrb(struct be_function_object *pfob); + +int be_rxf_mac_address_read_write(struct be_function_object *pfob, + bool port1, bool mac1, bool mgmt, + bool write, bool permanent, u8 *mac_address, + mcc_wrb_cqe_callback cb, + void *cb_context); + +int be_rxf_multicast_config(struct be_function_object *pfob, + bool promiscuous, u32 num, u8 *mac_table, + mcc_wrb_cqe_callback cb, + void *cb_context, + struct be_multicast_q_ctxt *q_ctxt); + +int be_rxf_vlan_config(struct be_function_object *pfob, + bool promiscuous, u32 num, u16 *vlan_tag_array, + mcc_wrb_cqe_callback cb, void *cb_context, + struct be_vlan_q_ctxt *q_ctxt); + + +int be_rxf_link_status(struct be_function_object *pfob, + struct BE_LINK_STATUS *link_status, + mcc_wrb_cqe_callback cb, + void *cb_context, + struct be_link_status_q_ctxt *q_ctxt); + + +int be_rxf_query_eth_statistics(struct be_function_object *pfob, + struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd, + u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb, + void *cb_context, + struct be_nonembedded_q_ctxt *q_ctxt); + +int be_rxf_promiscuous(struct be_function_object *pfob, + bool enable_port0, bool enable_port1, + mcc_wrb_cqe_callback cb, void *cb_context, + struct be_promiscuous_q_ctxt *q_ctxt); + + +int be_rxf_filter_config(struct be_function_object *pfob, + struct NTWK_RX_FILTER_SETTINGS *settings, + mcc_wrb_cqe_callback cb, + void *cb_context, + struct be_rxf_filter_q_ctxt *q_ctxt); + +/* + * ------------------------------------------------------ + * internal functions used by hwlib + * ------------------------------------------------------ + */ + + +int be_function_ring_destroy(struct be_function_object *pfob, + u32 id, u32 ring_type, mcc_wrb_cqe_callback cb, + void *cb_context, + mcc_wrb_cqe_callback internal_cb, + void *internal_callback_context); + +int be_function_post_mcc_wrb(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, + struct be_generic_q_ctxt *q_ctxt, + mcc_wrb_cqe_callback cb, void *cb_context, + mcc_wrb_cqe_callback internal_cb, + void *internal_cb_context, void *optional_fwcmd_va, + struct be_mcc_wrb_response_copy *response_copy); + +int be_function_queue_mcc_wrb(struct be_function_object *pfob, + struct be_generic_q_ctxt *q_ctxt); + +/* + * ------------------------------------------------------ + * MCC QUEUE + * ------------------------------------------------------ + */ + +int be_mpu_init_mailbox(struct be_function_object *pfob, struct ring_desc *rd); + + +struct MCC_WRB_AMAP * +_be_mpu_peek_ring_wrb(struct be_mcc_object *mcc, bool driving_queue); + +struct be_mcc_wrb_context * +_be_mcc_allocate_wrb_context(struct be_function_object *pfob); + +void _be_mcc_free_wrb_context(struct be_function_object *pfob, + struct be_mcc_wrb_context *context); + +int _be_mpu_post_wrb_mailbox(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context); + +int _be_mpu_post_wrb_ring(struct be_mcc_object *mcc, + struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context); + +void be_drive_mcc_wrb_queue(struct be_mcc_object *mcc); + + +/* + * ------------------------------------------------------ + * Ring Sizes + * ------------------------------------------------------ + */ +static inline u32 be_ring_encoding_to_length(u32 encoding, u32 object_size) +{ + + ASSERT(encoding != 1); /* 1 is rsvd */ + ASSERT(encoding < 16); + ASSERT(object_size > 0); + + if (encoding == 0) /* 32k deep */ + encoding = 16; + + return (1 << (encoding - 1)) * object_size; +} + +static inline +u32 be_ring_length_to_encoding(u32 length_in_bytes, u32 object_size) +{ + + u32 count, encoding; + + ASSERT(object_size > 0); + ASSERT(length_in_bytes % object_size == 0); + + count = length_in_bytes / object_size; + + ASSERT(count > 1); + ASSERT(count <= 32 * 1024); + ASSERT(length_in_bytes <= 8 * PAGE_SIZE); /* max ring size in UT */ + + encoding = __ilog2_u32(count) + 1; + + if (encoding == 16) + encoding = 0; /* 32k deep */ + + return encoding; +} + +void be_rd_to_pa_list(struct ring_desc *rd, struct PHYS_ADDR *pa_list, + u32 max_num); +#endif /* __hwlib_h__ */ diff --git a/trunk/drivers/staging/benet/mpu.c b/trunk/drivers/staging/benet/mpu.c new file mode 100644 index 000000000000..269cc11d3055 --- /dev/null +++ b/trunk/drivers/staging/benet/mpu.c @@ -0,0 +1,1364 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +#include +#include "hwlib.h" +#include "bestatus.h" + +static +inline void mp_ring_create(struct mp_ring *ring, u32 num, u32 size, void *va) +{ + ASSERT(ring); + memset(ring, 0, sizeof(struct mp_ring)); + ring->num = num; + ring->pages = DIV_ROUND_UP(num * size, PAGE_SIZE); + ring->itemSize = size; + ring->va = va; +} + +/* + * ----------------------------------------------------------------------- + * Interface for 2 index rings. i.e. consumer/producer rings + * -------------------------------------------------------------------------- + */ + +/* Returns number items pending on ring. */ +static inline u32 mp_ring_num_pending(struct mp_ring *ring) +{ + ASSERT(ring); + if (ring->num == 0) + return 0; + return be_subc(ring->pidx, ring->cidx, ring->num); +} + +/* Returns number items free on ring. */ +static inline u32 mp_ring_num_empty(struct mp_ring *ring) +{ + ASSERT(ring); + return ring->num - 1 - mp_ring_num_pending(ring); +} + +/* Consume 1 item */ +static inline void mp_ring_consume(struct mp_ring *ring) +{ + ASSERT(ring); + ASSERT(ring->pidx != ring->cidx); + + ring->cidx = be_addc(ring->cidx, 1, ring->num); +} + +/* Produce 1 item */ +static inline void mp_ring_produce(struct mp_ring *ring) +{ + ASSERT(ring); + ring->pidx = be_addc(ring->pidx, 1, ring->num); +} + +/* Consume count items */ +static inline void mp_ring_consume_multiple(struct mp_ring *ring, u32 count) +{ + ASSERT(ring); + ASSERT(mp_ring_num_pending(ring) >= count); + ring->cidx = be_addc(ring->cidx, count, ring->num); +} + +static inline void *mp_ring_item(struct mp_ring *ring, u32 index) +{ + ASSERT(ring); + ASSERT(index < ring->num); + ASSERT(ring->itemSize > 0); + return (u8 *) ring->va + index * ring->itemSize; +} + +/* Ptr to produce item */ +static inline void *mp_ring_producer_ptr(struct mp_ring *ring) +{ + ASSERT(ring); + return mp_ring_item(ring, ring->pidx); +} + +/* + * Returns a pointer to the current location in the ring. + * This is used for rings with 1 index. + */ +static inline void *mp_ring_current(struct mp_ring *ring) +{ + ASSERT(ring); + ASSERT(ring->pidx == 0); /* not used */ + + return mp_ring_item(ring, ring->cidx); +} + +/* + * Increment index for rings with only 1 index. + * This is used for rings with 1 index. + */ +static inline void *mp_ring_next(struct mp_ring *ring) +{ + ASSERT(ring); + ASSERT(ring->num > 0); + ASSERT(ring->pidx == 0); /* not used */ + + ring->cidx = be_addc(ring->cidx, 1, ring->num); + return mp_ring_current(ring); +} + +/* + This routine waits for a previously posted mailbox WRB to be completed. + Specifically it waits for the mailbox to say that it's ready to accept + more data by setting the LSB of the mailbox pd register to 1. + + pcontroller - The function object to post this data to + + IRQL < DISPATCH_LEVEL +*/ +static void be_mcc_mailbox_wait(struct be_function_object *pfob) +{ + struct MPU_MAILBOX_DB_AMAP mailbox_db; + u32 i = 0; + u32 ready; + + if (pfob->emulate) { + /* No waiting for mailbox in emulated mode. */ + return; + } + + mailbox_db.dw[0] = PD_READ(pfob, mcc_bootstrap_db); + ready = AMAP_GET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db); + + while (ready == false) { + if ((++i & 0x3FFFF) == 0) { + TRACE(DL_WARN, "Waiting for mailbox ready - %dk polls", + i / 1000); + } + udelay(1); + mailbox_db.dw[0] = PD_READ(pfob, mcc_bootstrap_db); + ready = AMAP_GET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db); + } +} + +/* + This routine tells the MCC mailbox that there is data to processed + in the mailbox. It does this by setting the physical address for the + mailbox location and clearing the LSB. This routine returns immediately + and does not wait for the WRB to be processed. + + pcontroller - The function object to post this data to + + IRQL < DISPATCH_LEVEL + +*/ +static void be_mcc_mailbox_notify(struct be_function_object *pfob) +{ + struct MPU_MAILBOX_DB_AMAP mailbox_db; + u32 pa; + + ASSERT(pfob->mailbox.pa); + ASSERT(pfob->mailbox.va); + + /* If emulated, do not ring the mailbox */ + if (pfob->emulate) { + TRACE(DL_WARN, "MPU disabled. Skipping mailbox notify."); + return; + } + + /* form the higher bits in the address */ + mailbox_db.dw[0] = 0; /* init */ + AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, hi, &mailbox_db, 1); + AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db, 0); + + /* bits 34 to 63 */ + pa = (u32) (pfob->mailbox.pa >> 34); + AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, address, &mailbox_db, pa); + + /* Wait for the MPU to be ready */ + be_mcc_mailbox_wait(pfob); + + /* Ring doorbell 1st time */ + PD_WRITE(pfob, mcc_bootstrap_db, mailbox_db.dw[0]); + + /* Wait for 1st write to be acknowledged. */ + be_mcc_mailbox_wait(pfob); + + /* lower bits 30 bits from 4th bit (bits 4 to 33)*/ + pa = (u32) (pfob->mailbox.pa >> 4) & 0x3FFFFFFF; + + AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, hi, &mailbox_db, 0); + AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db, 0); + AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, address, &mailbox_db, pa); + + /* Ring doorbell 2nd time */ + PD_WRITE(pfob, mcc_bootstrap_db, mailbox_db.dw[0]); +} + +/* + This routine tells the MCC mailbox that there is data to processed + in the mailbox. It does this by setting the physical address for the + mailbox location and clearing the LSB. This routine spins until the + MPU writes a 1 into the LSB indicating that the data has been received + and is ready to be processed. + + pcontroller - The function object to post this data to + + IRQL < DISPATCH_LEVEL +*/ +static void +be_mcc_mailbox_notify_and_wait(struct be_function_object *pfob) +{ + /* + * Notify it + */ + be_mcc_mailbox_notify(pfob); + /* + * Now wait for completion of WRB + */ + be_mcc_mailbox_wait(pfob); +} + +void +be_mcc_process_cqe(struct be_function_object *pfob, + struct MCC_CQ_ENTRY_AMAP *cqe) +{ + struct be_mcc_wrb_context *wrb_context = NULL; + u32 offset, status; + u8 *p; + + ASSERT(cqe); + /* + * A command completed. Commands complete out-of-order. + * Determine which command completed from the TAG. + */ + offset = offsetof(struct BE_MCC_CQ_ENTRY_AMAP, mcc_tag)/8; + p = (u8 *) cqe + offset; + wrb_context = (struct be_mcc_wrb_context *)(void *)(size_t)(*(u64 *)p); + ASSERT(wrb_context); + + /* + * Perform a response copy if requested. + * Only copy data if the FWCMD is successful. + */ + status = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, completion_status, cqe); + if (status == MGMT_STATUS_SUCCESS && wrb_context->copy.length > 0) { + ASSERT(wrb_context->wrb); + ASSERT(wrb_context->copy.va); + p = (u8 *)wrb_context->wrb + + offsetof(struct BE_MCC_WRB_AMAP, payload)/8; + memcpy(wrb_context->copy.va, + (u8 *)p + wrb_context->copy.fwcmd_offset, + wrb_context->copy.length); + } + + if (status) + status = BE_NOT_OK; + /* internal callback */ + if (wrb_context->internal_cb) { + wrb_context->internal_cb(wrb_context->internal_cb_context, + status, wrb_context->wrb); + } + + /* callback */ + if (wrb_context->cb) { + wrb_context->cb(wrb_context->cb_context, + status, wrb_context->wrb); + } + /* Free the context structure */ + _be_mcc_free_wrb_context(pfob, wrb_context); +} + +void be_drive_mcc_wrb_queue(struct be_mcc_object *mcc) +{ + struct be_function_object *pfob = NULL; + int status = BE_PENDING; + struct be_generic_q_ctxt *q_ctxt; + struct MCC_WRB_AMAP *wrb; + struct MCC_WRB_AMAP *queue_wrb; + u32 length, payload_length, sge_count, embedded; + unsigned long irql; + + BUILD_BUG_ON((sizeof(struct be_generic_q_ctxt) < + sizeof(struct be_queue_driver_context) + + sizeof(struct MCC_WRB_AMAP))); + pfob = mcc->parent_function; + + spin_lock_irqsave(&pfob->post_lock, irql); + + if (mcc->driving_backlog) { + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return; + } + /* Acquire the flag to limit 1 thread to redrive posts. */ + mcc->driving_backlog = 1; + + while (!list_empty(&mcc->backlog)) { + wrb = _be_mpu_peek_ring_wrb(mcc, true); /* Driving the queue */ + if (!wrb) + break; /* No space in the ring yet. */ + /* Get the next queued entry to process. */ + q_ctxt = list_first_entry(&mcc->backlog, + struct be_generic_q_ctxt, context.list); + list_del(&q_ctxt->context.list); + pfob->mcc->backlog_length--; + /* + * Compute the required length of the WRB. + * Since the queue element may be smaller than + * the complete WRB, copy only the required number of bytes. + */ + queue_wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; + embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, queue_wrb); + if (embedded) { + payload_length = AMAP_GET_BITS_PTR(MCC_WRB, + payload_length, queue_wrb); + length = sizeof(struct be_mcc_wrb_header) + + payload_length; + } else { + sge_count = AMAP_GET_BITS_PTR(MCC_WRB, sge_count, + queue_wrb); + ASSERT(sge_count == 1); /* only 1 frag. */ + length = sizeof(struct be_mcc_wrb_header) + + sge_count * sizeof(struct MCC_SGE_AMAP); + } + + /* + * Truncate the length based on the size of the + * queue element. Some elements that have output parameters + * can be smaller than the payload_length field would + * indicate. We really only need to copy the request + * parameters, not the response. + */ + length = min(length, (u32) (q_ctxt->context.bytes - + offsetof(struct be_generic_q_ctxt, wrb_header))); + + /* Copy the queue element WRB into the ring. */ + memcpy(wrb, &q_ctxt->wrb_header, length); + + /* Post the wrb. This should not fail assuming we have + * enough context structs. */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, + q_ctxt->context.cb, q_ctxt->context.cb_context, + q_ctxt->context.internal_cb, + q_ctxt->context.internal_cb_context, + q_ctxt->context.optional_fwcmd_va, + &q_ctxt->context.copy); + + if (status == BE_SUCCESS) { + /* + * Synchronous completion. Since it was queued, + * we will invoke the callback. + * To the user, this is an asynchronous request. + */ + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + + ASSERT(q_ctxt->context.cb); + + q_ctxt->context.cb( + q_ctxt->context.cb_context, + BE_SUCCESS, NULL); + + spin_lock_irqsave(&pfob->post_lock, irql); + + } else if (status != BE_PENDING) { + /* + * Another resource failed. Should never happen + * if we have sufficient MCC_WRB_CONTEXT structs. + * Return to head of the queue. + */ + TRACE(DL_WARN, "Failed to post a queued WRB. 0x%x", + status); + list_add(&q_ctxt->context.list, &mcc->backlog); + pfob->mcc->backlog_length++; + break; + } + } + + /* Free the flag to limit 1 thread to redrive posts. */ + mcc->driving_backlog = 0; + spin_unlock_irqrestore(&pfob->post_lock, irql); +} + +/* This function asserts that the WRB was consumed in order. */ +#ifdef BE_DEBUG +u32 be_mcc_wrb_consumed_in_order(struct be_mcc_object *mcc, + struct MCC_CQ_ENTRY_AMAP *cqe) +{ + struct be_mcc_wrb_context *wrb_context = NULL; + u32 wrb_index; + u32 wrb_consumed_in_order; + u32 offset; + u8 *p; + + ASSERT(cqe); + /* + * A command completed. Commands complete out-of-order. + * Determine which command completed from the TAG. + */ + offset = offsetof(struct BE_MCC_CQ_ENTRY_AMAP, mcc_tag)/8; + p = (u8 *) cqe + offset; + wrb_context = (struct be_mcc_wrb_context *)(void *)(size_t)(*(u64 *)p); + + ASSERT(wrb_context); + + wrb_index = (u32) (((u64)(size_t)wrb_context->ring_wrb - + (u64)(size_t)mcc->sq.ring.va) / sizeof(struct MCC_WRB_AMAP)); + + ASSERT(wrb_index < mcc->sq.ring.num); + + wrb_consumed_in_order = (u32) (wrb_index == mcc->consumed_index); + mcc->consumed_index = be_addc(mcc->consumed_index, 1, mcc->sq.ring.num); + return wrb_consumed_in_order; +} +#endif + +int be_mcc_process_cq(struct be_mcc_object *mcc, bool rearm) +{ + struct be_function_object *pfob = NULL; + struct MCC_CQ_ENTRY_AMAP *cqe; + struct CQ_DB_AMAP db; + struct mp_ring *cq_ring = &mcc->cq.ring; + struct mp_ring *mp_ring = &mcc->sq.ring; + u32 num_processed = 0; + u32 consumed = 0, valid, completed, cqe_consumed, async_event; + + pfob = mcc->parent_function; + + spin_lock_irqsave(&pfob->cq_lock, pfob->cq_irq); + + /* + * Verify that only one thread is processing the CQ at once. + * We cannot hold the lock while processing the CQ due to + * the callbacks into the OS. Therefore, this flag is used + * to control it. If any of the threads want to + * rearm the CQ, we need to honor that. + */ + if (mcc->processing != 0) { + mcc->rearm = mcc->rearm || rearm; + goto Error; + } else { + mcc->processing = 1; /* lock processing for this thread. */ + mcc->rearm = rearm; /* set our rearm setting */ + } + + spin_unlock_irqrestore(&pfob->cq_lock, pfob->cq_irq); + + cqe = mp_ring_current(cq_ring); + valid = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe); + while (valid) { + + if (num_processed >= 8) { + /* coalesce doorbells, but free space in cq + * ring while processing. */ + db.dw[0] = 0; /* clear */ + AMAP_SET_BITS_PTR(CQ_DB, qid, &db, cq_ring->id); + AMAP_SET_BITS_PTR(CQ_DB, rearm, &db, false); + AMAP_SET_BITS_PTR(CQ_DB, event, &db, false); + AMAP_SET_BITS_PTR(CQ_DB, num_popped, &db, + num_processed); + num_processed = 0; + + PD_WRITE(pfob, cq_db, db.dw[0]); + } + + async_event = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, async_event, cqe); + if (async_event) { + /* This is an asynchronous event. */ + struct ASYNC_EVENT_TRAILER_AMAP *async_trailer = + (struct ASYNC_EVENT_TRAILER_AMAP *) + ((u8 *) cqe + sizeof(struct MCC_CQ_ENTRY_AMAP) - + sizeof(struct ASYNC_EVENT_TRAILER_AMAP)); + u32 event_code; + async_event = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, + async_event, async_trailer); + ASSERT(async_event == 1); + + + valid = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, + valid, async_trailer); + ASSERT(valid == 1); + + /* Call the async event handler if it is installed. */ + if (mcc->async_cb) { + event_code = + AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, + event_code, async_trailer); + mcc->async_cb(mcc->async_context, + (u32) event_code, (void *) cqe); + } + + } else { + /* This is a completion entry. */ + + /* No vm forwarding in this driver. */ + + cqe_consumed = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, + consumed, cqe); + if (cqe_consumed) { + /* + * A command on the MCC ring was consumed. + * Update the consumer index. + * These occur in order. + */ + ASSERT(be_mcc_wrb_consumed_in_order(mcc, cqe)); + consumed++; + } + + completed = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, + completed, cqe); + if (completed) { + /* A command completed. Use tag to + * determine which command. */ + be_mcc_process_cqe(pfob, cqe); + } + } + + /* Reset the CQE */ + AMAP_SET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe, false); + num_processed++; + + /* Update our tracking for the CQ ring. */ + cqe = mp_ring_next(cq_ring); + valid = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe); + } + + TRACE(DL_INFO, "num_processed:0x%x, and consumed:0x%x", + num_processed, consumed); + /* + * Grab the CQ lock to synchronize the "rearm" setting for + * the doorbell, and for clearing the "processing" flag. + */ + spin_lock_irqsave(&pfob->cq_lock, pfob->cq_irq); + + /* + * Rearm the cq. This is done based on the global mcc->rearm + * flag which combines the rearm parameter from the current + * call to process_cq and any other threads + * that tried to process the CQ while this one was active. + * This handles the situation where a sync. fwcmd was processing + * the CQ while the interrupt/dpc tries to process it. + * The sync process gets to continue -- but it is now + * responsible for the rearming. + */ + if (num_processed > 0 || mcc->rearm == true) { + db.dw[0] = 0; /* clear */ + AMAP_SET_BITS_PTR(CQ_DB, qid, &db, cq_ring->id); + AMAP_SET_BITS_PTR(CQ_DB, rearm, &db, mcc->rearm); + AMAP_SET_BITS_PTR(CQ_DB, event, &db, false); + AMAP_SET_BITS_PTR(CQ_DB, num_popped, &db, num_processed); + + PD_WRITE(pfob, cq_db, db.dw[0]); + } + /* + * Update the consumer index after ringing the CQ doorbell. + * We don't want another thread to post more WRBs before we + * have CQ space available. + */ + mp_ring_consume_multiple(mp_ring, consumed); + + /* Clear the processing flag. */ + mcc->processing = 0; + +Error: + spin_unlock_irqrestore(&pfob->cq_lock, pfob->cq_irq); + /* + * Use the local variable to detect if the current thread + * holds the WRB post lock. If rearm is false, this is + * either a synchronous command, or the upper layer driver is polling + * from a thread. We do not drive the queue from that + * context since the driver may hold the + * wrb post lock already. + */ + if (rearm) + be_drive_mcc_wrb_queue(mcc); + else + pfob->pend_queue_driving = 1; + + return BE_SUCCESS; +} + +/* + *============================================================================ + * P U B L I C R O U T I N E S + *============================================================================ + */ + +/* + This routine creates an MCC object. This object contains an MCC send queue + and a CQ private to the MCC. + + pcontroller - Handle to a function object + + EqObject - EQ object that will be used to dispatch this MCC + + ppMccObject - Pointer to an internal Mcc Object returned. + + Returns BE_SUCCESS if successfull,, otherwise a useful error code + is returned. + + IRQL < DISPATCH_LEVEL + +*/ +int +be_mcc_ring_create(struct be_function_object *pfob, + struct ring_desc *rd, u32 length, + struct be_mcc_wrb_context *context_array, + u32 num_context_entries, + struct be_cq_object *cq, struct be_mcc_object *mcc) +{ + int status = 0; + + struct FWCMD_COMMON_MCC_CREATE *fwcmd = NULL; + struct MCC_WRB_AMAP *wrb = NULL; + u32 num_entries_encoded, n, i; + void *va = NULL; + unsigned long irql; + + if (length < sizeof(struct MCC_WRB_AMAP) * 2) { + TRACE(DL_ERR, "Invalid MCC ring length:%d", length); + return BE_NOT_OK; + } + /* + * Reduce the actual ring size to be less than the number + * of context entries. This ensures that we run out of + * ring WRBs first so the queuing works correctly. We never + * queue based on context structs. + */ + if (num_context_entries + 1 < + length / sizeof(struct MCC_WRB_AMAP) - 1) { + + u32 max_length = + (num_context_entries + 2) * sizeof(struct MCC_WRB_AMAP); + + if (is_power_of_2(max_length)) + length = __roundup_pow_of_two(max_length+1) / 2; + else + length = __roundup_pow_of_two(max_length) / 2; + + ASSERT(length <= max_length); + + TRACE(DL_WARN, + "MCC ring length reduced based on context entries." + " length:%d wrbs:%d context_entries:%d", length, + (int) (length / sizeof(struct MCC_WRB_AMAP)), + num_context_entries); + } + + spin_lock_irqsave(&pfob->post_lock, irql); + + num_entries_encoded = + be_ring_length_to_encoding(length, sizeof(struct MCC_WRB_AMAP)); + + /* Init MCC object. */ + memset(mcc, 0, sizeof(*mcc)); + mcc->parent_function = pfob; + mcc->cq_object = cq; + + INIT_LIST_HEAD(&mcc->backlog); + + wrb = be_function_peek_mcc_wrb(pfob); + if (!wrb) { + ASSERT(wrb); + TRACE(DL_ERR, "No free MCC WRBs in create EQ."); + status = BE_STATUS_NO_MCC_WRB; + goto error; + } + /* Prepares an embedded fwcmd, including request/response sizes. */ + fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_MCC_CREATE); + + fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE); + /* + * Program MCC ring context + */ + AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, pdid, + &fwcmd->params.request.context, 0); + AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, invalid, + &fwcmd->params.request.context, false); + AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, ring_size, + &fwcmd->params.request.context, num_entries_encoded); + + n = cq->cq_id; + AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, + cq_id, &fwcmd->params.request.context, n); + be_rd_to_pa_list(rd, fwcmd->params.request.pages, + ARRAY_SIZE(fwcmd->params.request.pages)); + /* Post the f/w command */ + status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, + NULL, NULL, fwcmd, NULL); + if (status != BE_SUCCESS) { + TRACE(DL_ERR, "MCC to create CQ failed."); + goto error; + } + /* + * Create a linked list of context structures + */ + mcc->wrb_context.base = context_array; + mcc->wrb_context.num = num_context_entries; + INIT_LIST_HEAD(&mcc->wrb_context.list_head); + memset(context_array, 0, + sizeof(struct be_mcc_wrb_context) * num_context_entries); + for (i = 0; i < mcc->wrb_context.num; i++) { + list_add_tail(&context_array[i].next, + &mcc->wrb_context.list_head); + } + + /* + * + * Create an mcc_ring for tracking WRB hw ring + */ + va = rd->va; + ASSERT(va); + mp_ring_create(&mcc->sq.ring, length / sizeof(struct MCC_WRB_AMAP), + sizeof(struct MCC_WRB_AMAP), va); + mcc->sq.ring.id = fwcmd->params.response.id; + /* + * Init a mcc_ring for tracking the MCC CQ. + */ + ASSERT(cq->va); + mp_ring_create(&mcc->cq.ring, cq->num_entries, + sizeof(struct MCC_CQ_ENTRY_AMAP), cq->va); + mcc->cq.ring.id = cq->cq_id; + + /* Force zeroing of CQ. */ + memset(cq->va, 0, cq->num_entries * sizeof(struct MCC_CQ_ENTRY_AMAP)); + + /* Initialize debug index. */ + mcc->consumed_index = 0; + + atomic_inc(&cq->ref_count); + pfob->mcc = mcc; + + TRACE(DL_INFO, "MCC ring created. id:%d bytes:%d cq_id:%d cq_entries:%d" + " num_context:%d", mcc->sq.ring.id, length, + cq->cq_id, cq->num_entries, num_context_entries); + +error: + spin_unlock_irqrestore(&pfob->post_lock, irql); + if (pfob->pend_queue_driving && pfob->mcc) { + pfob->pend_queue_driving = 0; + be_drive_mcc_wrb_queue(pfob->mcc); + } + return status; +} + +/* + This routine destroys an MCC send queue + + MccObject - Internal Mcc Object to be destroyed. + + Returns BE_SUCCESS if successfull, otherwise an error code is returned. + + IRQL < DISPATCH_LEVEL + + The caller of this routine must ensure that no other WRB may be posted + until this routine returns. + +*/ +int be_mcc_ring_destroy(struct be_mcc_object *mcc) +{ + int status = 0; + struct be_function_object *pfob = mcc->parent_function; + + + ASSERT(mcc->processing == 0); + + /* + * Remove the ring from the function object. + * This transitions back to mailbox mode. + */ + pfob->mcc = NULL; + + /* Send fwcmd to destroy the queue. (Using the mailbox.) */ + status = be_function_ring_destroy(mcc->parent_function, mcc->sq.ring.id, + FWCMD_RING_TYPE_MCC, NULL, NULL, NULL, NULL); + ASSERT(status == 0); + + /* Release the SQ reference to the CQ */ + atomic_dec(&mcc->cq_object->ref_count); + + return status; +} + +static void +mcc_wrb_sync_cb(void *context, int staus, struct MCC_WRB_AMAP *wrb) +{ + struct be_mcc_wrb_context *wrb_context = + (struct be_mcc_wrb_context *) context; + ASSERT(wrb_context); + *wrb_context->users_final_status = staus; +} + +/* + This routine posts a command to the MCC send queue + + mcc - Internal Mcc Object to be destroyed. + + wrb - wrb to post. + + Returns BE_SUCCESS if successfull, otherwise an error code is returned. + + IRQL < DISPATCH_LEVEL if CompletionCallback is not NULL + IRQL <=DISPATCH_LEVEL if CompletionCallback is NULL + + If this routine is called with CompletionCallback != NULL the + call is considered to be asynchronous and will return as soon + as the WRB is posted to the MCC with BE_PENDING. + + If CompletionCallback is NULL, then this routine will not return until + a completion for this MCC command has been processed. + If called at DISPATCH_LEVEL the CompletionCallback must be NULL. + + This routine should only be called if the MPU has been boostraped past + mailbox mode. + + +*/ +int +_be_mpu_post_wrb_ring(struct be_mcc_object *mcc, struct MCC_WRB_AMAP *wrb, + struct be_mcc_wrb_context *wrb_context) +{ + + struct MCC_WRB_AMAP *ring_wrb = NULL; + int status = BE_PENDING; + int final_status = BE_PENDING; + mcc_wrb_cqe_callback cb = NULL; + struct MCC_DB_AMAP mcc_db; + u32 embedded; + + ASSERT(mp_ring_num_empty(&mcc->sq.ring) > 0); + /* + * Input wrb is most likely the next wrb in the ring, since the client + * can peek at the address. + */ + ring_wrb = mp_ring_producer_ptr(&mcc->sq.ring); + if (wrb != ring_wrb) { + /* If not equal, copy it into the ring. */ + memcpy(ring_wrb, wrb, sizeof(struct MCC_WRB_AMAP)); + } +#ifdef BE_DEBUG + wrb_context->ring_wrb = ring_wrb; +#endif + embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, ring_wrb); + if (embedded) { + /* embedded commands will have the response within the WRB. */ + wrb_context->wrb = ring_wrb; + } else { + /* + * non-embedded commands will not have the response + * within the WRB, and they may complete out-of-order. + * The WRB will not be valid to inspect + * during the completion. + */ + wrb_context->wrb = NULL; + } + cb = wrb_context->cb; + + if (cb == NULL) { + /* Assign our internal callback if this is a + * synchronous call. */ + wrb_context->cb = mcc_wrb_sync_cb; + wrb_context->cb_context = wrb_context; + wrb_context->users_final_status = &final_status; + } + /* Increment producer index */ + + mcc_db.dw[0] = 0; /* initialize */ + AMAP_SET_BITS_PTR(MCC_DB, rid, &mcc_db, mcc->sq.ring.id); + AMAP_SET_BITS_PTR(MCC_DB, numPosted, &mcc_db, 1); + + mp_ring_produce(&mcc->sq.ring); + PD_WRITE(mcc->parent_function, mpu_mcc_db, mcc_db.dw[0]); + TRACE(DL_INFO, "pidx: %x and cidx: %x.", mcc->sq.ring.pidx, + mcc->sq.ring.cidx); + + if (cb == NULL) { + int polls = 0; /* At >= 1 us per poll */ + /* Wait until this command completes, polling the CQ. */ + do { + TRACE(DL_INFO, "FWCMD submitted in the poll mode."); + /* Do not rearm CQ in this context. */ + be_mcc_process_cq(mcc, false); + + if (final_status == BE_PENDING) { + if ((++polls & 0x7FFFF) == 0) { + TRACE(DL_WARN, + "Warning : polling MCC CQ for %d" + "ms.", polls / 1000); + } + + udelay(1); + } + + /* final_status changed when the command completes */ + } while (final_status == BE_PENDING); + + status = final_status; + } + + return status; +} + +struct MCC_WRB_AMAP * +_be_mpu_peek_ring_wrb(struct be_mcc_object *mcc, bool driving_queue) +{ + /* If we have queued items, do not allow a post to bypass the queue. */ + if (!driving_queue && !list_empty(&mcc->backlog)) + return NULL; + + if (mp_ring_num_empty(&mcc->sq.ring) <= 0) + return NULL; + return (struct MCC_WRB_AMAP *) mp_ring_producer_ptr(&mcc->sq.ring); +} + +int +be_mpu_init_mailbox(struct be_function_object *pfob, struct ring_desc *mailbox) +{ + ASSERT(mailbox); + pfob->mailbox.va = mailbox->va; + pfob->mailbox.pa = cpu_to_le64(mailbox->pa); + pfob->mailbox.length = mailbox->length; + + ASSERT(((u32)(size_t)pfob->mailbox.va & 0xf) == 0); + ASSERT(((u32)(size_t)pfob->mailbox.pa & 0xf) == 0); + /* + * Issue the WRB to set MPU endianness + */ + { + u64 *endian_check = (u64 *) (pfob->mailbox.va + + offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8); + *endian_check = 0xFF1234FFFF5678FFULL; + } + + be_mcc_mailbox_notify_and_wait(pfob); + + return BE_SUCCESS; +} + + +/* + This routine posts a command to the MCC mailbox. + + FuncObj - Function Object to post the WRB on behalf of. + wrb - wrb to post. + CompletionCallback - Address of a callback routine to invoke once the WRB + is completed. + CompletionCallbackContext - Opaque context to be passed during the call to + the CompletionCallback. + Returns BE_SUCCESS if successfull, otherwise an error code is returned. + + IRQL <=DISPATCH_LEVEL if CompletionCallback is NULL + + This routine will block until a completion for this MCC command has been + processed. If called at DISPATCH_LEVEL the CompletionCallback must be NULL. + + This routine should only be called if the MPU has not been boostraped past + mailbox mode. +*/ +int +_be_mpu_post_wrb_mailbox(struct be_function_object *pfob, + struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context) +{ + struct MCC_MAILBOX_AMAP *mailbox = NULL; + struct MCC_WRB_AMAP *mb_wrb; + struct MCC_CQ_ENTRY_AMAP *mb_cq; + u32 offset, status; + + ASSERT(pfob->mcc == NULL); + mailbox = pfob->mailbox.va; + ASSERT(mailbox); + + offset = offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8; + mb_wrb = (struct MCC_WRB_AMAP *) (u8 *)mailbox + offset; + if (mb_wrb != wrb) { + memset(mailbox, 0, sizeof(*mailbox)); + memcpy(mb_wrb, wrb, sizeof(struct MCC_WRB_AMAP)); + } + /* The callback can inspect the final WRB to get output parameters. */ + wrb_context->wrb = mb_wrb; + + be_mcc_mailbox_notify_and_wait(pfob); + + /* A command completed. Use tag to determine which command. */ + offset = offsetof(struct BE_MCC_MAILBOX_AMAP, cq)/8; + mb_cq = (struct MCC_CQ_ENTRY_AMAP *) ((u8 *)mailbox + offset); + be_mcc_process_cqe(pfob, mb_cq); + + status = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, completion_status, mb_cq); + if (status) + status = BE_NOT_OK; + return status; +} + +struct be_mcc_wrb_context * +_be_mcc_allocate_wrb_context(struct be_function_object *pfob) +{ + struct be_mcc_wrb_context *context = NULL; + unsigned long irq; + + spin_lock_irqsave(&pfob->mcc_context_lock, irq); + + if (!pfob->mailbox.default_context_allocated) { + /* Use the single default context that we + * always have allocated. */ + pfob->mailbox.default_context_allocated = true; + context = &pfob->mailbox.default_context; + } else if (pfob->mcc) { + /* Get a context from the free list. If any are available. */ + if (!list_empty(&pfob->mcc->wrb_context.list_head)) { + context = list_first_entry( + &pfob->mcc->wrb_context.list_head, + struct be_mcc_wrb_context, next); + } + } + + spin_unlock_irqrestore(&pfob->mcc_context_lock, irq); + + return context; +} + +void +_be_mcc_free_wrb_context(struct be_function_object *pfob, + struct be_mcc_wrb_context *context) +{ + unsigned long irq; + + ASSERT(context); + /* + * Zero during free to try and catch any bugs where the context + * is accessed after a free. + */ + memset(context, 0, sizeof(context)); + + spin_lock_irqsave(&pfob->mcc_context_lock, irq); + + if (context == &pfob->mailbox.default_context) { + /* Free the default context. */ + ASSERT(pfob->mailbox.default_context_allocated); + pfob->mailbox.default_context_allocated = false; + } else { + /* Add to free list. */ + ASSERT(pfob->mcc); + list_add_tail(&context->next, + &pfob->mcc->wrb_context.list_head); + } + + spin_unlock_irqrestore(&pfob->mcc_context_lock, irq); +} + +int +be_mcc_add_async_event_callback(struct be_mcc_object *mcc_object, + mcc_async_event_callback cb, void *cb_context) +{ + /* Lock against anyone trying to change the callback/context pointers + * while being used. */ + spin_lock_irqsave(&mcc_object->parent_function->cq_lock, + mcc_object->parent_function->cq_irq); + + /* Assign the async callback. */ + mcc_object->async_context = cb_context; + mcc_object->async_cb = cb; + + spin_unlock_irqrestore(&mcc_object->parent_function->cq_lock, + mcc_object->parent_function->cq_irq); + + return BE_SUCCESS; +} + +#define MPU_EP_CONTROL 0 +#define MPU_EP_SEMAPHORE 0xac + +/* + *------------------------------------------------------------------- + * Function: be_wait_for_POST_complete + * Waits until the BladeEngine POST completes (either in error or success). + * pfob - + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *------------------------------------------------------------------- + */ +static int be_wait_for_POST_complete(struct be_function_object *pfob) +{ + struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status; + int s; + u32 post_error, post_stage; + + const u32 us_per_loop = 1000; /* 1000us */ + const u32 print_frequency_loops = 1000000 / us_per_loop; + const u32 max_loops = 60 * print_frequency_loops; + u32 loops = 0; + + /* + * Wait for arm fw indicating it is done or a fatal error happened. + * Note: POST can take some time to complete depending on configuration + * settings (consider ARM attempts to acquire an IP address + * over DHCP!!!). + * + */ + do { + status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE); + post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, + error, &status); + post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, + stage, &status); + if (0 == (loops % print_frequency_loops)) { + /* Print current status */ + TRACE(DL_INFO, "POST status = 0x%x (stage = 0x%x)", + status.dw[0], post_stage); + } + udelay(us_per_loop); + } while ((post_error != 1) && + (post_stage != POST_STAGE_ARMFW_READY) && + (++loops < max_loops)); + + if (post_error == 1) { + TRACE(DL_ERR, "POST error! Status = 0x%x (stage = 0x%x)", + status.dw[0], post_stage); + s = BE_NOT_OK; + } else if (post_stage != POST_STAGE_ARMFW_READY) { + TRACE(DL_ERR, "POST time-out! Status = 0x%x (stage = 0x%x)", + status.dw[0], post_stage); + s = BE_NOT_OK; + } else { + s = BE_SUCCESS; + } + return s; +} + +/* + *------------------------------------------------------------------- + * Function: be_kickoff_and_wait_for_POST + * Interacts with the BladeEngine management processor to initiate POST, and + * subsequently waits until POST completes (either in error or success). + * The caller must acquire the reset semaphore before initiating POST + * to prevent multiple drivers interacting with the management processor. + * Once POST is complete the caller must release the reset semaphore. + * Callers who only want to wait for POST complete may call + * be_wait_for_POST_complete. + * pfob - + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *------------------------------------------------------------------- + */ +static int +be_kickoff_and_wait_for_POST(struct be_function_object *pfob) +{ + struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status; + int s; + + const u32 us_per_loop = 1000; /* 1000us */ + const u32 print_frequency_loops = 1000000 / us_per_loop; + const u32 max_loops = 5 * print_frequency_loops; + u32 loops = 0; + u32 post_error, post_stage; + + /* Wait for arm fw awaiting host ready or a fatal error happened. */ + TRACE(DL_INFO, "Wait for BladeEngine ready to POST"); + do { + status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE); + post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, + error, &status); + post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, + stage, &status); + if (0 == (loops % print_frequency_loops)) { + /* Print current status */ + TRACE(DL_INFO, "POST status = 0x%x (stage = 0x%x)", + status.dw[0], post_stage); + } + udelay(us_per_loop); + } while ((post_error != 1) && + (post_stage < POST_STAGE_AWAITING_HOST_RDY) && + (++loops < max_loops)); + + if (post_error == 1) { + TRACE(DL_ERR, "Pre-POST error! Status = 0x%x (stage = 0x%x)", + status.dw[0], post_stage); + s = BE_NOT_OK; + } else if (post_stage == POST_STAGE_AWAITING_HOST_RDY) { + iowrite32(POST_STAGE_HOST_RDY, pfob->csr_va + MPU_EP_SEMAPHORE); + + /* Wait for POST to complete */ + s = be_wait_for_POST_complete(pfob); + } else { + /* + * Either a timeout waiting for host ready signal or POST has + * moved ahead without requiring a host ready signal. + * Might as well give POST a chance to complete + * (or timeout again). + */ + s = be_wait_for_POST_complete(pfob); + } + return s; +} + +/* + *------------------------------------------------------------------- + * Function: be_pci_soft_reset + * This function is called to issue a BladeEngine soft reset. + * Callers should acquire the soft reset semaphore before calling this + * function. Additionaly, callers should ensure they cannot be pre-empted + * while the routine executes. Upon completion of this routine, callers + * should release the reset semaphore. This routine implicitly waits + * for BladeEngine POST to complete. + * pfob - + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *------------------------------------------------------------------- + */ +int be_pci_soft_reset(struct be_function_object *pfob) +{ + struct PCICFG_SOFT_RESET_CSR_AMAP soft_reset; + struct PCICFG_ONLINE0_CSR_AMAP pciOnline0; + struct PCICFG_ONLINE1_CSR_AMAP pciOnline1; + struct EP_CONTROL_CSR_AMAP epControlCsr; + int status = BE_SUCCESS; + u32 i, soft_reset_bit; + + TRACE(DL_NOTE, "PCI reset..."); + + /* Issue soft reset #1 to get BladeEngine into a known state. */ + soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset); + AMAP_SET_BITS_PTR(PCICFG_SOFT_RESET_CSR, softreset, soft_reset.dw, 1); + PCICFG0_WRITE(pfob, host_timer_int_ctrl, soft_reset.dw[0]); + /* + * wait til soft reset is deasserted - hardware + * deasserts after some time. + */ + i = 0; + do { + udelay(50); + soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset); + soft_reset_bit = AMAP_GET_BITS_PTR(PCICFG_SOFT_RESET_CSR, + softreset, soft_reset.dw); + } while (soft_reset_bit && (i++ < 1024)); + if (soft_reset_bit != 0) { + TRACE(DL_ERR, "Soft-reset #1 did not deassert as expected."); + status = BE_NOT_OK; + goto Error_label; + } + /* Mask everything */ + PCICFG0_WRITE(pfob, ue_status_low_mask, 0xFFFFFFFF); + PCICFG0_WRITE(pfob, ue_status_hi_mask, 0xFFFFFFFF); + /* + * Set everything offline except MPU IRAM (it is offline with + * the soft-reset, but soft-reset does not reset the PCICFG registers!) + */ + pciOnline0.dw[0] = 0; + pciOnline1.dw[0] = 0; + AMAP_SET_BITS_PTR(PCICFG_ONLINE1_CSR, mpu_iram_online, + pciOnline1.dw, 1); + PCICFG0_WRITE(pfob, online0, pciOnline0.dw[0]); + PCICFG0_WRITE(pfob, online1, pciOnline1.dw[0]); + + udelay(20000); + + /* Issue soft reset #2. */ + AMAP_SET_BITS_PTR(PCICFG_SOFT_RESET_CSR, softreset, soft_reset.dw, 1); + PCICFG0_WRITE(pfob, host_timer_int_ctrl, soft_reset.dw[0]); + /* + * wait til soft reset is deasserted - hardware + * deasserts after some time. + */ + i = 0; + do { + udelay(50); + soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset); + soft_reset_bit = AMAP_GET_BITS_PTR(PCICFG_SOFT_RESET_CSR, + softreset, soft_reset.dw); + } while (soft_reset_bit && (i++ < 1024)); + if (soft_reset_bit != 0) { + TRACE(DL_ERR, "Soft-reset #1 did not deassert as expected."); + status = BE_NOT_OK; + goto Error_label; + } + + + udelay(20000); + + /* Take MPU out of reset. */ + + epControlCsr.dw[0] = ioread32(pfob->csr_va + MPU_EP_CONTROL); + AMAP_SET_BITS_PTR(EP_CONTROL_CSR, CPU_reset, &epControlCsr, 0); + iowrite32((u32)epControlCsr.dw[0], pfob->csr_va + MPU_EP_CONTROL); + + /* Kickoff BE POST and wait for completion */ + status = be_kickoff_and_wait_for_POST(pfob); + +Error_label: + return status; +} + + +/* + *------------------------------------------------------------------- + * Function: be_pci_reset_required + * This private function is called to detect if a host entity is + * required to issue a PCI soft reset and subsequently drive + * BladeEngine POST. Scenarios where this is required: + * 1) BIOS-less configuration + * 2) Hot-swap/plug/power-on + * pfob - + * return true if a reset is required, false otherwise + *------------------------------------------------------------------- + */ +static bool be_pci_reset_required(struct be_function_object *pfob) +{ + struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status; + bool do_reset = false; + u32 post_error, post_stage; + + /* + * Read the POST status register + */ + status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE); + post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, error, + &status); + post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, stage, + &status); + if (post_stage <= POST_STAGE_AWAITING_HOST_RDY) { + /* + * If BladeEngine is waiting for host ready indication, + * we want to do a PCI reset. + */ + do_reset = true; + } + + return do_reset; +} + +/* + *------------------------------------------------------------------- + * Function: be_drive_POST + * This function is called to drive BladeEngine POST. The + * caller should ensure they cannot be pre-empted while this routine executes. + * pfob - + * return status - BE_SUCCESS (0) on success. Negative error code on failure. + *------------------------------------------------------------------- + */ +int be_drive_POST(struct be_function_object *pfob) +{ + int status; + + if (false != be_pci_reset_required(pfob)) { + /* PCI reset is needed (implicitly starts and waits for POST) */ + status = be_pci_soft_reset(pfob); + } else { + /* No PCI reset is needed, start POST */ + status = be_kickoff_and_wait_for_POST(pfob); + } + + return status; +} diff --git a/trunk/drivers/staging/benet/mpu.h b/trunk/drivers/staging/benet/mpu.h new file mode 100644 index 000000000000..41f3f87516e5 --- /dev/null +++ b/trunk/drivers/staging/benet/mpu.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __mpu_amap_h__ +#define __mpu_amap_h__ +#include "ep.h" + +/* Provide control parameters for the Managment Processor Unit. */ +struct BE_MPU_CSRMAP_AMAP { + struct BE_EP_CSRMAP_AMAP ep; + u8 rsvd0[128]; /* DWORD 64 */ + u8 rsvd1[32]; /* DWORD 68 */ + u8 rsvd2[192]; /* DWORD 69 */ + u8 rsvd3[192]; /* DWORD 75 */ + u8 rsvd4[32]; /* DWORD 81 */ + u8 rsvd5[32]; /* DWORD 82 */ + u8 rsvd6[32]; /* DWORD 83 */ + u8 rsvd7[32]; /* DWORD 84 */ + u8 rsvd8[32]; /* DWORD 85 */ + u8 rsvd9[32]; /* DWORD 86 */ + u8 rsvd10[32]; /* DWORD 87 */ + u8 rsvd11[32]; /* DWORD 88 */ + u8 rsvd12[32]; /* DWORD 89 */ + u8 rsvd13[32]; /* DWORD 90 */ + u8 rsvd14[32]; /* DWORD 91 */ + u8 rsvd15[32]; /* DWORD 92 */ + u8 rsvd16[32]; /* DWORD 93 */ + u8 rsvd17[32]; /* DWORD 94 */ + u8 rsvd18[32]; /* DWORD 95 */ + u8 rsvd19[32]; /* DWORD 96 */ + u8 rsvd20[32]; /* DWORD 97 */ + u8 rsvd21[32]; /* DWORD 98 */ + u8 rsvd22[32]; /* DWORD 99 */ + u8 rsvd23[32]; /* DWORD 100 */ + u8 rsvd24[32]; /* DWORD 101 */ + u8 rsvd25[32]; /* DWORD 102 */ + u8 rsvd26[32]; /* DWORD 103 */ + u8 rsvd27[32]; /* DWORD 104 */ + u8 rsvd28[96]; /* DWORD 105 */ + u8 rsvd29[32]; /* DWORD 108 */ + u8 rsvd30[32]; /* DWORD 109 */ + u8 rsvd31[32]; /* DWORD 110 */ + u8 rsvd32[32]; /* DWORD 111 */ + u8 rsvd33[32]; /* DWORD 112 */ + u8 rsvd34[96]; /* DWORD 113 */ + u8 rsvd35[32]; /* DWORD 116 */ + u8 rsvd36[32]; /* DWORD 117 */ + u8 rsvd37[32]; /* DWORD 118 */ + u8 rsvd38[32]; /* DWORD 119 */ + u8 rsvd39[32]; /* DWORD 120 */ + u8 rsvd40[32]; /* DWORD 121 */ + u8 rsvd41[134][32]; /* DWORD 122 */ +} __packed; +struct MPU_CSRMAP_AMAP { + u32 dw[256]; +}; + +#endif /* __mpu_amap_h__ */ diff --git a/trunk/drivers/staging/benet/mpu_context.h b/trunk/drivers/staging/benet/mpu_context.h new file mode 100644 index 000000000000..8ce90f9c46c2 --- /dev/null +++ b/trunk/drivers/staging/benet/mpu_context.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __mpu_context_amap_h__ +#define __mpu_context_amap_h__ + +/* + * Management command and control ring context. The MPUs BTLR_CTRL1 CSR + * controls the writeback behavior of the producer and consumer index values. + */ +struct BE_MCC_RING_CONTEXT_AMAP { + u8 con_index[16]; /* DWORD 0 */ + u8 ring_size[4]; /* DWORD 0 */ + u8 cq_id[11]; /* DWORD 0 */ + u8 rsvd0; /* DWORD 0 */ + u8 prod_index[16]; /* DWORD 1 */ + u8 pdid[15]; /* DWORD 1 */ + u8 invalid; /* DWORD 1 */ + u8 cmd_pending_current[7]; /* DWORD 2 */ + u8 rsvd1[25]; /* DWORD 2 */ + u8 hpi_port_cq_id[11]; /* DWORD 3 */ + u8 rsvd2[5]; /* DWORD 3 */ + u8 cmd_pending_max[7]; /* DWORD 3 */ + u8 rsvd3[9]; /* DWORD 3 */ +} __packed; +struct MCC_RING_CONTEXT_AMAP { + u32 dw[4]; +}; + +#endif /* __mpu_context_amap_h__ */ diff --git a/trunk/drivers/staging/benet/pcicfg.h b/trunk/drivers/staging/benet/pcicfg.h new file mode 100644 index 000000000000..7c15684adf4a --- /dev/null +++ b/trunk/drivers/staging/benet/pcicfg.h @@ -0,0 +1,825 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __pcicfg_amap_h__ +#define __pcicfg_amap_h__ + +/* Vendor and Device ID Register. */ +struct BE_PCICFG_ID_CSR_AMAP { + u8 vendorid[16]; /* DWORD 0 */ + u8 deviceid[16]; /* DWORD 0 */ +} __packed; +struct PCICFG_ID_CSR_AMAP { + u32 dw[1]; +}; + +/* IO Bar Register. */ +struct BE_PCICFG_IOBAR_CSR_AMAP { + u8 iospace; /* DWORD 0 */ + u8 rsvd0[7]; /* DWORD 0 */ + u8 iobar[24]; /* DWORD 0 */ +} __packed; +struct PCICFG_IOBAR_CSR_AMAP { + u32 dw[1]; +}; + +/* Memory BAR 0 Register. */ +struct BE_PCICFG_MEMBAR0_CSR_AMAP { + u8 memspace; /* DWORD 0 */ + u8 type[2]; /* DWORD 0 */ + u8 pf; /* DWORD 0 */ + u8 rsvd0[10]; /* DWORD 0 */ + u8 membar0[18]; /* DWORD 0 */ +} __packed; +struct PCICFG_MEMBAR0_CSR_AMAP { + u32 dw[1]; +}; + +/* Memory BAR 1 - Low Address Register. */ +struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP { + u8 memspace; /* DWORD 0 */ + u8 type[2]; /* DWORD 0 */ + u8 pf; /* DWORD 0 */ + u8 rsvd0[13]; /* DWORD 0 */ + u8 membar1lo[15]; /* DWORD 0 */ +} __packed; +struct PCICFG_MEMBAR1_LO_CSR_AMAP { + u32 dw[1]; +}; + +/* Memory BAR 1 - High Address Register. */ +struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP { + u8 membar1hi[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_MEMBAR1_HI_CSR_AMAP { + u32 dw[1]; +}; + +/* Memory BAR 2 - Low Address Register. */ +struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP { + u8 memspace; /* DWORD 0 */ + u8 type[2]; /* DWORD 0 */ + u8 pf; /* DWORD 0 */ + u8 rsvd0[17]; /* DWORD 0 */ + u8 membar2lo[11]; /* DWORD 0 */ +} __packed; +struct PCICFG_MEMBAR2_LO_CSR_AMAP { + u32 dw[1]; +}; + +/* Memory BAR 2 - High Address Register. */ +struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP { + u8 membar2hi[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_MEMBAR2_HI_CSR_AMAP { + u32 dw[1]; +}; + +/* Subsystem Vendor and ID (Function 0) Register. */ +struct BE_PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP { + u8 subsys_vendor_id[16]; /* DWORD 0 */ + u8 subsys_id[16]; /* DWORD 0 */ +} __packed; +struct PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP { + u32 dw[1]; +}; + +/* Subsystem Vendor and ID (Function 1) Register. */ +struct BE_PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP { + u8 subsys_vendor_id[16]; /* DWORD 0 */ + u8 subsys_id[16]; /* DWORD 0 */ +} __packed; +struct PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP { + u32 dw[1]; +}; + +/* Semaphore Register. */ +struct BE_PCICFG_SEMAPHORE_CSR_AMAP { + u8 locked; /* DWORD 0 */ + u8 rsvd0[31]; /* DWORD 0 */ +} __packed; +struct PCICFG_SEMAPHORE_CSR_AMAP { + u32 dw[1]; +}; + +/* Soft Reset Register. */ +struct BE_PCICFG_SOFT_RESET_CSR_AMAP { + u8 rsvd0[7]; /* DWORD 0 */ + u8 softreset; /* DWORD 0 */ + u8 rsvd1[16]; /* DWORD 0 */ + u8 nec_ll_rcvdetect_i[8]; /* DWORD 0 */ +} __packed; +struct PCICFG_SOFT_RESET_CSR_AMAP { + u32 dw[1]; +}; + +/* Unrecoverable Error Status (Low) Register. Each bit corresponds to + * an internal Unrecoverable Error. These are set by hardware and may be + * cleared by writing a one to the respective bit(s) to be cleared. Any + * bit being set that is also unmasked will result in Unrecoverable Error + * interrupt notification to the host CPU and/or Server Management chip + * and the transitioning of BladeEngine to an Offline state. + */ +struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP { + u8 cev_ue_status; /* DWORD 0 */ + u8 ctx_ue_status; /* DWORD 0 */ + u8 dbuf_ue_status; /* DWORD 0 */ + u8 erx_ue_status; /* DWORD 0 */ + u8 host_ue_status; /* DWORD 0 */ + u8 mpu_ue_status; /* DWORD 0 */ + u8 ndma_ue_status; /* DWORD 0 */ + u8 ptc_ue_status; /* DWORD 0 */ + u8 rdma_ue_status; /* DWORD 0 */ + u8 rxf_ue_status; /* DWORD 0 */ + u8 rxips_ue_status; /* DWORD 0 */ + u8 rxulp0_ue_status; /* DWORD 0 */ + u8 rxulp1_ue_status; /* DWORD 0 */ + u8 rxulp2_ue_status; /* DWORD 0 */ + u8 tim_ue_status; /* DWORD 0 */ + u8 tpost_ue_status; /* DWORD 0 */ + u8 tpre_ue_status; /* DWORD 0 */ + u8 txips_ue_status; /* DWORD 0 */ + u8 txulp0_ue_status; /* DWORD 0 */ + u8 txulp1_ue_status; /* DWORD 0 */ + u8 uc_ue_status; /* DWORD 0 */ + u8 wdma_ue_status; /* DWORD 0 */ + u8 txulp2_ue_status; /* DWORD 0 */ + u8 host1_ue_status; /* DWORD 0 */ + u8 p0_ob_link_ue_status; /* DWORD 0 */ + u8 p1_ob_link_ue_status; /* DWORD 0 */ + u8 host_gpio_ue_status; /* DWORD 0 */ + u8 mbox_netw_ue_status; /* DWORD 0 */ + u8 mbox_stor_ue_status; /* DWORD 0 */ + u8 axgmac0_ue_status; /* DWORD 0 */ + u8 axgmac1_ue_status; /* DWORD 0 */ + u8 mpu_intpend_ue_status; /* DWORD 0 */ +} __packed; +struct PCICFG_UE_STATUS_LOW_CSR_AMAP { + u32 dw[1]; +}; + +/* Unrecoverable Error Status (High) Register. Each bit corresponds to + * an internal Unrecoverable Error. These are set by hardware and may be + * cleared by writing a one to the respective bit(s) to be cleared. Any + * bit being set that is also unmasked will result in Unrecoverable Error + * interrupt notification to the host CPU and/or Server Management chip; + * and the transitioning of BladeEngine to an Offline state. + */ +struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP { + u8 jtag_ue_status; /* DWORD 0 */ + u8 lpcmemhost_ue_status; /* DWORD 0 */ + u8 mgmt_mac_ue_status; /* DWORD 0 */ + u8 mpu_iram_ue_status; /* DWORD 0 */ + u8 pcs0online_ue_status; /* DWORD 0 */ + u8 pcs1online_ue_status; /* DWORD 0 */ + u8 pctl0_ue_status; /* DWORD 0 */ + u8 pctl1_ue_status; /* DWORD 0 */ + u8 pmem_ue_status; /* DWORD 0 */ + u8 rr_ue_status; /* DWORD 0 */ + u8 rxpp_ue_status; /* DWORD 0 */ + u8 txpb_ue_status; /* DWORD 0 */ + u8 txp_ue_status; /* DWORD 0 */ + u8 xaui_ue_status; /* DWORD 0 */ + u8 arm_ue_status; /* DWORD 0 */ + u8 ipc_ue_status; /* DWORD 0 */ + u8 rsvd0[16]; /* DWORD 0 */ +} __packed; +struct PCICFG_UE_STATUS_HI_CSR_AMAP { + u32 dw[1]; +}; + +/* Unrecoverable Error Mask (Low) Register. Each bit, when set to one, + * will mask the associated Unrecoverable Error status bit from notification + * of Unrecoverable Error to the host CPU and/or Server Managment chip and the + * transitioning of all BladeEngine units to an Offline state. + */ +struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP { + u8 cev_ue_mask; /* DWORD 0 */ + u8 ctx_ue_mask; /* DWORD 0 */ + u8 dbuf_ue_mask; /* DWORD 0 */ + u8 erx_ue_mask; /* DWORD 0 */ + u8 host_ue_mask; /* DWORD 0 */ + u8 mpu_ue_mask; /* DWORD 0 */ + u8 ndma_ue_mask; /* DWORD 0 */ + u8 ptc_ue_mask; /* DWORD 0 */ + u8 rdma_ue_mask; /* DWORD 0 */ + u8 rxf_ue_mask; /* DWORD 0 */ + u8 rxips_ue_mask; /* DWORD 0 */ + u8 rxulp0_ue_mask; /* DWORD 0 */ + u8 rxulp1_ue_mask; /* DWORD 0 */ + u8 rxulp2_ue_mask; /* DWORD 0 */ + u8 tim_ue_mask; /* DWORD 0 */ + u8 tpost_ue_mask; /* DWORD 0 */ + u8 tpre_ue_mask; /* DWORD 0 */ + u8 txips_ue_mask; /* DWORD 0 */ + u8 txulp0_ue_mask; /* DWORD 0 */ + u8 txulp1_ue_mask; /* DWORD 0 */ + u8 uc_ue_mask; /* DWORD 0 */ + u8 wdma_ue_mask; /* DWORD 0 */ + u8 txulp2_ue_mask; /* DWORD 0 */ + u8 host1_ue_mask; /* DWORD 0 */ + u8 p0_ob_link_ue_mask; /* DWORD 0 */ + u8 p1_ob_link_ue_mask; /* DWORD 0 */ + u8 host_gpio_ue_mask; /* DWORD 0 */ + u8 mbox_netw_ue_mask; /* DWORD 0 */ + u8 mbox_stor_ue_mask; /* DWORD 0 */ + u8 axgmac0_ue_mask; /* DWORD 0 */ + u8 axgmac1_ue_mask; /* DWORD 0 */ + u8 mpu_intpend_ue_mask; /* DWORD 0 */ +} __packed; +struct PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP { + u32 dw[1]; +}; + +/* Unrecoverable Error Mask (High) Register. Each bit, when set to one, + * will mask the associated Unrecoverable Error status bit from notification + * of Unrecoverable Error to the host CPU and/or Server Managment chip and the + * transitioning of all BladeEngine units to an Offline state. + */ +struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP { + u8 jtag_ue_mask; /* DWORD 0 */ + u8 lpcmemhost_ue_mask; /* DWORD 0 */ + u8 mgmt_mac_ue_mask; /* DWORD 0 */ + u8 mpu_iram_ue_mask; /* DWORD 0 */ + u8 pcs0online_ue_mask; /* DWORD 0 */ + u8 pcs1online_ue_mask; /* DWORD 0 */ + u8 pctl0_ue_mask; /* DWORD 0 */ + u8 pctl1_ue_mask; /* DWORD 0 */ + u8 pmem_ue_mask; /* DWORD 0 */ + u8 rr_ue_mask; /* DWORD 0 */ + u8 rxpp_ue_mask; /* DWORD 0 */ + u8 txpb_ue_mask; /* DWORD 0 */ + u8 txp_ue_mask; /* DWORD 0 */ + u8 xaui_ue_mask; /* DWORD 0 */ + u8 arm_ue_mask; /* DWORD 0 */ + u8 ipc_ue_mask; /* DWORD 0 */ + u8 rsvd0[16]; /* DWORD 0 */ +} __packed; +struct PCICFG_UE_STATUS_HI_MASK_CSR_AMAP { + u32 dw[1]; +}; + +/* Online Control Register 0. This register controls various units within + * BladeEngine being in an Online or Offline state. + */ +struct BE_PCICFG_ONLINE0_CSR_AMAP { + u8 cev_online; /* DWORD 0 */ + u8 ctx_online; /* DWORD 0 */ + u8 dbuf_online; /* DWORD 0 */ + u8 erx_online; /* DWORD 0 */ + u8 host_online; /* DWORD 0 */ + u8 mpu_online; /* DWORD 0 */ + u8 ndma_online; /* DWORD 0 */ + u8 ptc_online; /* DWORD 0 */ + u8 rdma_online; /* DWORD 0 */ + u8 rxf_online; /* DWORD 0 */ + u8 rxips_online; /* DWORD 0 */ + u8 rxulp0_online; /* DWORD 0 */ + u8 rxulp1_online; /* DWORD 0 */ + u8 rxulp2_online; /* DWORD 0 */ + u8 tim_online; /* DWORD 0 */ + u8 tpost_online; /* DWORD 0 */ + u8 tpre_online; /* DWORD 0 */ + u8 txips_online; /* DWORD 0 */ + u8 txulp0_online; /* DWORD 0 */ + u8 txulp1_online; /* DWORD 0 */ + u8 uc_online; /* DWORD 0 */ + u8 wdma_online; /* DWORD 0 */ + u8 txulp2_online; /* DWORD 0 */ + u8 host1_online; /* DWORD 0 */ + u8 p0_ob_link_online; /* DWORD 0 */ + u8 p1_ob_link_online; /* DWORD 0 */ + u8 host_gpio_online; /* DWORD 0 */ + u8 mbox_netw_online; /* DWORD 0 */ + u8 mbox_stor_online; /* DWORD 0 */ + u8 axgmac0_online; /* DWORD 0 */ + u8 axgmac1_online; /* DWORD 0 */ + u8 mpu_intpend_online; /* DWORD 0 */ +} __packed; +struct PCICFG_ONLINE0_CSR_AMAP { + u32 dw[1]; +}; + +/* Online Control Register 1. This register controls various units within + * BladeEngine being in an Online or Offline state. + */ +struct BE_PCICFG_ONLINE1_CSR_AMAP { + u8 jtag_online; /* DWORD 0 */ + u8 lpcmemhost_online; /* DWORD 0 */ + u8 mgmt_mac_online; /* DWORD 0 */ + u8 mpu_iram_online; /* DWORD 0 */ + u8 pcs0online_online; /* DWORD 0 */ + u8 pcs1online_online; /* DWORD 0 */ + u8 pctl0_online; /* DWORD 0 */ + u8 pctl1_online; /* DWORD 0 */ + u8 pmem_online; /* DWORD 0 */ + u8 rr_online; /* DWORD 0 */ + u8 rxpp_online; /* DWORD 0 */ + u8 txpb_online; /* DWORD 0 */ + u8 txp_online; /* DWORD 0 */ + u8 xaui_online; /* DWORD 0 */ + u8 arm_online; /* DWORD 0 */ + u8 ipc_online; /* DWORD 0 */ + u8 rsvd0[16]; /* DWORD 0 */ +} __packed; +struct PCICFG_ONLINE1_CSR_AMAP { + u32 dw[1]; +}; + +/* Host Timer Register. */ +struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP { + u8 hosttimer[24]; /* DWORD 0 */ + u8 hostintr; /* DWORD 0 */ + u8 rsvd0[7]; /* DWORD 0 */ +} __packed; +struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP { + u32 dw[1]; +}; + +/* Scratchpad Register (for software use). */ +struct BE_PCICFG_SCRATCHPAD_CSR_AMAP { + u8 scratchpad[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_SCRATCHPAD_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express Capabilities Register. */ +struct BE_PCICFG_PCIE_CAP_CSR_AMAP { + u8 capid[8]; /* DWORD 0 */ + u8 nextcap[8]; /* DWORD 0 */ + u8 capver[4]; /* DWORD 0 */ + u8 devport[4]; /* DWORD 0 */ + u8 rsvd0[6]; /* DWORD 0 */ + u8 rsvd1[2]; /* DWORD 0 */ +} __packed; +struct PCICFG_PCIE_CAP_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express Device Capabilities Register. */ +struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP { + u8 payload[3]; /* DWORD 0 */ + u8 rsvd0[3]; /* DWORD 0 */ + u8 lo_lat[3]; /* DWORD 0 */ + u8 l1_lat[3]; /* DWORD 0 */ + u8 rsvd1[3]; /* DWORD 0 */ + u8 rsvd2[3]; /* DWORD 0 */ + u8 pwr_value[8]; /* DWORD 0 */ + u8 pwr_scale[2]; /* DWORD 0 */ + u8 rsvd3[4]; /* DWORD 0 */ +} __packed; +struct PCICFG_PCIE_DEVCAP_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express Device Control/Status Registers. */ +struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP { + u8 CorrErrReportEn; /* DWORD 0 */ + u8 NonFatalErrReportEn; /* DWORD 0 */ + u8 FatalErrReportEn; /* DWORD 0 */ + u8 UnsuppReqReportEn; /* DWORD 0 */ + u8 EnableRelaxOrder; /* DWORD 0 */ + u8 Max_Payload_Size[3]; /* DWORD 0 */ + u8 ExtendTagFieldEnable; /* DWORD 0 */ + u8 PhantomFnEnable; /* DWORD 0 */ + u8 AuxPwrPMEnable; /* DWORD 0 */ + u8 EnableNoSnoop; /* DWORD 0 */ + u8 Max_Read_Req_Size[3]; /* DWORD 0 */ + u8 rsvd0; /* DWORD 0 */ + u8 CorrErrDetect; /* DWORD 0 */ + u8 NonFatalErrDetect; /* DWORD 0 */ + u8 FatalErrDetect; /* DWORD 0 */ + u8 UnsuppReqDetect; /* DWORD 0 */ + u8 AuxPwrDetect; /* DWORD 0 */ + u8 TransPending; /* DWORD 0 */ + u8 rsvd1[10]; /* DWORD 0 */ +} __packed; +struct PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express Link Capabilities Register. */ +struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP { + u8 MaxLinkSpeed[4]; /* DWORD 0 */ + u8 MaxLinkWidth[6]; /* DWORD 0 */ + u8 ASPMSupport[2]; /* DWORD 0 */ + u8 L0sExitLat[3]; /* DWORD 0 */ + u8 L1ExitLat[3]; /* DWORD 0 */ + u8 rsvd0[6]; /* DWORD 0 */ + u8 PortNum[8]; /* DWORD 0 */ +} __packed; +struct PCICFG_PCIE_LINK_CAP_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express Link Status Register. */ +struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP { + u8 ASPMCtl[2]; /* DWORD 0 */ + u8 rsvd0; /* DWORD 0 */ + u8 ReadCmplBndry; /* DWORD 0 */ + u8 LinkDisable; /* DWORD 0 */ + u8 RetrainLink; /* DWORD 0 */ + u8 CommonClkConfig; /* DWORD 0 */ + u8 ExtendSync; /* DWORD 0 */ + u8 rsvd1[8]; /* DWORD 0 */ + u8 LinkSpeed[4]; /* DWORD 0 */ + u8 NegLinkWidth[6]; /* DWORD 0 */ + u8 LinkTrainErr; /* DWORD 0 */ + u8 LinkTrain; /* DWORD 0 */ + u8 SlotClkConfig; /* DWORD 0 */ + u8 rsvd2[3]; /* DWORD 0 */ +} __packed; +struct PCICFG_PCIE_LINK_STATUS_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express MSI Configuration Register. */ +struct BE_PCICFG_MSI_CSR_AMAP { + u8 capid[8]; /* DWORD 0 */ + u8 nextptr[8]; /* DWORD 0 */ + u8 tablesize[11]; /* DWORD 0 */ + u8 rsvd0[3]; /* DWORD 0 */ + u8 funcmask; /* DWORD 0 */ + u8 en; /* DWORD 0 */ +} __packed; +struct PCICFG_MSI_CSR_AMAP { + u32 dw[1]; +}; + +/* MSI-X Table Offset Register. */ +struct BE_PCICFG_MSIX_TABLE_CSR_AMAP { + u8 tablebir[3]; /* DWORD 0 */ + u8 offset[29]; /* DWORD 0 */ +} __packed; +struct PCICFG_MSIX_TABLE_CSR_AMAP { + u32 dw[1]; +}; + +/* MSI-X PBA Offset Register. */ +struct BE_PCICFG_MSIX_PBA_CSR_AMAP { + u8 pbabir[3]; /* DWORD 0 */ + u8 offset[29]; /* DWORD 0 */ +} __packed; +struct PCICFG_MSIX_PBA_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express MSI-X Message Vector Control Register. */ +struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP { + u8 vector_control; /* DWORD 0 */ + u8 rsvd0[31]; /* DWORD 0 */ +} __packed; +struct PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express MSI-X Message Data Register. */ +struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP { + u8 data[16]; /* DWORD 0 */ + u8 rsvd0[16]; /* DWORD 0 */ +} __packed; +struct PCICFG_MSIX_MSG_DATA_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express MSI-X Message Address Register - High Part. */ +struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP { + u8 addr[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP { + u32 dw[1]; +}; + +/* PCI Express MSI-X Message Address Register - Low Part. */ +struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP { + u8 rsvd0[2]; /* DWORD 0 */ + u8 addr[30]; /* DWORD 0 */ +} __packed; +struct PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP { + u32 dw[1]; +}; + +struct BE_PCICFG_ANON_18_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_ANON_18_RSVD_AMAP { + u32 dw[1]; +}; + +struct BE_PCICFG_ANON_19_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_ANON_19_RSVD_AMAP { + u32 dw[1]; +}; + +struct BE_PCICFG_ANON_20_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[25][32]; /* DWORD 1 */ +} __packed; +struct PCICFG_ANON_20_RSVD_AMAP { + u32 dw[26]; +}; + +struct BE_PCICFG_ANON_21_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[1919][32]; /* DWORD 1 */ +} __packed; +struct PCICFG_ANON_21_RSVD_AMAP { + u32 dw[1920]; +}; + +struct BE_PCICFG_ANON_22_MESSAGE_AMAP { + struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP vec_ctrl; + struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP msg_data; + struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP addr_hi; + struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP addr_low; +} __packed; +struct PCICFG_ANON_22_MESSAGE_AMAP { + u32 dw[4]; +}; + +struct BE_PCICFG_ANON_23_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[895][32]; /* DWORD 1 */ +} __packed; +struct PCICFG_ANON_23_RSVD_AMAP { + u32 dw[896]; +}; + +/* These PCI Configuration Space registers are for the Storage Function of + * BladeEngine (Function 0). In the memory map of the registers below their + * table, + */ +struct BE_PCICFG0_CSRMAP_AMAP { + struct BE_PCICFG_ID_CSR_AMAP id; + u8 rsvd0[32]; /* DWORD 1 */ + u8 rsvd1[32]; /* DWORD 2 */ + u8 rsvd2[32]; /* DWORD 3 */ + struct BE_PCICFG_IOBAR_CSR_AMAP iobar; + struct BE_PCICFG_MEMBAR0_CSR_AMAP membar0; + struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP membar1_lo; + struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP membar1_hi; + struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP membar2_lo; + struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP membar2_hi; + u8 rsvd3[32]; /* DWORD 10 */ + struct BE_PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP subsystem_id; + u8 rsvd4[32]; /* DWORD 12 */ + u8 rsvd5[32]; /* DWORD 13 */ + u8 rsvd6[32]; /* DWORD 14 */ + u8 rsvd7[32]; /* DWORD 15 */ + struct BE_PCICFG_SEMAPHORE_CSR_AMAP semaphore[4]; + struct BE_PCICFG_SOFT_RESET_CSR_AMAP soft_reset; + u8 rsvd8[32]; /* DWORD 21 */ + struct BE_PCICFG_SCRATCHPAD_CSR_AMAP scratchpad; + u8 rsvd9[32]; /* DWORD 23 */ + u8 rsvd10[32]; /* DWORD 24 */ + u8 rsvd11[32]; /* DWORD 25 */ + u8 rsvd12[32]; /* DWORD 26 */ + u8 rsvd13[32]; /* DWORD 27 */ + u8 rsvd14[2][32]; /* DWORD 28 */ + u8 rsvd15[32]; /* DWORD 30 */ + u8 rsvd16[32]; /* DWORD 31 */ + u8 rsvd17[8][32]; /* DWORD 32 */ + struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP ue_status_low; + struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP ue_status_hi; + struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP ue_status_low_mask; + struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP ue_status_hi_mask; + struct BE_PCICFG_ONLINE0_CSR_AMAP online0; + struct BE_PCICFG_ONLINE1_CSR_AMAP online1; + u8 rsvd18[32]; /* DWORD 46 */ + u8 rsvd19[32]; /* DWORD 47 */ + u8 rsvd20[32]; /* DWORD 48 */ + u8 rsvd21[32]; /* DWORD 49 */ + struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP host_timer_int_ctrl; + u8 rsvd22[32]; /* DWORD 51 */ + struct BE_PCICFG_PCIE_CAP_CSR_AMAP pcie_cap; + struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP pcie_devcap; + struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP pcie_control_status; + struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP pcie_link_cap; + struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP pcie_link_status; + struct BE_PCICFG_MSI_CSR_AMAP msi; + struct BE_PCICFG_MSIX_TABLE_CSR_AMAP msix_table_offset; + struct BE_PCICFG_MSIX_PBA_CSR_AMAP msix_pba_offset; + u8 rsvd23[32]; /* DWORD 60 */ + u8 rsvd24[32]; /* DWORD 61 */ + u8 rsvd25[32]; /* DWORD 62 */ + u8 rsvd26[32]; /* DWORD 63 */ + u8 rsvd27[32]; /* DWORD 64 */ + u8 rsvd28[32]; /* DWORD 65 */ + u8 rsvd29[32]; /* DWORD 66 */ + u8 rsvd30[32]; /* DWORD 67 */ + u8 rsvd31[32]; /* DWORD 68 */ + u8 rsvd32[32]; /* DWORD 69 */ + u8 rsvd33[32]; /* DWORD 70 */ + u8 rsvd34[32]; /* DWORD 71 */ + u8 rsvd35[32]; /* DWORD 72 */ + u8 rsvd36[32]; /* DWORD 73 */ + u8 rsvd37[32]; /* DWORD 74 */ + u8 rsvd38[32]; /* DWORD 75 */ + u8 rsvd39[32]; /* DWORD 76 */ + u8 rsvd40[32]; /* DWORD 77 */ + u8 rsvd41[32]; /* DWORD 78 */ + u8 rsvd42[32]; /* DWORD 79 */ + u8 rsvd43[32]; /* DWORD 80 */ + u8 rsvd44[32]; /* DWORD 81 */ + u8 rsvd45[32]; /* DWORD 82 */ + u8 rsvd46[32]; /* DWORD 83 */ + u8 rsvd47[32]; /* DWORD 84 */ + u8 rsvd48[32]; /* DWORD 85 */ + u8 rsvd49[32]; /* DWORD 86 */ + u8 rsvd50[32]; /* DWORD 87 */ + u8 rsvd51[32]; /* DWORD 88 */ + u8 rsvd52[32]; /* DWORD 89 */ + u8 rsvd53[32]; /* DWORD 90 */ + u8 rsvd54[32]; /* DWORD 91 */ + u8 rsvd55[32]; /* DWORD 92 */ + u8 rsvd56[832]; /* DWORD 93 */ + u8 rsvd57[32]; /* DWORD 119 */ + u8 rsvd58[32]; /* DWORD 120 */ + u8 rsvd59[32]; /* DWORD 121 */ + u8 rsvd60[32]; /* DWORD 122 */ + u8 rsvd61[32]; /* DWORD 123 */ + u8 rsvd62[32]; /* DWORD 124 */ + u8 rsvd63[32]; /* DWORD 125 */ + u8 rsvd64[32]; /* DWORD 126 */ + u8 rsvd65[32]; /* DWORD 127 */ + u8 rsvd66[61440]; /* DWORD 128 */ + struct BE_PCICFG_ANON_22_MESSAGE_AMAP message[32]; + u8 rsvd67[28672]; /* DWORD 2176 */ + u8 rsvd68[32]; /* DWORD 3072 */ + u8 rsvd69[1023][32]; /* DWORD 3073 */ +} __packed; +struct PCICFG0_CSRMAP_AMAP { + u32 dw[4096]; +}; + +struct BE_PCICFG_ANON_24_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_ANON_24_RSVD_AMAP { + u32 dw[1]; +}; + +struct BE_PCICFG_ANON_25_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_ANON_25_RSVD_AMAP { + u32 dw[1]; +}; + +struct BE_PCICFG_ANON_26_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ +} __packed; +struct PCICFG_ANON_26_RSVD_AMAP { + u32 dw[1]; +}; + +struct BE_PCICFG_ANON_27_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[32]; /* DWORD 1 */ +} __packed; +struct PCICFG_ANON_27_RSVD_AMAP { + u32 dw[2]; +}; + +struct BE_PCICFG_ANON_28_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[3][32]; /* DWORD 1 */ +} __packed; +struct PCICFG_ANON_28_RSVD_AMAP { + u32 dw[4]; +}; + +struct BE_PCICFG_ANON_29_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[36][32]; /* DWORD 1 */ +} __packed; +struct PCICFG_ANON_29_RSVD_AMAP { + u32 dw[37]; +}; + +struct BE_PCICFG_ANON_30_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[1930][32]; /* DWORD 1 */ +} __packed; +struct PCICFG_ANON_30_RSVD_AMAP { + u32 dw[1931]; +}; + +struct BE_PCICFG_ANON_31_MESSAGE_AMAP { + struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP vec_ctrl; + struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP msg_data; + struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP addr_hi; + struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP addr_low; +} __packed; +struct PCICFG_ANON_31_MESSAGE_AMAP { + u32 dw[4]; +}; + +struct BE_PCICFG_ANON_32_RSVD_AMAP { + u8 rsvd0[32]; /* DWORD 0 */ + u8 rsvd1[895][32]; /* DWORD 1 */ +} __packed; +struct PCICFG_ANON_32_RSVD_AMAP { + u32 dw[896]; +}; + +/* This PCI configuration space register map is for the Networking Function of + * BladeEngine (Function 1). + */ +struct BE_PCICFG1_CSRMAP_AMAP { + struct BE_PCICFG_ID_CSR_AMAP id; + u8 rsvd0[32]; /* DWORD 1 */ + u8 rsvd1[32]; /* DWORD 2 */ + u8 rsvd2[32]; /* DWORD 3 */ + struct BE_PCICFG_IOBAR_CSR_AMAP iobar; + struct BE_PCICFG_MEMBAR0_CSR_AMAP membar0; + struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP membar1_lo; + struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP membar1_hi; + struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP membar2_lo; + struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP membar2_hi; + u8 rsvd3[32]; /* DWORD 10 */ + struct BE_PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP subsystem_id; + u8 rsvd4[32]; /* DWORD 12 */ + u8 rsvd5[32]; /* DWORD 13 */ + u8 rsvd6[32]; /* DWORD 14 */ + u8 rsvd7[32]; /* DWORD 15 */ + struct BE_PCICFG_SEMAPHORE_CSR_AMAP semaphore[4]; + struct BE_PCICFG_SOFT_RESET_CSR_AMAP soft_reset; + u8 rsvd8[32]; /* DWORD 21 */ + struct BE_PCICFG_SCRATCHPAD_CSR_AMAP scratchpad; + u8 rsvd9[32]; /* DWORD 23 */ + u8 rsvd10[32]; /* DWORD 24 */ + u8 rsvd11[32]; /* DWORD 25 */ + u8 rsvd12[32]; /* DWORD 26 */ + u8 rsvd13[32]; /* DWORD 27 */ + u8 rsvd14[2][32]; /* DWORD 28 */ + u8 rsvd15[32]; /* DWORD 30 */ + u8 rsvd16[32]; /* DWORD 31 */ + u8 rsvd17[8][32]; /* DWORD 32 */ + struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP ue_status_low; + struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP ue_status_hi; + struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP ue_status_low_mask; + struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP ue_status_hi_mask; + struct BE_PCICFG_ONLINE0_CSR_AMAP online0; + struct BE_PCICFG_ONLINE1_CSR_AMAP online1; + u8 rsvd18[32]; /* DWORD 46 */ + u8 rsvd19[32]; /* DWORD 47 */ + u8 rsvd20[32]; /* DWORD 48 */ + u8 rsvd21[32]; /* DWORD 49 */ + struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP host_timer_int_ctrl; + u8 rsvd22[32]; /* DWORD 51 */ + struct BE_PCICFG_PCIE_CAP_CSR_AMAP pcie_cap; + struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP pcie_devcap; + struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP pcie_control_status; + struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP pcie_link_cap; + struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP pcie_link_status; + struct BE_PCICFG_MSI_CSR_AMAP msi; + struct BE_PCICFG_MSIX_TABLE_CSR_AMAP msix_table_offset; + struct BE_PCICFG_MSIX_PBA_CSR_AMAP msix_pba_offset; + u8 rsvd23[64]; /* DWORD 60 */ + u8 rsvd24[32]; /* DWORD 62 */ + u8 rsvd25[32]; /* DWORD 63 */ + u8 rsvd26[32]; /* DWORD 64 */ + u8 rsvd27[32]; /* DWORD 65 */ + u8 rsvd28[32]; /* DWORD 66 */ + u8 rsvd29[32]; /* DWORD 67 */ + u8 rsvd30[32]; /* DWORD 68 */ + u8 rsvd31[32]; /* DWORD 69 */ + u8 rsvd32[32]; /* DWORD 70 */ + u8 rsvd33[32]; /* DWORD 71 */ + u8 rsvd34[32]; /* DWORD 72 */ + u8 rsvd35[32]; /* DWORD 73 */ + u8 rsvd36[32]; /* DWORD 74 */ + u8 rsvd37[128]; /* DWORD 75 */ + u8 rsvd38[32]; /* DWORD 79 */ + u8 rsvd39[1184]; /* DWORD 80 */ + u8 rsvd40[61792]; /* DWORD 117 */ + struct BE_PCICFG_ANON_31_MESSAGE_AMAP message[32]; + u8 rsvd41[28672]; /* DWORD 2176 */ + u8 rsvd42[32]; /* DWORD 3072 */ + u8 rsvd43[1023][32]; /* DWORD 3073 */ +} __packed; +struct PCICFG1_CSRMAP_AMAP { + u32 dw[4096]; +}; + +#endif /* __pcicfg_amap_h__ */ diff --git a/trunk/drivers/staging/benet/post_codes.h b/trunk/drivers/staging/benet/post_codes.h new file mode 100644 index 000000000000..6d1621f5f5fb --- /dev/null +++ b/trunk/drivers/staging/benet/post_codes.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __post_codes_amap_h__ +#define __post_codes_amap_h__ + +/* --- MGMT_HBA_POST_STAGE_ENUM --- */ +#define POST_STAGE_POWER_ON_RESET (0) /* State after a cold or warm boot. */ +#define POST_STAGE_AWAITING_HOST_RDY (1) /* ARM boot code awaiting a + go-ahed from the host. */ +#define POST_STAGE_HOST_RDY (2) /* Host has given go-ahed to ARM. */ +#define POST_STAGE_BE_RESET (3) /* Host wants to reset chip, this is a chip + workaround */ +#define POST_STAGE_SEEPROM_CS_START (256) /* SEEPROM checksum + test start. */ +#define POST_STAGE_SEEPROM_CS_DONE (257) /* SEEPROM checksum test + done. */ +#define POST_STAGE_DDR_CONFIG_START (512) /* DDR configuration start. */ +#define POST_STAGE_DDR_CONFIG_DONE (513) /* DDR configuration done. */ +#define POST_STAGE_DDR_CALIBRATE_START (768) /* DDR calibration start. */ +#define POST_STAGE_DDR_CALIBRATE_DONE (769) /* DDR calibration done. */ +#define POST_STAGE_DDR_TEST_START (1024) /* DDR memory test start. */ +#define POST_STAGE_DDR_TEST_DONE (1025) /* DDR memory test done. */ +#define POST_STAGE_REDBOOT_INIT_START (1536) /* Redboot starts execution. */ +#define POST_STAGE_REDBOOT_INIT_DONE (1537) /* Redboot done execution. */ +#define POST_STAGE_FW_IMAGE_LOAD_START (1792) /* Firmware image load to + DDR start. */ +#define POST_STAGE_FW_IMAGE_LOAD_DONE (1793) /* Firmware image load + to DDR done. */ +#define POST_STAGE_ARMFW_START (2048) /* ARMfw runtime code + starts execution. */ +#define POST_STAGE_DHCP_QUERY_START (2304) /* DHCP server query start. */ +#define POST_STAGE_DHCP_QUERY_DONE (2305) /* DHCP server query done. */ +#define POST_STAGE_BOOT_TARGET_DISCOVERY_START (2560) /* Boot Target + Discovery Start. */ +#define POST_STAGE_BOOT_TARGET_DISCOVERY_DONE (2561) /* Boot Target + Discovery Done. */ +#define POST_STAGE_RC_OPTION_SET (2816) /* Remote configuration + option is set in SEEPROM */ +#define POST_STAGE_SWITCH_LINK (2817) /* Wait for link up on switch */ +#define POST_STAGE_SEND_ICDS_MESSAGE (2818) /* Send the ICDS message + to switch */ +#define POST_STAGE_PERFROM_TFTP (2819) /* Download xml using TFTP */ +#define POST_STAGE_PARSE_XML (2820) /* Parse XML file */ +#define POST_STAGE_DOWNLOAD_IMAGE (2821) /* Download IMAGE from + TFTP server */ +#define POST_STAGE_FLASH_IMAGE (2822) /* Flash the IMAGE */ +#define POST_STAGE_RC_DONE (2823) /* Remote configuration + complete */ +#define POST_STAGE_REBOOT_SYSTEM (2824) /* Upgrade IMAGE done, + reboot required */ +#define POST_STAGE_MAC_ADDRESS (3072) /* MAC Address Check */ +#define POST_STAGE_ARMFW_READY (49152) /* ARMfw is done with POST + and ready. */ +#define POST_STAGE_ARMFW_UE (61440) /* ARMfw has asserted an + unrecoverable error. The + lower 3 hex digits of the + stage code identify the + unique error code. + */ + +/* This structure defines the format of the MPU semaphore + * register when used for POST. + */ +struct BE_MGMT_HBA_POST_STATUS_STRUCT_AMAP { + u8 stage[16]; /* DWORD 0 */ + u8 rsvd0[10]; /* DWORD 0 */ + u8 iscsi_driver_loaded; /* DWORD 0 */ + u8 option_rom_installed; /* DWORD 0 */ + u8 iscsi_ip_conflict; /* DWORD 0 */ + u8 iscsi_no_ip; /* DWORD 0 */ + u8 backup_fw; /* DWORD 0 */ + u8 error; /* DWORD 0 */ +} __packed; +struct MGMT_HBA_POST_STATUS_STRUCT_AMAP { + u32 dw[1]; +}; + +/* --- MGMT_HBA_POST_DUMMY_BITS_ENUM --- */ +#define POST_BIT_ISCSI_LOADED (26) +#define POST_BIT_OPTROM_INST (27) +#define POST_BIT_BAD_IP_ADDR (28) +#define POST_BIT_NO_IP_ADDR (29) +#define POST_BIT_BACKUP_FW (30) +#define POST_BIT_ERROR (31) + +/* --- MGMT_HBA_POST_DUMMY_VALUES_ENUM --- */ +#define POST_ISCSI_DRIVER_LOADED (67108864) +#define POST_OPTROM_INSTALLED (134217728) +#define POST_ISCSI_IP_ADDRESS_CONFLICT (268435456) +#define POST_ISCSI_NO_IP_ADDRESS (536870912) +#define POST_BACKUP_FW_LOADED (1073741824) +#define POST_FATAL_ERROR (2147483648) + +#endif /* __post_codes_amap_h__ */ diff --git a/trunk/drivers/staging/benet/regmap.h b/trunk/drivers/staging/benet/regmap.h new file mode 100644 index 000000000000..e816ba210e83 --- /dev/null +++ b/trunk/drivers/staging/benet/regmap.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005 - 2008 ServerEngines + * 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 version 2 + * as published by the Free Software Foundation. The full GNU General + * Public License is included in this distribution in the file called COPYING. + * + * Contact Information: + * linux-drivers@serverengines.com + * + * ServerEngines + * 209 N. Fair Oaks Ave + * Sunnyvale, CA 94085 + */ +/* + * Autogenerated by srcgen version: 0127 + */ +#ifndef __regmap_amap_h__ +#define __regmap_amap_h__ +#include "pcicfg.h" +#include "ep.h" +#include "cev.h" +#include "mpu.h" +#include "doorbells.h" + +/* + * This is the control and status register map for BladeEngine, showing + * the relative size and offset of each sub-module. The CSR registers + * are identical for the network and storage PCI functions. The + * CSR map is shown below, followed by details of each block, + * in sub-sections. The sub-sections begin with a description + * of CSRs that are instantiated in multiple blocks. + */ +struct BE_BLADE_ENGINE_CSRMAP_AMAP { + struct BE_MPU_CSRMAP_AMAP mpu; + u8 rsvd0[8192]; /* DWORD 256 */ + u8 rsvd1[8192]; /* DWORD 512 */ + struct BE_CEV_CSRMAP_AMAP cev; + u8 rsvd2[8192]; /* DWORD 1024 */ + u8 rsvd3[8192]; /* DWORD 1280 */ + u8 rsvd4[8192]; /* DWORD 1536 */ + u8 rsvd5[8192]; /* DWORD 1792 */ + u8 rsvd6[8192]; /* DWORD 2048 */ + u8 rsvd7[8192]; /* DWORD 2304 */ + u8 rsvd8[8192]; /* DWORD 2560 */ + u8 rsvd9[8192]; /* DWORD 2816 */ + u8 rsvd10[8192]; /* DWORD 3072 */ + u8 rsvd11[8192]; /* DWORD 3328 */ + u8 rsvd12[8192]; /* DWORD 3584 */ + u8 rsvd13[8192]; /* DWORD 3840 */ + u8 rsvd14[8192]; /* DWORD 4096 */ + u8 rsvd15[8192]; /* DWORD 4352 */ + u8 rsvd16[8192]; /* DWORD 4608 */ + u8 rsvd17[8192]; /* DWORD 4864 */ + u8 rsvd18[8192]; /* DWORD 5120 */ + u8 rsvd19[8192]; /* DWORD 5376 */ + u8 rsvd20[8192]; /* DWORD 5632 */ + u8 rsvd21[8192]; /* DWORD 5888 */ + u8 rsvd22[8192]; /* DWORD 6144 */ + u8 rsvd23[17152][32]; /* DWORD 6400 */ +} __packed; +struct BLADE_ENGINE_CSRMAP_AMAP { + u32 dw[23552]; +}; + +#endif /* __regmap_amap_h__ */ diff --git a/trunk/drivers/staging/go7007/snd-go7007.c b/trunk/drivers/staging/go7007/snd-go7007.c index cd19be6c00e0..a7de401f61ab 100644 --- a/trunk/drivers/staging/go7007/snd-go7007.c +++ b/trunk/drivers/staging/go7007/snd-go7007.c @@ -248,11 +248,10 @@ int go7007_snd_init(struct go7007 *go) spin_lock_init(&gosnd->lock); gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0; gosnd->capturing = 0; - ret = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, - &gosnd->card); - if (ret < 0) { + gosnd->card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (gosnd->card == NULL) { kfree(gosnd); - return ret; + return -ENOMEM; } ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go, &go7007_snd_device_ops); diff --git a/trunk/drivers/usb/atm/cxacru.c b/trunk/drivers/usb/atm/cxacru.c index 6789089e2461..5ed4ae07bac1 100644 --- a/trunk/drivers/usb/atm/cxacru.c +++ b/trunk/drivers/usb/atm/cxacru.c @@ -485,7 +485,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n", wbuflen, rbuflen); ret = -ENOMEM; - goto err; + goto fail; } mutex_lock(&instance->cm_serialize); @@ -565,7 +565,6 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, dbg("cm %#x", cm); fail: mutex_unlock(&instance->cm_serialize); -err: return ret; } diff --git a/trunk/drivers/usb/class/usbtmc.c b/trunk/drivers/usb/class/usbtmc.c index c40a9b284cc9..0f5c05f6f9df 100644 --- a/trunk/drivers/usb/class/usbtmc.c +++ b/trunk/drivers/usb/class/usbtmc.c @@ -50,7 +50,6 @@ static struct usb_device_id usbtmc_devices[] = { { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, - { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), }, { 0, } /* terminating entry */ }; MODULE_DEVICE_TABLE(usb, usbtmc_devices); @@ -107,13 +106,12 @@ static int usbtmc_open(struct inode *inode, struct file *filp) { struct usb_interface *intf; struct usbtmc_device_data *data; - int retval = 0; + int retval = -ENODEV; intf = usb_find_interface(&usbtmc_driver, iminor(inode)); if (!intf) { printk(KERN_ERR KBUILD_MODNAME ": can not find device for minor %d", iminor(inode)); - retval = -ENODEV; goto exit; } diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index 6585f527e381..7513bb083c15 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -359,6 +359,11 @@ static void destroy_async(struct dev_state *ps, struct list_head *list) spin_lock_irqsave(&ps->lock, flags); } spin_unlock_irqrestore(&ps->lock, flags); + as = async_getcompleted(ps); + while (as) { + free_async(as); + as = async_getcompleted(ps); + } } static void destroy_async_on_interface(struct dev_state *ps, @@ -638,7 +643,6 @@ static int usbdev_release(struct inode *inode, struct file *file) struct dev_state *ps = file->private_data; struct usb_device *dev = ps->dev; unsigned int ifnum; - struct async *as; usb_lock_device(dev); @@ -657,12 +661,6 @@ static int usbdev_release(struct inode *inode, struct file *file) usb_unlock_device(dev); usb_put_dev(dev); put_pid(ps->disc_pid); - - as = async_getcompleted(ps); - while (as) { - free_async(as); - as = async_getcompleted(ps); - } kfree(ps); return 0; } diff --git a/trunk/drivers/usb/gadget/gmidi.c b/trunk/drivers/usb/gadget/gmidi.c index 14e09abbddfc..60d3f9e9b51f 100644 --- a/trunk/drivers/usb/gadget/gmidi.c +++ b/trunk/drivers/usb/gadget/gmidi.c @@ -1099,9 +1099,10 @@ static int gmidi_register_card(struct gmidi_device *dev) .dev_free = gmidi_snd_free, }; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) { - ERROR(dev, "snd_card_create failed\n"); + card = snd_card_new(index, id, THIS_MODULE, 0); + if (!card) { + ERROR(dev, "snd_card_new failed\n"); + err = -ENOMEM; goto fail; } dev->card = card; diff --git a/trunk/drivers/usb/host/ehci-q.c b/trunk/drivers/usb/host/ehci-q.c index ecc9b66c03cd..3712b925b315 100644 --- a/trunk/drivers/usb/host/ehci-q.c +++ b/trunk/drivers/usb/host/ehci-q.c @@ -1095,8 +1095,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) prev->qh_next = qh->qh_next; wmb (); - /* If the controller isn't running, we don't have to wait for it */ - if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) { + if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) { /* if (unlikely (qh->reclaim != 0)) * this will recurse, probably not much */ diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index 1d0b49e3f192..07bcb931021b 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -1536,7 +1536,7 @@ itd_link_urb ( struct ehci_itd, itd_list); list_move_tail (&itd->itd_list, &stream->td_list); itd->stream = iso_stream_get (stream); - itd->urb = urb; + itd->urb = usb_get_urb (urb); itd_init (ehci, stream, itd); } @@ -1645,7 +1645,7 @@ itd_complete ( (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; - if (unlikely(list_is_singular(&stream->td_list))) { + if (unlikely (list_empty (&stream->td_list))) { ehci_to_hcd(ehci)->self.bandwidth_allocated -= stream->bandwidth; ehci_vdbg (ehci, @@ -1656,6 +1656,7 @@ itd_complete ( iso_stream_put (ehci, stream); done: + usb_put_urb(urb); itd->urb = NULL; if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { /* OK to recycle this ITD now. */ @@ -1948,7 +1949,7 @@ sitd_link_urb ( struct ehci_sitd, sitd_list); list_move_tail (&sitd->sitd_list, &stream->td_list); sitd->stream = iso_stream_get (stream); - sitd->urb = urb; + sitd->urb = usb_get_urb (urb); sitd_patch(ehci, stream, sitd, sched, packet); sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, @@ -2033,7 +2034,7 @@ sitd_complete ( (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; - if (list_is_singular(&stream->td_list)) { + if (list_empty (&stream->td_list)) { ehci_to_hcd(ehci)->self.bandwidth_allocated -= stream->bandwidth; ehci_vdbg (ehci, @@ -2044,6 +2045,7 @@ sitd_complete ( iso_stream_put (ehci, stream); /* OK to recycle this SITD now that its completion callback ran. */ done: + usb_put_urb(urb); sitd->urb = NULL; sitd->stream = NULL; list_move(&sitd->sitd_list, &stream->free_list); diff --git a/trunk/drivers/usb/image/mdc800.c b/trunk/drivers/usb/image/mdc800.c index 972f20b3406c..878c77ca086e 100644 --- a/trunk/drivers/usb/image/mdc800.c +++ b/trunk/drivers/usb/image/mdc800.c @@ -499,7 +499,6 @@ static int mdc800_usb_probe (struct usb_interface *intf, retval = usb_register_dev(intf, &mdc800_class); if (retval) { dev_err(&intf->dev, "Not able to get a minor for this device.\n"); - mutex_unlock(&mdc800->io_lock); return -ENODEV; } diff --git a/trunk/drivers/usb/misc/adutux.c b/trunk/drivers/usb/misc/adutux.c index 203526542013..7b6922e08ed1 100644 --- a/trunk/drivers/usb/misc/adutux.c +++ b/trunk/drivers/usb/misc/adutux.c @@ -376,7 +376,7 @@ static int adu_release(struct inode *inode, struct file *file) if (dev->open_count <= 0) { dbg(1," %s : device not opened", __func__); retval = -ENODEV; - goto unlock; + goto exit; } adu_release_internal(dev); @@ -385,9 +385,9 @@ static int adu_release(struct inode *inode, struct file *file) if (!dev->open_count) /* ... and we're the last user */ adu_delete(dev); } -unlock: - mutex_unlock(&adutux_mutex); + exit: + mutex_unlock(&adutux_mutex); dbg(2," %s : leave, return value %d", __func__, retval); return retval; } diff --git a/trunk/drivers/usb/misc/vstusb.c b/trunk/drivers/usb/misc/vstusb.c index f26ea8dc1577..63dff9ba73c5 100644 --- a/trunk/drivers/usb/misc/vstusb.c +++ b/trunk/drivers/usb/misc/vstusb.c @@ -401,7 +401,6 @@ static ssize_t vstusb_write(struct file *file, const char __user *buffer, } if (copy_from_user(buf, buffer, count)) { - mutex_unlock(&vstdev->lock); dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__); retval = -EFAULT; goto exit; diff --git a/trunk/drivers/usb/serial/cp2101.c b/trunk/drivers/usb/serial/cp2101.c index 9b4082b58c5b..027f4b7dde86 100644 --- a/trunk/drivers/usb/serial/cp2101.c +++ b/trunk/drivers/usb/serial/cp2101.c @@ -79,7 +79,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ - { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index ae84c326a540..f92f4d773374 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -663,11 +663,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, - { USB_DEVICE(ATMEL_VID, STK541_PID) }, - { USB_DEVICE(DE_VID, STB_PID) }, - { USB_DEVICE(DE_VID, WHT_PID) }, - { USB_DEVICE(ADI_VID, ADI_GNICE_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index daaf63db0b50..e300c840f8ca 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -892,26 +892,6 @@ */ #define DIEBOLD_BCS_SE923_PID 0xfb99 -/* - * Atmel STK541 - */ -#define ATMEL_VID 0x03eb /* Vendor ID */ -#define STK541_PID 0x2109 /* Zigbee Controller */ - -/* - * Dresden Elektronic Sensor Terminal Board - */ -#define DE_VID 0x1cf1 /* Vendor ID */ -#define STB_PID 0x0001 /* Sensor Terminal Board */ -#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ - -/* - * Blackfin gnICE JTAG - * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice - */ -#define ADI_VID 0x0456 -#define ADI_GNICE_PID 0xF000 - /* * BmRequestType: 1100 0000b * bRequest: FTDI_E2_READ diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 61ebddc48497..b7c132bded7f 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -89,7 +89,6 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 #define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 #define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 -#define OPTION_PRODUCT_GTM380_MODEM 0x7201 #define HUAWEI_VENDOR_ID 0x12D1 #define HUAWEI_PRODUCT_E600 0x1001 @@ -198,7 +197,6 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po /* OVATION PRODUCTS */ #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 -#define NOVATELWIRELESS_PRODUCT_U727 0x5010 /* FUTURE NOVATEL PRODUCTS */ #define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000 @@ -290,11 +288,15 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po /* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2 -#define ZTE_PRODUCT_MF622 0x0001 #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_MF626 0x0031 #define ZTE_PRODUCT_CDMA_TECH 0xfffe +/* Ericsson products */ +#define ERICSSON_VENDOR_ID 0x0bdb +#define ERICSSON_PRODUCT_F3507G_1 0x1900 +#define ERICSSON_PRODUCT_F3507G_2 0x1902 + #define BENQ_VENDOR_ID 0x04a5 #define BENQ_PRODUCT_H10 0x4068 @@ -323,7 +325,6 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, @@ -414,7 +415,6 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ @@ -442,6 +442,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ @@ -509,10 +510,11 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, - { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, + { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_1) }, + { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_2) }, { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ { } /* Terminating entry */ diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index cfde74a6faa3..6f59c8e510ea 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -226,7 +226,7 @@ UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0610, US_FL_MAX_SECTORS_64 ), /* Reported by Manuel Osdoba */ -UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999, +UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452, "Nokia", "Nokia 6233", US_SC_DEVICE, US_PR_DEVICE, NULL, @@ -951,9 +951,7 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, US_FL_FIX_CAPACITY ), /* Reported by Richard -=[]=- */ -/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by - * Thomas Bartosik */ -UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100, +UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100, "Prolific Technology Inc.", "Mass Storage Device", US_SC_DEVICE, US_PR_DEVICE, NULL, @@ -1392,16 +1390,6 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, 0 ), -/* Reported by Jan Dumon - * This device (wrongly) has a vendor-specific device descriptor. - * The entry is needed so usb-storage can bind to it's mass-storage - * interface as an interface driver */ -UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, - "Option", - "GI 0431 SD-Card", - US_SC_DEVICE, US_PR_DEVICE, NULL, - 0 ), - /* Reported by Ben Efros */ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, "Seagate", diff --git a/trunk/drivers/usb/wusbcore/wa-xfer.c b/trunk/drivers/usb/wusbcore/wa-xfer.c index 613a5fc490d3..238a96aee3a1 100644 --- a/trunk/drivers/usb/wusbcore/wa-xfer.c +++ b/trunk/drivers/usb/wusbcore/wa-xfer.c @@ -921,10 +921,8 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer) result = -ENODEV; /* FIXME: segmentation broken -- kills DWA */ mutex_lock(&wusbhc->mutex); /* get a WUSB dev */ - if (urb->dev == NULL) { - mutex_unlock(&wusbhc->mutex); + if (urb->dev == NULL) goto error_dev_gone; - } wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); if (wusb_dev == NULL) { mutex_unlock(&wusbhc->mutex); diff --git a/trunk/drivers/video/aty/radeon_pm.c b/trunk/drivers/video/aty/radeon_pm.c index c6d7cc76516f..81603f85e17e 100644 --- a/trunk/drivers/video/aty/radeon_pm.c +++ b/trunk/drivers/video/aty/radeon_pm.c @@ -2507,25 +2507,6 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo) #endif /* CONFIG_PPC_OF */ -static void radeonfb_whack_power_state(struct radeonfb_info *rinfo, pci_power_t state) -{ - u16 pwr_cmd; - - for (;;) { - pci_read_config_word(rinfo->pdev, - rinfo->pm_reg+PCI_PM_CTRL, - &pwr_cmd); - if (pwr_cmd & 2) - break; - pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2; - pci_write_config_word(rinfo->pdev, - rinfo->pm_reg+PCI_PM_CTRL, - pwr_cmd); - msleep(500); - } - rinfo->pdev->current_state = state; -} - static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) { u32 tmp; @@ -2577,11 +2558,6 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) /* Switch PCI power management to D2. */ pci_disable_device(rinfo->pdev); pci_save_state(rinfo->pdev); - /* The chip seems to need us to whack the PM register - * repeatedly until it sticks. We do that -prior- to - * calling pci_set_power_state() - */ - radeonfb_whack_power_state(rinfo, PCI_D2); pci_set_power_state(rinfo->pdev, PCI_D2); } else { printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", diff --git a/trunk/drivers/video/logo/logo_linux_clut224.ppm b/trunk/drivers/video/logo/logo_linux_clut224.ppm index de93ff3fc1ad..3c14e43b82fe 100644 --- a/trunk/drivers/video/logo/logo_linux_clut224.ppm +++ b/trunk/drivers/video/logo/logo_linux_clut224.ppm @@ -1,2828 +1,1604 @@ P3 -145 113 +# Standard 224-color Linux logo +80 80 255 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 3 4 4 6 7 7 -8 10 10 8 10 10 6 8 8 6 7 7 3 4 4 2 2 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 4 5 5 17 18 17 -27 29 28 35 37 36 40 43 41 43 45 43 40 43 41 37 39 37 -32 34 33 27 30 29 23 25 24 17 21 21 15 18 18 12 15 15 -11 13 13 8 10 10 6 7 7 3 4 4 1 1 1 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 13 13 13 32 34 33 49 51 48 60 60 56 58 59 55 -55 57 54 55 56 53 49 51 48 43 45 43 39 40 39 33 37 35 -28 31 30 23 27 26 20 23 23 17 20 20 14 17 17 13 16 16 -11 14 14 10 13 13 10 12 12 9 11 11 8 10 10 6 7 7 -2 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 6 7 7 12 15 15 -12 15 15 8 9 9 2 3 3 0 0 0 1 1 1 25 27 26 -55 56 53 68 70 65 65 66 61 65 66 61 63 64 60 63 64 60 -58 59 55 51 52 50 47 48 46 41 42 42 35 37 36 30 32 31 -26 28 27 20 24 24 18 22 22 16 19 19 14 17 17 13 16 16 -12 15 15 11 14 14 10 13 13 10 12 12 9 11 11 8 10 10 -8 9 9 6 8 8 3 3 3 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 6 7 7 20 24 24 23 27 26 -23 27 26 18 22 22 11 13 13 23 24 24 61 63 57 72 73 67 -72 73 67 68 70 65 68 70 65 68 70 65 63 64 60 58 59 55 -55 56 53 47 48 46 41 42 42 35 37 36 30 32 31 26 28 27 -20 24 24 18 22 22 16 20 20 15 19 19 14 17 17 13 16 16 -12 15 15 12 15 15 11 14 14 10 13 13 10 12 12 9 11 11 -8 10 10 8 9 9 7 9 9 6 7 7 1 2 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 1 4 5 5 5 6 5 4 5 5 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 15 19 19 40 41 39 53 55 47 -33 36 34 27 30 29 51 52 50 72 73 67 72 73 67 72 73 67 -72 73 67 68 70 65 68 70 65 63 64 60 58 59 55 51 52 50 -47 48 46 40 43 41 33 37 35 30 32 31 26 28 27 20 24 24 -18 22 22 17 21 21 16 19 19 14 18 18 14 17 17 13 17 17 -13 16 16 12 15 15 12 15 15 11 14 14 10 13 13 10 12 12 -9 11 11 8 10 10 8 9 9 7 9 9 6 8 8 3 4 4 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 2 2 6 8 8 10 12 12 10 12 12 10 12 12 10 12 12 -6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 20 23 23 71 71 57 131 127 93 -115 113 82 63 64 60 72 73 67 72 73 67 72 73 67 72 73 67 -68 70 65 65 66 61 61 63 57 55 57 54 49 51 48 43 45 43 -39 40 39 33 36 34 28 31 30 23 27 26 20 24 24 20 23 23 -17 21 21 16 20 20 15 19 19 15 18 18 14 18 18 14 17 17 -13 17 17 13 16 16 12 15 15 12 15 15 11 14 14 10 13 13 -10 12 12 9 11 11 8 10 10 7 9 9 7 9 9 6 8 8 -4 5 5 0 0 0 0 0 0 0 0 0 1 1 1 6 7 7 -10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 -10 12 12 3 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 18 22 22 71 71 57 144 139 99 -84 83 72 68 70 65 72 73 67 72 73 67 68 70 65 65 66 61 -63 64 60 55 57 54 51 52 50 47 48 46 40 43 41 35 37 36 -30 32 31 27 29 28 23 27 26 20 24 24 18 22 22 17 21 21 -16 20 20 15 19 19 15 19 19 15 19 19 15 18 18 14 18 18 -14 17 17 13 17 17 13 16 16 12 15 15 12 15 15 11 14 14 -10 13 13 9 12 12 9 11 11 8 10 10 7 9 9 6 8 8 -6 8 8 3 4 4 0 0 0 2 2 2 8 10 10 10 12 12 -10 12 12 10 12 12 11 13 13 36 38 35 61 61 53 48 49 45 -10 12 12 7 9 9 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 15 19 19 61 61 53 84 83 72 -68 70 65 72 73 67 68 70 65 68 70 65 63 64 60 58 59 55 -51 52 50 47 48 46 41 42 42 37 39 37 32 35 33 28 31 30 -23 27 26 20 24 24 20 23 23 18 22 22 17 21 21 17 21 21 -17 21 21 17 21 21 17 20 20 16 20 20 16 20 20 16 19 19 -15 18 18 14 18 18 13 17 17 13 16 16 12 15 15 12 15 15 -11 14 14 10 13 13 9 12 12 9 11 11 8 10 10 7 9 9 -6 8 8 6 8 8 5 6 5 9 11 11 10 12 12 10 12 12 -19 20 18 82 81 62 149 145 103 160 154 106 142 137 94 96 95 69 -10 12 12 10 12 12 1 1 1 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 10 12 12 44 46 43 68 70 65 -72 73 67 68 70 65 68 70 65 63 64 60 55 57 54 49 51 48 -43 45 43 39 40 39 33 37 35 30 32 31 26 28 27 23 27 26 -20 24 24 18 22 22 18 22 22 18 22 22 18 22 22 20 23 23 -20 24 24 23 25 24 23 25 24 22 24 23 20 23 23 18 22 22 -17 20 20 15 19 19 15 18 18 14 17 17 13 16 16 12 15 15 -11 14 14 11 13 13 10 12 12 9 11 11 8 10 10 8 9 9 -7 9 9 7 9 9 10 12 12 10 12 12 10 12 12 71 71 57 -164 159 111 186 182 128 186 182 128 171 165 117 151 147 98 96 95 69 -10 12 12 10 12 12 3 3 3 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 8 10 10 63 64 60 68 70 65 -72 73 67 68 70 65 63 64 60 55 57 54 47 48 46 40 43 41 -33 37 35 30 32 31 27 29 28 23 27 26 20 24 24 20 23 23 -18 22 22 18 22 22 20 23 22 21 25 23 23 27 26 27 29 28 -28 31 30 31 33 31 31 33 31 31 33 31 28 31 30 26 28 27 -23 25 24 20 23 22 16 20 20 15 18 18 14 17 17 13 16 16 -12 15 15 11 14 14 10 13 13 10 12 12 9 11 11 8 10 10 -10 12 12 10 13 13 10 12 12 12 14 14 96 95 69 165 161 109 -186 182 128 192 187 134 192 187 134 176 171 126 160 154 106 103 101 77 -10 12 12 10 12 12 5 6 5 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 35 37 36 68 70 65 72 73 67 -68 70 65 65 66 61 58 59 55 49 51 48 40 43 41 33 37 35 -28 31 30 23 27 26 20 24 24 20 23 23 18 22 22 18 22 22 -18 22 22 20 23 23 23 27 26 27 30 29 32 35 33 37 39 37 -40 43 41 44 46 43 46 47 43 44 46 43 40 43 41 36 38 35 -31 33 31 27 29 28 22 24 23 17 21 21 15 18 18 14 17 17 -13 16 16 12 15 15 11 14 14 11 14 14 11 13 13 13 16 16 -13 16 16 11 14 14 10 12 12 79 78 62 142 137 94 164 159 111 -178 174 128 192 187 134 192 187 134 176 171 126 160 154 106 96 95 69 -10 12 12 10 12 12 6 7 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 55 57 54 68 70 65 72 73 67 -68 70 65 63 64 60 55 56 53 43 45 43 35 37 36 28 31 30 -23 27 26 20 24 24 18 22 22 17 21 21 17 21 21 17 21 21 -20 24 24 25 27 26 31 33 31 38 39 37 46 47 43 53 55 47 -61 61 53 66 65 55 66 65 55 66 65 55 61 61 53 53 55 47 -46 47 43 37 39 37 30 33 30 24 26 24 17 21 21 15 18 18 -13 17 17 12 15 15 12 15 15 13 16 16 14 18 18 14 18 18 -14 17 17 12 15 15 30 31 28 118 116 76 134 131 96 160 154 106 -174 170 121 178 174 128 178 174 128 171 165 117 151 147 98 96 95 69 -10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 63 64 60 68 70 65 68 70 65 -65 66 61 58 59 55 49 51 48 39 40 39 30 32 31 23 27 26 -20 24 24 18 22 22 17 21 21 16 20 20 17 21 21 20 23 23 -25 27 26 32 35 33 43 44 41 53 55 47 66 65 55 75 75 61 -82 81 62 84 83 72 87 86 72 87 86 72 82 81 62 75 75 61 -66 65 55 53 55 47 40 41 39 31 33 31 23 25 24 17 20 20 -14 18 18 13 16 16 12 15 15 12 15 15 13 17 17 14 18 18 -14 18 18 13 16 16 46 47 43 96 95 69 125 122 87 142 137 94 -160 154 106 165 161 109 164 159 111 155 149 109 142 137 94 75 75 61 -10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 60 60 56 68 70 65 68 70 65 -63 64 60 55 57 54 46 47 45 35 37 36 27 30 29 23 25 24 -18 22 22 17 21 21 16 20 20 17 21 21 18 22 22 23 27 26 -31 33 31 43 44 41 55 56 53 71 71 57 84 83 72 92 91 72 -103 101 77 92 91 72 82 81 62 82 81 62 87 86 72 92 91 72 -84 83 72 71 71 57 55 56 53 43 44 41 30 33 30 22 24 23 -16 19 19 14 17 17 12 15 15 12 15 15 13 16 16 14 18 18 -14 18 18 14 17 17 43 44 41 82 81 62 118 116 76 125 122 87 -142 137 94 144 139 99 144 139 99 134 131 96 118 116 76 53 55 47 -10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 47 48 46 63 64 60 63 64 60 -55 57 54 49 51 48 40 43 41 32 34 33 26 28 27 20 24 24 -18 22 22 16 20 20 16 20 20 17 21 21 20 24 24 28 31 30 -40 41 39 53 55 47 75 75 61 90 89 73 87 86 72 48 49 45 -14 14 13 2 2 2 1 2 2 1 1 1 1 1 1 2 2 2 -19 20 18 43 44 41 66 65 55 53 55 47 38 39 37 26 28 27 -18 22 22 14 18 18 13 16 16 12 15 15 12 15 15 13 17 17 -14 18 18 14 18 18 30 31 28 66 65 55 96 95 69 103 101 77 -118 116 76 118 116 76 118 116 76 118 116 76 103 101 77 36 38 35 -10 12 12 10 12 12 6 7 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 28 31 30 55 57 54 51 52 50 -49 51 48 41 42 42 35 37 36 28 31 30 23 27 26 20 23 23 -17 21 21 16 20 20 16 20 20 18 22 22 23 27 26 33 36 34 -48 49 45 71 71 57 82 81 62 43 44 41 8 9 9 6 7 7 -6 7 7 6 7 7 6 7 7 5 6 5 4 5 5 3 4 4 -2 3 3 1 2 2 4 5 4 36 38 35 48 49 45 32 35 33 -21 25 23 16 19 19 13 17 17 12 15 15 12 15 15 13 16 16 -14 18 18 14 18 18 16 18 16 36 38 35 61 61 53 82 81 62 -96 95 69 96 95 69 96 95 69 96 95 69 79 78 62 19 20 18 -10 12 12 10 12 12 4 5 5 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 13 13 13 46 47 45 43 45 43 -40 43 41 35 37 36 30 32 31 23 27 26 20 24 24 18 22 22 -17 21 21 16 20 20 17 21 21 20 23 23 27 30 29 40 41 39 -61 61 53 53 55 47 16 17 16 9 11 11 10 12 12 10 12 12 -10 12 12 10 12 12 10 12 12 9 11 11 8 10 10 8 9 9 -6 8 8 5 6 5 4 5 5 2 3 3 19 20 18 38 39 37 -26 28 27 17 21 21 14 17 17 13 16 16 12 15 15 12 15 15 -13 17 17 14 18 18 12 15 15 13 12 7 30 31 28 46 47 43 -53 55 47 66 65 55 66 65 55 53 55 47 36 38 35 10 12 12 -10 12 12 10 12 12 2 3 3 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 1 1 33 37 35 35 37 36 -32 35 33 28 31 30 23 27 26 20 24 24 18 22 22 17 21 21 -16 20 20 16 20 20 17 21 21 21 25 23 31 33 31 44 46 43 -31 33 31 11 13 13 12 14 14 12 15 15 13 16 16 14 17 17 -14 17 17 14 17 17 14 17 17 13 16 16 12 15 15 12 14 14 -11 13 13 9 11 11 8 10 10 6 8 8 4 5 5 17 18 17 -30 33 30 20 23 22 15 18 18 13 16 16 12 15 15 12 14 14 -13 16 16 14 17 17 14 18 18 11 12 11 7 7 5 16 17 12 -21 22 20 30 31 28 25 27 25 21 22 20 14 14 13 10 12 12 -10 12 12 9 11 11 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 18 22 22 27 30 29 -27 29 28 40 41 39 53 55 47 53 55 47 53 55 47 46 47 43 -25 27 25 16 20 20 17 21 21 23 25 24 31 33 31 20 20 20 -12 15 15 14 17 17 15 19 19 16 20 20 17 21 21 18 22 22 -18 22 22 18 22 22 18 22 22 17 21 21 17 21 21 16 19 19 -15 18 18 13 16 16 12 15 15 10 12 12 8 10 10 6 8 8 -21 22 21 22 24 23 15 19 19 13 17 17 13 16 16 12 15 15 -12 15 15 13 17 17 14 18 18 14 18 18 13 15 14 10 9 6 -7 7 5 7 7 5 7 7 5 9 11 11 10 12 12 10 12 12 -10 12 12 6 7 7 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 16 17 12 82 81 62 -118 116 76 118 116 76 161 156 96 161 156 96 161 156 96 118 116 76 -118 116 76 96 95 69 53 55 47 22 24 23 14 17 17 13 16 16 -15 19 19 17 21 21 18 22 22 20 24 24 20 24 24 23 27 26 -23 27 26 23 27 26 23 27 26 23 27 26 23 27 26 20 24 24 -20 23 23 17 21 21 16 19 19 14 17 17 12 15 15 10 12 12 -9 11 11 20 23 22 16 19 19 14 17 17 13 16 16 12 15 15 -11 14 14 13 16 16 14 17 17 14 18 18 14 17 17 12 15 15 -10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 -9 11 11 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 53 55 47 161 156 96 -161 156 96 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 161 156 96 118 116 76 96 95 69 21 22 20 16 19 19 -18 22 22 20 24 24 23 27 26 23 27 26 26 28 27 27 30 29 -27 30 29 18 22 22 12 14 14 8 10 10 9 11 11 17 21 21 -23 27 26 23 27 26 20 24 24 18 22 22 16 20 20 14 17 17 -12 14 14 14 17 17 16 20 20 14 17 17 13 17 17 13 16 16 -12 15 15 12 15 15 13 17 17 14 18 18 14 17 17 13 16 16 -11 13 13 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 -4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 13 12 7 118 116 76 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 161 156 96 118 116 76 30 31 28 -20 24 24 23 27 26 27 30 29 28 31 30 30 32 31 23 27 26 -16 19 19 17 21 21 12 15 15 9 11 11 10 12 12 9 11 11 -20 24 24 28 31 30 26 28 27 23 27 26 20 24 24 17 21 21 -15 19 19 13 16 16 16 19 19 14 18 18 14 17 17 13 16 16 -12 15 15 11 14 14 13 16 16 14 17 17 14 18 18 14 17 17 -12 15 15 10 12 12 10 12 12 10 12 12 10 12 12 8 9 9 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 82 81 62 161 156 96 230 229 82 -230 229 82 233 233 100 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 118 116 76 -27 29 28 27 30 29 30 32 31 30 32 31 23 27 26 20 24 24 -26 28 27 17 21 21 6 7 7 72 73 67 145 141 105 15 15 15 -14 17 17 33 37 35 30 32 31 28 31 30 26 28 27 23 27 26 -20 23 23 16 20 20 15 19 19 14 18 18 14 17 17 13 16 16 -12 15 15 11 14 14 12 15 15 13 17 17 14 18 18 14 17 17 -13 16 16 11 13 13 10 12 12 10 12 12 9 11 11 1 1 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 16 17 12 161 156 96 230 229 82 230 229 82 -243 242 120 235 234 117 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 -82 81 62 28 31 30 28 31 30 27 30 29 28 31 30 30 32 31 -33 37 35 13 16 16 3 3 3 105 104 92 210 208 158 12 14 14 -17 21 21 33 37 35 33 37 35 32 35 33 30 32 31 27 30 29 -23 27 26 20 23 23 17 20 20 15 18 18 14 18 18 13 17 17 -13 16 16 12 15 15 11 14 14 13 16 16 14 17 17 14 18 18 -13 17 17 12 15 15 10 12 12 10 12 12 3 4 4 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 96 95 69 230 229 82 230 229 82 244 244 132 -241 241 143 243 242 120 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -161 156 96 46 47 43 32 35 33 33 37 35 33 37 35 33 37 35 -40 43 41 23 27 26 1 1 1 2 2 2 24 26 24 14 17 17 -23 27 26 33 37 35 33 37 35 33 37 35 33 37 35 30 32 31 -27 30 29 23 27 26 20 23 23 15 18 18 14 18 18 14 17 17 -13 16 16 12 15 15 11 14 14 12 15 15 13 17 17 14 17 17 -14 17 17 13 16 16 11 13 13 6 8 8 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 16 17 12 161 156 96 230 229 82 235 234 117 239 239 170 -239 239 170 236 236 101 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 118 116 76 33 37 35 33 37 35 37 39 37 37 39 37 -43 45 43 49 51 48 20 24 24 8 10 10 17 20 20 35 37 36 -33 37 35 40 43 41 37 39 37 35 37 36 33 37 35 33 37 35 -30 32 31 27 30 29 23 27 26 15 19 19 14 18 18 14 17 17 -13 17 17 13 16 16 12 15 15 11 14 14 13 16 16 14 17 17 -14 17 17 13 17 17 11 14 14 4 5 5 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 96 95 69 230 229 82 230 229 82 239 239 170 251 251 187 -241 241 143 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 161 156 96 36 38 35 33 37 35 33 37 35 33 37 35 -37 39 37 47 48 46 55 57 54 55 57 54 49 51 48 43 45 43 -43 45 43 43 45 43 40 43 41 40 43 41 37 39 37 33 37 35 -33 37 35 28 31 30 26 28 27 16 20 20 15 18 18 14 18 18 -14 17 17 13 16 16 12 15 15 11 14 14 12 15 15 13 17 17 -14 17 17 14 17 17 8 10 10 5 7 7 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -16 17 12 230 229 82 230 229 82 243 242 120 251 251 187 251 251 187 -246 246 123 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 66 65 55 30 32 31 32 35 33 33 37 35 -33 37 35 37 39 37 40 43 41 47 48 46 49 51 48 51 52 50 -55 57 54 55 57 54 51 52 50 47 48 46 43 45 43 39 40 39 -33 37 35 30 32 31 26 28 27 17 21 21 15 19 19 14 18 18 -14 17 17 13 16 16 12 15 15 12 14 14 11 14 14 13 16 16 -14 17 17 12 15 15 7 9 9 6 8 8 1 1 1 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -96 95 69 230 229 82 230 229 82 239 239 170 251 251 187 239 239 170 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 96 95 69 27 30 29 28 31 30 30 32 31 -33 37 35 40 43 41 46 47 45 55 57 54 63 64 60 72 73 67 -72 73 67 72 73 67 72 73 67 65 66 61 55 57 54 47 48 46 -39 40 39 32 35 33 27 30 29 17 21 21 15 19 19 15 18 18 -14 18 18 13 17 17 13 16 16 12 15 15 11 14 14 12 14 14 -13 16 16 9 11 11 7 9 9 9 11 11 66 65 55 115 113 82 -21 22 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 12 7 -230 229 82 230 229 82 236 236 101 251 251 187 251 251 187 246 246 123 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 118 116 76 23 27 26 26 28 27 32 35 33 -51 52 50 90 89 73 110 109 94 145 141 105 168 163 120 177 172 135 -177 172 135 188 184 146 188 184 146 181 176 137 194 191 148 188 184 146 -184 179 149 188 184 146 188 184 146 156 151 111 177 172 135 181 176 137 -177 172 135 168 163 120 168 163 120 158 153 112 156 151 111 158 153 112 -156 151 111 158 153 112 177 172 135 188 184 146 188 184 146 194 189 146 -36 38 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 82 81 62 -230 229 82 230 229 82 244 244 132 251 251 187 244 244 132 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 82 81 62 -96 95 69 230 229 82 181 178 103 110 109 94 156 151 111 188 184 146 -188 184 146 197 193 154 188 184 146 184 181 136 188 184 146 168 163 120 -168 163 120 178 174 128 156 151 111 158 153 112 174 170 121 156 151 111 -156 151 111 158 153 112 156 151 111 168 163 120 178 174 128 181 176 137 -176 171 126 178 174 128 184 181 136 176 171 126 178 174 128 184 181 136 -176 171 126 178 174 128 184 181 136 164 159 111 155 149 109 96 95 69 -1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 161 156 96 -230 229 82 230 229 82 244 244 132 244 244 132 236 236 101 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 46 47 43 82 81 62 -158 153 112 197 193 154 194 189 146 184 181 136 188 184 146 168 163 120 -156 151 111 137 133 100 131 127 93 137 133 100 137 133 100 158 153 112 -121 119 87 137 133 100 156 151 111 145 141 105 99 98 80 84 83 72 -63 64 60 52 53 49 40 43 41 33 36 34 36 38 35 36 38 35 -38 39 37 43 44 41 43 44 41 46 47 43 48 49 45 48 49 45 -46 47 43 36 38 35 30 31 28 19 20 18 6 7 7 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 36 38 35 230 229 82 -230 229 82 230 229 82 246 246 123 236 236 101 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 53 55 47 121 119 87 -176 171 126 171 165 117 161 156 96 82 81 62 53 55 47 33 37 35 -39 40 39 63 64 60 99 98 80 121 119 87 137 133 100 177 172 135 -176 171 126 184 181 136 131 127 93 131 127 93 110 109 94 84 83 72 -51 52 50 39 40 39 27 29 28 18 22 22 16 19 19 15 19 19 -15 19 19 14 18 18 14 17 17 13 16 16 12 15 15 11 14 14 -10 13 13 9 12 12 9 11 11 8 9 9 7 9 9 1 1 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 -230 229 82 230 229 82 236 236 101 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 96 95 69 71 71 57 -36 38 35 118 116 76 118 116 76 12 15 15 15 18 18 20 24 24 -33 37 35 55 56 53 84 83 72 110 109 94 145 141 105 110 109 94 -168 163 120 121 119 87 156 151 111 131 127 93 87 86 72 61 63 57 -47 48 46 28 31 30 18 22 22 15 19 19 15 18 18 15 19 19 -15 19 19 14 18 18 14 17 17 13 17 17 13 16 16 12 15 15 -11 13 13 10 12 12 9 11 11 8 10 10 7 9 9 3 3 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 1 0 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 -161 156 96 230 229 82 118 116 76 11 14 14 14 17 17 18 22 22 -27 30 29 40 43 41 60 60 56 84 83 72 105 104 92 110 109 94 -110 109 94 110 109 94 99 98 80 90 89 73 68 70 65 47 48 46 -32 34 33 23 25 24 20 23 23 17 21 21 15 19 19 14 17 17 -15 19 19 15 18 18 14 18 18 13 17 17 13 16 16 12 15 15 -11 14 14 10 12 12 9 11 11 8 10 10 7 9 9 4 5 5 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 16 17 12 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 161 156 96 118 116 76 11 13 13 13 16 16 15 19 19 -20 24 24 30 32 31 40 43 41 51 52 50 63 64 60 72 73 67 -65 66 61 65 66 61 65 66 61 55 57 54 46 47 45 33 37 35 -27 29 28 20 24 24 17 21 21 16 20 20 16 20 20 15 19 19 -15 19 19 15 19 19 14 18 18 14 17 17 13 16 16 12 15 15 -11 14 14 10 13 13 9 12 12 8 10 10 7 9 9 6 7 7 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 53 55 47 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -161 156 96 118 116 76 53 55 47 10 13 13 12 15 15 14 17 17 -17 20 20 20 24 24 27 29 28 32 34 33 37 39 37 40 43 41 -43 45 43 41 42 42 35 37 36 30 32 31 28 31 30 23 27 26 -20 23 23 17 21 21 16 20 20 16 20 20 16 20 20 16 19 19 -15 19 19 15 19 19 14 18 18 14 17 17 13 16 16 12 15 15 -11 14 14 10 13 13 9 12 12 9 11 11 8 10 10 10 12 12 -1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 82 81 62 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 161 156 96 -118 116 76 82 81 62 13 14 12 10 13 13 12 15 15 13 17 17 -15 19 19 16 20 20 20 23 23 20 24 24 23 27 26 26 28 27 -26 28 27 26 28 27 23 27 26 18 22 22 20 23 23 17 21 21 -17 21 21 16 20 20 16 20 20 16 20 20 16 20 20 16 19 19 -15 19 19 15 19 19 15 18 18 14 17 17 13 17 17 13 16 16 -12 15 15 12 14 14 12 14 14 12 14 14 12 14 14 23 24 24 -6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 161 156 96 161 156 96 118 116 76 -71 71 57 13 14 12 9 12 12 10 13 13 12 15 15 13 17 17 -15 18 18 15 19 19 16 20 20 17 21 21 17 21 21 18 22 22 -18 22 22 18 22 22 17 21 21 16 19 19 15 18 18 14 18 18 -16 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -15 19 19 15 19 19 15 18 18 14 18 18 16 20 20 23 25 24 -17 21 21 25 27 26 47 48 46 47 48 46 51 52 50 72 73 67 -33 36 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 161 156 96 118 116 76 118 116 76 46 47 43 -9 11 11 9 11 11 10 12 12 11 13 13 12 15 15 14 17 17 -15 18 18 15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -15 19 19 16 20 20 20 24 24 55 56 53 32 34 33 84 83 72 -90 89 73 110 109 94 110 109 94 105 104 92 110 109 94 110 109 94 -72 73 67 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 96 95 69 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 161 156 96 118 116 76 82 81 62 16 17 12 9 11 11 -9 11 11 9 12 12 10 13 13 12 14 14 13 16 16 14 18 18 -15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 19 19 33 36 34 99 98 80 156 151 111 145 141 105 184 179 149 -168 163 120 184 179 149 177 172 135 156 151 111 145 141 105 110 109 94 -90 89 73 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 71 71 57 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 -230 229 82 161 156 96 230 229 82 230 229 82 230 229 82 161 156 96 -118 116 76 82 81 62 30 31 28 9 11 11 9 11 11 9 11 11 -10 12 12 10 13 13 11 14 14 13 16 16 14 17 17 15 18 18 -15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -18 22 22 58 59 55 137 133 100 197 193 154 214 212 158 210 208 158 -197 193 154 184 179 149 184 179 149 137 133 100 110 109 94 99 98 80 -84 83 72 10 10 9 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 16 17 12 230 229 82 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 -161 156 96 161 156 96 161 156 96 161 156 96 118 116 76 71 71 57 -21 22 20 12 14 14 11 13 13 10 12 12 10 12 12 10 13 13 -11 13 13 12 15 15 13 16 16 14 17 17 14 18 18 15 19 19 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 17 21 21 -23 27 26 84 83 72 184 179 149 251 251 187 210 208 158 184 179 149 -184 179 149 156 151 111 110 109 94 84 83 72 63 64 60 51 52 50 -18 22 22 6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 -230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 161 156 96 -161 156 96 161 156 96 118 116 76 53 55 47 20 23 22 16 19 19 -13 16 16 12 15 15 12 14 14 11 14 14 11 14 14 11 14 14 -12 15 15 13 16 16 14 17 17 15 19 19 16 20 20 17 21 21 -23 27 26 18 22 22 20 24 24 23 27 26 30 32 31 17 21 21 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -23 27 26 33 37 35 137 133 100 156 151 111 158 153 112 105 104 92 -105 104 92 68 70 65 39 40 39 18 22 22 12 14 14 12 15 15 -9 11 11 4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 16 17 12 230 229 82 -230 229 82 230 229 82 230 229 82 161 156 96 118 116 76 118 116 76 -118 116 76 66 65 55 43 45 43 32 34 33 25 27 26 20 23 22 -17 20 20 15 18 18 14 17 17 15 18 18 13 16 16 14 17 17 -14 18 18 16 20 20 32 34 33 55 57 54 58 59 55 72 73 67 -105 104 92 55 57 54 65 66 61 63 64 60 40 43 41 33 37 35 -41 42 42 20 24 24 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -17 21 21 26 28 27 30 32 31 35 37 36 68 70 65 39 40 39 -23 27 26 15 18 18 13 16 16 11 14 14 9 12 12 8 10 10 -7 9 9 6 7 7 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 38 35 -230 229 82 230 229 82 230 229 82 96 95 69 30 31 28 49 51 48 -90 89 73 68 70 65 55 57 54 47 48 46 47 48 46 43 45 43 -32 34 33 43 45 43 43 45 43 23 27 26 25 27 26 40 43 41 -40 43 41 90 89 73 110 109 94 145 141 105 156 151 111 156 151 111 -184 179 149 184 179 149 177 172 135 184 179 149 137 133 100 84 83 72 -105 104 92 63 64 60 49 51 48 47 48 46 28 31 30 18 22 22 -16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 15 19 19 15 19 19 15 19 19 18 22 22 15 19 19 -13 16 16 12 15 15 11 14 14 10 13 13 9 12 12 9 11 11 -8 10 10 6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -30 31 28 230 229 82 71 71 57 2 2 1 0 0 0 58 59 55 -105 104 92 84 83 72 65 66 61 84 83 72 110 109 94 110 109 94 -145 141 105 105 104 92 110 109 94 110 109 94 84 83 72 110 109 94 -158 153 112 197 193 154 197 193 154 239 239 170 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 197 193 154 -197 193 154 184 179 149 145 141 105 137 133 100 105 104 92 47 48 46 -20 23 23 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 19 19 15 19 19 15 19 19 14 18 18 14 17 17 -13 17 17 13 16 16 12 14 14 12 14 14 13 13 13 13 13 13 -13 13 13 12 12 12 10 10 9 6 7 7 2 2 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 65 66 61 -105 104 92 84 83 72 84 83 72 110 109 94 184 179 149 210 208 158 -210 208 158 210 208 158 214 212 158 197 193 154 214 212 158 210 208 158 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 251 251 187 239 239 170 251 251 187 184 179 149 84 83 72 -26 28 27 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 15 19 19 15 19 19 15 18 18 14 18 18 -13 17 17 13 16 16 15 15 15 14 14 13 14 14 13 14 14 13 -13 13 13 13 13 13 12 12 12 12 12 12 12 12 12 3 4 4 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 72 73 67 -105 104 92 99 98 80 84 83 72 99 98 80 177 172 135 197 193 154 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 214 212 158 197 193 154 99 98 80 -23 27 26 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 15 19 19 15 19 19 15 18 18 14 18 18 -14 17 17 16 16 16 16 16 16 16 16 16 15 15 15 14 14 13 -14 14 13 13 13 13 13 13 13 12 12 12 12 12 12 12 12 12 -3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 84 83 72 -110 109 94 99 98 80 72 73 67 63 64 60 99 98 80 177 172 135 -184 179 149 210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 210 208 158 184 179 149 177 172 135 110 109 94 33 37 35 -17 21 21 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -16 20 20 16 20 20 15 19 19 15 19 19 15 19 19 14 18 18 -15 18 18 18 19 18 18 19 18 17 17 17 16 16 16 15 15 15 -14 14 13 13 13 13 13 13 13 12 12 12 12 12 12 12 12 12 -10 10 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 105 104 92 -108 107 93 99 98 80 72 73 67 63 64 60 51 52 50 87 86 72 -105 104 92 110 109 94 108 107 93 156 151 111 184 179 149 184 179 149 -197 193 154 197 193 154 197 193 154 184 179 149 184 179 149 177 172 135 -197 193 154 156 151 111 177 172 135 184 179 149 168 163 120 137 133 100 -145 141 105 110 109 94 99 98 80 47 48 46 55 57 54 15 19 19 -16 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 -17 20 20 17 21 21 16 20 20 16 19 19 15 19 19 16 19 19 -20 20 20 21 22 21 20 20 20 19 20 19 18 19 18 16 16 16 -15 15 15 14 14 13 13 13 13 13 13 13 12 12 12 12 12 12 -12 12 12 4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 58 59 55 110 109 94 -105 104 92 90 89 73 72 73 67 55 57 54 43 45 43 39 40 39 -43 45 43 46 47 45 43 45 43 68 70 65 65 66 61 63 64 60 -108 107 93 72 73 67 105 104 92 90 89 73 72 73 67 40 43 41 -72 73 67 68 70 65 68 70 65 58 59 55 63 64 60 49 51 48 -43 45 43 33 36 34 27 30 29 20 24 24 16 20 20 15 19 19 -15 19 19 15 19 19 15 19 19 16 19 19 16 20 20 16 20 20 -17 21 21 20 24 24 20 23 22 17 21 21 17 20 20 20 20 20 -21 22 21 21 22 21 21 22 21 21 22 21 20 20 20 18 19 18 -16 16 16 15 15 15 13 13 13 13 13 13 12 12 12 12 12 12 -12 12 12 10 10 9 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 21 22 21 110 109 94 110 109 94 -105 104 92 84 83 72 68 70 65 51 52 50 41 42 42 33 37 35 -28 31 30 23 27 26 20 23 23 18 22 22 17 20 20 25 27 26 -26 28 27 27 30 29 25 27 26 20 23 23 23 27 26 30 32 31 -20 24 24 17 21 21 18 22 22 15 19 19 26 28 27 20 23 23 -14 18 18 15 19 19 15 18 18 15 19 19 15 19 19 15 19 19 -15 19 19 15 19 19 15 19 19 15 19 19 15 19 19 16 19 19 -16 20 20 22 24 23 24 26 24 22 24 23 20 23 22 22 24 23 -24 26 24 24 26 24 23 24 24 22 24 23 21 22 21 19 20 19 -17 17 17 15 15 15 14 14 13 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 2 2 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 2 2 2 99 98 80 110 109 94 108 107 93 -105 104 92 84 83 72 63 64 60 49 51 48 39 40 39 32 34 33 -27 30 29 23 25 24 20 23 23 17 20 20 15 19 19 14 18 18 -14 17 17 13 17 17 13 17 17 13 17 17 13 17 17 13 17 17 -14 17 17 14 17 17 14 17 17 14 17 17 14 17 17 14 17 17 -14 18 18 14 18 18 14 18 18 14 18 18 15 18 18 15 19 19 -15 19 19 15 19 19 15 19 19 15 19 19 15 19 19 15 19 19 -15 19 19 17 21 21 27 29 28 26 28 27 25 27 26 25 27 26 -27 29 28 27 29 28 26 28 27 24 26 24 21 22 21 20 20 20 -18 19 18 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 4 5 5 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 51 52 50 110 109 94 110 109 94 105 104 92 -90 89 73 72 73 67 55 57 54 43 45 43 35 37 36 30 32 31 -26 28 27 20 24 24 17 21 21 16 19 19 15 18 18 14 17 17 -13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 -13 16 16 13 16 16 13 16 16 13 17 17 13 17 17 14 17 17 -14 17 17 14 17 17 14 17 17 14 18 18 14 18 18 14 18 18 -15 18 18 15 18 18 15 19 19 15 19 19 15 19 19 15 19 19 -15 19 19 15 19 19 27 29 28 32 34 33 28 31 30 27 29 28 -30 32 31 30 32 31 30 31 28 26 28 27 23 24 24 21 22 21 -19 20 19 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 3 3 3 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 10 10 9 108 107 93 110 109 94 108 107 93 99 98 80 -84 83 72 63 64 60 49 51 48 40 43 41 33 36 34 27 30 29 -23 27 26 18 22 22 17 20 20 15 18 18 14 17 17 13 16 16 -13 16 16 13 16 16 12 15 15 12 15 15 12 15 15 12 15 15 -13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 -13 17 17 13 17 17 14 17 17 14 17 17 14 17 17 14 18 18 -14 18 18 14 18 18 15 18 18 15 18 18 15 19 19 15 19 19 -15 19 19 15 19 19 17 21 21 33 36 34 32 34 33 31 33 31 -33 36 34 33 36 34 31 33 31 27 29 28 25 27 26 21 22 21 -19 20 19 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 63 64 60 137 133 100 43 45 43 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 68 70 65 110 109 94 110 109 94 105 104 92 84 83 72 -68 70 65 55 57 54 43 45 43 35 37 36 30 32 31 26 28 27 -20 24 24 17 21 21 16 19 19 14 17 17 13 16 16 12 15 15 -12 15 15 12 15 15 12 15 15 12 15 15 12 15 15 12 15 15 -12 15 15 12 15 15 12 15 15 12 15 15 12 15 15 13 16 16 -13 16 16 13 16 16 13 16 16 13 17 17 13 17 17 14 17 17 -14 17 17 14 17 17 14 18 18 14 18 18 14 18 18 15 18 18 -15 19 19 15 19 19 15 19 19 20 24 24 32 34 33 35 37 36 -37 39 37 35 37 36 33 36 34 30 32 31 26 28 27 22 24 23 -20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 99 98 80 184 179 149 184 179 149 68 70 65 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -15 15 15 110 109 94 110 109 94 108 107 93 99 98 80 72 73 67 -61 63 57 49 51 48 39 40 39 33 36 34 27 30 29 23 25 24 -18 22 22 16 19 19 14 17 17 13 16 16 12 15 15 12 15 15 -11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 -11 14 14 11 14 14 12 14 14 12 15 15 12 15 15 12 15 15 -12 15 15 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 -13 17 17 14 17 17 14 17 17 14 17 17 14 18 18 14 18 18 -14 18 18 15 18 18 15 19 19 15 19 19 30 32 31 38 39 37 -39 40 39 39 40 39 35 37 36 31 33 31 27 29 28 22 24 23 -20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 -110 109 94 197 193 154 210 208 158 184 179 149 68 70 65 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -68 70 65 110 109 94 110 109 94 105 104 92 84 83 72 65 66 61 -51 52 50 43 45 43 35 37 36 30 32 31 25 27 26 20 23 23 -17 20 20 15 18 18 13 16 16 12 15 15 12 15 15 11 14 14 -11 14 14 11 14 14 11 13 13 11 13 13 11 13 13 11 13 13 -11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 -12 15 15 12 15 15 12 15 15 12 15 15 13 16 16 13 16 16 -13 16 16 13 16 16 13 17 17 13 17 17 14 17 17 14 17 17 -14 18 18 14 18 18 14 18 18 16 19 19 37 39 37 41 42 42 -41 42 42 41 42 42 38 39 37 32 34 33 27 29 28 23 24 24 -21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 11 11 11 137 133 100 -197 193 154 251 251 187 239 239 170 184 179 149 31 33 31 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 12 12 -110 109 94 110 109 94 105 104 92 90 89 73 72 73 67 58 59 55 -46 47 45 37 39 37 31 33 31 26 28 27 20 24 24 17 21 21 -15 18 18 13 16 16 12 15 15 12 14 14 11 13 13 11 13 13 -10 13 13 10 13 13 10 13 13 10 13 13 10 13 13 10 13 13 -10 13 13 10 13 13 11 13 13 11 13 13 11 14 14 11 14 14 -11 14 14 11 14 14 12 14 14 12 15 15 12 15 15 12 15 15 -13 16 16 13 16 16 13 16 16 13 16 16 13 17 17 13 17 17 -14 17 17 14 17 17 14 18 18 23 27 26 41 42 42 41 42 42 -43 45 43 41 42 42 39 40 39 33 36 34 27 29 28 23 24 24 -21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 27 29 28 168 163 120 210 208 158 -251 251 187 251 251 187 210 208 158 137 133 100 1 1 1 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 60 56 -110 109 94 105 104 92 105 104 92 84 83 72 65 66 61 51 52 50 -40 43 41 33 36 34 27 30 29 23 25 24 18 22 22 16 19 19 -14 17 17 12 15 15 11 14 14 11 14 14 10 13 13 10 13 13 -10 13 13 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 -10 12 12 10 12 12 10 13 13 10 13 13 10 13 13 11 13 13 -11 13 13 11 14 14 11 14 14 11 14 14 11 14 14 12 15 15 -12 15 15 12 15 15 12 15 15 13 16 16 13 16 16 13 16 16 -13 17 17 13 17 17 14 17 17 32 34 33 43 45 43 43 45 43 -43 45 43 43 45 43 39 40 39 33 36 34 27 29 28 23 24 24 -21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 1 1 68 70 65 184 179 149 210 208 158 251 251 187 -251 251 187 214 212 158 184 179 149 37 39 37 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 6 7 7 105 104 92 -105 104 92 105 104 92 99 98 80 72 73 67 58 59 55 46 47 45 -35 37 36 30 32 31 25 27 26 20 23 23 16 19 19 14 17 17 -12 15 15 12 14 14 11 13 13 10 13 13 10 12 12 10 12 12 -10 12 12 10 12 12 9 12 12 9 12 12 9 12 12 9 12 12 -10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 13 13 -10 13 13 10 13 13 11 13 13 11 13 13 11 14 14 11 14 14 -11 14 14 12 15 15 12 15 15 12 15 15 12 15 15 13 16 16 -13 16 16 13 16 16 17 20 20 41 42 42 46 47 45 46 47 45 -46 47 45 43 45 43 40 41 39 33 36 34 27 29 28 23 24 24 -20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 4 5 5 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -15 15 15 110 109 94 197 193 154 214 212 158 251 251 187 251 251 187 -239 239 170 184 179 149 84 83 72 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 47 48 46 105 104 92 -105 104 92 99 98 80 84 83 72 68 70 65 51 52 50 40 43 41 -32 34 33 27 29 28 22 24 23 17 21 21 15 18 18 13 16 16 -12 15 15 11 13 13 10 13 13 10 12 12 9 12 12 9 12 12 -9 12 12 9 12 12 9 11 11 9 11 11 9 11 11 9 11 11 -9 12 12 9 12 12 9 12 12 9 12 12 10 12 12 10 12 12 -10 12 12 10 12 12 10 13 13 10 13 13 10 13 13 11 13 13 -11 14 14 11 14 14 11 14 14 12 14 14 12 15 15 12 15 15 -12 15 15 13 16 16 28 31 30 43 45 43 47 48 46 47 48 46 -47 48 46 43 45 43 40 41 39 33 36 34 27 29 28 22 24 23 -20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 3 4 4 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 60 60 56 -177 172 135 197 193 154 251 251 187 251 251 187 251 251 187 251 251 187 -184 179 149 110 109 94 3 4 4 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 1 1 99 98 80 105 104 92 -99 98 80 87 86 72 84 83 72 63 64 60 46 47 45 35 37 36 -30 32 31 25 27 26 18 22 22 16 19 19 14 17 17 12 15 15 -11 14 14 10 13 13 9 12 12 9 12 12 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 11 11 9 12 12 9 12 12 -9 12 12 10 12 12 10 12 12 10 12 12 10 13 13 10 13 13 -10 13 13 11 13 13 11 14 14 11 14 14 11 14 14 12 15 15 -12 15 15 14 17 17 41 42 42 47 48 46 49 51 48 51 52 50 -47 48 46 43 45 43 40 41 39 33 36 34 27 29 28 22 24 23 -19 20 19 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 2 2 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 23 24 24 137 133 100 184 179 149 -210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 184 179 149 -110 109 94 13 13 13 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 30 32 31 105 104 92 99 98 80 -84 83 72 84 83 72 72 73 67 55 57 54 41 42 42 32 34 33 -27 29 28 20 24 24 17 20 20 14 17 17 13 16 16 12 14 14 -10 13 13 10 12 12 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 12 12 9 12 12 10 12 12 10 12 12 10 12 12 -10 13 13 10 13 13 10 13 13 11 13 13 11 14 14 11 14 14 -11 14 14 27 29 28 55 56 53 72 73 67 51 52 50 51 52 50 -49 51 48 43 45 43 39 40 39 32 34 33 26 28 27 21 22 21 -19 20 19 16 16 16 18 19 17 13 13 13 12 12 12 12 12 12 -12 12 12 12 12 12 1 1 1 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 8 8 7 84 83 72 184 179 149 197 193 154 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 184 179 149 145 141 105 -19 20 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 14 14 13 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 72 73 67 105 104 92 84 83 72 -72 73 67 84 83 72 68 70 65 49 51 48 39 40 39 30 32 31 -25 27 26 18 22 22 15 18 18 13 16 16 12 15 15 11 13 13 -10 12 12 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 12 12 9 12 12 9 12 12 -10 12 12 10 12 12 10 12 12 10 13 13 10 13 13 11 13 13 -13 16 16 41 42 42 99 98 80 158 153 112 65 66 61 51 52 50 -49 51 48 43 45 43 39 40 39 31 33 31 25 27 26 21 22 21 -21 22 21 68 70 65 55 56 53 13 13 13 12 12 12 12 12 12 -12 12 12 11 11 11 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 -63 64 60 158 153 112 184 179 149 210 208 158 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 184 179 149 137 133 100 27 29 28 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -21 22 21 110 109 94 5 6 5 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 13 13 13 105 104 92 90 89 73 72 73 67 -68 70 65 84 83 72 63 64 60 46 47 45 35 37 36 27 29 28 -22 24 23 17 20 20 14 17 17 12 15 15 11 14 14 10 12 12 -10 12 12 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 12 12 9 12 12 10 12 12 10 12 12 10 13 13 10 13 13 -30 32 31 47 48 46 177 172 135 210 208 158 137 133 100 55 56 53 -49 51 48 43 45 43 38 39 37 31 33 31 25 27 26 22 24 23 -110 109 94 184 179 149 63 64 60 13 13 13 12 12 12 12 12 12 -12 12 12 8 9 9 0 0 0 1 1 1 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 21 22 21 105 104 92 -184 179 149 210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 251 251 187 184 179 149 145 141 105 23 24 24 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -68 70 65 184 179 149 105 104 92 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 51 52 50 99 98 80 84 83 72 63 64 60 -68 70 65 72 73 67 55 57 54 41 42 42 32 34 33 25 27 26 -20 23 23 16 19 19 13 16 16 12 14 14 10 13 13 10 12 12 -9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 12 12 9 12 12 10 12 12 17 20 20 -46 47 45 72 73 67 210 208 158 251 251 187 210 208 158 63 64 60 -49 51 48 43 45 43 37 39 37 30 32 31 24 26 24 105 104 92 -210 208 158 197 193 154 47 48 46 13 13 13 12 12 12 12 12 12 -12 12 12 6 7 7 33 36 34 48 49 45 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 8 8 7 23 24 24 55 56 53 110 109 94 -210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 184 179 149 110 109 94 20 20 20 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -110 109 94 251 251 187 210 208 158 47 48 46 0 0 0 0 0 0 -0 0 0 1 1 1 90 89 73 90 89 73 72 73 67 55 56 53 -72 73 67 68 70 65 51 52 50 37 39 37 28 31 30 23 25 24 -17 21 21 15 18 18 12 15 15 11 14 14 10 13 13 9 12 12 -9 11 11 9 11 11 9 11 11 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 9 12 12 13 16 16 41 42 42 -49 51 48 110 109 94 251 251 187 251 251 187 251 251 187 105 104 92 -49 51 48 43 45 43 35 37 36 30 31 28 47 48 46 197 193 154 -251 251 187 197 193 154 31 33 31 12 12 12 12 12 12 12 12 12 -12 12 12 51 52 50 184 179 149 72 73 67 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 -11 11 11 21 22 21 30 32 31 40 41 39 60 60 56 145 141 105 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158 -184 179 149 110 109 94 13 13 13 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 4 5 4 61 61 53 48 49 45 3 4 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -156 151 111 251 251 187 251 251 187 184 179 149 11 11 11 0 0 0 -0 0 0 26 28 27 99 98 80 84 83 72 60 60 56 43 45 43 -72 73 67 65 66 61 49 51 48 35 37 36 27 29 28 20 24 24 -17 20 20 14 17 17 12 15 15 11 13 13 10 12 12 9 11 11 -9 11 11 9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 9 11 11 9 11 11 -9 11 11 9 11 11 9 11 11 11 13 13 37 39 37 47 48 46 -51 52 50 184 179 149 251 251 187 251 251 187 251 251 187 145 141 105 -47 48 46 41 42 42 35 37 36 27 29 28 137 133 100 251 251 187 -251 251 187 197 193 154 19 20 19 12 12 12 12 12 12 12 12 12 -27 29 28 184 179 149 214 212 158 63 64 60 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 1 6 7 7 16 16 16 24 26 24 -30 32 31 38 39 37 47 48 46 55 57 54 68 70 65 110 109 94 -197 193 154 251 251 187 251 251 187 251 251 187 210 208 158 184 179 149 -105 104 92 8 8 7 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 65 66 61 184 179 149 156 151 111 -30 32 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -168 163 120 251 251 187 251 251 187 251 251 187 110 109 94 0 0 0 -0 0 0 60 60 56 84 83 72 68 70 65 51 52 50 38 39 37 -84 83 72 63 64 60 43 45 43 33 36 34 25 27 26 20 23 22 -15 18 18 13 16 16 12 14 14 10 13 13 9 12 12 9 11 11 -9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -9 11 11 9 11 11 10 12 12 33 36 34 46 47 45 51 52 50 -72 73 67 210 208 158 251 251 187 251 251 187 251 251 187 177 172 135 -47 48 46 41 42 42 35 37 36 37 39 37 184 179 149 251 251 187 -251 251 187 197 193 154 13 13 13 12 12 12 12 12 12 12 12 12 -110 109 94 251 251 187 251 251 187 37 39 37 0 0 0 0 0 0 -0 0 0 21 22 20 2 2 1 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 5 5 12 12 12 21 22 21 25 27 26 30 32 31 38 39 37 -46 47 45 55 56 53 60 60 56 65 66 61 68 70 65 105 104 92 -110 109 94 197 193 154 210 208 158 197 193 154 184 179 149 84 83 72 -2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 13 13 13 184 179 149 251 251 187 -197 193 154 43 44 41 0 0 0 0 0 0 0 0 0 0 0 0 -145 141 105 251 251 187 251 251 187 251 251 187 214 212 158 43 45 43 -2 2 2 84 83 72 72 73 67 58 59 55 41 42 42 38 39 37 -72 73 67 58 59 55 41 42 42 31 33 31 25 27 26 18 22 22 -14 17 17 12 15 15 12 14 14 10 12 12 9 12 12 9 11 11 -9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 9 12 12 31 33 31 43 45 43 49 51 48 55 56 53 -110 109 94 251 251 187 251 251 187 251 251 187 251 251 187 168 163 120 -47 48 46 41 42 42 33 36 34 63 64 60 197 193 154 251 251 187 -251 251 187 184 179 149 13 13 13 12 12 12 12 12 12 16 16 16 -197 193 154 251 251 187 239 239 170 20 20 20 0 0 0 2 2 1 -108 107 93 110 109 94 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 1 4 5 5 11 11 11 18 19 18 -22 24 23 26 28 27 32 34 33 39 40 39 46 47 45 51 52 50 -55 57 54 60 60 56 63 64 60 63 64 60 63 64 60 58 59 55 -63 64 60 99 98 80 145 141 105 137 133 100 43 45 43 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 3 4 3 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 110 109 94 251 251 187 -251 251 187 184 179 149 25 27 26 0 0 0 0 0 0 0 0 0 -99 98 80 251 251 187 251 251 187 251 251 187 251 251 187 156 151 111 -25 27 26 84 83 72 65 66 61 47 48 46 32 34 33 39 40 39 -72 73 67 55 57 54 40 41 39 30 32 31 23 25 24 18 22 22 -14 17 17 12 15 15 11 13 13 10 12 12 9 11 11 9 11 11 -9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -9 11 11 28 31 30 41 42 42 47 48 46 55 56 53 58 59 55 -137 133 100 251 251 187 251 251 187 251 251 187 210 208 158 137 133 100 -47 48 46 40 41 39 32 34 33 75 75 61 184 179 149 239 239 170 -251 251 187 177 172 135 13 13 13 12 12 12 12 12 12 43 44 41 -197 193 154 251 251 187 210 208 158 10 10 9 0 0 0 84 83 72 -251 251 187 84 83 72 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 -6 7 7 11 11 11 17 17 17 20 20 20 23 24 24 27 29 28 -32 34 33 38 39 37 43 45 43 47 48 46 51 52 50 55 56 53 -58 59 55 58 59 55 55 57 54 55 56 53 47 48 46 41 42 42 -35 37 36 31 33 31 47 48 46 14 14 13 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 66 65 55 99 98 80 20 20 20 -0 0 0 0 0 0 0 0 0 0 0 0 43 45 43 214 212 158 -251 251 187 251 251 187 145 141 105 3 3 3 0 0 0 0 0 0 -48 49 45 184 179 149 239 239 170 251 251 187 239 239 170 177 172 135 -84 83 72 72 73 67 55 56 53 39 40 39 26 28 27 39 40 39 -68 70 65 51 52 50 39 40 39 28 31 30 22 24 23 17 20 20 -14 17 17 12 14 14 10 13 13 9 11 11 9 11 11 9 11 11 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -27 29 28 40 41 39 46 47 45 51 52 50 55 57 54 63 64 60 -131 127 93 197 193 154 210 208 158 197 193 154 168 163 120 96 95 69 -47 48 46 40 41 39 32 34 33 71 71 57 145 141 105 184 179 149 -184 179 149 131 127 93 13 13 13 12 12 12 12 12 12 48 49 45 -168 163 120 184 179 149 156 151 111 6 7 7 14 14 13 177 172 135 -239 239 170 40 41 39 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 3 3 3 6 7 7 11 11 11 16 16 16 -18 19 18 21 22 21 23 24 24 27 29 28 32 34 33 37 39 37 -41 42 42 43 45 43 47 48 46 51 52 50 51 52 50 51 52 50 -51 52 50 49 51 48 46 47 45 40 41 39 32 34 33 25 27 26 -20 20 20 14 14 13 2 2 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 33 36 34 197 193 154 184 179 149 -41 42 42 0 0 0 0 0 0 0 0 0 3 3 3 184 179 149 -251 251 187 251 251 187 184 179 149 48 49 45 0 0 0 0 0 0 -16 17 12 121 119 87 177 172 135 194 189 146 188 184 146 145 141 105 -82 81 62 63 64 60 46 47 45 31 33 31 21 22 21 35 37 36 -68 70 65 51 52 50 37 39 37 27 30 29 22 24 23 17 20 20 -13 16 16 12 14 14 10 13 13 9 11 11 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 25 27 26 -38 39 37 43 45 43 51 52 50 55 56 53 60 60 56 63 64 60 -92 91 72 158 153 112 176 171 126 171 165 117 149 143 98 82 81 62 -44 46 43 38 39 37 30 32 31 71 71 57 131 127 93 160 154 106 -149 143 98 82 81 62 13 13 13 12 12 12 12 12 12 46 47 43 -121 119 87 134 131 96 96 95 69 7 7 6 38 39 37 131 127 93 -145 141 105 12 13 12 0 0 0 1 1 1 3 3 3 6 7 7 -10 10 9 12 12 12 14 14 13 16 16 16 18 19 18 21 22 21 -22 24 23 26 28 27 30 31 28 33 36 34 37 39 37 40 41 39 -41 42 42 43 45 43 46 47 45 46 47 45 46 47 45 43 45 43 -41 42 42 37 39 37 31 33 31 26 28 27 21 22 21 16 16 16 -6 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 177 172 135 251 251 187 -197 193 154 27 29 28 0 0 0 0 0 0 0 0 0 110 109 94 -239 239 170 239 239 170 184 179 149 87 86 72 2 2 1 0 0 0 -1 1 1 82 81 62 142 137 94 165 161 109 165 161 109 131 127 93 -75 75 61 55 56 53 37 39 37 25 27 26 19 20 19 32 34 33 -65 66 61 49 51 48 35 37 36 27 29 28 20 23 23 16 19 19 -13 16 16 13 13 13 10 12 12 9 11 11 8 10 10 8 10 10 -8 9 9 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 22 24 23 35 37 36 -41 42 42 47 48 46 55 56 53 58 59 55 63 64 60 65 66 61 -71 71 57 131 127 93 160 154 106 160 154 106 142 137 94 82 81 62 -46 47 43 40 41 39 33 36 34 66 65 55 125 122 87 149 143 98 -142 137 94 82 81 62 17 17 17 18 19 17 14 14 13 46 47 43 -118 116 76 125 122 87 96 95 69 16 17 12 71 71 57 103 101 77 -82 81 62 11 11 11 11 11 11 13 13 13 14 14 13 14 14 13 -15 15 15 16 16 16 17 17 17 19 20 19 21 22 21 23 24 24 -26 28 27 27 29 28 31 33 31 33 36 34 35 37 36 38 39 37 -39 40 39 39 40 39 38 39 37 37 39 37 35 37 36 31 33 31 -27 29 28 24 26 24 21 22 21 17 17 17 12 12 12 2 2 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 68 70 65 251 251 187 -251 251 187 156 151 111 2 2 1 0 0 0 0 0 0 43 44 41 -177 172 135 184 179 149 158 153 112 103 101 77 19 20 18 0 0 0 -0 0 0 46 47 43 131 127 93 160 154 106 160 154 106 131 127 93 -71 71 57 43 45 43 30 32 31 21 22 21 16 16 16 26 28 27 -63 64 60 47 48 46 35 37 36 26 28 27 20 23 23 16 19 19 -13 16 16 13 13 13 10 12 12 9 11 11 8 10 10 8 10 10 -7 9 9 7 9 9 8 9 9 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 20 20 20 33 36 34 40 41 39 -46 47 45 51 52 50 55 57 54 60 60 56 63 64 60 65 66 61 -66 65 55 118 116 76 151 147 98 165 161 109 151 147 98 121 119 87 -96 95 69 96 95 69 96 95 69 103 101 77 142 137 94 151 147 98 -142 137 94 103 101 77 82 81 62 82 81 62 82 81 62 96 95 69 -131 127 93 142 137 94 103 101 77 46 47 43 96 95 69 118 116 76 -71 71 57 14 14 13 14 14 13 15 15 15 15 15 15 16 16 16 -16 16 16 17 17 17 18 19 18 20 20 20 21 22 21 23 24 24 -25 27 26 27 29 28 30 31 28 30 32 31 31 33 31 31 33 31 -31 33 31 31 33 31 30 31 28 27 29 28 25 27 26 22 24 23 -20 20 20 16 16 16 13 13 13 6 7 7 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -58 59 55 68 70 65 8 8 7 0 0 0 10 10 9 210 208 158 -251 251 187 184 179 149 38 39 37 0 0 0 0 0 0 8 8 7 -103 101 77 149 143 98 149 143 98 118 116 76 40 41 39 25 27 25 -53 55 47 82 81 62 144 139 99 165 161 109 165 161 109 142 137 94 -71 71 57 35 37 36 24 26 24 18 19 18 15 15 15 22 24 23 -63 64 60 46 47 45 33 36 34 26 28 27 20 23 22 17 18 17 -12 15 15 11 13 13 10 12 12 9 11 11 8 10 10 8 10 10 -7 9 9 7 9 9 7 9 9 7 9 9 8 9 9 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 16 16 16 30 31 28 35 37 36 41 42 42 -47 48 46 55 56 53 58 59 55 63 64 60 65 66 61 65 66 61 -61 61 53 103 101 77 151 147 98 171 165 117 171 165 117 168 163 120 -158 153 112 158 153 112 155 149 109 151 147 98 151 147 98 160 154 106 -151 147 98 149 143 98 142 137 94 149 143 98 149 143 98 149 143 98 -155 149 109 151 147 98 131 127 93 103 101 77 125 122 87 118 116 76 -71 71 57 16 16 16 16 16 16 16 16 16 17 17 17 17 17 17 -17 17 17 17 17 17 18 19 18 19 20 19 20 20 20 21 22 21 -23 24 24 24 26 24 25 27 26 26 28 27 26 28 27 26 28 27 -25 27 26 24 26 24 22 24 23 21 22 21 19 20 19 16 16 16 -14 14 13 8 8 7 1 1 1 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -20 20 20 184 179 149 168 163 120 21 22 21 0 0 0 105 104 92 -177 172 135 145 141 105 71 71 57 0 0 0 0 0 0 0 0 0 -66 65 55 131 127 93 151 147 98 142 137 94 118 116 76 121 119 87 -145 141 105 158 153 112 176 171 126 178 174 128 176 171 126 149 145 103 -96 95 69 31 33 31 21 22 21 16 16 16 14 14 13 18 19 18 -60 60 56 46 47 45 33 36 34 25 27 26 21 22 21 15 18 18 -12 15 15 11 13 13 9 11 11 8 10 10 8 10 10 8 9 9 -7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 8 9 9 -8 9 9 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 10 12 12 26 28 27 31 33 31 38 39 37 43 45 43 -51 52 50 55 56 53 60 60 56 63 64 60 65 66 61 68 70 65 -63 64 60 96 95 69 158 153 112 178 174 128 188 184 146 194 189 146 -194 189 146 188 184 146 184 181 136 176 171 126 171 165 117 173 167 111 -173 167 111 165 161 109 171 165 117 174 170 121 176 171 126 178 174 128 -178 174 128 174 170 121 160 154 106 149 143 98 149 143 98 125 122 87 -71 71 57 16 16 16 16 16 16 17 17 17 17 17 17 17 17 17 -17 17 17 17 17 17 17 17 17 18 19 18 19 20 19 20 20 20 -21 22 21 21 22 21 21 22 21 22 24 23 21 22 21 21 22 21 -21 22 21 19 20 19 18 19 18 16 16 16 14 14 13 11 11 11 -3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 105 104 92 197 193 154 110 109 94 9 9 8 36 38 35 -121 119 87 131 127 93 96 95 69 18 19 17 30 31 28 66 65 55 -96 95 69 142 137 94 160 154 106 160 154 106 160 154 106 168 163 120 -184 181 136 194 191 148 197 193 154 197 193 154 194 189 146 168 163 120 -125 122 87 46 47 43 18 19 18 15 15 15 13 13 13 14 14 13 -55 57 54 43 45 43 32 34 33 25 27 26 18 22 22 17 17 17 -12 14 14 10 12 12 9 11 11 8 10 10 8 9 9 7 9 9 -6 8 8 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 -7 9 9 8 9 9 8 9 9 8 10 10 8 10 10 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 32 34 33 41 42 42 35 37 36 39 40 39 37 39 37 -35 37 36 55 57 54 60 60 56 63 64 60 65 66 61 65 66 61 -61 63 57 115 113 82 168 163 120 194 191 148 204 201 155 210 208 158 -210 208 158 210 208 158 197 193 154 194 189 146 186 182 128 176 171 126 -174 170 121 176 171 126 186 182 128 190 186 136 194 191 148 197 193 154 -197 193 154 188 184 146 181 176 137 174 170 121 165 161 109 142 137 94 -82 81 62 24 26 24 16 16 16 16 16 16 16 16 16 16 16 16 -17 17 17 17 17 17 17 17 17 17 17 17 18 19 18 19 20 19 -19 20 19 19 20 19 20 20 20 19 20 19 19 20 19 18 19 18 -17 17 17 15 15 15 13 13 13 12 12 12 6 7 7 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 17 18 17 137 133 100 115 113 82 53 55 47 19 20 18 -103 101 77 144 139 99 137 133 100 115 113 82 137 133 100 156 151 111 -158 153 112 164 159 111 171 165 117 174 170 121 178 174 128 194 189 146 -204 201 155 214 212 158 214 212 158 214 212 158 210 208 158 188 184 146 -158 153 112 87 86 72 17 17 17 13 13 13 13 13 13 15 15 15 -55 56 53 43 45 43 32 34 33 24 26 24 17 20 20 16 16 16 -12 14 14 10 12 12 8 10 10 8 10 10 7 9 9 6 8 8 -6 8 8 6 8 8 6 8 8 7 9 9 7 9 9 7 9 9 -7 9 9 7 9 9 7 9 9 7 9 9 8 9 9 8 10 10 -8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 -8 10 10 110 109 94 84 83 72 49 51 48 26 28 27 8 10 10 -8 9 9 51 52 50 58 59 55 63 64 60 63 64 60 63 64 60 -66 65 55 134 131 96 181 176 137 210 208 158 214 212 158 239 239 170 -239 239 170 224 223 159 210 208 158 204 201 155 194 189 146 186 182 128 -186 182 128 184 181 136 194 189 146 204 201 155 210 208 158 210 208 158 -210 208 158 210 208 158 197 193 154 190 186 136 176 171 126 155 149 109 -118 116 76 36 38 35 15 15 15 16 16 16 16 16 16 16 16 16 -16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 17 17 17 -17 17 17 17 17 17 17 17 17 16 16 16 16 16 16 15 15 15 -13 13 13 12 12 12 8 8 7 2 2 2 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 53 55 47 103 101 77 96 95 69 53 55 47 -103 101 77 158 153 112 177 172 135 184 179 149 188 184 146 197 193 154 -194 189 146 190 186 136 184 181 136 184 181 136 194 189 146 210 208 158 -214 212 158 239 239 170 251 251 187 251 251 187 224 223 159 204 201 155 -177 172 135 121 119 87 30 31 28 13 13 13 12 12 12 39 40 39 -60 60 56 43 45 43 32 34 33 23 25 24 18 19 18 13 16 16 -13 13 13 9 11 11 8 10 10 8 9 9 6 8 8 6 8 8 -6 8 8 6 8 8 6 8 8 6 8 8 6 8 8 7 9 9 -7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 -7 9 9 8 9 9 8 9 9 8 10 10 8 10 10 8 10 10 -14 17 17 197 193 154 158 153 112 55 57 54 7 9 9 7 9 9 -8 10 10 51 52 50 58 59 55 60 60 56 63 64 60 63 64 60 -71 71 57 155 149 109 194 191 148 214 212 158 251 251 187 251 251 187 -251 251 187 251 251 187 239 239 170 210 208 158 197 193 154 190 186 136 -190 186 136 194 189 146 204 201 155 210 208 158 224 223 159 239 239 170 -239 239 170 224 223 159 210 208 158 204 201 155 190 186 136 164 159 111 -125 122 87 40 41 39 15 15 15 15 15 15 15 15 15 15 15 15 -16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 -16 16 16 16 16 16 15 15 15 14 14 13 13 13 13 12 12 12 -8 9 9 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 21 22 20 96 95 69 125 122 87 121 119 87 -144 139 99 177 172 135 197 193 154 210 208 158 214 212 158 214 212 158 -210 208 158 204 201 155 194 191 148 194 189 146 204 201 155 214 212 158 -239 239 170 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158 -188 184 146 145 141 105 53 55 47 12 12 12 15 15 15 63 64 60 -63 64 60 41 42 42 31 33 31 23 24 24 17 18 17 12 15 15 -11 13 13 9 11 11 8 9 9 7 9 9 6 8 8 6 8 8 -6 7 7 6 7 7 6 8 8 6 8 8 6 8 8 6 8 8 -6 8 8 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 -7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 8 8 7 -43 45 43 251 251 187 156 151 111 8 10 10 7 9 9 7 9 9 -21 22 21 51 52 50 55 56 53 55 57 54 58 59 55 58 59 55 -75 75 61 158 153 112 197 193 154 224 223 159 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 214 212 158 204 201 155 194 189 146 -190 186 136 197 193 154 210 208 158 224 223 159 251 251 187 251 251 187 -251 251 187 251 251 187 239 239 170 210 208 158 197 193 154 176 171 126 -125 122 87 36 38 35 14 14 13 14 14 13 15 15 15 15 15 15 -15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 -15 15 15 14 14 13 13 13 13 12 12 12 10 10 9 3 4 4 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 7 7 5 71 71 57 131 127 93 158 153 112 -177 172 135 197 193 154 214 212 158 239 239 170 251 251 187 251 251 187 -238 237 168 210 208 158 204 201 155 197 193 154 204 201 155 214 212 158 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158 -197 193 154 156 151 111 66 65 55 12 12 12 37 39 37 58 59 55 -58 59 55 41 42 42 31 33 31 22 24 23 17 17 17 12 14 14 -10 12 12 8 10 10 6 8 8 6 8 8 6 7 7 6 7 7 -6 7 7 5 7 7 6 7 7 6 7 7 6 8 8 6 8 8 -6 8 8 6 8 8 6 8 8 7 9 9 7 9 9 7 9 9 -7 9 9 6 8 8 6 8 8 6 8 8 6 8 8 6 8 8 -61 63 57 197 193 154 16 19 19 6 8 8 6 8 8 8 9 9 -41 42 42 47 48 46 51 52 50 51 52 50 55 56 53 55 56 53 -71 71 57 158 153 112 197 193 154 224 223 159 251 251 187 251 251 187 -251 251 187 251 251 187 239 239 170 214 212 158 204 201 155 194 189 146 -190 186 136 197 193 154 210 208 158 239 239 170 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 224 223 159 204 201 155 177 172 135 -121 119 87 30 31 28 13 13 13 14 14 13 14 14 13 14 14 13 -14 14 13 14 14 13 15 15 15 15 15 15 14 14 13 13 13 13 -12 12 12 12 12 12 10 10 9 4 5 5 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 48 49 45 131 127 93 174 170 121 -194 189 146 210 208 158 239 239 170 251 251 187 251 251 187 251 251 187 -251 251 187 214 212 158 204 201 155 197 193 154 204 201 155 210 208 158 -239 239 170 251 251 187 251 251 187 251 251 187 239 239 170 214 212 158 -194 191 148 156 151 111 71 71 57 19 20 19 51 52 50 51 52 50 -51 52 50 41 42 42 30 32 31 21 22 21 17 17 17 13 13 13 -9 11 11 8 9 9 6 8 8 6 7 7 6 7 7 5 7 7 -5 6 5 5 6 5 5 7 7 5 7 7 6 7 7 6 7 7 -6 8 8 6 8 8 6 8 8 6 7 7 6 7 7 6 7 7 -6 7 7 6 8 8 6 8 8 6 8 8 6 8 8 6 8 8 -55 56 53 43 45 43 6 8 8 6 8 8 6 8 8 47 48 46 -60 60 56 47 48 46 46 47 45 47 48 46 38 39 37 10 12 12 -66 65 55 145 141 105 197 193 154 214 212 158 251 251 187 251 251 187 -251 251 187 251 251 187 224 223 159 210 208 158 194 191 148 184 181 136 -184 181 136 194 189 146 204 201 155 224 223 159 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 181 176 137 -115 113 82 21 22 20 13 13 13 13 13 13 13 13 13 13 13 13 -14 14 13 13 13 13 13 13 13 13 13 13 12 12 12 11 11 11 -10 10 9 6 7 7 1 1 1 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 2 2 1 66 65 55 144 139 99 178 174 128 -204 201 155 214 212 158 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 214 212 158 204 201 155 194 191 148 197 193 154 204 201 155 -214 212 158 239 239 170 239 239 170 239 239 170 214 212 158 210 208 158 -184 181 136 149 145 103 66 65 55 41 42 42 47 48 46 46 47 45 -43 45 43 39 40 39 28 31 30 21 22 21 16 16 16 10 12 12 -8 10 10 6 8 8 6 7 7 6 7 7 5 6 5 5 6 5 -5 6 5 5 6 5 5 6 5 5 6 5 5 7 7 5 7 7 -6 7 7 6 7 7 6 7 7 5 7 7 5 7 7 5 7 7 -5 7 7 6 7 7 6 7 7 6 7 7 6 7 7 6 8 8 -6 8 8 6 8 8 6 7 7 6 7 7 46 47 45 156 151 111 -105 104 92 58 59 55 43 45 43 32 34 33 6 8 8 6 8 8 -49 51 48 125 122 87 181 176 137 204 201 155 214 212 158 239 239 170 -239 239 170 214 212 158 210 208 158 197 193 154 181 176 137 176 171 126 -176 171 126 184 181 136 197 193 154 210 208 158 239 239 170 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 177 172 135 -99 98 80 13 13 13 12 12 12 12 12 12 13 13 13 12 12 12 -12 12 12 12 12 12 11 11 11 11 11 11 8 9 9 4 5 5 -1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 1 1 0 61 61 53 142 137 94 181 176 137 -204 201 155 224 223 159 251 251 187 251 251 187 251 251 187 251 251 187 -251 251 187 214 212 158 197 193 154 190 186 136 184 181 136 188 184 146 -197 193 154 204 201 155 210 208 158 210 208 158 204 201 155 194 189 146 -176 171 126 134 131 96 66 65 55 43 45 43 41 42 42 39 40 39 -35 37 36 33 36 34 27 29 28 20 20 20 15 15 15 9 11 11 -8 9 9 6 7 7 5 6 5 5 6 5 4 5 5 4 5 5 -4 5 5 4 5 5 4 5 5 4 5 5 5 6 5 4 5 5 -4 5 5 5 6 5 4 5 5 5 6 5 5 6 5 5 6 5 -5 7 7 5 7 7 5 7 7 5 7 7 5 7 7 5 7 7 -6 7 7 6 7 7 6 7 7 28 31 30 184 179 149 184 179 149 -145 141 105 84 83 72 27 29 28 5 7 7 5 6 5 16 16 16 -43 44 41 96 95 69 158 153 112 188 184 146 204 201 155 210 208 158 -204 201 155 197 193 154 184 179 149 177 172 135 168 163 120 164 159 111 -164 159 111 174 170 121 184 181 136 197 193 154 214 212 158 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 177 172 135 -71 71 57 11 11 11 12 12 12 11 11 11 11 11 11 11 11 11 -10 10 9 10 10 9 8 8 7 3 4 4 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 31 33 31 121 119 87 176 171 126 -197 193 154 214 212 158 251 251 187 251 251 187 251 251 187 251 251 187 -239 239 170 210 208 158 194 189 146 178 174 128 174 170 121 176 171 126 -177 172 135 181 176 137 184 179 149 184 179 149 181 176 137 178 174 128 -158 153 112 121 119 87 53 55 47 37 39 37 33 36 34 30 32 31 -27 29 28 25 27 26 24 26 24 19 20 19 13 13 13 8 10 10 -6 8 8 6 7 7 5 6 5 4 5 5 4 5 5 4 5 5 -4 5 5 4 5 5 4 5 5 3 4 4 3 4 4 4 5 5 -4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 -5 6 5 5 6 5 5 6 5 5 6 5 5 6 5 5 6 5 -5 6 5 5 6 5 12 14 14 145 141 105 184 179 149 177 172 135 -90 89 73 21 22 21 5 6 5 5 6 5 4 5 5 37 39 37 -38 39 37 61 61 53 134 131 96 168 163 120 184 181 136 188 184 146 -184 179 149 177 172 135 168 163 120 164 159 111 155 149 109 151 147 98 -151 147 98 164 159 111 176 171 126 184 179 149 210 208 158 239 239 170 -251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 158 153 112 -46 47 43 10 10 9 10 10 9 10 10 9 8 9 9 8 9 9 -6 7 7 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 13 12 7 82 81 62 158 153 112 -188 184 146 210 208 158 239 239 170 251 251 187 251 251 187 251 251 187 -224 223 159 204 201 155 184 181 136 171 165 117 164 159 111 160 154 106 -158 153 112 164 159 111 168 163 120 168 163 120 168 163 120 164 159 111 -142 137 94 96 95 69 43 44 41 27 29 28 26 28 27 23 24 24 -21 22 21 18 19 18 17 17 17 18 19 18 13 13 13 8 8 7 -6 7 7 5 6 5 4 5 5 3 4 4 3 4 4 3 4 4 -3 4 4 3 4 4 3 3 3 3 3 3 3 4 4 3 4 4 -3 4 4 3 4 4 4 5 5 4 5 5 4 5 5 4 5 5 -4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 -4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 -4 5 5 4 5 5 4 5 5 4 5 5 31 33 31 65 66 61 -37 39 37 38 39 37 96 95 69 144 139 99 168 163 120 174 170 121 -168 163 120 164 159 111 155 149 109 149 145 103 149 143 98 142 137 94 -149 143 98 151 147 98 164 159 111 177 172 135 197 193 154 210 208 158 -251 251 187 251 251 187 251 251 187 239 239 170 197 193 154 137 133 100 -24 26 24 8 9 9 8 9 9 8 8 7 6 7 7 2 2 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 46 47 43 125 122 87 -176 171 126 197 193 154 210 208 158 239 239 170 251 251 187 239 239 170 -214 212 158 197 193 154 181 176 137 164 159 111 151 147 98 149 143 98 -149 143 98 149 143 98 149 145 103 155 149 109 160 154 106 149 143 98 -118 116 76 82 81 62 30 31 28 21 22 21 19 20 19 17 17 17 -14 14 13 12 12 12 10 10 9 12 12 12 10 12 12 6 8 8 -4 5 5 3 4 4 3 4 4 3 4 4 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 3 3 2 3 3 2 3 3 -3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 4 5 5 -4 5 5 3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 -4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 -4 5 5 3 4 4 3 4 4 23 24 24 110 109 94 72 73 67 -39 40 39 22 24 23 46 47 43 103 101 77 142 137 94 155 149 109 -160 154 106 155 149 109 149 143 98 142 137 94 142 137 94 142 137 94 -142 137 94 149 143 98 155 149 109 176 171 126 184 179 149 210 208 158 -239 239 170 251 251 187 251 251 187 214 212 158 184 179 149 105 104 92 -10 10 9 6 7 7 3 4 4 1 1 1 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 12 12 9 82 81 62 -149 145 103 181 176 137 197 193 154 210 208 158 214 212 158 214 212 158 -210 208 158 197 193 154 177 172 135 158 153 112 149 143 98 142 137 94 -142 137 94 142 137 94 149 143 98 151 147 98 151 147 98 131 127 93 -103 101 77 71 71 57 22 24 23 15 15 15 13 13 13 11 11 11 -8 9 9 6 7 7 6 7 7 4 5 5 8 9 9 6 7 7 -4 5 5 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 -2 3 3 2 3 3 2 3 3 3 4 4 3 4 4 3 4 4 -3 4 4 3 4 4 3 3 3 3 4 4 3 4 4 3 4 4 -3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 -3 4 4 3 4 4 21 22 21 145 141 105 145 141 105 72 73 67 -17 18 17 3 4 4 21 22 20 66 65 55 118 116 76 142 137 94 -149 143 98 151 147 98 149 143 98 142 137 94 142 137 94 142 137 94 -142 137 94 149 143 98 155 149 109 168 163 120 184 179 149 210 208 158 -239 239 170 251 251 187 251 251 187 210 208 158 177 172 135 71 71 57 -3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 38 35 -115 113 82 158 153 112 181 176 137 197 193 154 204 201 155 210 208 158 -204 201 155 188 184 146 177 172 135 164 159 111 149 145 103 142 137 94 -142 137 94 142 137 94 149 143 98 151 147 98 149 143 98 125 122 87 -96 95 69 61 61 53 16 17 12 8 9 9 8 8 7 6 7 7 -4 5 5 3 4 4 3 3 3 3 3 3 3 3 3 5 6 5 -3 4 4 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 -2 2 2 2 2 2 2 3 3 2 3 3 2 3 3 2 3 3 -3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 -3 3 3 2 3 3 2 3 3 3 4 4 3 4 4 3 4 4 -3 4 4 3 4 4 3 4 4 8 9 9 8 8 7 3 3 3 -3 3 3 3 3 3 9 9 8 36 38 35 82 81 62 118 116 76 -142 137 94 151 147 98 151 147 98 151 147 98 149 143 98 149 143 98 -149 143 98 151 147 98 160 154 106 176 171 126 188 184 146 210 208 158 -239 239 170 251 251 187 239 239 170 210 208 158 156 151 111 31 33 31 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 5 -66 65 55 125 122 87 158 153 112 181 176 137 194 189 146 197 193 154 -197 193 154 184 179 149 177 172 135 168 163 120 156 151 111 151 147 98 -151 147 98 151 147 98 151 147 98 161 156 96 149 143 98 118 116 76 -82 81 62 53 55 47 12 12 9 4 5 5 3 4 4 3 3 3 -3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 2 2 -3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 -1 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 3 3 -2 3 3 2 3 3 2 3 3 2 3 3 2 2 2 2 2 2 -2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 -2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 3 3 3 -3 3 3 3 3 3 72 73 67 61 61 53 53 55 47 96 95 69 -131 127 93 151 147 98 161 156 96 161 156 96 151 147 98 151 147 98 -161 156 96 160 154 106 164 159 111 177 172 135 197 193 154 210 208 158 -239 239 170 251 251 187 224 223 159 197 193 154 131 127 93 9 9 8 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -24 26 24 82 81 62 131 127 93 164 159 111 178 174 128 188 184 146 -188 184 146 188 184 146 181 176 137 176 171 126 168 163 120 164 159 111 -160 154 106 160 154 106 160 154 106 160 154 106 151 147 98 125 122 87 -82 81 62 61 61 53 12 12 9 3 3 3 3 3 3 2 2 2 -2 2 2 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 -0 0 0 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 2 2 1 2 2 1 2 2 1 2 2 -1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 -2 3 3 30 32 31 72 73 67 31 33 31 36 38 35 82 81 62 -118 116 76 149 143 98 161 156 96 161 156 96 161 156 96 160 154 106 -165 161 109 165 161 109 176 171 126 188 184 146 204 201 155 214 212 158 -239 239 170 239 239 170 214 212 158 184 179 149 82 81 62 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 2 2 43 44 41 96 95 69 131 127 93 160 154 106 176 171 126 -184 181 136 184 181 136 184 181 136 181 176 137 178 174 128 174 170 121 -171 165 117 173 167 111 173 167 111 173 167 111 160 154 106 131 127 93 -96 95 69 66 65 55 16 17 12 2 2 2 1 1 1 1 1 1 -1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 10 9 6 30 31 28 71 71 57 -118 116 76 149 143 98 165 161 109 165 161 109 165 161 109 173 167 111 -173 167 111 176 171 126 184 181 136 197 193 154 210 208 158 224 223 159 -251 251 187 239 239 170 210 208 158 168 163 120 40 41 39 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 13 12 7 61 61 53 96 95 69 131 127 93 160 154 106 -176 171 126 184 181 136 184 181 136 188 184 146 184 181 136 184 181 136 -184 181 136 186 182 128 186 182 128 178 174 128 174 170 121 149 145 103 -118 116 76 82 81 62 21 22 20 1 1 1 1 1 1 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 -1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 3 3 3 30 31 28 66 65 55 -118 116 76 149 143 98 165 161 109 173 167 111 173 167 111 174 170 121 -186 182 128 190 186 136 197 193 154 210 208 158 224 223 159 251 251 187 -251 251 187 239 239 170 197 193 154 137 133 100 12 12 9 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 30 31 28 71 71 57 103 101 77 134 131 96 -164 159 111 176 171 126 184 181 136 188 184 146 194 189 146 197 193 154 -197 193 154 197 193 154 194 191 148 194 189 146 190 186 136 176 171 126 -145 141 105 103 101 77 40 41 39 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 -1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 -1 2 2 1 2 2 1 2 2 1 2 2 30 31 28 71 71 57 -118 116 76 160 154 106 173 167 111 178 174 128 186 182 128 190 186 136 -194 191 148 204 201 155 210 208 158 224 223 159 251 251 187 251 251 187 -251 251 187 214 212 158 184 179 149 84 83 72 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 5 5 3 43 44 41 82 81 62 103 101 77 -142 137 94 165 161 109 178 174 128 190 186 136 197 193 154 204 201 155 -210 208 158 210 208 158 210 208 158 210 208 158 210 208 158 197 193 154 -177 172 135 145 141 105 79 78 62 5 4 3 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 2 2 1 2 2 30 31 28 82 81 62 -142 137 94 165 161 109 178 174 128 190 186 136 194 191 148 204 201 155 -210 208 158 214 212 158 239 239 170 251 251 187 251 251 187 251 251 187 -251 251 187 210 208 158 168 163 120 36 38 35 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 16 17 12 53 55 47 82 81 62 -118 116 76 151 147 98 171 165 117 184 181 136 194 191 148 210 208 158 -214 212 158 224 223 159 239 239 170 239 239 170 224 223 159 214 212 158 -197 193 154 176 171 126 115 113 82 24 26 24 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 40 41 39 103 101 77 -151 147 98 176 171 126 190 186 136 197 193 154 210 208 158 214 212 158 -239 239 170 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -239 239 170 197 193 154 110 109 94 3 4 3 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 30 31 28 66 65 55 -96 95 69 125 122 87 160 154 106 178 174 128 194 189 146 204 201 155 -214 212 158 239 239 170 251 251 187 251 251 187 251 251 187 239 239 170 -210 208 158 188 184 146 149 145 103 61 61 53 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 61 61 53 131 127 93 -164 159 111 184 181 136 197 193 154 210 208 158 224 223 159 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 -210 208 158 168 163 120 43 44 41 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 4 3 2 36 38 35 -71 71 57 96 95 69 142 137 94 165 161 109 184 181 136 197 193 154 -210 208 158 239 239 170 251 251 187 251 251 187 251 251 187 251 251 187 -214 212 158 197 193 154 168 163 120 103 101 77 7 7 5 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 0 0 0 0 0 0 0 0 0 82 81 62 142 137 94 -174 170 121 194 189 146 210 208 158 224 223 159 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 224 223 159 -184 179 149 99 98 80 3 3 3 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 5 -43 44 41 82 81 62 118 116 76 142 137 94 171 165 117 190 186 136 -204 201 155 224 223 159 251 251 187 251 251 187 251 251 187 251 251 187 -214 212 158 197 193 154 174 170 121 125 122 87 30 31 28 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 3 4 3 82 81 62 149 143 98 -176 171 126 194 191 148 210 208 158 239 239 170 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 251 251 187 239 239 170 204 201 155 -145 141 105 30 31 28 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -10 9 6 46 47 43 82 81 62 118 116 76 149 143 98 174 170 121 -194 189 146 210 208 158 224 223 159 251 251 187 251 251 187 224 223 159 -210 208 158 194 191 148 174 170 121 134 131 96 53 55 47 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 7 7 5 96 95 69 149 143 98 -176 171 126 194 191 148 210 208 158 239 239 170 251 251 187 251 251 187 -251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 177 172 135 -75 75 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 10 9 6 46 47 43 82 81 62 118 116 76 149 143 98 -176 171 126 194 191 148 210 208 158 214 212 158 214 212 158 210 208 158 -197 193 154 184 181 136 164 159 111 131 127 93 53 55 47 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 7 7 5 96 95 69 149 143 98 -174 170 121 194 189 146 204 201 155 214 212 158 239 239 170 251 251 187 -251 251 187 251 251 187 239 239 170 210 208 158 184 179 149 110 109 94 -12 12 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 10 9 6 43 44 41 82 81 62 115 113 82 -144 139 99 168 163 120 188 184 146 197 193 154 197 193 154 194 189 146 -184 181 136 174 170 121 151 147 98 118 116 76 36 38 35 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 4 3 2 82 81 62 142 137 94 -171 165 117 186 182 128 194 191 148 210 208 158 214 212 158 224 223 159 -239 239 170 224 223 159 210 208 158 184 179 149 137 133 100 36 38 35 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 7 7 5 36 38 35 71 71 57 -103 101 77 131 127 93 155 149 109 168 163 120 168 163 120 168 163 120 -164 159 111 149 143 98 125 122 87 82 81 62 13 12 7 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 61 61 53 125 122 87 -160 154 106 174 170 121 184 181 136 194 189 146 204 201 155 210 208 158 -210 208 158 204 201 155 184 179 149 145 141 105 61 61 53 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 3 3 2 30 31 28 -61 61 53 82 81 62 103 101 77 121 119 87 125 122 87 125 122 87 -118 116 76 103 101 77 79 78 62 24 26 24 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 25 27 25 96 95 69 -142 137 94 160 154 106 171 165 117 178 174 128 184 181 136 184 181 136 -181 176 137 177 172 135 145 141 105 75 75 61 5 5 3 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -16 17 12 40 41 39 61 61 53 71 71 57 71 71 57 71 71 57 -66 65 55 43 44 41 12 12 9 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 46 47 43 -96 95 69 125 122 87 142 137 94 149 145 103 155 149 109 155 149 109 -145 141 105 121 119 87 66 65 55 7 7 5 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 1 1 16 17 12 24 26 24 25 27 25 19 20 18 -7 7 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 -25 27 25 61 61 53 82 81 62 96 95 69 96 95 69 82 81 62 -61 61 53 25 27 25 2 2 1 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 5 6 5 13 12 7 10 9 6 3 4 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 6 6 6 10 10 10 10 10 10 + 10 10 10 6 6 6 6 6 6 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 6 6 6 10 10 10 14 14 14 + 22 22 22 26 26 26 30 30 30 34 34 34 + 30 30 30 30 30 30 26 26 26 18 18 18 + 14 14 14 10 10 10 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 14 14 14 26 26 26 42 42 42 + 54 54 54 66 66 66 78 78 78 78 78 78 + 78 78 78 74 74 74 66 66 66 54 54 54 + 42 42 42 26 26 26 18 18 18 10 10 10 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 22 22 22 42 42 42 66 66 66 86 86 86 + 66 66 66 38 38 38 38 38 38 22 22 22 + 26 26 26 34 34 34 54 54 54 66 66 66 + 86 86 86 70 70 70 46 46 46 26 26 26 + 14 14 14 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 10 10 10 26 26 26 + 50 50 50 82 82 82 58 58 58 6 6 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 6 6 6 54 54 54 86 86 86 66 66 66 + 38 38 38 18 18 18 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 6 6 6 22 22 22 50 50 50 + 78 78 78 34 34 34 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 6 6 6 70 70 70 + 78 78 78 46 46 46 22 22 22 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 18 18 18 42 42 42 82 82 82 + 26 26 26 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 14 14 14 + 46 46 46 34 34 34 6 6 6 2 2 6 + 42 42 42 78 78 78 42 42 42 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 10 10 10 30 30 30 66 66 66 58 58 58 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 26 26 26 + 86 86 86 101 101 101 46 46 46 10 10 10 + 2 2 6 58 58 58 70 70 70 34 34 34 + 10 10 10 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 14 14 14 42 42 42 86 86 86 10 10 10 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 30 30 30 + 94 94 94 94 94 94 58 58 58 26 26 26 + 2 2 6 6 6 6 78 78 78 54 54 54 + 22 22 22 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 22 22 22 62 62 62 62 62 62 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 26 26 26 + 54 54 54 38 38 38 18 18 18 10 10 10 + 2 2 6 2 2 6 34 34 34 82 82 82 + 38 38 38 14 14 14 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 30 30 30 78 78 78 30 30 30 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 10 10 10 + 10 10 10 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 78 78 78 + 50 50 50 18 18 18 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 38 38 38 86 86 86 14 14 14 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 54 54 54 + 66 66 66 26 26 26 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 42 42 42 82 82 82 2 2 6 2 2 6 + 2 2 6 6 6 6 10 10 10 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 6 6 6 + 14 14 14 10 10 10 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 18 18 18 + 82 82 82 34 34 34 10 10 10 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 46 46 46 86 86 86 2 2 6 2 2 6 + 6 6 6 6 6 6 22 22 22 34 34 34 + 6 6 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 18 18 18 34 34 34 + 10 10 10 50 50 50 22 22 22 2 2 6 + 2 2 6 2 2 6 2 2 6 10 10 10 + 86 86 86 42 42 42 14 14 14 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 46 46 46 86 86 86 2 2 6 2 2 6 + 38 38 38 116 116 116 94 94 94 22 22 22 + 22 22 22 2 2 6 2 2 6 2 2 6 + 14 14 14 86 86 86 138 138 138 162 162 162 +154 154 154 38 38 38 26 26 26 6 6 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 86 86 86 46 46 46 14 14 14 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 46 46 46 86 86 86 2 2 6 14 14 14 +134 134 134 198 198 198 195 195 195 116 116 116 + 10 10 10 2 2 6 2 2 6 6 6 6 +101 98 89 187 187 187 210 210 210 218 218 218 +214 214 214 134 134 134 14 14 14 6 6 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 86 86 86 50 50 50 18 18 18 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 1 0 0 0 + 0 0 1 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 46 46 46 86 86 86 2 2 6 54 54 54 +218 218 218 195 195 195 226 226 226 246 246 246 + 58 58 58 2 2 6 2 2 6 30 30 30 +210 210 210 253 253 253 174 174 174 123 123 123 +221 221 221 234 234 234 74 74 74 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 70 70 70 58 58 58 22 22 22 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 46 46 46 82 82 82 2 2 6 106 106 106 +170 170 170 26 26 26 86 86 86 226 226 226 +123 123 123 10 10 10 14 14 14 46 46 46 +231 231 231 190 190 190 6 6 6 70 70 70 + 90 90 90 238 238 238 158 158 158 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 70 70 70 58 58 58 22 22 22 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 1 0 0 0 + 0 0 1 0 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 42 42 42 86 86 86 6 6 6 116 116 116 +106 106 106 6 6 6 70 70 70 149 149 149 +128 128 128 18 18 18 38 38 38 54 54 54 +221 221 221 106 106 106 2 2 6 14 14 14 + 46 46 46 190 190 190 198 198 198 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 74 74 74 62 62 62 22 22 22 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 1 0 0 0 + 0 0 1 0 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 42 42 42 94 94 94 14 14 14 101 101 101 +128 128 128 2 2 6 18 18 18 116 116 116 +118 98 46 121 92 8 121 92 8 98 78 10 +162 162 162 106 106 106 2 2 6 2 2 6 + 2 2 6 195 195 195 195 195 195 6 6 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 74 74 74 62 62 62 22 22 22 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 1 0 0 1 + 0 0 1 0 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 38 38 38 90 90 90 14 14 14 58 58 58 +210 210 210 26 26 26 54 38 6 154 114 10 +226 170 11 236 186 11 225 175 15 184 144 12 +215 174 15 175 146 61 37 26 9 2 2 6 + 70 70 70 246 246 246 138 138 138 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 70 70 70 66 66 66 26 26 26 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 38 38 38 86 86 86 14 14 14 10 10 10 +195 195 195 188 164 115 192 133 9 225 175 15 +239 182 13 234 190 10 232 195 16 232 200 30 +245 207 45 241 208 19 232 195 16 184 144 12 +218 194 134 211 206 186 42 42 42 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 50 50 50 74 74 74 30 30 30 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 34 34 34 86 86 86 14 14 14 2 2 6 +121 87 25 192 133 9 219 162 10 239 182 13 +236 186 11 232 195 16 241 208 19 244 214 54 +246 218 60 246 218 38 246 215 20 241 208 19 +241 208 19 226 184 13 121 87 25 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 50 50 50 82 82 82 34 34 34 10 10 10 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 34 34 34 82 82 82 30 30 30 61 42 6 +180 123 7 206 145 10 230 174 11 239 182 13 +234 190 10 238 202 15 241 208 19 246 218 74 +246 218 38 246 215 20 246 215 20 246 215 20 +226 184 13 215 174 15 184 144 12 6 6 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 26 26 26 94 94 94 42 42 42 14 14 14 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 30 30 30 78 78 78 50 50 50 104 69 6 +192 133 9 216 158 10 236 178 12 236 186 11 +232 195 16 241 208 19 244 214 54 245 215 43 +246 215 20 246 215 20 241 208 19 198 155 10 +200 144 11 216 158 10 156 118 10 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 6 6 6 90 90 90 54 54 54 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 30 30 30 78 78 78 46 46 46 22 22 22 +137 92 6 210 162 10 239 182 13 238 190 10 +238 202 15 241 208 19 246 215 20 246 215 20 +241 208 19 203 166 17 185 133 11 210 150 10 +216 158 10 210 150 10 102 78 10 2 2 6 + 6 6 6 54 54 54 14 14 14 2 2 6 + 2 2 6 62 62 62 74 74 74 30 30 30 + 10 10 10 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 34 34 34 78 78 78 50 50 50 6 6 6 + 94 70 30 139 102 15 190 146 13 226 184 13 +232 200 30 232 195 16 215 174 15 190 146 13 +168 122 10 192 133 9 210 150 10 213 154 11 +202 150 34 182 157 106 101 98 89 2 2 6 + 2 2 6 78 78 78 116 116 116 58 58 58 + 2 2 6 22 22 22 90 90 90 46 46 46 + 18 18 18 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 38 38 38 86 86 86 50 50 50 6 6 6 +128 128 128 174 154 114 156 107 11 168 122 10 +198 155 10 184 144 12 197 138 11 200 144 11 +206 145 10 206 145 10 197 138 11 188 164 115 +195 195 195 198 198 198 174 174 174 14 14 14 + 2 2 6 22 22 22 116 116 116 116 116 116 + 22 22 22 2 2 6 74 74 74 70 70 70 + 30 30 30 10 10 10 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 18 18 18 + 50 50 50 101 101 101 26 26 26 10 10 10 +138 138 138 190 190 190 174 154 114 156 107 11 +197 138 11 200 144 11 197 138 11 192 133 9 +180 123 7 190 142 34 190 178 144 187 187 187 +202 202 202 221 221 221 214 214 214 66 66 66 + 2 2 6 2 2 6 50 50 50 62 62 62 + 6 6 6 2 2 6 10 10 10 90 90 90 + 50 50 50 18 18 18 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 10 10 10 34 34 34 + 74 74 74 74 74 74 2 2 6 6 6 6 +144 144 144 198 198 198 190 190 190 178 166 146 +154 121 60 156 107 11 156 107 11 168 124 44 +174 154 114 187 187 187 190 190 190 210 210 210 +246 246 246 253 253 253 253 253 253 182 182 182 + 6 6 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 62 62 62 + 74 74 74 34 34 34 14 14 14 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 10 10 10 22 22 22 54 54 54 + 94 94 94 18 18 18 2 2 6 46 46 46 +234 234 234 221 221 221 190 190 190 190 190 190 +190 190 190 187 187 187 187 187 187 190 190 190 +190 190 190 195 195 195 214 214 214 242 242 242 +253 253 253 253 253 253 253 253 253 253 253 253 + 82 82 82 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 14 14 14 + 86 86 86 54 54 54 22 22 22 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 18 18 18 46 46 46 90 90 90 + 46 46 46 18 18 18 6 6 6 182 182 182 +253 253 253 246 246 246 206 206 206 190 190 190 +190 190 190 190 190 190 190 190 190 190 190 190 +206 206 206 231 231 231 250 250 250 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +202 202 202 14 14 14 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 42 42 42 86 86 86 42 42 42 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 14 14 14 38 38 38 74 74 74 66 66 66 + 2 2 6 6 6 6 90 90 90 250 250 250 +253 253 253 253 253 253 238 238 238 198 198 198 +190 190 190 190 190 190 195 195 195 221 221 221 +246 246 246 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 82 82 82 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 78 78 78 70 70 70 34 34 34 + 14 14 14 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 34 34 34 66 66 66 78 78 78 6 6 6 + 2 2 6 18 18 18 218 218 218 253 253 253 +253 253 253 253 253 253 253 253 253 246 246 246 +226 226 226 231 231 231 246 246 246 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 178 178 178 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 18 18 18 90 90 90 62 62 62 + 30 30 30 10 10 10 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 10 10 10 26 26 26 + 58 58 58 90 90 90 18 18 18 2 2 6 + 2 2 6 110 110 110 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +250 250 250 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 231 231 231 18 18 18 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 18 18 18 94 94 94 + 54 54 54 26 26 26 10 10 10 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 6 6 6 22 22 22 50 50 50 + 90 90 90 26 26 26 2 2 6 2 2 6 + 14 14 14 195 195 195 250 250 250 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +250 250 250 242 242 242 54 54 54 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 38 38 38 + 86 86 86 50 50 50 22 22 22 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 14 14 14 38 38 38 82 82 82 + 34 34 34 2 2 6 2 2 6 2 2 6 + 42 42 42 195 195 195 246 246 246 253 253 253 +253 253 253 253 253 253 253 253 253 250 250 250 +242 242 242 242 242 242 250 250 250 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 250 250 250 246 246 246 238 238 238 +226 226 226 231 231 231 101 101 101 6 6 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 38 38 38 82 82 82 42 42 42 14 14 14 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 10 10 10 26 26 26 62 62 62 66 66 66 + 2 2 6 2 2 6 2 2 6 6 6 6 + 70 70 70 170 170 170 206 206 206 234 234 234 +246 246 246 250 250 250 250 250 250 238 238 238 +226 226 226 231 231 231 238 238 238 250 250 250 +250 250 250 250 250 250 246 246 246 231 231 231 +214 214 214 206 206 206 202 202 202 202 202 202 +198 198 198 202 202 202 182 182 182 18 18 18 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 62 62 62 66 66 66 30 30 30 + 10 10 10 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 14 14 14 42 42 42 82 82 82 18 18 18 + 2 2 6 2 2 6 2 2 6 10 10 10 + 94 94 94 182 182 182 218 218 218 242 242 242 +250 250 250 253 253 253 253 253 253 250 250 250 +234 234 234 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 246 246 246 +238 238 238 226 226 226 210 210 210 202 202 202 +195 195 195 195 195 195 210 210 210 158 158 158 + 6 6 6 14 14 14 50 50 50 14 14 14 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 6 6 6 86 86 86 46 46 46 + 18 18 18 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 22 22 22 54 54 54 70 70 70 2 2 6 + 2 2 6 10 10 10 2 2 6 22 22 22 +166 166 166 231 231 231 250 250 250 253 253 253 +253 253 253 253 253 253 253 253 253 250 250 250 +242 242 242 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 246 246 246 +231 231 231 206 206 206 198 198 198 226 226 226 + 94 94 94 2 2 6 6 6 6 38 38 38 + 30 30 30 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 62 62 62 66 66 66 + 26 26 26 10 10 10 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 30 30 30 74 74 74 50 50 50 2 2 6 + 26 26 26 26 26 26 2 2 6 106 106 106 +238 238 238 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 246 246 246 218 218 218 202 202 202 +210 210 210 14 14 14 2 2 6 2 2 6 + 30 30 30 22 22 22 2 2 6 2 2 6 + 2 2 6 2 2 6 18 18 18 86 86 86 + 42 42 42 14 14 14 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 42 42 42 90 90 90 22 22 22 2 2 6 + 42 42 42 2 2 6 18 18 18 218 218 218 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 250 250 250 221 221 221 +218 218 218 101 101 101 2 2 6 14 14 14 + 18 18 18 38 38 38 10 10 10 2 2 6 + 2 2 6 2 2 6 2 2 6 78 78 78 + 58 58 58 22 22 22 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 18 18 18 + 54 54 54 82 82 82 2 2 6 26 26 26 + 22 22 22 2 2 6 123 123 123 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 250 250 250 +238 238 238 198 198 198 6 6 6 38 38 38 + 58 58 58 26 26 26 38 38 38 2 2 6 + 2 2 6 2 2 6 2 2 6 46 46 46 + 78 78 78 30 30 30 10 10 10 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 10 10 10 30 30 30 + 74 74 74 58 58 58 2 2 6 42 42 42 + 2 2 6 22 22 22 231 231 231 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 250 250 250 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 246 246 246 46 46 46 38 38 38 + 42 42 42 14 14 14 38 38 38 14 14 14 + 2 2 6 2 2 6 2 2 6 6 6 6 + 86 86 86 46 46 46 14 14 14 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 6 6 6 14 14 14 42 42 42 + 90 90 90 18 18 18 18 18 18 26 26 26 + 2 2 6 116 116 116 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 250 250 250 238 238 238 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 94 94 94 6 6 6 + 2 2 6 2 2 6 10 10 10 34 34 34 + 2 2 6 2 2 6 2 2 6 2 2 6 + 74 74 74 58 58 58 22 22 22 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 10 10 10 26 26 26 66 66 66 + 82 82 82 2 2 6 38 38 38 6 6 6 + 14 14 14 210 210 210 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 246 246 246 242 242 242 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 144 144 144 2 2 6 + 2 2 6 2 2 6 2 2 6 46 46 46 + 2 2 6 2 2 6 2 2 6 2 2 6 + 42 42 42 74 74 74 30 30 30 10 10 10 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 14 14 14 42 42 42 90 90 90 + 26 26 26 6 6 6 42 42 42 2 2 6 + 74 74 74 250 250 250 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 242 242 242 242 242 242 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 182 182 182 2 2 6 + 2 2 6 2 2 6 2 2 6 46 46 46 + 2 2 6 2 2 6 2 2 6 2 2 6 + 10 10 10 86 86 86 38 38 38 10 10 10 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 10 10 10 26 26 26 66 66 66 82 82 82 + 2 2 6 22 22 22 18 18 18 2 2 6 +149 149 149 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 234 234 234 242 242 242 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 206 206 206 2 2 6 + 2 2 6 2 2 6 2 2 6 38 38 38 + 2 2 6 2 2 6 2 2 6 2 2 6 + 6 6 6 86 86 86 46 46 46 14 14 14 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 18 18 18 46 46 46 86 86 86 18 18 18 + 2 2 6 34 34 34 10 10 10 6 6 6 +210 210 210 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 234 234 234 242 242 242 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 221 221 221 6 6 6 + 2 2 6 2 2 6 6 6 6 30 30 30 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 82 82 82 54 54 54 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 26 26 26 66 66 66 62 62 62 2 2 6 + 2 2 6 38 38 38 10 10 10 26 26 26 +238 238 238 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 238 238 238 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 6 6 6 + 2 2 6 2 2 6 10 10 10 30 30 30 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 66 66 66 58 58 58 22 22 22 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 38 38 38 78 78 78 6 6 6 2 2 6 + 2 2 6 46 46 46 14 14 14 42 42 42 +246 246 246 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 242 242 242 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 234 234 234 10 10 10 + 2 2 6 2 2 6 22 22 22 14 14 14 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 66 66 66 62 62 62 22 22 22 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 18 18 18 + 50 50 50 74 74 74 2 2 6 2 2 6 + 14 14 14 70 70 70 34 34 34 62 62 62 +250 250 250 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 246 246 246 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 234 234 234 14 14 14 + 2 2 6 2 2 6 30 30 30 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 66 66 66 62 62 62 22 22 22 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 18 18 18 + 54 54 54 62 62 62 2 2 6 2 2 6 + 2 2 6 30 30 30 46 46 46 70 70 70 +250 250 250 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 246 246 246 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 226 226 226 10 10 10 + 2 2 6 6 6 6 30 30 30 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 66 66 66 58 58 58 22 22 22 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 22 22 22 + 58 58 58 62 62 62 2 2 6 2 2 6 + 2 2 6 2 2 6 30 30 30 78 78 78 +250 250 250 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 246 246 246 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 206 206 206 2 2 6 + 22 22 22 34 34 34 18 14 6 22 22 22 + 26 26 26 18 18 18 6 6 6 2 2 6 + 2 2 6 82 82 82 54 54 54 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 26 26 26 + 62 62 62 106 106 106 74 54 14 185 133 11 +210 162 10 121 92 8 6 6 6 62 62 62 +238 238 238 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 246 246 246 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 158 158 158 18 18 18 + 14 14 14 2 2 6 2 2 6 2 2 6 + 6 6 6 18 18 18 66 66 66 38 38 38 + 6 6 6 94 94 94 50 50 50 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 10 10 10 10 10 10 18 18 18 38 38 38 + 78 78 78 142 134 106 216 158 10 242 186 14 +246 190 14 246 190 14 156 118 10 10 10 10 + 90 90 90 238 238 238 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 250 250 250 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 246 230 190 +238 204 91 238 204 91 181 142 44 37 26 9 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 38 38 38 46 46 46 + 26 26 26 106 106 106 54 54 54 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 6 6 6 14 14 14 22 22 22 + 30 30 30 38 38 38 50 50 50 70 70 70 +106 106 106 190 142 34 226 170 11 242 186 14 +246 190 14 246 190 14 246 190 14 154 114 10 + 6 6 6 74 74 74 226 226 226 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 231 231 231 250 250 250 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 228 184 62 +241 196 14 241 208 19 232 195 16 38 30 10 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 6 6 6 30 30 30 26 26 26 +203 166 17 154 142 90 66 66 66 26 26 26 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 18 18 18 38 38 38 58 58 58 + 78 78 78 86 86 86 101 101 101 123 123 123 +175 146 61 210 150 10 234 174 13 246 186 14 +246 190 14 246 190 14 246 190 14 238 190 10 +102 78 10 2 2 6 46 46 46 198 198 198 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 234 234 234 242 242 242 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 224 178 62 +242 186 14 241 196 14 210 166 10 22 18 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 6 6 6 121 92 8 +238 202 15 232 195 16 82 82 82 34 34 34 + 10 10 10 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 14 14 14 38 38 38 70 70 70 154 122 46 +190 142 34 200 144 11 197 138 11 197 138 11 +213 154 11 226 170 11 242 186 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +225 175 15 46 32 6 2 2 6 22 22 22 +158 158 158 250 250 250 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 250 250 250 242 242 242 224 178 62 +239 182 13 236 186 11 213 154 11 46 32 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 61 42 6 225 175 15 +238 190 10 236 186 11 112 100 78 42 42 42 + 14 14 14 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 22 22 22 54 54 54 154 122 46 213 154 11 +226 170 11 230 174 11 226 170 11 226 170 11 +236 178 12 242 186 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +241 196 14 184 144 12 10 10 10 2 2 6 + 6 6 6 116 116 116 242 242 242 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 231 231 231 198 198 198 214 170 54 +236 178 12 236 178 12 210 150 10 137 92 6 + 18 14 6 2 2 6 2 2 6 2 2 6 + 6 6 6 70 47 6 200 144 11 236 178 12 +239 182 13 239 182 13 124 112 88 58 58 58 + 22 22 22 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 30 30 30 70 70 70 180 133 36 226 170 11 +239 182 13 242 186 14 242 186 14 246 186 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 232 195 16 98 70 6 2 2 6 + 2 2 6 2 2 6 66 66 66 221 221 221 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 206 206 206 198 198 198 214 166 58 +230 174 11 230 174 11 216 158 10 192 133 9 +163 110 8 116 81 8 102 78 10 116 81 8 +167 114 7 197 138 11 226 170 11 239 182 13 +242 186 14 242 186 14 162 146 94 78 78 78 + 34 34 34 14 14 14 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 30 30 30 78 78 78 190 142 34 226 170 11 +239 182 13 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 241 196 14 203 166 17 22 18 6 + 2 2 6 2 2 6 2 2 6 38 38 38 +218 218 218 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +250 250 250 206 206 206 198 198 198 202 162 69 +226 170 11 236 178 12 224 166 10 210 150 10 +200 144 11 197 138 11 192 133 9 197 138 11 +210 150 10 226 170 11 242 186 14 246 190 14 +246 190 14 246 186 14 225 175 15 124 112 88 + 62 62 62 30 30 30 14 14 14 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 30 30 30 78 78 78 174 135 50 224 166 10 +239 182 13 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 241 196 14 139 102 15 + 2 2 6 2 2 6 2 2 6 2 2 6 + 78 78 78 250 250 250 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +250 250 250 214 214 214 198 198 198 190 150 46 +219 162 10 236 178 12 234 174 13 224 166 10 +216 158 10 213 154 11 213 154 11 216 158 10 +226 170 11 239 182 13 246 190 14 246 190 14 +246 190 14 246 190 14 242 186 14 206 162 42 +101 101 101 58 58 58 30 30 30 14 14 14 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 30 30 30 74 74 74 174 135 50 216 158 10 +236 178 12 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 241 196 14 226 184 13 + 61 42 6 2 2 6 2 2 6 2 2 6 + 22 22 22 238 238 238 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 226 226 226 187 187 187 180 133 36 +216 158 10 236 178 12 239 182 13 236 178 12 +230 174 11 226 170 11 226 170 11 230 174 11 +236 178 12 242 186 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 186 14 239 182 13 +206 162 42 106 106 106 66 66 66 34 34 34 + 14 14 14 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 26 26 26 70 70 70 163 133 67 213 154 11 +236 178 12 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 241 196 14 +190 146 13 18 14 6 2 2 6 2 2 6 + 46 46 46 246 246 246 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 221 221 221 86 86 86 156 107 11 +216 158 10 236 178 12 242 186 14 246 186 14 +242 186 14 239 182 13 239 182 13 242 186 14 +242 186 14 246 186 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +242 186 14 225 175 15 142 122 72 66 66 66 + 30 30 30 10 10 10 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 26 26 26 70 70 70 163 133 67 210 150 10 +236 178 12 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +232 195 16 121 92 8 34 34 34 106 106 106 +221 221 221 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +242 242 242 82 82 82 18 14 6 163 110 8 +216 158 10 236 178 12 242 186 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 242 186 14 163 133 67 + 46 46 46 18 18 18 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 10 10 10 + 30 30 30 78 78 78 163 133 67 210 150 10 +236 178 12 246 186 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +241 196 14 215 174 15 190 178 144 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 218 218 218 + 58 58 58 2 2 6 22 18 6 167 114 7 +216 158 10 236 178 12 246 186 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 186 14 242 186 14 190 150 46 + 54 54 54 22 22 22 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 38 38 38 86 86 86 180 133 36 213 154 11 +236 178 12 246 186 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 232 195 16 190 146 13 214 214 214 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 250 250 250 170 170 170 26 26 26 + 2 2 6 2 2 6 37 26 9 163 110 8 +219 162 10 239 182 13 246 186 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 186 14 236 178 12 224 166 10 142 122 72 + 46 46 46 18 18 18 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 18 18 18 + 50 50 50 109 106 95 192 133 9 224 166 10 +242 186 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +242 186 14 226 184 13 210 162 10 142 110 46 +226 226 226 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +253 253 253 253 253 253 253 253 253 253 253 253 +198 198 198 66 66 66 2 2 6 2 2 6 + 2 2 6 2 2 6 50 34 6 156 107 11 +219 162 10 239 182 13 246 186 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 242 186 14 +234 174 13 213 154 11 154 122 46 66 66 66 + 30 30 30 10 10 10 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 22 22 22 + 58 58 58 154 121 60 206 145 10 234 174 13 +242 186 14 246 186 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 186 14 236 178 12 210 162 10 163 110 8 + 61 42 6 138 138 138 218 218 218 250 250 250 +253 253 253 253 253 253 253 253 253 250 250 250 +242 242 242 210 210 210 144 144 144 66 66 66 + 6 6 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 61 42 6 163 110 8 +216 158 10 236 178 12 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 239 182 13 230 174 11 216 158 10 +190 142 34 124 112 88 70 70 70 38 38 38 + 18 18 18 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 22 22 22 + 62 62 62 168 124 44 206 145 10 224 166 10 +236 178 12 239 182 13 242 186 14 242 186 14 +246 186 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 236 178 12 216 158 10 175 118 6 + 80 54 7 2 2 6 6 6 6 30 30 30 + 54 54 54 62 62 62 50 50 50 38 38 38 + 14 14 14 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 6 6 6 80 54 7 167 114 7 +213 154 11 236 178 12 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 190 14 242 186 14 239 182 13 239 182 13 +230 174 11 210 150 10 174 135 50 124 112 88 + 82 82 82 54 54 54 34 34 34 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 18 18 18 + 50 50 50 158 118 36 192 133 9 200 144 11 +216 158 10 219 162 10 224 166 10 226 170 11 +230 174 11 236 178 12 239 182 13 239 182 13 +242 186 14 246 186 14 246 190 14 246 190 14 +246 190 14 246 190 14 246 190 14 246 190 14 +246 186 14 230 174 11 210 150 10 163 110 8 +104 69 6 10 10 10 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 6 6 6 91 60 6 167 114 7 +206 145 10 230 174 11 242 186 14 246 190 14 +246 190 14 246 190 14 246 186 14 242 186 14 +239 182 13 230 174 11 224 166 10 213 154 11 +180 133 36 124 112 88 86 86 86 58 58 58 + 38 38 38 22 22 22 10 10 10 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 14 14 14 + 34 34 34 70 70 70 138 110 50 158 118 36 +167 114 7 180 123 7 192 133 9 197 138 11 +200 144 11 206 145 10 213 154 11 219 162 10 +224 166 10 230 174 11 239 182 13 242 186 14 +246 186 14 246 186 14 246 186 14 246 186 14 +239 182 13 216 158 10 185 133 11 152 99 6 +104 69 6 18 14 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 2 2 6 2 2 6 2 2 6 + 2 2 6 6 6 6 80 54 7 152 99 6 +192 133 9 219 162 10 236 178 12 239 182 13 +246 186 14 242 186 14 239 182 13 236 178 12 +224 166 10 206 145 10 192 133 9 154 121 60 + 94 94 94 62 62 62 42 42 42 22 22 22 + 14 14 14 6 6 6 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 18 18 18 34 34 34 58 58 58 78 78 78 +101 98 89 124 112 88 142 110 46 156 107 11 +163 110 8 167 114 7 175 118 6 180 123 7 +185 133 11 197 138 11 210 150 10 219 162 10 +226 170 11 236 178 12 236 178 12 234 174 13 +219 162 10 197 138 11 163 110 8 130 83 6 + 91 60 6 10 10 10 2 2 6 2 2 6 + 18 18 18 38 38 38 38 38 38 38 38 38 + 38 38 38 38 38 38 38 38 38 38 38 38 + 38 38 38 38 38 38 26 26 26 2 2 6 + 2 2 6 6 6 6 70 47 6 137 92 6 +175 118 6 200 144 11 219 162 10 230 174 11 +234 174 13 230 174 11 219 162 10 210 150 10 +192 133 9 163 110 8 124 112 88 82 82 82 + 50 50 50 30 30 30 14 14 14 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 14 14 14 22 22 22 34 34 34 + 42 42 42 58 58 58 74 74 74 86 86 86 +101 98 89 122 102 70 130 98 46 121 87 25 +137 92 6 152 99 6 163 110 8 180 123 7 +185 133 11 197 138 11 206 145 10 200 144 11 +180 123 7 156 107 11 130 83 6 104 69 6 + 50 34 6 54 54 54 110 110 110 101 98 89 + 86 86 86 82 82 82 78 78 78 78 78 78 + 78 78 78 78 78 78 78 78 78 78 78 78 + 78 78 78 82 82 82 86 86 86 94 94 94 +106 106 106 101 101 101 86 66 34 124 80 6 +156 107 11 180 123 7 192 133 9 200 144 11 +206 145 10 200 144 11 192 133 9 175 118 6 +139 102 15 109 106 95 70 70 70 42 42 42 + 22 22 22 10 10 10 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 6 6 6 10 10 10 + 14 14 14 22 22 22 30 30 30 38 38 38 + 50 50 50 62 62 62 74 74 74 90 90 90 +101 98 89 112 100 78 121 87 25 124 80 6 +137 92 6 152 99 6 152 99 6 152 99 6 +138 86 6 124 80 6 98 70 6 86 66 30 +101 98 89 82 82 82 58 58 58 46 46 46 + 38 38 38 34 34 34 34 34 34 34 34 34 + 34 34 34 34 34 34 34 34 34 34 34 34 + 34 34 34 34 34 34 38 38 38 42 42 42 + 54 54 54 82 82 82 94 86 76 91 60 6 +134 86 6 156 107 11 167 114 7 175 118 6 +175 118 6 167 114 7 152 99 6 121 87 25 +101 98 89 62 62 62 34 34 34 18 18 18 + 6 6 6 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 6 6 6 6 6 6 10 10 10 + 18 18 18 22 22 22 30 30 30 42 42 42 + 50 50 50 66 66 66 86 86 86 101 98 89 +106 86 58 98 70 6 104 69 6 104 69 6 +104 69 6 91 60 6 82 62 34 90 90 90 + 62 62 62 38 38 38 22 22 22 14 14 14 + 10 10 10 10 10 10 10 10 10 10 10 10 + 10 10 10 10 10 10 6 6 6 10 10 10 + 10 10 10 10 10 10 10 10 10 14 14 14 + 22 22 22 42 42 42 70 70 70 89 81 66 + 80 54 7 104 69 6 124 80 6 137 92 6 +134 86 6 116 81 8 100 82 52 86 86 86 + 58 58 58 30 30 30 14 14 14 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 6 6 6 10 10 10 14 14 14 + 18 18 18 26 26 26 38 38 38 54 54 54 + 70 70 70 86 86 86 94 86 76 89 81 66 + 89 81 66 86 86 86 74 74 74 50 50 50 + 30 30 30 14 14 14 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 18 18 18 34 34 34 58 58 58 + 82 82 82 89 81 66 89 81 66 89 81 66 + 94 86 66 94 86 76 74 74 74 50 50 50 + 26 26 26 14 14 14 6 6 6 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 6 6 6 6 6 6 14 14 14 18 18 18 + 30 30 30 38 38 38 46 46 46 54 54 54 + 50 50 50 42 42 42 30 30 30 18 18 18 + 10 10 10 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 6 6 6 14 14 14 26 26 26 + 38 38 38 50 50 50 58 58 58 58 58 58 + 54 54 54 42 42 42 30 30 30 18 18 18 + 10 10 10 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 6 6 6 10 10 10 14 14 14 18 18 18 + 18 18 18 14 14 14 10 10 10 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 6 6 6 + 14 14 14 18 18 18 22 22 22 22 22 22 + 18 18 18 14 14 14 10 10 10 6 6 6 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/trunk/drivers/video/logo/logo_linux_vga16.ppm b/trunk/drivers/video/logo/logo_linux_vga16.ppm index 12ac3a5454c0..1850c15e6feb 100644 --- a/trunk/drivers/video/logo/logo_linux_vga16.ppm +++ b/trunk/drivers/video/logo/logo_linux_vga16.ppm @@ -1,2739 +1,1604 @@ P3 -142 114 +# Standard 16-color Linux logo +80 80 255 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 -0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 170 170 170 170 85 0 170 170 170 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 -255 255 85 170 170 170 170 170 170 170 85 0 85 255 85 170 85 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 170 85 0 -170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 170 170 170 -170 170 170 170 85 0 170 170 170 170 170 170 170 85 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 255 85 -255 85 85 85 255 85 170 170 170 170 85 0 170 170 170 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 85 85 85 -170 170 170 170 85 0 170 170 170 85 85 85 170 85 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 -85 85 85 85 85 85 170 85 0 85 255 85 85 85 85 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 170 85 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 170 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -170 85 0 85 255 85 170 85 0 170 85 0 170 85 0 85 255 85 -170 85 0 170 85 0 0 170 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 170 85 0 -255 255 85 170 85 0 255 255 85 255 255 85 255 255 85 170 85 0 -255 255 85 85 255 85 170 85 0 170 85 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 -85 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 -255 255 85 170 85 0 255 255 85 85 255 85 170 85 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 170 85 0 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 -255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 85 255 85 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 -255 255 85 255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 -255 255 85 170 85 0 255 255 85 170 85 0 255 255 85 170 85 0 -170 85 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 170 85 0 255 255 85 85 255 85 255 255 85 -170 170 170 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 255 255 85 -85 255 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 255 255 85 -255 255 255 255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 -255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 255 255 85 -170 85 0 170 85 0 0 170 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 170 85 0 85 255 85 255 255 85 170 170 170 255 255 255 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 -255 255 85 85 255 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 255 255 85 255 255 85 255 255 85 255 255 255 255 255 85 -255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 85 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 -255 255 85 170 85 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -170 85 0 170 85 0 255 255 85 255 255 85 255 255 255 170 170 170 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -170 85 0 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 -255 255 85 85 255 85 170 85 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -255 255 85 85 255 85 255 255 85 170 170 170 255 255 255 255 255 85 -255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 85 255 85 170 85 0 -255 255 85 170 85 0 170 85 0 0 0 0 85 85 85 0 0 0 -85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170 -85 255 85 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 -170 85 0 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 85 255 85 255 255 85 170 85 0 170 85 0 -170 85 0 85 255 85 255 255 85 85 85 85 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 85 255 85 170 170 170 170 170 170 -85 85 85 170 170 170 170 170 170 170 85 0 170 170 170 170 170 170 -85 255 85 170 170 170 170 85 0 170 170 170 85 255 85 255 85 85 -85 255 85 170 170 170 255 255 85 85 85 85 255 255 85 170 170 170 -85 255 85 170 170 170 255 255 85 170 170 170 170 170 170 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 255 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 -255 255 85 255 255 85 255 255 85 170 85 0 0 170 0 85 85 85 -170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 85 255 85 -255 85 85 85 255 85 85 85 85 255 85 85 85 85 85 170 170 170 -170 85 0 170 170 170 85 85 85 85 255 85 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 -170 85 0 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 170 85 0 255 255 85 85 85 85 85 85 85 -255 255 85 170 170 170 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 85 85 85 170 170 170 170 85 0 170 170 170 -170 170 170 255 255 85 170 170 170 85 85 85 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 170 85 0 170 85 0 0 170 0 -0 0 0 170 85 0 170 85 0 0 170 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 85 85 85 170 170 170 85 85 85 -170 170 170 85 85 85 85 85 85 170 170 170 170 85 0 85 85 85 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 170 85 0 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 -255 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 -170 85 0 255 255 85 85 255 85 255 255 85 255 255 85 170 85 0 -170 85 0 255 255 85 170 85 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 255 255 85 -255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 -85 255 85 170 85 0 0 170 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 170 0 170 85 0 255 255 85 -85 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -170 85 0 255 255 85 85 255 85 255 255 85 255 255 85 170 85 0 -85 255 85 170 85 0 170 85 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 170 85 0 -255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 85 255 85 -170 85 0 170 85 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 170 85 0 -255 255 85 170 85 0 255 255 85 170 85 0 255 255 85 85 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 170 85 0 255 255 85 85 255 85 170 85 0 170 85 0 -0 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 85 255 85 -255 255 85 85 255 85 170 85 0 170 85 0 85 255 85 170 85 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 85 255 85 -255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 255 255 85 -255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 255 255 85 -170 85 0 170 85 0 85 255 85 170 85 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 255 255 85 -170 85 0 255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 -255 255 85 85 255 85 170 85 0 255 255 85 170 85 0 85 255 85 -170 85 0 170 85 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 170 170 170 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 85 85 85 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 85 255 85 -170 85 0 255 255 85 170 85 0 85 255 85 170 85 0 170 85 0 -0 170 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 170 170 170 170 170 170 255 255 255 170 170 170 -170 170 170 170 170 170 85 85 85 85 85 85 85 85 85 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 255 85 255 255 85 -170 85 0 255 255 85 255 255 85 170 85 0 85 255 85 170 85 0 -255 255 85 170 85 0 0 170 0 170 85 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 170 170 170 170 170 170 170 170 170 85 85 85 -85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 -255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 170 85 0 -0 170 0 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -255 255 85 255 255 85 170 85 0 0 170 0 85 85 85 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 85 85 85 -170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 170 85 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -170 170 170 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255 -255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 -170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 -255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 -255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 -255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 -255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 -255 255 255 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 -255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 -255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 255 255 255 -255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 -170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 -255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 -255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 -170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 170 170 170 -170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -170 170 170 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 -85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 170 170 170 85 85 85 -85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 170 170 170 85 85 85 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 170 170 170 170 170 170 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 170 170 170 85 85 85 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 255 255 255 170 170 170 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 -170 170 170 255 255 255 170 170 170 170 170 170 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 -255 255 255 255 255 255 170 170 170 170 170 170 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 255 255 255 -255 255 255 170 170 170 170 170 170 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -170 170 170 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 -170 170 170 170 170 170 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 -170 170 170 170 170 170 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 -170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 -170 170 170 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 170 170 170 -255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 -255 255 255 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 170 170 170 255 255 255 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 -255 255 255 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 170 170 170 255 255 255 170 170 170 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 -170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 255 255 255 255 255 255 255 255 255 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 -255 255 255 170 170 170 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 -170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 -170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -170 170 170 255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 255 255 255 -255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 -170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -170 170 170 255 255 255 255 255 255 255 255 255 85 85 85 0 0 0 -0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 -0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 255 255 255 -255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 -170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 -170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 -0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 -85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 255 255 255 -255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 -170 170 170 255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 170 170 170 85 85 85 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 -255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 -0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 255 255 255 -170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 85 85 85 -170 170 170 255 255 255 255 255 255 0 0 0 0 0 0 85 85 85 -255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255 -255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 255 255 255 170 170 170 170 170 170 170 170 170 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 170 170 170 255 255 255 170 170 170 170 170 170 85 85 85 -85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 170 170 170 -170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 -170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 170 170 170 -170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 -255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 170 170 170 170 170 170 255 255 85 85 85 85 -85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 -85 85 85 170 170 170 170 170 170 170 170 170 170 85 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 170 85 0 -170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -170 85 0 170 170 170 85 85 85 0 0 0 85 85 85 85 85 85 -170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 -170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 170 85 0 170 170 170 170 170 170 85 85 85 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 170 85 0 85 255 85 170 85 0 170 170 170 85 85 85 -85 85 85 0 0 0 0 0 0 85 85 85 170 85 0 85 255 85 -170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -85 85 85 85 85 85 170 85 0 0 0 0 85 85 85 85 85 85 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255 -255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 -170 170 170 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 170 170 170 170 85 0 170 170 170 170 85 0 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 255 85 85 170 170 170 85 255 85 170 85 0 -85 85 85 85 85 85 170 85 0 85 85 85 170 170 170 85 85 85 -170 170 170 170 85 0 85 85 85 85 85 85 85 85 85 85 85 85 -170 85 0 85 255 85 85 85 85 85 85 85 85 85 85 170 85 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 170 170 170 -255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 85 0 170 170 170 170 85 0 85 85 85 0 0 0 -85 85 85 85 85 85 85 255 85 170 170 170 170 170 170 170 85 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 85 255 85 255 85 85 170 170 170 170 170 170 -170 170 170 85 255 85 170 170 170 170 85 0 170 170 170 170 85 0 -170 170 170 85 85 85 85 255 85 170 85 0 170 170 170 170 85 0 -170 170 170 170 170 170 170 85 0 85 85 85 85 85 85 85 255 85 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 170 170 170 170 170 170 0 0 0 0 0 0 85 85 85 -170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 255 255 85 85 85 85 85 85 85 85 85 85 -85 255 85 255 85 85 170 170 170 170 85 0 170 170 170 85 255 85 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 170 85 0 170 170 170 170 170 170 255 255 85 -170 170 170 255 85 85 170 170 170 170 170 170 255 255 85 170 170 170 -85 255 85 170 170 170 255 85 85 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 170 85 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 170 170 170 85 85 85 0 0 0 85 85 85 -85 85 85 170 85 0 85 85 85 0 0 0 85 85 85 85 85 85 -85 85 85 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 -170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 85 85 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 170 170 170 255 255 85 170 170 170 170 170 170 -170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 85 0 -170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 255 255 85 -170 170 170 255 255 85 170 170 170 170 170 170 85 255 85 170 85 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 170 170 170 85 85 85 85 85 85 0 0 0 -85 85 85 85 85 85 170 170 170 85 85 85 170 170 170 170 85 0 -170 170 170 85 255 85 170 170 170 170 85 0 170 170 170 170 170 170 -255 255 85 170 170 170 170 170 170 255 255 255 255 255 85 170 170 170 -255 255 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 255 255 255 -170 170 170 255 255 255 255 255 85 170 170 170 255 255 85 170 170 170 -255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 255 85 85 170 170 170 170 170 170 -85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 85 85 85 -85 85 85 255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 -255 255 85 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 -170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 -170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 255 85 170 170 170 255 255 85 255 255 255 255 255 255 -255 255 255 170 170 170 255 255 255 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 255 255 85 170 170 170 255 255 85 255 255 255 -255 255 85 255 255 255 255 255 85 170 170 170 170 170 170 170 85 0 -170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 -170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 255 255 85 -255 255 255 255 255 255 255 255 85 255 255 255 255 255 255 170 170 170 -255 255 85 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 170 170 170 170 170 170 170 170 170 255 255 255 170 170 170 -255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 255 255 85 -170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 -255 255 255 255 255 255 170 170 170 255 255 85 170 170 170 255 255 85 -85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 170 170 170 -255 255 85 170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 -170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 -255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 -170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 -85 85 85 170 85 0 255 255 255 170 170 170 255 255 255 255 255 255 -255 255 85 255 255 255 170 170 170 255 255 85 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 255 255 85 255 255 255 255 255 255 -170 170 170 255 255 255 255 255 255 170 170 170 170 170 170 170 170 170 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 255 85 170 170 170 -170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 -255 255 255 255 255 255 255 255 85 170 170 170 170 170 170 255 255 255 -170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 255 255 85 -170 170 170 170 85 0 85 85 85 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 170 170 170 170 170 170 255 255 85 170 170 170 255 255 255 -255 255 255 170 170 170 255 255 255 170 170 170 170 170 170 255 255 85 -170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 -255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 255 255 85 -85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 170 170 170 -170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 -170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 -255 255 85 255 255 255 170 170 170 255 255 255 170 170 170 170 170 170 -170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 85 85 85 -0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -85 85 85 85 85 85 170 170 170 170 170 170 255 255 255 170 170 170 -255 255 255 170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 -255 85 85 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255 -170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 170 170 170 -255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 -255 255 85 255 255 255 170 170 170 255 255 85 170 170 170 170 170 170 -170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 255 85 -170 170 170 170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 -170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 170 170 170 255 255 85 170 170 170 170 170 170 -255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 255 85 85 -85 255 85 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 -255 255 255 255 255 255 255 255 255 255 255 85 170 170 170 170 170 170 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 -170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 -255 255 255 170 170 170 170 170 170 170 170 170 170 170 170 255 85 85 -170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 -170 170 170 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 -85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 170 170 170 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 85 255 85 -255 85 85 170 170 170 255 255 85 170 170 170 170 170 170 255 255 255 -255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 170 170 170 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 -170 170 170 255 255 85 170 170 170 255 255 85 255 255 255 255 255 255 -170 170 170 170 170 170 255 255 85 170 170 170 255 85 85 85 255 85 -170 170 170 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 -170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 85 85 85 85 85 85 85 85 85 170 170 170 255 255 85 -170 170 170 170 85 0 170 170 170 170 170 170 170 85 0 85 85 85 -170 170 170 170 85 0 85 85 85 170 170 170 170 170 170 170 170 170 -170 170 170 255 255 255 255 255 255 255 255 85 170 170 170 170 170 170 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 -170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 -255 255 255 170 170 170 170 170 170 170 85 0 170 170 170 85 85 85 -170 170 170 170 170 170 170 85 0 170 170 170 170 85 0 85 85 85 -85 255 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 85 85 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170 -170 85 0 170 170 170 85 255 85 170 85 0 170 170 170 85 85 85 -170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 255 255 255 -255 255 85 255 255 255 170 170 170 170 170 170 170 170 170 170 85 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 -170 170 170 255 255 85 170 170 170 170 170 170 85 255 85 170 170 170 -170 85 0 170 85 0 170 170 170 85 255 85 85 85 85 170 170 170 -170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 85 85 85 -0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 -170 170 170 170 85 0 170 170 170 85 85 85 170 170 170 170 85 0 -170 170 170 85 255 85 170 85 0 170 170 170 170 170 170 170 170 170 -255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -170 85 0 170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 -170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 170 85 0 -170 170 170 85 255 85 170 85 0 170 170 170 170 85 0 85 85 85 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -85 255 85 170 170 170 170 85 0 170 170 170 170 85 0 85 255 85 -170 170 170 170 85 0 170 170 170 170 170 170 170 170 170 255 255 85 -170 170 170 255 255 255 170 170 170 170 170 170 170 170 170 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 85 0 85 85 85 170 170 170 255 255 85 170 170 170 -170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 85 0 -170 170 170 85 85 85 170 170 170 170 85 0 170 170 170 85 85 85 -170 85 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 170 85 0 -85 85 85 255 85 85 85 255 85 170 85 0 170 170 170 170 170 170 -170 85 0 170 170 170 85 85 85 255 255 85 170 170 170 170 170 170 -255 255 255 170 170 170 255 255 255 255 255 85 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 170 170 170 170 85 0 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 255 255 85 85 85 85 170 170 170 -85 255 85 255 85 85 170 170 170 85 255 85 255 85 85 85 255 85 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 -85 85 85 85 255 85 255 85 85 170 170 170 85 255 85 170 85 0 -170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 255 255 -170 170 170 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 170 170 170 85 85 85 255 255 85 -170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 255 255 85 -85 85 85 255 255 85 170 170 170 170 85 0 170 170 170 85 85 85 -170 85 0 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -170 170 170 170 85 0 170 170 170 170 85 0 170 170 170 170 170 170 -170 85 0 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 -255 255 85 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170 -170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 170 85 0 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -170 85 0 85 255 85 170 170 170 170 170 170 255 255 85 170 170 170 -255 255 85 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255 -255 255 255 170 170 170 255 255 85 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 -170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 -170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 -170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 170 85 0 170 170 170 170 85 0 170 170 170 170 170 170 -170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 255 255 255 -170 170 170 255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 -170 85 0 170 170 170 170 85 0 255 255 85 170 170 170 170 170 170 -170 170 170 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 -255 255 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 -170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 -170 170 170 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 85 85 85 -170 85 0 85 255 85 170 170 170 170 170 170 170 170 170 255 255 85 -255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 -170 170 170 255 255 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -170 85 0 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 -170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 -255 255 255 255 255 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 -170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 -170 170 170 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 255 85 -170 170 170 255 255 85 170 170 170 255 255 85 255 255 255 255 255 255 -255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 -170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 85 85 85 170 85 0 170 170 170 170 170 170 -255 255 85 170 170 170 255 255 255 255 255 85 255 255 255 255 255 255 -170 170 170 255 255 85 170 170 170 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 -170 170 170 170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 -170 170 170 255 255 255 170 170 170 255 255 255 255 255 85 255 255 255 -170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 170 85 0 85 85 85 170 170 170 170 170 170 170 170 170 -170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 -255 255 85 170 170 170 170 170 170 170 85 0 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 -255 255 85 170 170 170 255 255 85 170 170 170 255 255 255 255 255 255 -255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 -170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 85 85 85 170 85 0 170 170 170 -255 255 85 170 170 170 255 255 85 255 255 255 170 170 170 255 255 255 -170 170 170 170 170 170 170 170 170 170 170 170 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 -170 85 0 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 -255 255 255 255 255 255 170 170 170 255 255 255 255 255 85 170 170 170 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170 -170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 -255 255 85 170 170 170 170 85 0 85 255 85 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 -170 170 170 170 170 170 255 255 85 170 170 170 255 255 255 255 255 255 -255 255 85 255 255 255 170 170 170 255 255 255 170 170 170 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 -170 170 170 170 170 170 170 170 170 170 85 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -255 255 85 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 -255 255 255 170 170 170 255 255 85 170 170 170 85 85 85 85 85 85 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 170 170 170 -170 85 0 170 170 170 170 85 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 -170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 -170 170 170 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -85 85 85 85 85 85 85 85 85 170 85 0 85 85 85 170 85 0 -85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 -85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 255 255 85 -170 170 170 170 170 170 170 85 0 85 85 85 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 -85 85 85 85 255 85 170 85 0 170 170 170 170 85 0 170 170 170 -85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 -85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 85 85 85 85 85 85 85 85 85 + 85 85 85 85 85 85 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 85 85 85 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 85 85 85 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 170 170 170 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 +170 170 170 170 170 170 85 85 85 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 85 85 85 170 170 170 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 170 170 170 170 170 +170 170 170 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 85 85 85 170 170 170 170 170 170 170 170 170 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 170 170 170 255 255 255 255 255 255 +255 255 255 170 170 170 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 85 85 85 +170 170 170 170 170 170 255 255 255 255 255 255 + 0 0 0 0 0 0 0 0 0 0 0 0 +170 170 170 255 255 255 170 170 170 170 170 170 +255 255 255 170 170 170 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 85 85 85 +170 170 170 0 0 0 0 0 0 255 255 255 + 85 85 85 0 0 0 0 0 0 0 0 0 +255 255 255 170 170 170 0 0 0 85 85 85 +170 170 170 255 255 255 170 170 170 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 85 85 85 + 85 85 85 0 0 0 0 0 0 170 170 170 + 85 85 85 0 0 0 0 0 0 0 0 0 +255 255 255 85 85 85 0 0 0 0 0 0 + 85 85 85 255 255 255 170 170 170 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 85 85 85 +170 170 170 0 0 0 0 0 0 170 170 170 + 85 85 85 85 85 85 85 85 85 85 85 85 +255 255 255 85 85 85 0 0 0 0 0 0 + 85 85 85 255 255 255 170 170 170 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 +255 255 255 0 0 0 0 0 0 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 0 0 0 0 0 0 + 85 85 85 255 255 255 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 +170 170 170 170 170 170 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 170 170 170 170 170 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 85 85 85 0 0 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 170 85 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 85 85 85 0 0 0 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 170 85 0 +170 85 0 170 85 0 85 85 85 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 85 85 85 0 0 0 + 85 85 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 85 85 85 0 0 0 + 0 0 0 85 85 85 170 170 170 85 85 85 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 85 85 85 0 0 0 + 85 85 85 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 170 170 170 170 170 170 170 170 0 0 0 + 0 0 0 0 0 0 170 170 170 170 170 170 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 85 85 85 170 170 170 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 85 85 85 + 0 0 0 0 0 0 85 85 85 85 85 85 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 85 85 85 170 170 170 170 170 170 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 170 170 170 170 170 170 170 170 170 170 170 +255 255 255 255 255 255 255 255 255 170 170 170 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 85 85 85 +255 255 255 255 255 255 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 170 170 170 +255 255 255 255 255 255 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +170 170 170 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 85 85 85 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 85 85 85 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 85 85 85 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 85 85 85 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 85 85 85 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 170 170 170 170 170 170 170 170 170 +255 255 255 255 255 255 255 255 255 170 170 170 +170 170 170 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 +170 170 170 170 170 170 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +170 170 170 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 85 85 85 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 +170 170 170 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 170 170 170 170 170 170 + 0 0 0 0 0 0 0 0 0 85 85 85 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 85 85 85 0 0 0 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 170 170 170 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 170 170 170 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +170 170 170 85 85 85 0 0 0 0 0 0 + 0 0 0 85 85 85 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 85 85 85 + 0 0 0 0 0 0 85 85 85 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 0 0 0 85 85 85 + 85 85 85 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 85 85 85 + 0 0 0 85 85 85 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 0 0 0 85 85 85 + 85 85 85 0 0 0 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 85 85 85 + 0 0 0 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 85 85 85 0 0 0 + 0 0 0 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 85 85 85 0 0 0 + 85 85 85 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 85 85 85 0 0 0 0 0 0 +170 170 170 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 0 0 0 + 85 85 85 85 85 85 85 85 85 85 85 85 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 0 0 0 170 85 0 +255 255 85 170 85 0 0 0 0 0 0 0 + 85 85 85 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 85 85 85 85 85 85 0 0 0 + 0 0 0 85 85 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 0 0 0 + 0 0 0 85 85 85 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 85 170 85 0 255 255 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 85 85 85 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 + 0 0 0 0 0 0 85 85 85 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 85 +170 85 0 255 255 85 170 85 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 +170 85 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 0 0 0 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 85 0 +255 255 85 170 85 0 255 255 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 170 85 0 +255 255 85 170 85 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 0 0 0 0 0 0 0 0 0 + 85 85 85 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 85 +170 85 0 255 255 85 170 85 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 255 255 85 +170 85 0 255 255 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 0 0 0 0 0 0 + 0 0 0 85 85 85 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 255 255 85 170 85 0 +255 255 85 170 85 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 0 0 0 + 0 0 0 0 0 0 85 85 85 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 170 170 170 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 170 170 170 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 170 170 170 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 0 0 0 0 0 0 0 0 0 + 0 0 0 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 170 170 170 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 0 0 0 0 0 0 0 0 0 + 85 85 85 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 85 85 85 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 85 85 85 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +170 170 170 85 85 85 85 85 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 + 85 85 85 0 0 0 0 0 0 170 85 0 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 85 85 85 + 0 0 0 0 0 0 0 0 0 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +170 170 170 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +170 170 170 85 85 85 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 170 85 0 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 170 85 0 +170 85 0 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 85 85 85 + 85 85 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +170 85 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 170 85 0 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 170 85 0 170 85 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 170 85 0 +170 85 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +170 85 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +170 85 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 85 85 85 170 85 0 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 170 85 0 170 85 0 170 85 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 170 85 0 +170 85 0 0 0 0 0 0 0 0 0 0 + 85 85 85 85 85 85 85 85 85 85 85 85 + 85 85 85 85 85 85 85 85 85 85 85 85 + 85 85 85 85 85 85 85 85 85 0 0 0 + 0 0 0 0 0 0 0 0 0 170 85 0 +170 85 0 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 255 255 85 170 85 0 +170 85 0 170 85 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 255 255 85 170 85 0 +255 255 85 170 85 0 170 85 0 170 85 0 + 85 85 85 85 85 85 85 85 85 85 85 85 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 85 85 85 + 85 85 85 85 85 85 85 85 85 170 85 0 +170 85 0 170 85 0 170 85 0 255 255 85 +170 85 0 255 255 85 170 85 0 170 85 0 +170 85 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 170 85 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 +170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 76da12537956..8fa77e233944 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -443,7 +443,7 @@ static struct kiocb *__aio_get_req(struct kioctx *ctx) req->private = NULL; req->ki_iovec = NULL; INIT_LIST_HEAD(&req->ki_run_list); - req->ki_eventfd = NULL; + req->ki_eventfd = ERR_PTR(-EINVAL); /* Check if the completion queue has enough free space to * accept an event from this io. @@ -485,6 +485,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) { assert_spin_locked(&ctx->ctx_lock); + if (!IS_ERR(req->ki_eventfd)) + fput(req->ki_eventfd); if (req->ki_dtor) req->ki_dtor(req); if (req->ki_iovec != &req->ki_inline_vec) @@ -506,11 +508,8 @@ static void aio_fput_routine(struct work_struct *data) list_del(&req->ki_list); spin_unlock_irq(&fput_lock); - /* Complete the fput(s) */ - if (req->ki_filp != NULL) - __fput(req->ki_filp); - if (req->ki_eventfd != NULL) - __fput(req->ki_eventfd); + /* Complete the fput */ + __fput(req->ki_filp); /* Link the iocb into the context's free list */ spin_lock_irq(&ctx->ctx_lock); @@ -528,14 +527,12 @@ static void aio_fput_routine(struct work_struct *data) */ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) { - int schedule_putreq = 0; - dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n", req, atomic_long_read(&req->ki_filp->f_count)); assert_spin_locked(&ctx->ctx_lock); - req->ki_users--; + req->ki_users --; BUG_ON(req->ki_users < 0); if (likely(req->ki_users)) return 0; @@ -543,23 +540,10 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) req->ki_cancel = NULL; req->ki_retry = NULL; - /* - * Try to optimize the aio and eventfd file* puts, by avoiding to - * schedule work in case it is not __fput() time. In normal cases, - * we would not be holding the last reference to the file*, so - * this function will be executed w/out any aio kthread wakeup. + /* Must be done under the lock to serialise against cancellation. + * Call this aio_fput as it duplicates fput via the fput_work. */ - if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) - schedule_putreq++; - else - req->ki_filp = NULL; - if (req->ki_eventfd != NULL) { - if (unlikely(atomic_long_dec_and_test(&req->ki_eventfd->f_count))) - schedule_putreq++; - else - req->ki_eventfd = NULL; - } - if (unlikely(schedule_putreq)) { + if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) { get_ioctx(ctx); spin_lock(&fput_lock); list_add(&req->ki_list, &fput_head); @@ -587,7 +571,7 @@ int aio_put_req(struct kiocb *req) static struct kioctx *lookup_ioctx(unsigned long ctx_id) { struct mm_struct *mm = current->mm; - struct kioctx *ctx, *ret = NULL; + struct kioctx *ctx = NULL; struct hlist_node *n; rcu_read_lock(); @@ -595,13 +579,12 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id) hlist_for_each_entry_rcu(ctx, n, &mm->ioctx_list, list) { if (ctx->user_id == ctx_id && !ctx->dead) { get_ioctx(ctx); - ret = ctx; break; } } rcu_read_unlock(); - return ret; + return ctx; } /* @@ -1026,7 +1009,7 @@ int aio_complete(struct kiocb *iocb, long res, long res2) * eventfd. The eventfd_signal() function is safe to be called * from IRQ context. */ - if (iocb->ki_eventfd != NULL) + if (!IS_ERR(iocb->ki_eventfd)) eventfd_signal(iocb->ki_eventfd, 1); put_rq: @@ -1625,7 +1608,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd); if (IS_ERR(req->ki_eventfd)) { ret = PTR_ERR(req->ki_eventfd); - req->ki_eventfd = NULL; goto out_put_req; } } diff --git a/trunk/fs/bio-integrity.c b/trunk/fs/bio-integrity.c index fe2b1aa2464e..549b0144da11 100644 --- a/trunk/fs/bio-integrity.c +++ b/trunk/fs/bio-integrity.c @@ -685,20 +685,19 @@ EXPORT_SYMBOL(bio_integrity_split); * bio_integrity_clone - Callback for cloning bios with integrity metadata * @bio: New bio * @bio_src: Original bio - * @gfp_mask: Memory allocation mask * @bs: bio_set to allocate bip from * * Description: Called to allocate a bip when cloning a bio */ int bio_integrity_clone(struct bio *bio, struct bio *bio_src, - gfp_t gfp_mask, struct bio_set *bs) + struct bio_set *bs) { struct bio_integrity_payload *bip_src = bio_src->bi_integrity; struct bio_integrity_payload *bip; BUG_ON(bip_src == NULL); - bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs); + bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs); if (bip == NULL) return -EIO; diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index d4f06327c810..124b95c4d582 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -463,12 +463,10 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) if (bio_integrity(bio)) { int ret; - ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set); + ret = bio_integrity_clone(b, bio, fs_bio_set); - if (ret < 0) { - bio_put(b); + if (ret < 0) return NULL; - } } return b; diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 5e1d4e30e9d8..82491ba8fa40 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -784,14 +784,7 @@ struct btrfs_fs_info { struct list_head dirty_cowonly_roots; struct btrfs_fs_devices *fs_devices; - - /* - * the space_info list is almost entirely read only. It only changes - * when we add a new raid type to the FS, and that happens - * very rarely. RCU is used to protect it. - */ struct list_head space_info; - spinlock_t delalloc_lock; spinlock_t new_trans_lock; u64 delalloc_bytes; @@ -1804,8 +1797,6 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root); int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); -void btrfs_clear_space_info_full(struct btrfs_fs_info *info); - int btrfs_check_metadata_free_space(struct btrfs_root *root); int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, u64 bytes); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index fefe83ad2059..9abf81f71c46 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "compat.h" #include "hash.h" #include "crc32c.h" @@ -331,33 +330,13 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, { struct list_head *head = &info->space_info; struct btrfs_space_info *found; - - rcu_read_lock(); - list_for_each_entry_rcu(found, head, list) { - if (found->flags == flags) { - rcu_read_unlock(); + list_for_each_entry(found, head, list) { + if (found->flags == flags) return found; - } } - rcu_read_unlock(); return NULL; } -/* - * after adding space to the filesystem, we need to clear the full flags - * on all the space infos. - */ -void btrfs_clear_space_info_full(struct btrfs_fs_info *info) -{ - struct list_head *head = &info->space_info; - struct btrfs_space_info *found; - - rcu_read_lock(); - list_for_each_entry_rcu(found, head, list) - found->full = 0; - rcu_read_unlock(); -} - static u64 div_factor(u64 num, int factor) { if (factor == 10) @@ -1924,6 +1903,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, if (!found) return -ENOMEM; + list_add(&found->list, &info->space_info); INIT_LIST_HEAD(&found->block_groups); init_rwsem(&found->groups_sem); spin_lock_init(&found->lock); @@ -1937,7 +1917,6 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, found->full = 0; found->force_alloc = 0; *space_info = found; - list_add_rcu(&found->list, &info->space_info); return 0; } @@ -6341,7 +6320,6 @@ static int find_first_block_group(struct btrfs_root *root, int btrfs_free_block_groups(struct btrfs_fs_info *info) { struct btrfs_block_group_cache *block_group; - struct btrfs_space_info *space_info; struct rb_node *n; spin_lock(&info->block_group_cache_lock); @@ -6363,23 +6341,6 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) spin_lock(&info->block_group_cache_lock); } spin_unlock(&info->block_group_cache_lock); - - /* now that all the block groups are freed, go through and - * free all the space_info structs. This is only called during - * the final stages of unmount, and so we know nobody is - * using them. We call synchronize_rcu() once before we start, - * just to be on the safe side. - */ - synchronize_rcu(); - - while(!list_empty(&info->space_info)) { - space_info = list_entry(info->space_info.next, - struct btrfs_space_info, - list); - - list_del(&space_info->list); - kfree(space_info); - } return 0; } diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index dd06e18e5aac..1316139bf9e8 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -1374,12 +1374,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) ret = btrfs_add_device(trans, root, device); } - /* - * we've got more storage, clear any full flags on the space - * infos - */ - btrfs_clear_space_info_full(root->fs_info); - unlock_chunks(root); btrfs_commit_transaction(trans, root); @@ -1465,8 +1459,6 @@ static int __btrfs_grow_device(struct btrfs_trans_handle *trans, device->fs_devices->total_rw_bytes += diff; device->total_bytes = new_size; - btrfs_clear_space_info_full(device->dev_root->fs_info); - return btrfs_update_device(trans, device); } diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 891e1c78e4f1..9f697419ed8e 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -760,9 +760,15 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode); * If warn is true, then emit a warning if the page is not uptodate and has * not been truncated. */ -static void __set_page_dirty(struct page *page, +static int __set_page_dirty(struct page *page, struct address_space *mapping, int warn) { + if (unlikely(!mapping)) + return !TestSetPageDirty(page); + + if (TestSetPageDirty(page)) + return 0; + spin_lock_irq(&mapping->tree_lock); if (page->mapping) { /* Race with truncate? */ WARN_ON_ONCE(warn && !PageUptodate(page)); @@ -779,6 +785,8 @@ static void __set_page_dirty(struct page *page, } spin_unlock_irq(&mapping->tree_lock); __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); + + return 1; } /* @@ -808,7 +816,6 @@ static void __set_page_dirty(struct page *page, */ int __set_page_dirty_buffers(struct page *page) { - int newly_dirty; struct address_space *mapping = page_mapping(page); if (unlikely(!mapping)) @@ -824,12 +831,9 @@ int __set_page_dirty_buffers(struct page *page) bh = bh->b_this_page; } while (bh != head); } - newly_dirty = !TestSetPageDirty(page); spin_unlock(&mapping->private_lock); - if (newly_dirty) - __set_page_dirty(page, mapping, 1); - return newly_dirty; + return __set_page_dirty(page, mapping, 1); } EXPORT_SYMBOL(__set_page_dirty_buffers); @@ -1258,11 +1262,8 @@ void mark_buffer_dirty(struct buffer_head *bh) return; } - if (!test_set_buffer_dirty(bh)) { - struct page *page = bh->b_page; - if (!TestSetPageDirty(page)) - __set_page_dirty(page, page_mapping(page), 0); - } + if (!test_set_buffer_dirty(bh)) + __set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0); } /* diff --git a/trunk/fs/ecryptfs/crypto.c b/trunk/fs/ecryptfs/crypto.c index 8b65f289ee00..f6caeb1d1106 100644 --- a/trunk/fs/ecryptfs/crypto.c +++ b/trunk/fs/ecryptfs/crypto.c @@ -946,8 +946,6 @@ static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs( list_for_each_entry(global_auth_tok, &mount_crypt_stat->global_auth_tok_list, mount_crypt_stat_list) { - if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_FNEK) - continue; rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig); if (rc) { printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc); @@ -1324,13 +1322,14 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max, } static int -ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry, - char *virt, size_t virt_len) +ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, + struct dentry *ecryptfs_dentry, + char *virt) { int rc; rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, - 0, virt_len); + 0, crypt_stat->num_header_bytes_at_front); if (rc) printk(KERN_ERR "%s: Error attempting to write header " "information to lower file; rc = [%d]\n", __func__, @@ -1340,6 +1339,7 @@ ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry, static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, + struct ecryptfs_crypt_stat *crypt_stat, char *page_virt, size_t size) { int rc; @@ -1349,17 +1349,6 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, return rc; } -static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask, - unsigned int order) -{ - struct page *page; - - page = alloc_pages(gfp_mask | __GFP_ZERO, order); - if (page) - return (unsigned long) page_address(page); - return 0; -} - /** * ecryptfs_write_metadata * @ecryptfs_dentry: The eCryptfs dentry @@ -1376,9 +1365,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) { struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; - unsigned int order; char *virt; - size_t virt_len; size_t size = 0; int rc = 0; @@ -1394,35 +1381,33 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) rc = -EINVAL; goto out; } - virt_len = crypt_stat->num_header_bytes_at_front; - order = get_order(virt_len); /* Released in this function */ - virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); + virt = (char *)get_zeroed_page(GFP_KERNEL); if (!virt) { printk(KERN_ERR "%s: Out of memory\n", __func__); rc = -ENOMEM; goto out; } - rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat, - ecryptfs_dentry); + rc = ecryptfs_write_headers_virt(virt, PAGE_CACHE_SIZE, &size, + crypt_stat, ecryptfs_dentry); if (unlikely(rc)) { printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", __func__, rc); goto out_free; } if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) - rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt, - size); + rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, + crypt_stat, virt, size); else - rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt, - virt_len); + rc = ecryptfs_write_metadata_to_contents(crypt_stat, + ecryptfs_dentry, virt); if (rc) { printk(KERN_ERR "%s: Error writing metadata out to lower file; " "rc = [%d]\n", __func__, rc); goto out_free; } out_free: - free_pages((unsigned long)virt, order); + free_page((unsigned long)virt); out: return rc; } @@ -2221,19 +2206,17 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, struct dentry *ecryptfs_dir_dentry, const char *name, size_t name_size) { - struct ecryptfs_mount_crypt_stat *mount_crypt_stat = - &ecryptfs_superblock_to_private( - ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; char *decoded_name; size_t decoded_name_size; size_t packet_size; int rc = 0; - if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) - && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) - && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) + if ((name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) { + struct ecryptfs_mount_crypt_stat *mount_crypt_stat = + &ecryptfs_superblock_to_private( + ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; const char *orig_name = name; size_t orig_name_size = name_size; diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index ac749d4d644f..c11fc95714ab 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -328,7 +328,6 @@ struct ecryptfs_dentry_info { */ struct ecryptfs_global_auth_tok { #define ECRYPTFS_AUTH_TOK_INVALID 0x00000001 -#define ECRYPTFS_AUTH_TOK_FNEK 0x00000002 u32 flags; struct list_head mount_crypt_stat_list; struct key *global_auth_tok_key; @@ -620,6 +619,7 @@ int ecryptfs_interpose(struct dentry *hidden_dentry, u32 flags); int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, struct dentry *lower_dentry, + struct ecryptfs_crypt_stat *crypt_stat, struct inode *ecryptfs_dir_inode, struct nameidata *ecryptfs_nd); int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, @@ -696,7 +696,7 @@ ecryptfs_write_header_metadata(char *virt, int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); int ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, - char *sig, u32 global_auth_tok_flags); + char *sig); int ecryptfs_get_global_auth_tok_for_sig( struct ecryptfs_global_auth_tok **global_auth_tok, struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 55b3145b8072..5697899a168d 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -246,6 +246,7 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, */ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, struct dentry *lower_dentry, + struct ecryptfs_crypt_stat *crypt_stat, struct inode *ecryptfs_dir_inode, struct nameidata *ecryptfs_nd) { @@ -253,7 +254,6 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, struct vfsmount *lower_mnt; struct inode *lower_inode; struct ecryptfs_mount_crypt_stat *mount_crypt_stat; - struct ecryptfs_crypt_stat *crypt_stat; char *page_virt = NULL; u64 file_size; int rc = 0; @@ -314,11 +314,6 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, goto out_free_kmem; } } - crypt_stat = &ecryptfs_inode_to_private( - ecryptfs_dentry->d_inode)->crypt_stat; - /* TODO: lock for crypt_stat comparison */ - if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) - ecryptfs_set_default_sizes(crypt_stat); rc = ecryptfs_read_and_validate_header_region(page_virt, ecryptfs_dentry->d_inode); if (rc) { @@ -367,7 +362,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, { char *encrypted_and_encoded_name = NULL; size_t encrypted_and_encoded_name_size; + struct ecryptfs_crypt_stat *crypt_stat = NULL; struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; + struct ecryptfs_inode_info *inode_info; struct dentry *lower_dir_dentry, *lower_dentry; int rc = 0; @@ -391,15 +388,26 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, } if (lower_dentry->d_inode) goto lookup_and_interpose; - mount_crypt_stat = &ecryptfs_superblock_to_private( - ecryptfs_dentry->d_sb)->mount_crypt_stat; - if (!(mount_crypt_stat - && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) + inode_info = ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); + if (inode_info) { + crypt_stat = &inode_info->crypt_stat; + /* TODO: lock for crypt_stat comparison */ + if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) + ecryptfs_set_default_sizes(crypt_stat); + } + if (crypt_stat) + mount_crypt_stat = crypt_stat->mount_crypt_stat; + else + mount_crypt_stat = &ecryptfs_superblock_to_private( + ecryptfs_dentry->d_sb)->mount_crypt_stat; + if (!(crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCRYPT_FILENAMES)) + && !(mount_crypt_stat && (mount_crypt_stat->flags + & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) goto lookup_and_interpose; dput(lower_dentry); rc = ecryptfs_encrypt_and_encode_filename( &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, - NULL, mount_crypt_stat, ecryptfs_dentry->d_name.name, + crypt_stat, mount_crypt_stat, ecryptfs_dentry->d_name.name, ecryptfs_dentry->d_name.len); if (rc) { printk(KERN_ERR "%s: Error attempting to encrypt and encode " @@ -418,7 +426,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, } lookup_and_interpose: rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, - ecryptfs_dir_inode, + crypt_stat, ecryptfs_dir_inode, ecryptfs_nd); goto out; out_d_drop: diff --git a/trunk/fs/ecryptfs/keystore.c b/trunk/fs/ecryptfs/keystore.c index e4a6223c3145..ff539420cc6f 100644 --- a/trunk/fs/ecryptfs/keystore.c +++ b/trunk/fs/ecryptfs/keystore.c @@ -2375,7 +2375,7 @@ struct kmem_cache *ecryptfs_global_auth_tok_cache; int ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, - char *sig, u32 global_auth_tok_flags) + char *sig) { struct ecryptfs_global_auth_tok *new_auth_tok; int rc = 0; @@ -2389,7 +2389,6 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, goto out; } memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); - new_auth_tok->flags = global_auth_tok_flags; new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); list_add(&new_auth_tok->mount_crypt_stat_list, diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index aed56c25539b..789cf2e1be1e 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -319,7 +319,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) case ecryptfs_opt_ecryptfs_sig: sig_src = args[0].from; rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, - sig_src, 0); + sig_src); if (rc) { printk(KERN_ERR "Error attempting to register " "global sig; rc = [%d]\n", rc); @@ -370,8 +370,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) ECRYPTFS_SIG_SIZE_HEX] = '\0'; rc = ecryptfs_add_global_auth_tok( mount_crypt_stat, - mount_crypt_stat->global_default_fnek_sig, - ECRYPTFS_AUTH_TOK_FNEK); + mount_crypt_stat->global_default_fnek_sig); if (rc) { printk(KERN_ERR "Error attempting to register " "global fnek sig [%s]; rc = [%d]\n", diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index e0aa4fe4f596..e2eab196875f 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -1122,8 +1122,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path, struct ext4_extent_idx *ix; struct ext4_extent *ex; ext4_fsblk_t block; - int depth; /* Note, NOT eh_depth; depth from top of tree */ - int ee_len; + int depth, ee_len; BUG_ON(path == NULL); depth = path->p_depth; @@ -1180,8 +1179,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path, if (bh == NULL) return -EIO; eh = ext_block_hdr(bh); - /* subtract from p_depth to get proper eh_depth */ - if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) { + if (ext4_ext_check_header(inode, eh, depth)) { put_bh(bh); return -EIO; } diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c index 2d2b3585ee91..627f8c3337a3 100644 --- a/trunk/fs/ext4/ialloc.c +++ b/trunk/fs/ext4/ialloc.c @@ -698,7 +698,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) struct inode *ret; ext4_group_t i; int free = 0; - static int once = 1; ext4_group_t flex_group; /* Cannot create files in a deleted directory */ @@ -720,8 +719,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) ret2 = find_group_flex(sb, dir, &group); if (ret2 == -1) { ret2 = find_group_other(sb, dir, &group); - if (ret2 == 0 && once) - once = 0; + if (ret2 == 0 && printk_ratelimit()) printk(KERN_NOTICE "ext4: find_group_flex " "failed, fallback succeeded dir %lu\n", dir->i_ino); diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index 9f61e62f435f..4415beeb0b62 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -1447,7 +1447,7 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac, struct ext4_free_extent *gex = &ac->ac_g_ex; BUG_ON(ex->fe_len <= 0); - BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); + BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); BUG_ON(ac->ac_status != AC_STATUS_CONTINUE); @@ -3292,7 +3292,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, } BUG_ON(start + size <= ac->ac_o_ex.fe_logical && start > ac->ac_o_ex.fe_logical); - BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); + BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); /* now prepare goal request */ @@ -3589,7 +3589,6 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, struct super_block *sb, struct ext4_prealloc_space *pa) { ext4_group_t grp; - ext4_fsblk_t grp_blk; if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) return; @@ -3604,12 +3603,8 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, pa->pa_deleted = 1; spin_unlock(&pa->pa_lock); - grp_blk = pa->pa_pstart; - /* If linear, pa_pstart may be in the next group when pa is used up */ - if (pa->pa_linear) - grp_blk--; - - ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL); + /* -1 is to protect from crossing allocation group */ + ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL); /* * possible race: diff --git a/trunk/fs/lockd/clntlock.c b/trunk/fs/lockd/clntlock.c index aedc47a264c1..1f3b0fc0d351 100644 --- a/trunk/fs/lockd/clntlock.c +++ b/trunk/fs/lockd/clntlock.c @@ -139,55 +139,6 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) return 0; } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -static const struct in6_addr *nlmclnt_map_v4addr(const struct sockaddr *sap, - struct in6_addr *addr_mapped) -{ - const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; - - switch (sap->sa_family) { - case AF_INET6: - return &((const struct sockaddr_in6 *)sap)->sin6_addr; - case AF_INET: - ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, addr_mapped); - return addr_mapped; - } - - return NULL; -} - -/* - * If lockd is using a PF_INET6 listener, all incoming requests appear - * to come from AF_INET6 remotes. The address of AF_INET remotes are - * mapped to AF_INET6 automatically by the network layer. In case the - * user passed an AF_INET server address at mount time, ensure both - * addresses are AF_INET6 before comparing them. - */ -static int nlmclnt_cmp_addr(const struct nlm_host *host, - const struct sockaddr *sap) -{ - const struct in6_addr *addr1; - const struct in6_addr *addr2; - struct in6_addr addr1_mapped; - struct in6_addr addr2_mapped; - - addr1 = nlmclnt_map_v4addr(nlm_addr(host), &addr1_mapped); - if (likely(addr1 != NULL)) { - addr2 = nlmclnt_map_v4addr(sap, &addr2_mapped); - if (likely(addr2 != NULL)) - return ipv6_addr_equal(addr1, addr2); - } - - return 0; -} -#else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ -static int nlmclnt_cmp_addr(const struct nlm_host *host, - const struct sockaddr *sap) -{ - return nlm_cmp_addr(nlm_addr(host), sap); -} -#endif /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ - /* * The server lockd has called us back to tell us the lock was granted */ @@ -215,7 +166,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) */ if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) continue; - if (!nlmclnt_cmp_addr(block->b_host, addr)) + if (!nlm_cmp_addr(nlm_addr(block->b_host), addr)) continue; if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) continue; diff --git a/trunk/fs/minix/inode.c b/trunk/fs/minix/inode.c index 618865b3128b..d1d1eb84679d 100644 --- a/trunk/fs/minix/inode.c +++ b/trunk/fs/minix/inode.c @@ -3,7 +3,7 @@ * * Copyright (C) 1991, 1992 Linus Torvalds * - * Copyright (C) 1996 Gertjan van Wingerde + * Copyright (C) 1996 Gertjan van Wingerde (gertjan@cs.vu.nl) * Minix V2 fs support. * * Modified for 680x0 by Andreas Schwab diff --git a/trunk/fs/nfs/client.c b/trunk/fs/nfs/client.c index 574158ae2398..9b728f3565a1 100644 --- a/trunk/fs/nfs/client.c +++ b/trunk/fs/nfs/client.c @@ -255,32 +255,6 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, } return 0; } - -/* - * Test if two ip6 socket addresses refer to the same socket by - * comparing relevant fields. The padding bytes specifically, are not - * compared. sin6_flowinfo is not compared because it only affects QoS - * and sin6_scope_id is only compared if the address is "link local" - * because "link local" addresses need only be unique to a specific - * link. Conversely, ordinary unicast addresses might have different - * sin6_scope_id. - * - * The caller should ensure both socket addresses are AF_INET6. - */ -static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1, - const struct sockaddr *sa2) -{ - const struct sockaddr_in6 *saddr1 = (const struct sockaddr_in6 *)sa1; - const struct sockaddr_in6 *saddr2 = (const struct sockaddr_in6 *)sa2; - - if (!ipv6_addr_equal(&saddr1->sin6_addr, - &saddr1->sin6_addr)) - return 0; - if (ipv6_addr_scope(&saddr1->sin6_addr) == IPV6_ADDR_SCOPE_LINKLOCAL && - saddr1->sin6_scope_id != saddr2->sin6_scope_id) - return 0; - return saddr1->sin6_port == saddr2->sin6_port; -} #else static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, const struct sockaddr_in *sa2) @@ -296,51 +270,8 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, (const struct sockaddr_in *)sa2); } - -static int nfs_sockaddr_cmp_ip6(const struct sockaddr * sa1, - const struct sockaddr * sa2) -{ - return 0; -} #endif -/* - * Test if two ip4 socket addresses refer to the same socket, by - * comparing relevant fields. The padding bytes specifically, are - * not compared. - * - * The caller should ensure both socket addresses are AF_INET. - */ -static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1, - const struct sockaddr *sa2) -{ - const struct sockaddr_in *saddr1 = (const struct sockaddr_in *)sa1; - const struct sockaddr_in *saddr2 = (const struct sockaddr_in *)sa2; - - if (saddr1->sin_addr.s_addr != saddr2->sin_addr.s_addr) - return 0; - return saddr1->sin_port == saddr2->sin_port; -} - -/* - * Test if two socket addresses represent the same actual socket, - * by comparing (only) relevant fields. - */ -static int nfs_sockaddr_cmp(const struct sockaddr *sa1, - const struct sockaddr *sa2) -{ - if (sa1->sa_family != sa2->sa_family) - return 0; - - switch (sa1->sa_family) { - case AF_INET: - return nfs_sockaddr_cmp_ip4(sa1, sa2); - case AF_INET6: - return nfs_sockaddr_cmp_ip6(sa1, sa2); - } - return 0; -} - /* * Find a client by IP address and protocol version * - returns NULL if no such client @@ -413,10 +344,8 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp) static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) { struct nfs_client *clp; - const struct sockaddr *sap = data->addr; list_for_each_entry(clp, &nfs_client_list, cl_share_link) { - const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; /* Don't match clients that failed to initialise properly */ if (clp->cl_cons_state < 0) continue; @@ -429,7 +358,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat continue; /* Match the full socket address */ - if (!nfs_sockaddr_cmp(sap, clap)) + if (memcmp(&clp->cl_addr, data->addr, sizeof(clp->cl_addr)) != 0) continue; atomic_inc(&clp->cl_count); diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index 672368f865ca..e35c8199f82f 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -1892,14 +1892,8 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) cache.cred = cred; cache.jiffies = jiffies; status = NFS_PROTO(inode)->access(inode, &cache); - if (status != 0) { - if (status == -ESTALE) { - nfs_zap_caches(inode); - if (!S_ISDIR(inode->i_mode)) - set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); - } + if (status != 0) return status; - } nfs_access_add_cache(inode, &cache); out: if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) diff --git a/trunk/fs/nfs/nfs3acl.c b/trunk/fs/nfs/nfs3acl.c index 6bbf0e6daad2..cef62557c87d 100644 --- a/trunk/fs/nfs/nfs3acl.c +++ b/trunk/fs/nfs/nfs3acl.c @@ -292,7 +292,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, { struct nfs_server *server = NFS_SERVER(inode); struct nfs_fattr fattr; - struct page *pages[NFSACL_MAXPAGES]; + struct page *pages[NFSACL_MAXPAGES] = { }; struct nfs3_setaclargs args = { .inode = inode, .mask = NFS_ACL, @@ -303,7 +303,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, .rpc_argp = &args, .rpc_resp = &fattr, }; - int status; + int status, count; status = -EOPNOTSUPP; if (!nfs_server_capable(inode, NFS_CAP_ACLS)) @@ -319,20 +319,6 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, if (S_ISDIR(inode->i_mode)) { args.mask |= NFS_DFACL; args.acl_default = dfacl; - args.len = nfsacl_size(acl, dfacl); - } else - args.len = nfsacl_size(acl, NULL); - - if (args.len > NFS_ACL_INLINE_BUFSIZE) { - unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT); - - status = -ENOMEM; - do { - args.pages[args.npages] = alloc_page(GFP_KERNEL); - if (args.pages[args.npages] == NULL) - goto out_freepages; - args.npages++; - } while (args.npages < npages); } dprintk("NFS call setacl\n"); @@ -343,6 +329,10 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, nfs_zap_acl_cache(inode); dprintk("NFS reply setacl: %d\n", status); + /* pages may have been allocated at the xdr layer. */ + for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++) + __free_page(args.pages[count]); + switch (status) { case 0: status = nfs_refresh_inode(inode, &fattr); @@ -356,11 +346,6 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, case -ENOTSUPP: status = -EOPNOTSUPP; } -out_freepages: - while (args.npages != 0) { - args.npages--; - __free_page(args.pages[args.npages]); - } out: return status; } diff --git a/trunk/fs/nfs/nfs3xdr.c b/trunk/fs/nfs/nfs3xdr.c index 6cdeacffde46..11cdddec1432 100644 --- a/trunk/fs/nfs/nfs3xdr.c +++ b/trunk/fs/nfs/nfs3xdr.c @@ -82,10 +82,8 @@ #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) #define ACL3_getaclargs_sz (NFS3_fh_sz+1) -#define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \ - XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) -#define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \ - XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) +#define ACL3_setaclargs_sz (NFS3_fh_sz+1+2*(2+5*3)) +#define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+2*(2+5*3)) #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) /* @@ -705,18 +703,28 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, struct nfs3_setaclargs *args) { struct xdr_buf *buf = &req->rq_snd_buf; - unsigned int base; - int err; + unsigned int base, len_in_head, len = nfsacl_size( + (args->mask & NFS_ACL) ? args->acl_access : NULL, + (args->mask & NFS_DFACL) ? args->acl_default : NULL); + int count, err; p = xdr_encode_fhandle(p, NFS_FH(args->inode)); *p++ = htonl(args->mask); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - base = req->rq_slen; - - if (args->npages != 0) - xdr_encode_pages(buf, args->pages, 0, args->len); - else - req->rq_slen += args->len; + base = (char *)p - (char *)buf->head->iov_base; + /* put as much of the acls into head as possible. */ + len_in_head = min_t(unsigned int, buf->head->iov_len - base, len); + len -= len_in_head; + req->rq_slen = xdr_adjust_iovec(req->rq_svec, p + (len_in_head >> 2)); + + for (count = 0; (count << PAGE_SHIFT) < len; count++) { + args->pages[count] = alloc_page(GFP_KERNEL); + if (!args->pages[count]) { + while (count) + __free_page(args->pages[--count]); + return -ENOMEM; + } + } + xdr_encode_pages(buf, args->pages, 0, len); err = nfsacl_encode(buf, base, args->inode, (args->mask & NFS_ACL) ? diff --git a/trunk/fs/nfs/nfs4namespace.c b/trunk/fs/nfs/nfs4namespace.c index 2a2a0a7143ad..30befc39b3c6 100644 --- a/trunk/fs/nfs/nfs4namespace.c +++ b/trunk/fs/nfs/nfs4namespace.c @@ -21,9 +21,7 @@ #define NFSDBG_FACILITY NFSDBG_VFS /* - * Convert the NFSv4 pathname components into a standard posix path. - * - * Note that the resulting string will be placed at the end of the buffer + * Check if fs_root is valid */ static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, char *buffer, ssize_t buflen) @@ -101,20 +99,21 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, { struct vfsmount *mnt = ERR_PTR(-ENOENT); char *mnt_path; - unsigned int maxbuflen; + int page2len; unsigned int s; mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); if (IS_ERR(mnt_path)) return mnt; mountdata->mnt_path = mnt_path; - maxbuflen = mnt_path - 1 - page2; + page2 += strlen(mnt_path) + 1; + page2len = PAGE_SIZE - strlen(mnt_path) - 1; for (s = 0; s < location->nservers; s++) { const struct nfs4_string *buf = &location->servers[s]; struct sockaddr_storage addr; - if (buf->len <= 0 || buf->len >= maxbuflen) + if (buf->len <= 0 || buf->len >= PAGE_SIZE) continue; mountdata->addr = (struct sockaddr *)&addr; @@ -127,8 +126,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, continue; nfs_set_port(mountdata->addr, NFS_PORT); - memcpy(page2, buf->data, buf->len); - page2[buf->len] = '\0'; + strncpy(page2, buf->data, page2len); + page2[page2len] = '\0'; mountdata->hostname = page2; snprintf(page, PAGE_SIZE, "%s:%s", diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index 9250067943d8..f65953be39c0 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -2596,7 +2596,6 @@ static nfsd4_enc nfsd4_enc_ops[] = { [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, - [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, diff --git a/trunk/fs/ocfs2/alloc.c b/trunk/fs/ocfs2/alloc.c index 19e3a96aa02c..3a9e5deed74d 100644 --- a/trunk/fs/ocfs2/alloc.c +++ b/trunk/fs/ocfs2/alloc.c @@ -176,8 +176,7 @@ static int ocfs2_dinode_insert_check(struct inode *inode, BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); mlog_bug_on_msg(!ocfs2_sparse_alloc(osb) && - (OCFS2_I(inode)->ip_clusters != - le32_to_cpu(rec->e_cpos)), + (OCFS2_I(inode)->ip_clusters != rec->e_cpos), "Device %s, asking for sparse allocation: inode %llu, " "cpos %u, clusters %u\n", osb->dev_str, diff --git a/trunk/fs/ocfs2/aops.c b/trunk/fs/ocfs2/aops.c index 8e1709a679b7..a067a6cffb01 100644 --- a/trunk/fs/ocfs2/aops.c +++ b/trunk/fs/ocfs2/aops.c @@ -227,7 +227,7 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page, size = i_size_read(inode); if (size > PAGE_CACHE_SIZE || - size > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) { + size > ocfs2_max_inline_data(inode->i_sb)) { ocfs2_error(inode->i_sb, "Inode %llu has with inline data has bad size: %Lu", (unsigned long long)OCFS2_I(inode)->ip_blkno, @@ -1555,7 +1555,6 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping, int ret, written = 0; loff_t end = pos + len; struct ocfs2_inode_info *oi = OCFS2_I(inode); - struct ocfs2_dinode *di = NULL; mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n", (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos, @@ -1588,9 +1587,7 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping, /* * Check whether the write can fit. */ - di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; - if (mmap_page || - end > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) + if (mmap_page || end > ocfs2_max_inline_data(inode->i_sb)) return 0; do_inline_write: diff --git a/trunk/fs/ocfs2/namei.c b/trunk/fs/ocfs2/namei.c index 4b11762f249e..084aba86c3b2 100644 --- a/trunk/fs/ocfs2/namei.c +++ b/trunk/fs/ocfs2/namei.c @@ -532,8 +532,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); - fe->id2.i_data.id_count = cpu_to_le16( - ocfs2_max_inline_data_with_xattr(osb->sb, fe)); + fe->id2.i_data.id_count = cpu_to_le16(ocfs2_max_inline_data(osb->sb)); } else { fel = &fe->id2.i_list; fel->l_tree_depth = 0; diff --git a/trunk/fs/ocfs2/ocfs2_fs.h b/trunk/fs/ocfs2/ocfs2_fs.h index 2332ef740f4f..c7ae45aaa36c 100644 --- a/trunk/fs/ocfs2/ocfs2_fs.h +++ b/trunk/fs/ocfs2/ocfs2_fs.h @@ -1070,6 +1070,12 @@ static inline int ocfs2_fast_symlink_chars(struct super_block *sb) offsetof(struct ocfs2_dinode, id2.i_symlink); } +static inline int ocfs2_max_inline_data(struct super_block *sb) +{ + return sb->s_blocksize - + offsetof(struct ocfs2_dinode, id2.i_data.id_data); +} + static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb, struct ocfs2_dinode *di) { diff --git a/trunk/fs/ocfs2/xattr.c b/trunk/fs/ocfs2/xattr.c index 2563df89fc2a..4ddd788add67 100644 --- a/trunk/fs/ocfs2/xattr.c +++ b/trunk/fs/ocfs2/xattr.c @@ -547,12 +547,8 @@ int ocfs2_calc_xattr_init(struct inode *dir, * when blocksize = 512, may reserve one more cluser for * xattr bucket, otherwise reserve one metadata block * for them is ok. - * If this is a new directory with inline data, - * we choose to reserve the entire inline area for - * directory contents and force an external xattr block. */ if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE || - (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) || (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); if (ret) { @@ -4795,33 +4791,19 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode, char *val, int value_len) { - int ret, offset, block_off; + int offset; struct ocfs2_xattr_value_root *xv; struct ocfs2_xattr_entry *xe = xs->here; - struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); - void *base; BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); - ret = ocfs2_xattr_bucket_get_name_value(inode, xh, - xe - xh->xh_entries, - &block_off, - &offset); - if (ret) { - mlog_errno(ret); - goto out; - } + offset = le16_to_cpu(xe->xe_name_offset) + + OCFS2_XATTR_SIZE(xe->xe_name_len); - base = bucket_block(xs->bucket, block_off); - xv = (struct ocfs2_xattr_value_root *)(base + offset + - OCFS2_XATTR_SIZE(xe->xe_name_len)); + xv = (struct ocfs2_xattr_value_root *)(xs->base + offset); - ret = __ocfs2_xattr_set_value_outside(inode, handle, - xv, val, value_len); - if (ret) - mlog_errno(ret); -out: - return ret; + return __ocfs2_xattr_set_value_outside(inode, handle, + xv, val, value_len); } static int ocfs2_rm_xattr_cluster(struct inode *inode, diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index beaa0ce3b82e..0c9de19a1633 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -3066,6 +3066,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi int retval = -ENOENT; ino_t ino; int tid; + unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ struct pid_namespace *ns; task = get_proc_task(inode); @@ -3082,18 +3083,18 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi goto out_no_task; retval = 0; - switch ((unsigned long)filp->f_pos) { + switch (pos) { case 0: ino = inode->i_ino; - if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0) + if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0) goto out; - filp->f_pos++; + pos++; /* fall through */ case 1: ino = parent_ino(dentry); - if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) < 0) + if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0) goto out; - filp->f_pos++; + pos++; /* fall through */ } @@ -3103,9 +3104,9 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi ns = filp->f_dentry->d_sb->s_fs_info; tid = (int)filp->f_version; filp->f_version = 0; - for (task = first_tid(leader, tid, filp->f_pos - 2, ns); + for (task = first_tid(leader, tid, pos - 2, ns); task; - task = next_tid(task), filp->f_pos++) { + task = next_tid(task), pos++) { tid = task_pid_nr_ns(task, ns); if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { /* returning this tgid failed, save it as the first @@ -3116,6 +3117,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi } } out: + filp->f_pos = pos; put_task_struct(leader); out_no_task: return retval; diff --git a/trunk/fs/ramfs/file-nommu.c b/trunk/fs/ramfs/file-nommu.c index 5d7c7ececa64..b9b567a28376 100644 --- a/trunk/fs/ramfs/file-nommu.c +++ b/trunk/fs/ramfs/file-nommu.c @@ -114,9 +114,6 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) if (!pagevec_add(&lru_pvec, page)) __pagevec_lru_add_file(&lru_pvec); - /* prevent the page from being discarded on memory pressure */ - SetPageDirty(page); - unlock_page(page); } @@ -129,7 +126,6 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) return -EFBIG; add_error: - pagevec_lru_add_file(&lru_pvec); page_cache_release(pages + loop); for (loop++; loop < npages; loop++) __free_page(pages + loop); diff --git a/trunk/fs/ufs/super.c b/trunk/fs/ufs/super.c index 261a1c2f22dd..e65212dfb60e 100644 --- a/trunk/fs/ufs/super.c +++ b/trunk/fs/ufs/super.c @@ -41,7 +41,7 @@ * Stefan Reinauer * * Module usage counts added on 96/04/29 by - * Gertjan van Wingerde + * Gertjan van Wingerde * * Clean swab support on 19970406 by * Francois-Rene Rideau diff --git a/trunk/arch/arm/plat-s3c24xx/include/plat/regs-iis.h b/trunk/include/asm-arm/plat-s3c24xx/regs-iis.h similarity index 100% rename from trunk/arch/arm/plat-s3c24xx/include/plat/regs-iis.h rename to trunk/include/asm-arm/plat-s3c24xx/regs-iis.h diff --git a/trunk/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h b/trunk/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h similarity index 93% rename from trunk/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h rename to trunk/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h index 0fad7571030e..25d4058bcfed 100644 --- a/trunk/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h +++ b/trunk/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h @@ -33,9 +33,6 @@ #define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) #define S3C2412_IISCON_IIS_ACTIVE (1 << 0) -#define S3C64XX_IISMOD_IMS_PCLK (0 << 10) -#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) - #define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10) #define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10) #define S3C2412_IISMOD_SLAVE (2 << 10) @@ -47,8 +44,8 @@ #define S3C2412_IISMOD_LR_LLOW (0 << 7) #define S3C2412_IISMOD_LR_RLOW (1 << 7) #define S3C2412_IISMOD_SDF_IIS (0 << 5) -#define S3C2412_IISMOD_SDF_MSB (1 << 5) -#define S3C2412_IISMOD_SDF_LSB (2 << 5) +#define S3C2412_IISMOD_SDF_MSB (0 << 5) +#define S3C2412_IISMOD_SDF_LSB (0 << 5) #define S3C2412_IISMOD_SDF_MASK (3 << 5) #define S3C2412_IISMOD_RCLK_256FS (0 << 3) #define S3C2412_IISMOD_RCLK_512FS (1 << 3) diff --git a/trunk/include/linux/bio.h b/trunk/include/linux/bio.h index d8bd43bfdcf5..1b16108a5417 100644 --- a/trunk/include/linux/bio.h +++ b/trunk/include/linux/bio.h @@ -531,7 +531,7 @@ extern void bio_integrity_endio(struct bio *, int); extern void bio_integrity_advance(struct bio *, unsigned int); extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int); extern void bio_integrity_split(struct bio *, struct bio_pair *, int); -extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t, struct bio_set *); +extern int bio_integrity_clone(struct bio *, struct bio *, struct bio_set *); extern int bioset_integrity_create(struct bio_set *, int); extern void bioset_integrity_free(struct bio_set *); extern void bio_integrity_init_slab(void); @@ -542,7 +542,7 @@ extern void bio_integrity_init_slab(void); #define bioset_integrity_create(a, b) (0) #define bio_integrity_prep(a) (0) #define bio_integrity_enabled(a) (0) -#define bio_integrity_clone(a, b, c,d ) (0) +#define bio_integrity_clone(a, b, c) (0) #define bioset_integrity_free(a) do { } while (0) #define bio_integrity_free(a, b) do { } while (0) #define bio_integrity_endio(a, b) do { } while (0) diff --git a/trunk/include/linux/capability.h b/trunk/include/linux/capability.h index 4864a43b2b45..1b9872556131 100644 --- a/trunk/include/linux/capability.h +++ b/trunk/include/linux/capability.h @@ -393,10 +393,8 @@ struct cpu_vfs_cap_data { # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) # define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } }) -# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ - | CAP_TO_MASK(CAP_SYS_RESOURCE) \ - | CAP_TO_MASK(CAP_MKNOD), \ - CAP_FS_MASK_B1 } }) +# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ + CAP_FS_MASK_B1 } }) #endif /* _KERNEL_CAPABILITY_U32S != 2 */ diff --git a/trunk/include/linux/compiler-gcc.h b/trunk/include/linux/compiler-gcc.h index a3ed7cb8ca34..1514d534deeb 100644 --- a/trunk/include/linux/compiler-gcc.h +++ b/trunk/include/linux/compiler-gcc.h @@ -52,15 +52,7 @@ #define __deprecated __attribute__((deprecated)) #define __packed __attribute__((packed)) #define __weak __attribute__((weak)) - -/* - * it doesn't make sense on ARM (currently the only user of __naked) to trace - * naked functions because then mcount is called without stack and frame pointer - * being set up and there is no chance to restore the lr register to the value - * before mcount was called. - */ -#define __naked __attribute__((naked)) notrace - +#define __naked __attribute__((naked)) #define __noreturn __attribute__((noreturn)) /* diff --git a/trunk/include/linux/dca.h b/trunk/include/linux/dca.h index 9c20c7e87d0a..b00a753eda53 100644 --- a/trunk/include/linux/dca.h +++ b/trunk/include/linux/dca.h @@ -1,23 +1,3 @@ -/* - * Copyright(c) 2007 - 2009 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. - */ #ifndef DCA_H #define DCA_H /* DCA Provider API */ diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index 25087aead657..e0cedfe9fad4 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -797,7 +797,6 @@ typedef struct hwif_s { struct scatterlist *sg_table; int sg_max_nents; /* Maximum number of entries in it */ int sg_nents; /* Current number of entries in it */ - int orig_sg_nents; int sg_dma_direction; /* dma transfer direction */ /* data phase of the active command (currently only valid for PIO/DMA) */ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index 6b28048fc568..1249a0c20a38 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -661,7 +661,6 @@ struct input_absinfo { #define SW_DOCK 0x05 /* set = plugged into dock */ #define SW_LINEOUT_INSERT 0x06 /* set = inserted */ #define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */ -#define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */ #define SW_MAX 0x0f #define SW_CNT (SW_MAX+1) diff --git a/trunk/include/linux/lockd/lockd.h b/trunk/include/linux/lockd/lockd.h index 51855dfd8adb..aa6fe7026de7 100644 --- a/trunk/include/linux/lockd/lockd.h +++ b/trunk/include/linux/lockd/lockd.h @@ -346,7 +346,6 @@ static inline int __nlm_cmp_addr4(const struct sockaddr *sap1, return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr; } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static inline int __nlm_cmp_addr6(const struct sockaddr *sap1, const struct sockaddr *sap2) { @@ -354,13 +353,6 @@ static inline int __nlm_cmp_addr6(const struct sockaddr *sap1, const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2; return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr); } -#else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ -static inline int __nlm_cmp_addr6(const struct sockaddr *sap1, - const struct sockaddr *sap2) -{ - return 0; -} -#endif /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ /* * Compare two host addresses diff --git a/trunk/include/linux/mfd/wm8350/audio.h b/trunk/include/linux/mfd/wm8350/audio.h index d899dc0223ba..af95a1d2f3a1 100644 --- a/trunk/include/linux/mfd/wm8350/audio.h +++ b/trunk/include/linux/mfd/wm8350/audio.h @@ -490,7 +490,6 @@ /* * R231 (0xE7) - Jack Status */ -#define WM8350_JACK_L_LVL 0x0800 #define WM8350_JACK_R_LVL 0x0400 /* diff --git a/trunk/include/linux/mfd/wm8400-audio.h b/trunk/include/linux/mfd/wm8400-audio.h index e06ed3eb1d0a..b6640e018046 100644 --- a/trunk/include/linux/mfd/wm8400-audio.h +++ b/trunk/include/linux/mfd/wm8400-audio.h @@ -1181,7 +1181,6 @@ #define WM8400_FLL_OUTDIV_SHIFT 0 /* FLL_OUTDIV - [2:0] */ #define WM8400_FLL_OUTDIV_WIDTH 3 /* FLL_OUTDIV - [2:0] */ -struct wm8400; void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400); #endif diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 2e5f00066afd..a550b528319f 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -406,8 +406,6 @@ struct nfs3_setaclargs { int mask; struct posix_acl * acl_access; struct posix_acl * acl_default; - size_t len; - unsigned int npages; struct page ** pages; }; diff --git a/trunk/include/linux/nfsacl.h b/trunk/include/linux/nfsacl.h index 43011b69297c..54487a99beb8 100644 --- a/trunk/include/linux/nfsacl.h +++ b/trunk/include/linux/nfsacl.h @@ -37,9 +37,6 @@ #define NFSACL_MAXPAGES ((2*(8+12*NFS_ACL_MAX_ENTRIES) + PAGE_SIZE-1) \ >> PAGE_SHIFT) -#define NFS_ACL_MAX_ENTRIES_INLINE (5) -#define NFS_ACL_INLINE_BUFSIZE ((2*(2+3*NFS_ACL_MAX_ENTRIES_INLINE)) << 2) - static inline unsigned int nfsacl_size(struct posix_acl *acl_access, struct posix_acl *acl_default) { diff --git a/trunk/include/net/netfilter/nf_conntrack_core.h b/trunk/include/net/netfilter/nf_conntrack_core.h index 5a449b44ba33..c25068e38516 100644 --- a/trunk/include/net/netfilter/nf_conntrack_core.h +++ b/trunk/include/net/netfilter/nf_conntrack_core.h @@ -62,8 +62,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb) if (ct && ct != &nf_conntrack_untracked) { if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) ret = __nf_conntrack_confirm(skb); - if (likely(ret == NF_ACCEPT)) - nf_ct_deliver_cached_events(ct); + nf_ct_deliver_cached_events(ct); } return ret; } diff --git a/trunk/include/scsi/fc/fc_fcoe.h b/trunk/include/scsi/fc/fc_fcoe.h index f271d9cc0fc2..57aaa8f0d613 100644 --- a/trunk/include/scsi/fc/fc_fcoe.h +++ b/trunk/include/scsi/fc/fc_fcoe.h @@ -31,6 +31,10 @@ #define ETH_P_FCOE 0x8906 /* FCOE ether type */ #endif +#ifndef ETH_P_8021Q +#define ETH_P_8021Q 0x8100 +#endif + /* * FC_FCOE_OUI hasn't been standardized yet. XXX TBD. */ diff --git a/trunk/include/scsi/fc/fc_fs.h b/trunk/include/scsi/fc/fc_fs.h index 1b7af3a64c7c..3e4801d2bdbb 100644 --- a/trunk/include/scsi/fc/fc_fs.h +++ b/trunk/include/scsi/fc/fc_fs.h @@ -337,9 +337,4 @@ enum fc_pf_rjt_reason { FC_RJT_VENDOR = 0xff, /* vendor specific reject */ }; -/* default timeout values */ - -#define FC_DEF_E_D_TOV 2000UL -#define FC_DEF_R_A_TOV 10000UL - #endif /* _FC_FS_H_ */ diff --git a/trunk/include/scsi/libfc.h b/trunk/include/scsi/libfc.h index a2e126b86e3e..9f2876397dda 100644 --- a/trunk/include/scsi/libfc.h +++ b/trunk/include/scsi/libfc.h @@ -68,6 +68,9 @@ /* * FC HBA status */ +#define FC_PAUSE (1 << 1) +#define FC_LINK_UP (1 << 0) + enum fc_lport_state { LPORT_ST_NONE = 0, LPORT_ST_FLOGI, @@ -336,17 +339,31 @@ struct fc_exch { struct libfc_function_template { + /** + * Mandatory Fields + * + * These handlers must be implemented by the LLD. + */ + /* * Interface to send a FC frame - * - * STATUS: REQUIRED */ int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp); - /* - * Interface to send ELS/CT frames + /** + * Optional Fields * - * STATUS: OPTIONAL + * The LLD may choose to implement any of the following handlers. + * If LLD doesn't specify hander and leaves its pointer NULL then + * the default libfc function will be used for that handler. + */ + + /** + * ELS/CT interfaces + */ + + /* + * elsct_send - sends ELS/CT frame */ struct fc_seq *(*elsct_send)(struct fc_lport *lport, struct fc_rport *rport, @@ -356,6 +373,9 @@ struct libfc_function_template { struct fc_frame *fp, void *arg), void *arg, u32 timer_msec); + /** + * Exhance Manager interfaces + */ /* * Send the FC frame payload using a new exchange and sequence. @@ -387,8 +407,6 @@ struct libfc_function_template { * timer_msec argument is specified. The timer is canceled when * it fires or when the exchange is done. The exchange timeout handler * is registered by EM layer. - * - * STATUS: OPTIONAL */ struct fc_seq *(*exch_seq_send)(struct fc_lport *lp, struct fc_frame *fp, @@ -400,18 +418,14 @@ struct libfc_function_template { void *arg, unsigned int timer_msec); /* - * Send a frame using an existing sequence and exchange. - * - * STATUS: OPTIONAL + * send a frame using existing sequence and exchange. */ int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp); /* - * Send an ELS response using infomation from a previous - * exchange and sequence. - * - * STATUS: OPTIONAL + * Send ELS response using mainly infomation + * in exchange and sequence in EM layer. */ void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd, struct fc_seq_els_data *els_data); @@ -423,8 +437,6 @@ struct libfc_function_template { * A timer_msec can be specified for abort timeout, if non-zero * timer_msec value is specified then exchange resp handler * will be called with timeout error if no response to abort. - * - * STATUS: OPTIONAL */ int (*seq_exch_abort)(const struct fc_seq *req_sp, unsigned int timer_msec); @@ -432,8 +444,6 @@ struct libfc_function_template { /* * Indicate that an exchange/sequence tuple is complete and the memory * allocated for the related objects may be freed. - * - * STATUS: OPTIONAL */ void (*exch_done)(struct fc_seq *sp); @@ -441,8 +451,6 @@ struct libfc_function_template { * Assigns a EM and a free XID for an new exchange and then * allocates a new exchange and sequence pair. * The fp can be used to determine free XID. - * - * STATUS: OPTIONAL */ struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); @@ -450,16 +458,12 @@ struct libfc_function_template { * Release previously assigned XID by exch_get API. * The LLD may implement this if XID is assigned by LLD * in exch_get(). - * - * STATUS: OPTIONAL */ void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, u16 ex_id); /* * Start a new sequence on the same exchange/sequence tuple. - * - * STATUS: OPTIONAL */ struct fc_seq *(*seq_start_next)(struct fc_seq *sp); @@ -467,38 +471,26 @@ struct libfc_function_template { * Reset an exchange manager, completing all sequences and exchanges. * If s_id is non-zero, reset only exchanges originating from that FID. * If d_id is non-zero, reset only exchanges sending to that FID. - * - * STATUS: OPTIONAL */ - void (*exch_mgr_reset)(struct fc_lport *, + void (*exch_mgr_reset)(struct fc_exch_mgr *, u32 s_id, u32 d_id); - /* - * Flush the rport work queue. Generally used before shutdown. - * - * STATUS: OPTIONAL - */ void (*rport_flush_queue)(void); + /** + * Local Port interfaces + */ /* - * Receive a frame for a local port. - * - * STATUS: OPTIONAL + * Receive a frame to a local port. */ void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp); - /* - * Reset the local port. - * - * STATUS: OPTIONAL - */ int (*lport_reset)(struct fc_lport *); - /* - * Create a remote port + /** + * Remote Port interfaces */ - struct fc_rport *(*rport_create)(struct fc_disc_port *); /* * Initiates the RP state machine. It is called from the LP module. @@ -508,72 +500,57 @@ struct libfc_function_template { * - PLOGI * - PRLI * - RTV - * - * STATUS: OPTIONAL */ int (*rport_login)(struct fc_rport *rport); /* * Logoff, and remove the rport from the transport if * it had been added. This will send a LOGO to the target. - * - * STATUS: OPTIONAL */ int (*rport_logoff)(struct fc_rport *rport); /* * Recieve a request from a remote port. - * - * STATUS: OPTIONAL */ void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, struct fc_rport *); - /* - * lookup an rport by it's port ID. - * - * STATUS: OPTIONAL - */ struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); + /** + * FCP interfaces + */ + /* * Send a fcp cmd from fsp pkt. * Called with the SCSI host lock unlocked and irqs disabled. * * The resp handler is called when FCP_RSP received. * - * STATUS: OPTIONAL */ int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp, void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg)); /* - * Cleanup the FCP layer, used durring link down and reset - * - * STATUS: OPTIONAL + * Used at least durring linkdown and reset */ void (*fcp_cleanup)(struct fc_lport *lp); /* * Abort all I/O on a local port - * - * STATUS: OPTIONAL */ void (*fcp_abort_io)(struct fc_lport *lp); - /* - * Receive a request for the discovery layer. - * - * STATUS: OPTIONAL + /** + * Discovery interfaces */ + void (*disc_recv_req)(struct fc_seq *, struct fc_frame *, struct fc_lport *); /* * Start discovery for a local port. - * - * STATUS: OPTIONAL */ void (*disc_start)(void (*disc_callback)(struct fc_lport *, enum fc_disc_event), @@ -582,8 +559,6 @@ struct libfc_function_template { /* * Stop discovery for a given lport. This will remove * all discovered rports - * - * STATUS: OPTIONAL */ void (*disc_stop) (struct fc_lport *); @@ -591,8 +566,6 @@ struct libfc_function_template { * Stop discovery for a given lport. This will block * until all discovered rports are deleted from the * FC transport class - * - * STATUS: OPTIONAL */ void (*disc_stop_final) (struct fc_lport *); }; @@ -630,8 +603,7 @@ struct fc_lport { /* Operational Information */ struct libfc_function_template tt; - u8 link_up; - u8 qfull; + u16 link_status; enum fc_lport_state state; unsigned long boot_time; @@ -665,7 +637,7 @@ struct fc_lport { struct delayed_work disc_work; }; -/* +/** * FC_LPORT HELPER FUNCTIONS *****************************/ static inline void *lport_priv(const struct fc_lport *lp) @@ -697,7 +669,7 @@ static inline void fc_lport_state_enter(struct fc_lport *lp, } -/* +/** * LOCAL PORT LAYER *****************************/ int fc_lport_init(struct fc_lport *lp); @@ -731,6 +703,12 @@ void fc_linkup(struct fc_lport *); */ void fc_linkdown(struct fc_lport *); +/* + * Pause and unpause traffic. + */ +void fc_pause(struct fc_lport *); +void fc_unpause(struct fc_lport *); + /* * Configure the local port. */ @@ -747,19 +725,19 @@ int fc_lport_reset(struct fc_lport *); int fc_set_mfs(struct fc_lport *lp, u32 mfs); -/* +/** * REMOTE PORT LAYER *****************************/ int fc_rport_init(struct fc_lport *lp); void fc_rport_terminate_io(struct fc_rport *rp); -/* +/** * DISCOVERY LAYER *****************************/ int fc_disc_init(struct fc_lport *lp); -/* +/** * SCSI LAYER *****************************/ /* @@ -820,7 +798,7 @@ int fc_change_queue_type(struct scsi_device *sdev, int tag_type); */ void fc_fcp_destroy(struct fc_lport *); -/* +/** * ELS/CT interface *****************************/ /* @@ -829,7 +807,7 @@ void fc_fcp_destroy(struct fc_lport *); int fc_elsct_init(struct fc_lport *lp); -/* +/** * EXCHANGE MANAGER LAYER *****************************/ /* @@ -938,7 +916,7 @@ struct fc_seq *fc_seq_start_next(struct fc_seq *sp); * If s_id is non-zero, reset only exchanges originating from that FID. * If d_id is non-zero, reset only exchanges sending to that FID. */ -void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); +void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id); /* * Functions for fc_functions_template diff --git a/trunk/include/scsi/libfcoe.h b/trunk/include/scsi/libfcoe.h index 941818f29f59..89fdbb9a6a1b 100644 --- a/trunk/include/scsi/libfcoe.h +++ b/trunk/include/scsi/libfcoe.h @@ -46,7 +46,6 @@ struct fcoe_softc { struct net_device *phys_dev; /* device with ethtool_ops */ struct packet_type fcoe_packet_type; struct sk_buff_head fcoe_pending_queue; - u8 fcoe_pending_queue_active; u8 dest_addr[ETH_ALEN]; u8 ctl_src_addr[ETH_ALEN]; @@ -59,10 +58,16 @@ struct fcoe_softc { u8 address_mode; }; +static inline struct fcoe_softc *fcoe_softc( + const struct fc_lport *lp) +{ + return (struct fcoe_softc *)lport_priv(lp); +} + static inline struct net_device *fcoe_netdev( const struct fc_lport *lp) { - return ((struct fcoe_softc *)lport_priv(lp))->real_dev; + return fcoe_softc(lp)->real_dev; } static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb) diff --git a/trunk/include/sound/ad1816a.h b/trunk/include/sound/ad1816a.h index d010858c33c2..b3aa62ee3c8d 100644 --- a/trunk/include/sound/ad1816a.h +++ b/trunk/include/sound/ad1816a.h @@ -169,7 +169,5 @@ extern int snd_ad1816a_create(struct snd_card *card, unsigned long port, extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm); extern int snd_ad1816a_mixer(struct snd_ad1816a *chip); -extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device, - struct snd_timer **rtimer); #endif /* __SOUND_AD1816A_H */ diff --git a/trunk/include/sound/asound.h b/trunk/include/sound/asound.h index fad3e0c7b932..1c02ed1d7c4a 100644 --- a/trunk/include/sound/asound.h +++ b/trunk/include/sound/asound.h @@ -126,10 +126,12 @@ struct snd_hwdep_dsp_image { unsigned long driver_data; /* W: driver-specific data */ }; -#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int) -#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct snd_hwdep_info) -#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status) -#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image) +enum { + SNDRV_HWDEP_IOCTL_PVERSION = _IOR ('H', 0x00, int), + SNDRV_HWDEP_IOCTL_INFO = _IOR ('H', 0x01, struct snd_hwdep_info), + SNDRV_HWDEP_IOCTL_DSP_STATUS = _IOR('H', 0x02, struct snd_hwdep_dsp_status), + SNDRV_HWDEP_IOCTL_DSP_LOAD = _IOW('H', 0x03, struct snd_hwdep_dsp_image) +}; /***************************************************************************** * * @@ -449,35 +451,40 @@ enum { SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC, }; -#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int) -#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info) -#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int) -#define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int) -#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params) -#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params) -#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12) -#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct snd_pcm_sw_params) -#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct snd_pcm_status) -#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t) -#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22) -#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr) -#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info) -#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40) -#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41) -#define SNDRV_PCM_IOCTL_START _IO('A', 0x42) -#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43) -#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44) -#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int) -#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, snd_pcm_uframes_t) -#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47) -#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48) -#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, snd_pcm_uframes_t) -#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi) -#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct snd_xferi) -#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct snd_xfern) -#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct snd_xfern) -#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int) -#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61) +enum { + SNDRV_PCM_IOCTL_PVERSION = _IOR('A', 0x00, int), + SNDRV_PCM_IOCTL_INFO = _IOR('A', 0x01, struct snd_pcm_info), + SNDRV_PCM_IOCTL_TSTAMP = _IOW('A', 0x02, int), + SNDRV_PCM_IOCTL_TTSTAMP = _IOW('A', 0x03, int), + SNDRV_PCM_IOCTL_HW_REFINE = _IOWR('A', 0x10, struct snd_pcm_hw_params), + SNDRV_PCM_IOCTL_HW_PARAMS = _IOWR('A', 0x11, struct snd_pcm_hw_params), + SNDRV_PCM_IOCTL_HW_FREE = _IO('A', 0x12), + SNDRV_PCM_IOCTL_SW_PARAMS = _IOWR('A', 0x13, struct snd_pcm_sw_params), + SNDRV_PCM_IOCTL_STATUS = _IOR('A', 0x20, struct snd_pcm_status), + SNDRV_PCM_IOCTL_DELAY = _IOR('A', 0x21, snd_pcm_sframes_t), + SNDRV_PCM_IOCTL_HWSYNC = _IO('A', 0x22), + SNDRV_PCM_IOCTL_SYNC_PTR = _IOWR('A', 0x23, struct snd_pcm_sync_ptr), + SNDRV_PCM_IOCTL_CHANNEL_INFO = _IOR('A', 0x32, struct snd_pcm_channel_info), + SNDRV_PCM_IOCTL_PREPARE = _IO('A', 0x40), + SNDRV_PCM_IOCTL_RESET = _IO('A', 0x41), + SNDRV_PCM_IOCTL_START = _IO('A', 0x42), + SNDRV_PCM_IOCTL_DROP = _IO('A', 0x43), + SNDRV_PCM_IOCTL_DRAIN = _IO('A', 0x44), + SNDRV_PCM_IOCTL_PAUSE = _IOW('A', 0x45, int), + SNDRV_PCM_IOCTL_REWIND = _IOW('A', 0x46, snd_pcm_uframes_t), + SNDRV_PCM_IOCTL_RESUME = _IO('A', 0x47), + SNDRV_PCM_IOCTL_XRUN = _IO('A', 0x48), + SNDRV_PCM_IOCTL_FORWARD = _IOW('A', 0x49, snd_pcm_uframes_t), + SNDRV_PCM_IOCTL_WRITEI_FRAMES = _IOW('A', 0x50, struct snd_xferi), + SNDRV_PCM_IOCTL_READI_FRAMES = _IOR('A', 0x51, struct snd_xferi), + SNDRV_PCM_IOCTL_WRITEN_FRAMES = _IOW('A', 0x52, struct snd_xfern), + SNDRV_PCM_IOCTL_READN_FRAMES = _IOR('A', 0x53, struct snd_xfern), + SNDRV_PCM_IOCTL_LINK = _IOW('A', 0x60, int), + SNDRV_PCM_IOCTL_UNLINK = _IO('A', 0x61), +}; + +/* Trick to make alsa-lib/acinclude.m4 happy */ +#define SNDRV_PCM_IOCTL_REWIND SNDRV_PCM_IOCTL_REWIND /***************************************************************************** * * @@ -531,12 +538,14 @@ struct snd_rawmidi_status { unsigned char reserved[16]; /* reserved for future use */ }; -#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) -#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info) -#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params) -#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status) -#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) -#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int) +enum { + SNDRV_RAWMIDI_IOCTL_PVERSION = _IOR('W', 0x00, int), + SNDRV_RAWMIDI_IOCTL_INFO = _IOR('W', 0x01, struct snd_rawmidi_info), + SNDRV_RAWMIDI_IOCTL_PARAMS = _IOWR('W', 0x10, struct snd_rawmidi_params), + SNDRV_RAWMIDI_IOCTL_STATUS = _IOWR('W', 0x20, struct snd_rawmidi_status), + SNDRV_RAWMIDI_IOCTL_DROP = _IOW('W', 0x30, int), + SNDRV_RAWMIDI_IOCTL_DRAIN = _IOW('W', 0x31, int), +}; /* * Timer section - /dev/snd/timer @@ -645,21 +654,23 @@ struct snd_timer_status { unsigned char reserved[64]; /* reserved */ }; -#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int) -#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id) -#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int) -#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo) -#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams) -#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus) -#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct snd_timer_select) -#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct snd_timer_info) -#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct snd_timer_params) -#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct snd_timer_status) -/* The following four ioctls are changed since 1.0.9 due to confliction */ -#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0) -#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1) -#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2) -#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3) +enum { + SNDRV_TIMER_IOCTL_PVERSION = _IOR('T', 0x00, int), + SNDRV_TIMER_IOCTL_NEXT_DEVICE = _IOWR('T', 0x01, struct snd_timer_id), + SNDRV_TIMER_IOCTL_TREAD = _IOW('T', 0x02, int), + SNDRV_TIMER_IOCTL_GINFO = _IOWR('T', 0x03, struct snd_timer_ginfo), + SNDRV_TIMER_IOCTL_GPARAMS = _IOW('T', 0x04, struct snd_timer_gparams), + SNDRV_TIMER_IOCTL_GSTATUS = _IOWR('T', 0x05, struct snd_timer_gstatus), + SNDRV_TIMER_IOCTL_SELECT = _IOW('T', 0x10, struct snd_timer_select), + SNDRV_TIMER_IOCTL_INFO = _IOR('T', 0x11, struct snd_timer_info), + SNDRV_TIMER_IOCTL_PARAMS = _IOW('T', 0x12, struct snd_timer_params), + SNDRV_TIMER_IOCTL_STATUS = _IOR('T', 0x14, struct snd_timer_status), + /* The following four ioctls are changed since 1.0.9 due to confliction */ + SNDRV_TIMER_IOCTL_START = _IO('T', 0xa0), + SNDRV_TIMER_IOCTL_STOP = _IO('T', 0xa1), + SNDRV_TIMER_IOCTL_CONTINUE = _IO('T', 0xa2), + SNDRV_TIMER_IOCTL_PAUSE = _IO('T', 0xa3), +}; struct snd_timer_read { unsigned int resolution; @@ -836,31 +847,33 @@ struct snd_ctl_tlv { unsigned int tlv[0]; /* first TLV */ }; -#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) -#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info) -#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list) -#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info) -#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value) -#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct snd_ctl_elem_value) -#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct snd_ctl_elem_id) -#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct snd_ctl_elem_id) -#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int) -#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct snd_ctl_elem_info) -#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct snd_ctl_elem_info) -#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct snd_ctl_elem_id) -#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct snd_ctl_tlv) -#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct snd_ctl_tlv) -#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct snd_ctl_tlv) -#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int) -#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct snd_hwdep_info) -#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int) -#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct snd_pcm_info) -#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int) -#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int) -#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info) -#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int) -#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int) -#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int) +enum { + SNDRV_CTL_IOCTL_PVERSION = _IOR('U', 0x00, int), + SNDRV_CTL_IOCTL_CARD_INFO = _IOR('U', 0x01, struct snd_ctl_card_info), + SNDRV_CTL_IOCTL_ELEM_LIST = _IOWR('U', 0x10, struct snd_ctl_elem_list), + SNDRV_CTL_IOCTL_ELEM_INFO = _IOWR('U', 0x11, struct snd_ctl_elem_info), + SNDRV_CTL_IOCTL_ELEM_READ = _IOWR('U', 0x12, struct snd_ctl_elem_value), + SNDRV_CTL_IOCTL_ELEM_WRITE = _IOWR('U', 0x13, struct snd_ctl_elem_value), + SNDRV_CTL_IOCTL_ELEM_LOCK = _IOW('U', 0x14, struct snd_ctl_elem_id), + SNDRV_CTL_IOCTL_ELEM_UNLOCK = _IOW('U', 0x15, struct snd_ctl_elem_id), + SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS = _IOWR('U', 0x16, int), + SNDRV_CTL_IOCTL_ELEM_ADD = _IOWR('U', 0x17, struct snd_ctl_elem_info), + SNDRV_CTL_IOCTL_ELEM_REPLACE = _IOWR('U', 0x18, struct snd_ctl_elem_info), + SNDRV_CTL_IOCTL_ELEM_REMOVE = _IOWR('U', 0x19, struct snd_ctl_elem_id), + SNDRV_CTL_IOCTL_TLV_READ = _IOWR('U', 0x1a, struct snd_ctl_tlv), + SNDRV_CTL_IOCTL_TLV_WRITE = _IOWR('U', 0x1b, struct snd_ctl_tlv), + SNDRV_CTL_IOCTL_TLV_COMMAND = _IOWR('U', 0x1c, struct snd_ctl_tlv), + SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE = _IOWR('U', 0x20, int), + SNDRV_CTL_IOCTL_HWDEP_INFO = _IOR('U', 0x21, struct snd_hwdep_info), + SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE = _IOR('U', 0x30, int), + SNDRV_CTL_IOCTL_PCM_INFO = _IOWR('U', 0x31, struct snd_pcm_info), + SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE = _IOW('U', 0x32, int), + SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE = _IOWR('U', 0x40, int), + SNDRV_CTL_IOCTL_RAWMIDI_INFO = _IOWR('U', 0x41, struct snd_rawmidi_info), + SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE = _IOW('U', 0x42, int), + SNDRV_CTL_IOCTL_POWER = _IOWR('U', 0xd0, int), + SNDRV_CTL_IOCTL_POWER_STATE = _IOR('U', 0xd1, int), +}; /* * Read interface. @@ -906,4 +919,18 @@ struct snd_ctl_event { #define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream" #define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what +/* + * + */ + +struct snd_xferv { + const struct iovec *vector; + unsigned long count; +}; + +enum { + SNDRV_IOCTL_READV = _IOW('K', 0x00, struct snd_xferv), + SNDRV_IOCTL_WRITEV = _IOW('K', 0x01, struct snd_xferv), +}; + #endif /* __SOUND_ASOUND_H */ diff --git a/trunk/include/sound/atmel-abdac.h b/trunk/include/sound/atmel-abdac.h deleted file mode 100644 index edff6a8ba1b5..000000000000 --- a/trunk/include/sound/atmel-abdac.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Driver for the Atmel Audio Bitstream DAC (ABDAC) - * - * Copyright (C) 2009 Atmel Corporation - * - * 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. - */ -#ifndef __INCLUDE_SOUND_ATMEL_ABDAC_H -#define __INCLUDE_SOUND_ATMEL_ABDAC_H - -#include - -/** - * struct atmel_abdac_pdata - board specific ABDAC configuration - * @dws: DMA slave interface to use for sound playback. - */ -struct atmel_abdac_pdata { - struct dw_dma_slave dws; -}; - -#endif /* __INCLUDE_SOUND_ATMEL_ABDAC_H */ diff --git a/trunk/include/sound/atmel-ac97c.h b/trunk/include/sound/atmel-ac97c.h deleted file mode 100644 index e6aabdb45865..000000000000 --- a/trunk/include/sound/atmel-ac97c.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Driver for the Atmel AC97C controller - * - * Copyright (C) 2005-2009 Atmel Corporation - * - * 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. - */ -#ifndef __INCLUDE_SOUND_ATMEL_AC97C_H -#define __INCLUDE_SOUND_ATMEL_AC97C_H - -#include - -#define AC97C_CAPTURE 0x01 -#define AC97C_PLAYBACK 0x02 -#define AC97C_BOTH (AC97C_CAPTURE | AC97C_PLAYBACK) - -/** - * struct atmel_ac97c_pdata - board specific AC97C configuration - * @rx_dws: DMA slave interface to use for sound capture. - * @tx_dws: DMA slave interface to use for sound playback. - * @reset_pin: GPIO pin wired to the reset input on the external AC97 codec, - * optional to use, set to -ENODEV if not in use. AC97 layer will - * try to do a software reset of the external codec anyway. - * @flags: Flags for which directions should be enabled. - * - * If the user do not want to use a DMA channel for playback or capture, i.e. - * only one feature is required on the board. The slave for playback or capture - * can be set to NULL. The AC97C driver will take use of this when setting up - * the sound streams. - */ -struct ac97c_platform_data { - struct dw_dma_slave rx_dws; - struct dw_dma_slave tx_dws; - unsigned int flags; - int reset_pin; -}; - -#endif /* __INCLUDE_SOUND_ATMEL_AC97C_H */ diff --git a/trunk/include/sound/control.h b/trunk/include/sound/control.h index ef96f07aa03b..4721b4bba053 100644 --- a/trunk/include/sound/control.h +++ b/trunk/include/sound/control.h @@ -171,54 +171,6 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, */ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, const unsigned int *tlv); -int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, - unsigned int flags); -/* optional flags for slave */ -#define SND_CTL_SLAVE_NEED_UPDATE (1 << 0) - -/** - * snd_ctl_add_slave - Add a virtual slave control - * @master: vmaster element - * @slave: slave element to add - * - * Add a virtual slave control to the given master element created via - * snd_ctl_create_virtual_master() beforehand. - * Returns zero if successful or a negative error code. - * - * All slaves must be the same type (returning the same information - * via info callback). The fucntion doesn't check it, so it's your - * responsibility. - * - * Also, some additional limitations: - * at most two channels, - * logarithmic volume control (dB level) thus no linear volume, - * master can only attenuate the volume without gain - */ -static inline int -snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave) -{ - return _snd_ctl_add_slave(master, slave, 0); -} - -/** - * snd_ctl_add_slave_uncached - Add a virtual slave control - * @master: vmaster element - * @slave: slave element to add - * - * Add a virtual slave control to the given master. - * Unlike snd_ctl_add_slave(), the element added via this function - * is supposed to have volatile values, and get callback is called - * at each time quried from the master. - * - * When the control peeks the hardware values directly and the value - * can be changed by other means than the put callback of the element, - * this function should be used to keep the value always up-to-date. - */ -static inline int -snd_ctl_add_slave_uncached(struct snd_kcontrol *master, - struct snd_kcontrol *slave) -{ - return _snd_ctl_add_slave(master, slave, SND_CTL_SLAVE_NEED_UPDATE); -} - +int snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave); + #endif /* __SOUND_CONTROL_H */ diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index 3dea79829acc..f632484bc743 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -97,9 +97,9 @@ struct snd_device { struct snd_monitor_file { struct file *file; + struct snd_monitor_file *next; const struct file_operations *disconnected_f_op; - struct list_head shutdown_list; /* still need to shutdown */ - struct list_head list; /* link of monitor files */ + struct list_head shutdown_list; }; /* main structure for soundcard */ @@ -134,7 +134,7 @@ struct snd_card { struct snd_info_entry *proc_id; /* the card id */ struct proc_dir_entry *proc_root_link; /* number link to real id */ - struct list_head files_list; /* all files associated to this card */ + struct snd_monitor_file *files; /* all files associated to this card */ struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown state */ spinlock_t files_lock; /* lock the files for this card */ @@ -296,20 +296,8 @@ int snd_card_locked(int card); extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd); #endif -int snd_card_create(int idx, const char *id, - struct module *module, int extra_size, - struct snd_card **card_ret); - -static inline __deprecated struct snd_card *snd_card_new(int idx, const char *id, - struct module *module, int extra_size) -{ - struct snd_card *card; - if (snd_card_create(idx, id, module, extra_size, &card) < 0) - return NULL; - return card; -} - + struct module *module, int extra_size); int snd_card_disconnect(struct snd_card *card); int snd_card_free(struct snd_card *card); int snd_card_free_when_closed(struct snd_card *card); @@ -458,33 +446,21 @@ static inline int __snd_bug_on(int cond) struct snd_pci_quirk { unsigned short subvendor; /* PCI subvendor ID */ unsigned short subdevice; /* PCI subdevice ID */ - unsigned short subdevice_mask; /* bitmask to match */ int value; /* value */ #ifdef CONFIG_SND_DEBUG_VERBOSE const char *name; /* name of the device (optional) */ #endif }; -#define _SND_PCI_QUIRK_ID_MASK(vend, mask, dev) \ - .subvendor = (vend), .subdevice = (dev), .subdevice_mask = (mask) -#define _SND_PCI_QUIRK_ID(vend, dev) \ - _SND_PCI_QUIRK_ID_MASK(vend, 0xffff, dev) +#define _SND_PCI_QUIRK_ID(vend,dev) \ + .subvendor = (vend), .subdevice = (dev) #define SND_PCI_QUIRK_ID(vend,dev) {_SND_PCI_QUIRK_ID(vend, dev)} #ifdef CONFIG_SND_DEBUG_VERBOSE #define SND_PCI_QUIRK(vend,dev,xname,val) \ {_SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname)} -#define SND_PCI_QUIRK_VENDOR(vend, xname, val) \ - {_SND_PCI_QUIRK_ID_MASK(vend, 0, 0), .value = (val), .name = (xname)} -#define SND_PCI_QUIRK_MASK(vend, mask, dev, xname, val) \ - {_SND_PCI_QUIRK_ID_MASK(vend, mask, dev), \ - .value = (val), .name = (xname)} #else #define SND_PCI_QUIRK(vend,dev,xname,val) \ {_SND_PCI_QUIRK_ID(vend, dev), .value = (val)} -#define SND_PCI_QUIRK_MASK(vend, mask, dev, xname, val) \ - {_SND_PCI_QUIRK_ID_MASK(vend, mask, dev), .value = (val)} -#define SND_PCI_QUIRK_VENDOR(vend, xname, val) \ - {_SND_PCI_QUIRK_ID_MASK(vend, 0, 0), .value = (val)} #endif const struct snd_pci_quirk * diff --git a/trunk/include/sound/hwdep.h b/trunk/include/sound/hwdep.h index 8c05e47a4090..d9eea013c753 100644 --- a/trunk/include/sound/hwdep.h +++ b/trunk/include/sound/hwdep.h @@ -27,28 +27,18 @@ struct snd_hwdep; -/* hwdep file ops; all ops can be NULL */ struct snd_hwdep_ops { - long long (*llseek)(struct snd_hwdep *hw, struct file *file, - long long offset, int orig); - long (*read)(struct snd_hwdep *hw, char __user *buf, - long count, loff_t *offset); - long (*write)(struct snd_hwdep *hw, const char __user *buf, - long count, loff_t *offset); - int (*open)(struct snd_hwdep *hw, struct file * file); - int (*release)(struct snd_hwdep *hw, struct file * file); - unsigned int (*poll)(struct snd_hwdep *hw, struct file *file, - poll_table *wait); - int (*ioctl)(struct snd_hwdep *hw, struct file *file, - unsigned int cmd, unsigned long arg); - int (*ioctl_compat)(struct snd_hwdep *hw, struct file *file, - unsigned int cmd, unsigned long arg); - int (*mmap)(struct snd_hwdep *hw, struct file *file, - struct vm_area_struct *vma); - int (*dsp_status)(struct snd_hwdep *hw, - struct snd_hwdep_dsp_status *status); - int (*dsp_load)(struct snd_hwdep *hw, - struct snd_hwdep_dsp_image *image); + long long (*llseek) (struct snd_hwdep *hw, struct file * file, long long offset, int orig); + long (*read) (struct snd_hwdep *hw, char __user *buf, long count, loff_t *offset); + long (*write) (struct snd_hwdep *hw, const char __user *buf, long count, loff_t *offset); + int (*open) (struct snd_hwdep * hw, struct file * file); + int (*release) (struct snd_hwdep *hw, struct file * file); + unsigned int (*poll) (struct snd_hwdep *hw, struct file * file, poll_table * wait); + int (*ioctl) (struct snd_hwdep *hw, struct file * file, unsigned int cmd, unsigned long arg); + int (*ioctl_compat) (struct snd_hwdep *hw, struct file * file, unsigned int cmd, unsigned long arg); + int (*mmap) (struct snd_hwdep *hw, struct file * file, struct vm_area_struct * vma); + int (*dsp_status) (struct snd_hwdep *hw, struct snd_hwdep_dsp_status *status); + int (*dsp_load) (struct snd_hwdep *hw, struct snd_hwdep_dsp_image *image); }; struct snd_hwdep { @@ -71,9 +61,9 @@ struct snd_hwdep { void (*private_free) (struct snd_hwdep *hwdep); struct mutex open_mutex; - int used; /* reference counter */ - unsigned int dsp_loaded; /* bit fields of loaded dsp indices */ - unsigned int exclusive:1; /* exclusive access mode */ + int used; + unsigned int dsp_loaded; + unsigned int exclusive: 1; }; extern int snd_hwdep_new(struct snd_card *card, char *id, int device, diff --git a/trunk/include/sound/jack.h b/trunk/include/sound/jack.h index 6b013c6f6a04..2e0315cdd0d6 100644 --- a/trunk/include/sound/jack.h +++ b/trunk/include/sound/jack.h @@ -30,9 +30,6 @@ struct input_dev; /** * Jack types which can be reported. These values are used as a * bitmask. - * - * Note that this must be kept in sync with the lookup table in - * sound/core/jack.c. */ enum snd_jack_types { SND_JACK_HEADPHONE = 0x0001, @@ -40,8 +37,6 @@ enum snd_jack_types { SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE, SND_JACK_LINEOUT = 0x0004, SND_JACK_MECHANICAL = 0x0008, /* If detected separately */ - SND_JACK_VIDEOOUT = 0x0010, - SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT, }; struct snd_jack { diff --git a/trunk/include/sound/pcm.h b/trunk/include/sound/pcm.h index 8904b1900d7f..40c5a6fa6bcd 100644 --- a/trunk/include/sound/pcm.h +++ b/trunk/include/sound/pcm.h @@ -364,6 +364,7 @@ struct snd_pcm_substream { /* -- timer section -- */ struct snd_timer *timer; /* timer */ unsigned timer_running: 1; /* time is running */ + spinlock_t timer_lock; /* -- next substream -- */ struct snd_pcm_substream *next; /* -- linked substreams -- */ @@ -450,7 +451,7 @@ struct snd_pcm_notify { extern const struct file_operations snd_pcm_f_ops[2]; -int snd_pcm_new(struct snd_card *card, const char *id, int device, +int snd_pcm_new(struct snd_card *card, char *id, int device, int playback_count, int capture_count, struct snd_pcm **rpcm); int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count); diff --git a/trunk/include/sound/pxa2xx-lib.h b/trunk/include/sound/pxa2xx-lib.h index 2c894b600e5b..2fd3d251d9a5 100644 --- a/trunk/include/sound/pxa2xx-lib.h +++ b/trunk/include/sound/pxa2xx-lib.h @@ -42,19 +42,4 @@ extern int pxa2xx_ac97_hw_resume(void); extern int pxa2xx_ac97_hw_probe(struct platform_device *dev); extern void pxa2xx_ac97_hw_remove(struct platform_device *dev); -/* AC97 platform_data */ -/** - * struct pxa2xx_ac97_platform_data - pxa ac97 platform data - * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) - * a -1 value means no gpio will be used for reset - * - * Platform data should only be specified for pxa27x CPUs where a silicon bug - * prevents correct operation of the reset line. If not specified, the default - * behaviour is to consider gpio 113 as the AC97 reset line, which is the - * default on most boards. - */ -struct pxa2xx_ac97_platform_data { - int reset_gpio; -}; - #endif diff --git a/trunk/include/sound/rawmidi.h b/trunk/include/sound/rawmidi.h index c23c26585700..b550a416d075 100644 --- a/trunk/include/sound/rawmidi.h +++ b/trunk/include/sound/rawmidi.h @@ -42,6 +42,7 @@ #define SNDRV_RAWMIDI_LFLG_INPUT (1<<1) #define SNDRV_RAWMIDI_LFLG_OPEN (3<<0) #define SNDRV_RAWMIDI_LFLG_APPEND (1<<2) +#define SNDRV_RAWMIDI_LFLG_NOOPENLOCK (1<<3) struct snd_rawmidi; struct snd_rawmidi_substream; diff --git a/trunk/include/sound/sfnt_info.h b/trunk/include/sound/sfnt_info.h index 1bce7fd1725f..5d1ab9c4950f 100644 --- a/trunk/include/sound/sfnt_info.h +++ b/trunk/include/sound/sfnt_info.h @@ -202,11 +202,13 @@ struct snd_emux_misc_mode { int value2; /* reserved */ }; -#define SNDRV_EMUX_IOCTL_VERSION _IOR('H', 0x80, unsigned int) -#define SNDRV_EMUX_IOCTL_LOAD_PATCH _IOWR('H', 0x81, struct soundfont_patch_info) -#define SNDRV_EMUX_IOCTL_RESET_SAMPLES _IO('H', 0x82) -#define SNDRV_EMUX_IOCTL_REMOVE_LAST_SAMPLES _IO('H', 0x83) -#define SNDRV_EMUX_IOCTL_MEM_AVAIL _IOW('H', 0x84, int) -#define SNDRV_EMUX_IOCTL_MISC_MODE _IOWR('H', 0x84, struct snd_emux_misc_mode) +enum { + SNDRV_EMUX_IOCTL_VERSION = _IOR('H', 0x80, unsigned int), + SNDRV_EMUX_IOCTL_LOAD_PATCH = _IOWR('H', 0x81, struct soundfont_patch_info), + SNDRV_EMUX_IOCTL_RESET_SAMPLES = _IO('H', 0x82), + SNDRV_EMUX_IOCTL_REMOVE_LAST_SAMPLES = _IO('H', 0x83), + SNDRV_EMUX_IOCTL_MEM_AVAIL = _IOW('H', 0x84, int), + SNDRV_EMUX_IOCTL_MISC_MODE = _IOWR('H', 0x84, struct snd_emux_misc_mode), +}; #endif /* __SOUND_SFNT_INFO_H */ diff --git a/trunk/include/sound/soc-dai.h b/trunk/include/sound/soc-dai.h index 13676472ddfc..24247f763608 100644 --- a/trunk/include/sound/soc-dai.h +++ b/trunk/include/sound/soc-dai.h @@ -203,7 +203,7 @@ struct snd_soc_dai { int (*resume)(struct snd_soc_dai *dai); /* ops */ - struct snd_soc_dai_ops *ops; + struct snd_soc_dai_ops ops; /* DAI capabilities */ struct snd_soc_pcm_stream capture; diff --git a/trunk/include/sound/soc-dapm.h b/trunk/include/sound/soc-dapm.h index a7def6a9a030..dfa804958820 100644 --- a/trunk/include/sound/soc-dapm.h +++ b/trunk/include/sound/soc-dapm.h @@ -76,11 +76,6 @@ wcontrols, wncontrols)\ { .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} -#define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \ - wcontrols, wncontrols)\ -{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, .reg = wreg, \ - .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ - .num_kcontrols = wncontrols} #define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \ { .id = snd_soc_dapm_micbias, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = NULL, .num_kcontrols = 0} @@ -106,11 +101,6 @@ { .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ .event = wevent, .event_flags = wflags} -#define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \ - wcontrols, wncontrols, wevent, wflags) \ -{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, \ - .num_kcontrols = wncontrols, .event = wevent, .event_flags = wflags} #define SND_SOC_DAPM_MICBIAS_E(wname, wreg, wshift, winvert, wevent, wflags) \ { .id = snd_soc_dapm_micbias, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = NULL, .num_kcontrols = 0, \ @@ -192,12 +182,6 @@ .get = snd_soc_dapm_get_value_enum_double, \ .put = snd_soc_dapm_put_value_enum_double, \ .private_value = (unsigned long)&xenum } -#define SOC_DAPM_PIN_SWITCH(xname) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \ - .info = snd_soc_dapm_info_pin_switch, \ - .get = snd_soc_dapm_get_pin_switch, \ - .put = snd_soc_dapm_put_pin_switch, \ - .private_value = (unsigned long)xname } /* dapm stream operations */ #define SND_SOC_DAPM_STREAM_NOP 0x0 @@ -244,12 +228,6 @@ int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *uncontrol); -int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *uncontrol); int snd_soc_dapm_new_control(struct snd_soc_codec *codec, const struct snd_soc_dapm_widget *widget); int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, @@ -272,10 +250,10 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, int snd_soc_dapm_sys_add(struct device *dev); /* dapm audio pin control and status */ -int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin); +int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin); +int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin); +int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin); +int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin); int snd_soc_dapm_sync(struct snd_soc_codec *codec); /* dapm widget types */ @@ -285,7 +263,6 @@ enum snd_soc_dapm_type { snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */ snd_soc_dapm_value_mux, /* selects 1 analog signal from many inputs */ snd_soc_dapm_mixer, /* mixes several analog signals together */ - snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */ snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */ snd_soc_dapm_adc, /* analog to digital converter */ snd_soc_dapm_dac, /* digital to analog converter */ diff --git a/trunk/include/sound/soc.h b/trunk/include/sound/soc.h index a40bc6f316fc..24593ac3ea19 100644 --- a/trunk/include/sound/soc.h +++ b/trunk/include/sound/soc.h @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include #include #include @@ -156,8 +154,6 @@ enum snd_soc_bias_level { SND_SOC_BIAS_OFF, }; -struct snd_jack; -struct snd_soc_card; struct snd_soc_device; struct snd_soc_pcm_stream; struct snd_soc_ops; @@ -168,11 +164,6 @@ struct snd_soc_platform; struct snd_soc_codec; struct soc_enum; struct snd_soc_ac97_ops; -struct snd_soc_jack; -struct snd_soc_jack_pin; -#ifdef CONFIG_GPIOLIB -struct snd_soc_jack_gpio; -#endif typedef int (*hw_write_t)(void *,const char* ,int); typedef int (*hw_read_t)(void *,char* ,int); @@ -193,19 +184,6 @@ int snd_soc_init_card(struct snd_soc_device *socdev); int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, const struct snd_pcm_hardware *hw); -/* Jack reporting */ -int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, - struct snd_soc_jack *jack); -void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); -int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, - struct snd_soc_jack_pin *pins); -#ifdef CONFIG_GPIOLIB -int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, - struct snd_soc_jack_gpio *gpios); -void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, - struct snd_soc_jack_gpio *gpios); -#endif - /* codec IO */ #define snd_soc_read(codec, reg) codec->read(codec, reg) #define snd_soc_write(codec, reg, value) codec->write(codec, reg, value) @@ -225,8 +203,6 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); */ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, void *data, char *long_name); -int snd_soc_add_controls(struct snd_soc_codec *codec, - const struct snd_kcontrol_new *controls, int num_controls); int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol, @@ -261,48 +237,6 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -/** - * struct snd_soc_jack_pin - Describes a pin to update based on jack detection - * - * @pin: name of the pin to update - * @mask: bits to check for in reported jack status - * @invert: if non-zero then pin is enabled when status is not reported - */ -struct snd_soc_jack_pin { - struct list_head list; - const char *pin; - int mask; - bool invert; -}; - -/** - * struct snd_soc_jack_gpio - Describes a gpio pin for jack detection - * - * @gpio: gpio number - * @name: gpio name - * @report: value to report when jack detected - * @invert: report presence in low state - * @debouce_time: debouce time in ms - */ -#ifdef CONFIG_GPIOLIB -struct snd_soc_jack_gpio { - unsigned int gpio; - const char *name; - int report; - int invert; - int debounce_time; - struct snd_soc_jack *jack; - struct work_struct work; -}; -#endif - -struct snd_soc_jack { - struct snd_jack *jack; - struct snd_soc_card *card; - struct list_head pins; - int status; -}; - /* SoC PCM stream information */ struct snd_soc_pcm_stream { char *stream_name; @@ -450,8 +384,6 @@ struct snd_soc_card { struct snd_soc_device *socdev; - struct snd_soc_codec *codec; - struct snd_soc_platform *platform; struct delayed_work delayed_work; struct work_struct deferred_resume_work; @@ -461,6 +393,7 @@ struct snd_soc_card { struct snd_soc_device { struct device *dev; struct snd_soc_card *card; + struct snd_soc_codec *codec; struct snd_soc_codec_device *codec_dev; void *codec_data; }; diff --git a/trunk/include/sound/uda1341.h b/trunk/include/sound/uda1341.h new file mode 100644 index 000000000000..110d5dc3a2be --- /dev/null +++ b/trunk/include/sound/uda1341.h @@ -0,0 +1,126 @@ +/* + * linux/include/linux/l3/uda1341.h + * + * Philips UDA1341 mixer device driver for ALSA + * + * Copyright (c) 2002 Tomas Kasparek + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + * + * History: + * + * 2002-03-13 Tomas Kasparek Initial release - based on uda1341.h from OSS + * 2002-03-30 Tomas Kasparek Proc filesystem support, complete mixer and DSP + * features support + */ + +#define UDA1341_ALSA_NAME "snd-uda1341" + +/* + * Default rate set after inicialization + */ +#define AUDIO_RATE_DEFAULT 44100 + +/* + * UDA1341 L3 address and command types + */ +#define UDA1341_L3ADDR 5 +#define UDA1341_DATA0 (UDA1341_L3ADDR << 2 | 0) +#define UDA1341_DATA1 (UDA1341_L3ADDR << 2 | 1) +#define UDA1341_STATUS (UDA1341_L3ADDR << 2 | 2) + +enum uda1341_onoff { + OFF=0, + ON, +}; + +enum uda1341_format { + I2S=0, + LSB16, + LSB18, + LSB20, + MSB, + LSB16MSB, + LSB18MSB, + LSB20MSB, +}; + +enum uda1341_fs { + F512=0, + F384, + F256, + Funused, +}; + +enum uda1341_peak { + BEFORE=0, + AFTER, +}; + +enum uda1341_filter { + FLAT=0, + MIN, + MIN2, + MAX, +}; + +enum uda1341_mixer { + DOUBLE, + LINE, + MIC, + MIXER, +}; + +enum uda1341_deemp { + NONE, + D32, + D44, + D48, +}; + +enum uda1341_config { + CMD_READ_REG = 0, + CMD_RESET, + CMD_FS, + CMD_FORMAT, + CMD_OGAIN, + CMD_IGAIN, + CMD_DAC, + CMD_ADC, + CMD_VOLUME, + CMD_BASS, + CMD_TREBBLE, + CMD_PEAK, + CMD_DEEMP, + CMD_MUTE, + CMD_FILTER, + CMD_CH1, + CMD_CH2, + CMD_MIC, + CMD_MIXER, + CMD_AGC, + CMD_IG, + CMD_AGC_TIME, + CMD_AGC_LEVEL, +#ifdef CONFIG_PM + CMD_SUSPEND, + CMD_RESUME, +#endif + CMD_LAST, +}; + +enum write_through { + //used in update_bits (write_cfg) to avoid l3_write - just update local copy of regs. + REGS_ONLY=0, + //update local regs and write value to uda1341 - do l3_write + FLUSH, +}; + +int __init snd_chip_uda1341_mixer_new(struct snd_card *card, struct l3_client **clnt); + +/* + * Local variables: + * indent-tabs-mode: t + * End: + */ diff --git a/trunk/include/sound/version.h b/trunk/include/sound/version.h index a7e74e23ad2e..2b48237e23bf 100644 --- a/trunk/include/sound/version.h +++ b/trunk/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h */ -#define CONFIG_SND_VERSION "1.0.19" +#define CONFIG_SND_VERSION "1.0.18a" #define CONFIG_SND_DATE "" diff --git a/trunk/include/sound/wss.h b/trunk/include/sound/wss.h index 6d65f322f1d5..fd01f22825cd 100644 --- a/trunk/include/sound/wss.h +++ b/trunk/include/sound/wss.h @@ -154,7 +154,6 @@ int snd_wss_create(struct snd_card *card, unsigned short hardware, unsigned short hwshare, struct snd_wss **rchip); -int snd_wss_free(struct snd_wss *chip); int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm); int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer); int snd_wss_mixer(struct snd_wss *chip); diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 1196f5d11700..ba22484a987e 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -2015,6 +2015,14 @@ static noinline struct module *load_module(void __user *umod, if (err < 0) goto free_mod; +#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) + mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), + mod->name); + if (!mod->refptr) { + err = -ENOMEM; + goto free_mod; + } +#endif if (pcpuindex) { /* We have a special allocation for this section. */ percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, @@ -2022,7 +2030,7 @@ static noinline struct module *load_module(void __user *umod, mod->name); if (!percpu) { err = -ENOMEM; - goto free_mod; + goto free_percpu; } sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; mod->percpu = percpu; @@ -2074,14 +2082,6 @@ static noinline struct module *load_module(void __user *umod, /* Module has been moved. */ mod = (void *)sechdrs[modindex].sh_addr; -#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) - mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), - mod->name); - if (!mod->refptr) { - err = -ENOMEM; - goto free_init; - } -#endif /* Now we've moved module, initialize linked lists, etc. */ module_unload_init(mod); @@ -2288,17 +2288,15 @@ static noinline struct module *load_module(void __user *umod, ftrace_release(mod->module_core, mod->core_size); free_unload: module_unload_free(mod); - free_init: -#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) - percpu_modfree(mod->refptr); -#endif module_free(mod, mod->module_init); free_core: module_free(mod, mod->module_core); - /* mod will be freed with core. Don't access it beyond this line! */ free_percpu: if (percpu) percpu_modfree(percpu); +#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) + percpu_modfree(mod->refptr); +#endif free_mod: kfree(args); free_hdr: diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 1c8814481a11..2a74fe87c0dd 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -1575,15 +1575,7 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) read_lock(&tasklist_lock); if (may_ptrace_stop()) { do_notify_parent_cldstop(current, CLD_TRAPPED); - /* - * Don't want to allow preemption here, because - * sys_ptrace() needs this task to be inactive. - * - * XXX: implement read_unlock_no_resched(). - */ - preempt_disable(); read_unlock(&tasklist_lock); - preempt_enable_no_resched(); schedule(); } else { /* diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 56ddf41149eb..e89517141657 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -1262,6 +1262,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, * Move the pages to the [file or anon] inactive list. */ pagevec_init(&pvec, 1); + pgmoved = 0; lru = LRU_BASE + file * LRU_FILE; spin_lock_irq(&zone->lru_lock); @@ -1273,7 +1274,6 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, */ reclaim_stat->recent_rotated[!!file] += pgmoved; - pgmoved = 0; while (!list_empty(&l_inactive)) { page = lru_to_page(&l_inactive); prefetchw_prev_lru_page(page, &l_inactive, flags); diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index e3fe5c705606..f1129706ce7b 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -2588,9 +2588,9 @@ static int process_backlog(struct napi_struct *napi, int quota) local_irq_disable(); skb = __skb_dequeue(&queue->input_pkt_queue); if (!skb) { + __napi_complete(napi); local_irq_enable(); - napi_complete(napi); - goto out; + break; } local_irq_enable(); @@ -2599,7 +2599,6 @@ static int process_backlog(struct napi_struct *napi, int quota) napi_gro_flush(napi); -out: return work; } @@ -2672,7 +2671,7 @@ void netif_napi_del(struct napi_struct *napi) struct sk_buff *skb, *next; list_del_init(&napi->dev_list); - kfree_skb(napi->skb); + kfree(napi->skb); for (skb = napi->gro_list; skb; skb = next) { next = skb->next; diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 7985346653bd..6659ac000eeb 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -463,7 +463,6 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, struct net_device *dev) { - struct net *net = container_of(qp->q.net, struct net, ipv4.frags); struct iphdr *iph; struct sk_buff *fp, *head = qp->q.fragments; int len; @@ -549,7 +548,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, iph = ip_hdr(head); iph->frag_off = 0; iph->tot_len = htons(len); - IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS); + IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMOKS); qp->q.fragments = NULL; return 0; diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index 9c8309ed35cf..da944eca2ca6 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -1192,9 +1192,6 @@ module_init(inet6_init); static void __exit inet6_exit(void) { - if (disable_ipv6) - return; - /* First of all disallow new sockets creation. */ sock_unregister(PF_INET6); /* Disallow any further netlink messages */ diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 058a5e4a60c3..ed4d79a9e4a6 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -528,14 +528,14 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff) if (!ipv6_ext_hdr(nexthdr)) { return -1; } - if (nexthdr == NEXTHDR_NONE) { - pr_debug("next header is none\n"); - return -1; - } if (len < (int)sizeof(struct ipv6_opt_hdr)) { pr_debug("too short\n"); return -1; } + if (nexthdr == NEXTHDR_NONE) { + pr_debug("next header is none\n"); + return -1; + } if (skb_copy_bits(skb, start, &hdr, sizeof(hdr))) BUG(); if (nexthdr == NEXTHDR_AUTH) diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index e9ac7a12f595..3c575118fca5 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -452,7 +452,6 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, struct net_device *dev) { - struct net *net = container_of(fq->q.net, struct net, ipv6.frags); struct sk_buff *fp, *head = fq->q.fragments; int payload_len; unsigned int nhoff; @@ -552,7 +551,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, head->csum); rcu_read_lock(); - IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); + IP6_INC_STATS_BH(dev_net(dev), + __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); rcu_read_unlock(); fq->q.fragments = NULL; return 1; @@ -566,7 +566,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); out_fail: rcu_read_lock(); - IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); + IP6_INC_STATS_BH(dev_net(dev), + __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); rcu_read_unlock(); return -1; } diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index 5cee2bcbcece..d3467e563f02 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -188,9 +188,9 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, } nt = netdev_priv(dev); + ipip6_tunnel_init(dev); nt->parms = *parms; - ipip6_tunnel_init(dev); if (parms->i_flags & SIT_ISATAP) dev->priv_flags |= IFF_ISATAP; diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 37e3d5ef7e3f..94de5033f0b6 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -752,8 +752,6 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) skb_copy_queue_mapping(frag, first); frag->do_not_encrypt = first->do_not_encrypt; - frag->dev = first->dev; - frag->iif = first->iif; pos += copylen; left -= copylen; diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index f4935e344b61..90ce9ddb9451 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -726,7 +726,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, NF_CT_ASSERT(skb->nfct); ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum); - if (ret <= 0) { + if (ret < 0) { /* Invalid: inverse of the return code tells * the netfilter core what to do */ pr_debug("nf_conntrack_in: Can't track with proto module\n"); diff --git a/trunk/net/netfilter/nf_conntrack_netlink.c b/trunk/net/netfilter/nf_conntrack_netlink.c index ed6d873ad384..cb78aa00399e 100644 --- a/trunk/net/netfilter/nf_conntrack_netlink.c +++ b/trunk/net/netfilter/nf_conntrack_netlink.c @@ -1780,7 +1780,6 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3, u32 pid, int report) goto out; } - exp->class = 0; exp->expectfn = NULL; exp->flags = 0; exp->master = ct; diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index f3fd154d1ddd..a1edb9c1adee 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -859,7 +859,7 @@ static int tcp_packet(struct nf_conn *ct, */ if (nf_ct_kill(ct)) return -NF_REPEAT; - return NF_DROP; + return -NF_DROP; } /* Fall through */ case TCP_CONNTRACK_IGNORE: @@ -892,7 +892,7 @@ static int tcp_packet(struct nf_conn *ct, nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: killing out of sync session "); nf_ct_kill(ct); - return NF_DROP; + return -NF_DROP; } ct->proto.tcp.last_index = index; ct->proto.tcp.last_dir = dir; diff --git a/trunk/net/sctp/endpointola.c b/trunk/net/sctp/endpointola.c index 905fda582b92..4c8d9f45ce09 100644 --- a/trunk/net/sctp/endpointola.c +++ b/trunk/net/sctp/endpointola.c @@ -111,8 +111,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, if (sctp_addip_enable) { auth_chunks->chunks[0] = SCTP_CID_ASCONF; auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; - auth_chunks->param_hdr.length = - htons(sizeof(sctp_paramhdr_t) + 2); + auth_chunks->param_hdr.length += htons(2); } } diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index ff50a0546865..385f427bedad 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -293,6 +293,11 @@ static void rpc_make_runnable(struct rpc_task *task) rpc_clear_queued(task); if (rpc_test_and_set_running(task)) return; + /* We might have raced */ + if (RPC_IS_QUEUED(task)) { + rpc_clear_running(task); + return; + } if (RPC_IS_ASYNC(task)) { int status; @@ -602,9 +607,7 @@ void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) */ static void __rpc_execute(struct rpc_task *task) { - struct rpc_wait_queue *queue; - int task_is_async = RPC_IS_ASYNC(task); - int status = 0; + int status = 0; dprintk("RPC: %5u __rpc_execute flags=0x%x\n", task->tk_pid, task->tk_flags); @@ -644,25 +647,15 @@ static void __rpc_execute(struct rpc_task *task) */ if (!RPC_IS_QUEUED(task)) continue; - /* - * The queue->lock protects against races with - * rpc_make_runnable(). - * - * Note that once we clear RPC_TASK_RUNNING on an asynchronous - * rpc_task, rpc_make_runnable() can assign it to a - * different workqueue. We therefore cannot assume that the - * rpc_task pointer may still be dereferenced. - */ - queue = task->tk_waitqueue; - spin_lock_bh(&queue->lock); - if (!RPC_IS_QUEUED(task)) { - spin_unlock_bh(&queue->lock); + rpc_clear_running(task); + if (RPC_IS_ASYNC(task)) { + /* Careful! we may have raced... */ + if (RPC_IS_QUEUED(task)) + return; + if (rpc_test_and_set_running(task)) + return; continue; } - rpc_clear_running(task); - spin_unlock_bh(&queue->lock); - if (task_is_async) - return; /* sync task: sleep here */ dprintk("RPC: %5u sync task going to sleep\n", task->tk_pid); diff --git a/trunk/net/sunrpc/xprt.c b/trunk/net/sunrpc/xprt.c index 62098d101a1f..29e401bb612e 100644 --- a/trunk/net/sunrpc/xprt.c +++ b/trunk/net/sunrpc/xprt.c @@ -663,7 +663,7 @@ void xprt_connect(struct rpc_task *task) xprt, (xprt_connected(xprt) ? "is" : "is not")); if (!xprt_bound(xprt)) { - task->tk_status = -EAGAIN; + task->tk_status = -EIO; return; } if (!xprt_lock_write(xprt, task)) diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index 29c71e645b27..5cbb404c4cdf 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -467,7 +467,7 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, int err, sent = 0; if (unlikely(!sock)) - return -ENOTSOCK; + return -ENOTCONN; clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags); if (base != 0) { @@ -577,8 +577,6 @@ static int xs_udp_send_request(struct rpc_task *task) req->rq_svec->iov_base, req->rq_svec->iov_len); - if (!xprt_bound(xprt)) - return -ENOTCONN; status = xs_sendpages(transport->sock, xs_addr(xprt), xprt->addrlen, xdr, @@ -596,10 +594,6 @@ static int xs_udp_send_request(struct rpc_task *task) } switch (status) { - case -ENOTSOCK: - status = -ENOTCONN; - /* Should we call xs_close() here? */ - break; case -EAGAIN: xs_nospace(task); break; @@ -699,10 +693,6 @@ static int xs_tcp_send_request(struct rpc_task *task) } switch (status) { - case -ENOTSOCK: - status = -ENOTCONN; - /* Should we call xs_close() here? */ - break; case -EAGAIN: xs_nospace(task); break; @@ -1533,7 +1523,7 @@ static void xs_udp_connect_worker4(struct work_struct *work) struct socket *sock = transport->sock; int err, status = -EIO; - if (xprt->shutdown) + if (xprt->shutdown || !xprt_bound(xprt)) goto out; /* Start by resetting any existing state */ @@ -1574,7 +1564,7 @@ static void xs_udp_connect_worker6(struct work_struct *work) struct socket *sock = transport->sock; int err, status = -EIO; - if (xprt->shutdown) + if (xprt->shutdown || !xprt_bound(xprt)) goto out; /* Start by resetting any existing state */ @@ -1658,9 +1648,6 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) write_unlock_bh(&sk->sk_callback_lock); } - if (!xprt_bound(xprt)) - return -ENOTCONN; - /* Tell the socket layer to start connecting... */ xprt->stat.connect_count++; xprt->stat.connect_start = jiffies; @@ -1681,7 +1668,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work) struct socket *sock = transport->sock; int err, status = -EIO; - if (xprt->shutdown) + if (xprt->shutdown || !xprt_bound(xprt)) goto out; if (!sock) { @@ -1741,7 +1728,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work) struct socket *sock = transport->sock; int err, status = -EIO; - if (xprt->shutdown) + if (xprt->shutdown || !xprt_bound(xprt)) goto out; if (!sock) { diff --git a/trunk/net/wireless/Kconfig b/trunk/net/wireless/Kconfig index 092ae6faccca..e28e2b8fa436 100644 --- a/trunk/net/wireless/Kconfig +++ b/trunk/net/wireless/Kconfig @@ -102,13 +102,3 @@ config LIB80211_CRYPT_CCMP config LIB80211_CRYPT_TKIP tristate - -config LIB80211_DEBUG - bool "lib80211 debugging messages" - depends on LIB80211 - default n - ---help--- - You can enable this if you want verbose debugging messages - from lib80211. - - If unsure, say N. diff --git a/trunk/net/wireless/lib80211_crypt_ccmp.c b/trunk/net/wireless/lib80211_crypt_ccmp.c index 2301dc1edc4c..db428194c16a 100644 --- a/trunk/net/wireless/lib80211_crypt_ccmp.c +++ b/trunk/net/wireless/lib80211_crypt_ccmp.c @@ -337,7 +337,6 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) pos += 8; if (ccmp_replay_check(pn, key->rx_pn)) { -#ifdef CONFIG_LIB80211_DEBUG if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: replay detected: STA=%pM " "previous PN %02x%02x%02x%02x%02x%02x " @@ -347,7 +346,6 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); } -#endif key->dot11RSNAStatsCCMPReplays++; return -4; } diff --git a/trunk/net/wireless/lib80211_crypt_tkip.c b/trunk/net/wireless/lib80211_crypt_tkip.c index c36287399d7e..7e8e22bfed90 100644 --- a/trunk/net/wireless/lib80211_crypt_tkip.c +++ b/trunk/net/wireless/lib80211_crypt_tkip.c @@ -465,14 +465,12 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) pos += 8; if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { -#ifdef CONFIG_LIB80211_DEBUG if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" " previous TSC %08x%04x received TSC " "%08x%04x\n", hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); } -#endif tkey->dot11RSNAStatsTKIPReplays++; return -4; } @@ -507,12 +505,10 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) * it needs to be recalculated for the next packet. */ tkey->rx_phase1_done = 0; } -#ifdef CONFIG_LIB80211_DEBUG if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: ICV error detected: STA=" "%pM\n", hdr->addr2); } -#endif tkey->dot11RSNAStatsTKIPICVErrors++; return -5; } diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 31b807af3235..1e728fff474e 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -1908,11 +1908,6 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, if (err) return err; - if (!drv->ops->get_mesh_params) { - err = -EOPNOTSUPP; - goto out; - } - /* Get the mesh params */ rtnl_lock(); err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params); @@ -2022,11 +2017,6 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) if (err) return err; - if (!drv->ops->set_mesh_params) { - err = -EOPNOTSUPP; - goto out; - } - /* This makes sure that there aren't more than 32 mesh config * parameters (otherwise our bitfield scheme would not work.) */ BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32); @@ -2071,7 +2061,6 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask); rtnl_unlock(); - out: /* cleanup */ cfg80211_put_dev(drv); dev_put(dev); diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index 62a5425cc6aa..e25ff62ab2a6 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -748,51 +748,12 @@ static void xfrm_hash_grow_check(struct net *net, int have_hash_collision) schedule_work(&net->xfrm.state_hash_work); } -static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x, - struct flowi *fl, unsigned short family, - xfrm_address_t *daddr, xfrm_address_t *saddr, - struct xfrm_state **best, int *acq_in_progress, - int *error) -{ - /* Resolution logic: - * 1. There is a valid state with matching selector. Done. - * 2. Valid state with inappropriate selector. Skip. - * - * Entering area of "sysdeps". - * - * 3. If state is not valid, selector is temporary, it selects - * only session which triggered previous resolution. Key - * manager will do something to install a state with proper - * selector. - */ - if (x->km.state == XFRM_STATE_VALID) { - if ((x->sel.family && - !xfrm_selector_match(&x->sel, fl, x->sel.family)) || - !security_xfrm_state_pol_flow_match(x, pol, fl)) - return; - - if (!*best || - (*best)->km.dying > x->km.dying || - ((*best)->km.dying == x->km.dying && - (*best)->curlft.add_time < x->curlft.add_time)) - *best = x; - } else if (x->km.state == XFRM_STATE_ACQ) { - *acq_in_progress = 1; - } else if (x->km.state == XFRM_STATE_ERROR || - x->km.state == XFRM_STATE_EXPIRED) { - if (xfrm_selector_match(&x->sel, fl, x->sel.family) && - security_xfrm_state_pol_flow_match(x, pol, fl)) - *error = -ESRCH; - } -} - struct xfrm_state * xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, struct flowi *fl, struct xfrm_tmpl *tmpl, struct xfrm_policy *pol, int *err, unsigned short family) { - static xfrm_address_t saddr_wildcard = { }; struct net *net = xp_net(pol); unsigned int h; struct hlist_node *entry; @@ -812,27 +773,40 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, xfrm_state_addr_check(x, daddr, saddr, family) && tmpl->mode == x->props.mode && tmpl->id.proto == x->id.proto && - (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) - xfrm_state_look_at(pol, x, fl, family, daddr, saddr, - &best, &acquire_in_progress, &error); - } - if (best) - goto found; - - h = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, family); - hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { - if (x->props.family == family && - x->props.reqid == tmpl->reqid && - !(x->props.flags & XFRM_STATE_WILDRECV) && - xfrm_state_addr_check(x, daddr, saddr, family) && - tmpl->mode == x->props.mode && - tmpl->id.proto == x->id.proto && - (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) - xfrm_state_look_at(pol, x, fl, family, daddr, saddr, - &best, &acquire_in_progress, &error); + (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) { + /* Resolution logic: + 1. There is a valid state with matching selector. + Done. + 2. Valid state with inappropriate selector. Skip. + + Entering area of "sysdeps". + + 3. If state is not valid, selector is temporary, + it selects only session which triggered + previous resolution. Key manager will do + something to install a state with proper + selector. + */ + if (x->km.state == XFRM_STATE_VALID) { + if ((x->sel.family && !xfrm_selector_match(&x->sel, fl, x->sel.family)) || + !security_xfrm_state_pol_flow_match(x, pol, fl)) + continue; + if (!best || + best->km.dying > x->km.dying || + (best->km.dying == x->km.dying && + best->curlft.add_time < x->curlft.add_time)) + best = x; + } else if (x->km.state == XFRM_STATE_ACQ) { + acquire_in_progress = 1; + } else if (x->km.state == XFRM_STATE_ERROR || + x->km.state == XFRM_STATE_EXPIRED) { + if (xfrm_selector_match(&x->sel, fl, x->sel.family) && + security_xfrm_state_pol_flow_match(x, pol, fl)) + error = -ESRCH; + } + } } -found: x = best; if (!x && !error && !acquire_in_progress) { if (tmpl->id.spi && diff --git a/trunk/scripts/kconfig/conf.c b/trunk/scripts/kconfig/conf.c index d190092c3b6e..3e1057f885c6 100644 --- a/trunk/scripts/kconfig/conf.c +++ b/trunk/scripts/kconfig/conf.c @@ -11,7 +11,6 @@ #include #include #include -#include #define LKC_DIRECT_LINK #include "lkc.h" @@ -465,22 +464,9 @@ int main(int ac, char **av) input_mode = set_yes; break; case 'r': - { - struct timeval now; - unsigned int seed; - - /* - * Use microseconds derived seed, - * compensate for systems where it may be zero - */ - gettimeofday(&now, NULL); - - seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); - srand(seed); - input_mode = set_random; + srand(time(NULL)); break; - } case 'h': printf(_("See README for usage info\n")); exit(0); diff --git a/trunk/scripts/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c index 273d73888f9d..830d9eae11f9 100644 --- a/trunk/scripts/kconfig/confdata.c +++ b/trunk/scripts/kconfig/confdata.c @@ -843,7 +843,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) default: continue; } - if (!(sym_is_choice(sym) && mode == def_random)) + if (!sym_is_choice(sym) || mode != def_random) sym->flags |= SYMBOL_DEF_USER; break; default: @@ -856,49 +856,28 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) if (mode != def_random) return; - /* - * We have different type of choice blocks. - * If curr.tri equal to mod then we can select several - * choice symbols in one block. - * In this case we do nothing. - * If curr.tri equal yes then only one symbol can be - * selected in a choice block and we set it to yes, - * and the rest to no. - */ + for_all_symbols(i, csym) { if (sym_has_value(csym) || !sym_is_choice(csym)) continue; sym_calc_value(csym); - - if (csym->curr.tri != yes) - continue; - prop = sym_get_choice_prop(csym); - - /* count entries in choice block */ - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) - cnt++; - - /* - * find a random value and set it to yes, - * set the rest to no so we have only one set - */ - def = (rand() % cnt); - - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) { - if (def == cnt++) { - sym->def[S_DEF_USER].tri = yes; - csym->def[S_DEF_USER].val = sym; - } - else { - sym->def[S_DEF_USER].tri = no; + def = -1; + while (1) { + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) { + if (sym->visible == no) + continue; + if (def == cnt++) { + csym->def[S_DEF_USER].val = sym; + break; + } } + if (def >= 0 || cnt < 2) + break; + def = (rand() % cnt) + 1; } csym->flags |= SYMBOL_DEF_USER; - /* clear VALID to get value calculated */ - csym->flags &= ~(SYMBOL_VALID); } } diff --git a/trunk/sound/Kconfig b/trunk/sound/Kconfig index 1eceb85287c5..200aca1faa71 100644 --- a/trunk/sound/Kconfig +++ b/trunk/sound/Kconfig @@ -60,8 +60,6 @@ source "sound/aoa/Kconfig" source "sound/arm/Kconfig" -source "sound/atmel/Kconfig" - source "sound/spi/Kconfig" source "sound/mips/Kconfig" diff --git a/trunk/sound/Makefile b/trunk/sound/Makefile index ec467decfa79..c76d70716fa5 100644 --- a/trunk/sound/Makefile +++ b/trunk/sound/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o obj-$(CONFIG_SOUND_PRIME) += oss/ obj-$(CONFIG_DMASOUND) += oss/ obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \ - sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ + sparc/ spi/ parisc/ pcmcia/ mips/ soc/ obj-$(CONFIG_SND_AOA) += aoa/ # This one must be compilable even if sound is configured out diff --git a/trunk/sound/aoa/aoa-gpio.h b/trunk/sound/aoa/aoa-gpio.h index 6065b0344e23..ee64f5de8966 100644 --- a/trunk/sound/aoa/aoa-gpio.h +++ b/trunk/sound/aoa/aoa-gpio.h @@ -34,12 +34,10 @@ struct gpio_methods { void (*set_headphone)(struct gpio_runtime *rt, int on); void (*set_speakers)(struct gpio_runtime *rt, int on); void (*set_lineout)(struct gpio_runtime *rt, int on); - void (*set_master)(struct gpio_runtime *rt, int on); int (*get_headphone)(struct gpio_runtime *rt); int (*get_speakers)(struct gpio_runtime *rt); int (*get_lineout)(struct gpio_runtime *rt); - int (*get_master)(struct gpio_runtime *rt); void (*set_hw_reset)(struct gpio_runtime *rt, int on); diff --git a/trunk/sound/aoa/core/alsa.c b/trunk/sound/aoa/core/alsa.c index 0fa3855b4790..617850463582 100644 --- a/trunk/sound/aoa/core/alsa.c +++ b/trunk/sound/aoa/core/alsa.c @@ -23,10 +23,9 @@ int aoa_alsa_init(char *name, struct module *mod, struct device *dev) /* cannot be EEXIST due to usage in aoa_fabric_register */ return -EBUSY; - err = snd_card_create(index, name, mod, sizeof(struct aoa_card), - &alsa_card); - if (err < 0) - return err; + alsa_card = snd_card_new(index, name, mod, sizeof(struct aoa_card)); + if (!alsa_card) + return -ENOMEM; aoa_card = alsa_card->private_data; aoa_card->alsa_card = alsa_card; alsa_card->dev = dev; diff --git a/trunk/sound/aoa/core/gpio-feature.c b/trunk/sound/aoa/core/gpio-feature.c index de8e03afa97b..c93ad5dec66b 100644 --- a/trunk/sound/aoa/core/gpio-feature.c +++ b/trunk/sound/aoa/core/gpio-feature.c @@ -14,7 +14,7 @@ #include #include "../aoa.h" -/* TODO: these are lots of global variables +/* TODO: these are 20 global variables * that aren't used on most machines... * Move them into a dynamically allocated * structure and use that. @@ -23,7 +23,6 @@ /* these are the GPIO numbers (register addresses as offsets into * the GPIO space) */ static int headphone_mute_gpio; -static int master_mute_gpio; static int amp_mute_gpio; static int lineout_mute_gpio; static int hw_reset_gpio; @@ -33,7 +32,6 @@ static int linein_detect_gpio; /* see the SWITCH_GPIO macro */ static int headphone_mute_gpio_activestate; -static int master_mute_gpio_activestate; static int amp_mute_gpio_activestate; static int lineout_mute_gpio_activestate; static int hw_reset_gpio_activestate; @@ -158,7 +156,6 @@ static int ftr_gpio_get_##name(struct gpio_runtime *rt) \ FTR_GPIO(headphone, 0); FTR_GPIO(amp, 1); FTR_GPIO(lineout, 2); -FTR_GPIO(master, 3); static void ftr_gpio_set_hw_reset(struct gpio_runtime *rt, int on) { @@ -175,8 +172,6 @@ static void ftr_gpio_set_hw_reset(struct gpio_runtime *rt, int on) hw_reset_gpio, v); } -static struct gpio_methods methods; - static void ftr_gpio_all_amps_off(struct gpio_runtime *rt) { int saved; @@ -186,8 +181,6 @@ static void ftr_gpio_all_amps_off(struct gpio_runtime *rt) ftr_gpio_set_headphone(rt, 0); ftr_gpio_set_amp(rt, 0); ftr_gpio_set_lineout(rt, 0); - if (methods.set_master) - ftr_gpio_set_master(rt, 0); rt->implementation_private = saved; } @@ -200,8 +193,6 @@ static void ftr_gpio_all_amps_restore(struct gpio_runtime *rt) ftr_gpio_set_headphone(rt, (s>>0)&1); ftr_gpio_set_amp(rt, (s>>1)&1); ftr_gpio_set_lineout(rt, (s>>2)&1); - if (methods.set_master) - ftr_gpio_set_master(rt, (s>>3)&1); } static void ftr_handle_notify(struct work_struct *work) @@ -240,12 +231,6 @@ static void ftr_gpio_init(struct gpio_runtime *rt) get_gpio("hw-reset", "audio-hw-reset", &hw_reset_gpio, &hw_reset_gpio_activestate); - if (get_gpio("master-mute", NULL, - &master_mute_gpio, - &master_mute_gpio_activestate)) { - methods.set_master = ftr_gpio_set_master; - methods.get_master = ftr_gpio_get_master; - } headphone_detect_node = get_gpio("headphone-detect", NULL, &headphone_detect_gpio, diff --git a/trunk/sound/aoa/fabrics/layout.c b/trunk/sound/aoa/fabrics/layout.c index fbf5c933baa4..ad60f5d10e82 100644 --- a/trunk/sound/aoa/fabrics/layout.c +++ b/trunk/sound/aoa/fabrics/layout.c @@ -1,14 +1,16 @@ /* - * Apple Onboard Audio driver -- layout/machine id fabric + * Apple Onboard Audio driver -- layout fabric * - * Copyright 2006-2008 Johannes Berg + * Copyright 2006 Johannes Berg * * GPL v2, can be found in COPYING. * * - * This fabric module looks for sound codecs based on the - * layout-id or device-id property in the device tree. + * This fabric module looks for sound codecs + * based on the layout-id property in the device tree. + * */ + #include #include #include @@ -61,7 +63,7 @@ struct codec_connect_info { #define LAYOUT_FLAG_COMBO_LINEOUT_SPDIF (1<<0) struct layout { - unsigned int layout_id, device_id; + unsigned int layout_id; struct codec_connect_info codecs[MAX_CODECS_PER_BUS]; int flags; @@ -109,10 +111,6 @@ MODULE_ALIAS("sound-layout-96"); MODULE_ALIAS("sound-layout-98"); MODULE_ALIAS("sound-layout-100"); -MODULE_ALIAS("aoa-device-id-14"); -MODULE_ALIAS("aoa-device-id-22"); -MODULE_ALIAS("aoa-device-id-35"); - /* onyx with all but microphone connected */ static struct codec_connection onyx_connections_nomic[] = { { @@ -520,27 +518,6 @@ static struct layout layouts[] = { .connections = onyx_connections_noheadphones, }, }, - /* PowerMac3,4 */ - { .device_id = 14, - .codecs[0] = { - .name = "tas", - .connections = tas_connections_noline, - }, - }, - /* PowerMac3,6 */ - { .device_id = 22, - .codecs[0] = { - .name = "tas", - .connections = tas_connections_all, - }, - }, - /* PowerBook5,2 */ - { .device_id = 35, - .codecs[0] = { - .name = "tas", - .connections = tas_connections_all, - }, - }, {} }; @@ -549,7 +526,7 @@ static struct layout *find_layout_by_id(unsigned int id) struct layout *l; l = layouts; - while (l->codecs[0].name) { + while (l->layout_id) { if (l->layout_id == id) return l; l++; @@ -557,19 +534,6 @@ static struct layout *find_layout_by_id(unsigned int id) return NULL; } -static struct layout *find_layout_by_device(unsigned int id) -{ - struct layout *l; - - l = layouts; - while (l->codecs[0].name) { - if (l->device_id == id) - return l; - l++; - } - return NULL; -} - static void use_layout(struct layout *l) { int i; @@ -600,7 +564,6 @@ struct layout_dev { struct snd_kcontrol *headphone_ctrl; struct snd_kcontrol *lineout_ctrl; struct snd_kcontrol *speaker_ctrl; - struct snd_kcontrol *master_ctrl; struct snd_kcontrol *headphone_detected_ctrl; struct snd_kcontrol *lineout_detected_ctrl; @@ -652,7 +615,6 @@ static struct snd_kcontrol_new n##_ctl = { \ AMP_CONTROL(headphone, "Headphone Switch"); AMP_CONTROL(speakers, "Speakers Switch"); AMP_CONTROL(lineout, "Line-Out Switch"); -AMP_CONTROL(master, "Master Switch"); static int detect_choice_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -893,11 +855,6 @@ static void layout_attached_codec(struct aoa_codec *codec) lineout = codec->gpio->methods->get_detect(codec->gpio, AOA_NOTIFY_LINE_OUT); - if (codec->gpio->methods->set_master) { - ctl = snd_ctl_new1(&master_ctl, codec->gpio); - ldev->master_ctrl = ctl; - aoa_snd_ctl_add(ctl); - } while (cc->connected) { if (cc->connected & CC_SPEAKERS) { if (headphones <= 0 && lineout <= 0) @@ -981,8 +938,8 @@ static struct aoa_fabric layout_fabric = { static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) { struct device_node *sound = NULL; - const unsigned int *id; - struct layout *layout = NULL; + const unsigned int *layout_id; + struct layout *layout; struct layout_dev *ldev = NULL; int err; @@ -995,18 +952,15 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) if (sound->type && strcasecmp(sound->type, "soundchip") == 0) break; } - if (!sound) - return -ENODEV; + if (!sound) return -ENODEV; - id = of_get_property(sound, "layout-id", NULL); - if (id) { - layout = find_layout_by_id(*id); - } else { - id = of_get_property(sound, "device-id", NULL); - if (id) - layout = find_layout_by_device(*id); - } + layout_id = of_get_property(sound, "layout-id", NULL); + if (!layout_id) + goto outnodev; + printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d\n", + *layout_id); + layout = find_layout_by_id(*layout_id); if (!layout) { printk(KERN_ERR "snd-aoa-fabric-layout: unknown layout\n"); goto outnodev; @@ -1022,7 +976,6 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) ldev->layout = layout; ldev->gpio.node = sound->parent; switch (layout->layout_id) { - case 0: /* anything with device_id, not layout_id */ case 41: /* that unknown machine no one seems to have */ case 51: /* PowerBook5,4 */ case 58: /* Mac Mini */ diff --git a/trunk/sound/aoa/soundbus/i2sbus/core.c b/trunk/sound/aoa/soundbus/i2sbus/core.c index 418c84c99d69..be468edf3ecb 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/core.c +++ b/trunk/sound/aoa/soundbus/i2sbus/core.c @@ -1,7 +1,7 @@ /* * i2sbus driver * - * Copyright 2006-2008 Johannes Berg + * Copyright 2006 Johannes Berg * * GPL v2, can be found in COPYING. */ @@ -186,25 +186,13 @@ static int i2sbus_add_dev(struct macio_dev *macio, } } if (i == 1) { - const u32 *id = of_get_property(sound, "layout-id", NULL); - - if (id) { - layout = *id; + const u32 *layout_id = + of_get_property(sound, "layout-id", NULL); + if (layout_id) { + layout = *layout_id; snprintf(dev->sound.modalias, 32, "sound-layout-%d", layout); ok = 1; - } else { - id = of_get_property(sound, "device-id", NULL); - /* - * We probably cannot handle all device-id machines, - * so restrict to those we do handle for now. - */ - if (id && (*id == 22 || *id == 14 || *id == 35)) { - snprintf(dev->sound.modalias, 32, - "aoa-device-id-%d", *id); - ok = 1; - layout = -1; - } } } /* for the time being, until we can handle non-layout-id diff --git a/trunk/sound/arm/Kconfig b/trunk/sound/arm/Kconfig index 885683a3b0bd..f8e6de48d816 100644 --- a/trunk/sound/arm/Kconfig +++ b/trunk/sound/arm/Kconfig @@ -11,6 +11,17 @@ menuconfig SND_ARM if SND_ARM +config SND_SA11XX_UDA1341 + tristate "SA11xx UDA1341TS driver (iPaq H3600)" + depends on ARCH_SA1100 && L3 + select SND_PCM + help + Say Y here if you have a Compaq iPaq H3x00 handheld computer + and want to use its Philips UDA 1341 audio chip. + + To compile this driver as a module, choose M here: the module + will be called snd-sa11xx-uda1341. + config SND_ARMAACI tristate "ARM PrimeCell PL041 AC Link support" depends on ARM_AMBA diff --git a/trunk/sound/arm/Makefile b/trunk/sound/arm/Makefile index 5a549ed6c8aa..2054de11de8a 100644 --- a/trunk/sound/arm/Makefile +++ b/trunk/sound/arm/Makefile @@ -2,6 +2,9 @@ # Makefile for ALSA # +obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-sa11xx-uda1341.o +snd-sa11xx-uda1341-objs := sa11xx-uda1341.o + obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o snd-aaci-objs := aaci.o devdma.o diff --git a/trunk/sound/arm/aaci.c b/trunk/sound/arm/aaci.c index 7fbd68fab944..772901e41ecb 100644 --- a/trunk/sound/arm/aaci.c +++ b/trunk/sound/arm/aaci.c @@ -995,11 +995,10 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) { struct aaci *aaci; struct snd_card *card; - int err; - err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, sizeof(struct aaci), &card); - if (err < 0) + card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, + THIS_MODULE, sizeof(struct aaci)); + if (card == NULL) return NULL; card->private_free = aaci_free_card; diff --git a/trunk/sound/arm/pxa2xx-ac97-lib.c b/trunk/sound/arm/pxa2xx-ac97-lib.c index 2e6355f4cbb9..35afd0c33be5 100644 --- a/trunk/sound/arm/pxa2xx-ac97-lib.c +++ b/trunk/sound/arm/pxa2xx-ac97-lib.c @@ -31,7 +31,6 @@ static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; static struct clk *ac97_clk; static struct clk *ac97conf_clk; -static int reset_gpio; /* * Beware PXA27x bugs: @@ -43,45 +42,6 @@ static int reset_gpio; * 1 jiffy timeout if interrupt never comes). */ -enum { - RESETGPIO_FORCE_HIGH, - RESETGPIO_FORCE_LOW, - RESETGPIO_NORMAL_ALTFUNC -}; - -/** - * set_resetgpio_mode - computes and sets the AC97_RESET gpio mode on PXA - * @mode: chosen action - * - * As the PXA27x CPUs suffer from a AC97 bug, a manual control of the reset line - * must be done to insure proper work of AC97 reset line. This function - * computes the correct gpio_mode for further use by reset functions, and - * applied the change through pxa_gpio_mode. - */ -static void set_resetgpio_mode(int resetgpio_action) -{ - int mode = 0; - - if (reset_gpio) - switch (resetgpio_action) { - case RESETGPIO_NORMAL_ALTFUNC: - if (reset_gpio == 113) - mode = 113 | GPIO_OUT | GPIO_DFLT_LOW; - if (reset_gpio == 95) - mode = 95 | GPIO_ALT_FN_1_OUT; - break; - case RESETGPIO_FORCE_LOW: - mode = reset_gpio | GPIO_OUT | GPIO_DFLT_LOW; - break; - case RESETGPIO_FORCE_HIGH: - mode = reset_gpio | GPIO_OUT | GPIO_DFLT_HIGH; - break; - }; - - if (mode) - pxa_gpio_mode(mode); -} - unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { unsigned short val = -1; @@ -177,10 +137,10 @@ static inline void pxa_ac97_warm_pxa27x(void) /* warm reset broken on Bulverde, so manually keep AC97 reset high */ - set_resetgpio_mode(RESETGPIO_FORCE_HIGH); + pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); udelay(10); GCR |= GCR_WARM_RST; - set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); + pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); udelay(500); } @@ -348,8 +308,8 @@ int pxa2xx_ac97_hw_resume(void) pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); } if (cpu_is_pxa27x()) { - /* Use GPIO 113 or 95 as AC97 Reset on Bulverde */ - set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); + /* Use GPIO 113 as AC97 Reset on Bulverde */ + pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); } clk_enable(ac97_clk); return 0; @@ -360,27 +320,6 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume); int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) { int ret; - struct pxa2xx_ac97_platform_data *pdata = dev->dev.platform_data; - - if (pdata) { - switch (pdata->reset_gpio) { - case 95: - case 113: - reset_gpio = pdata->reset_gpio; - break; - case 0: - reset_gpio = 113; - break; - case -1: - break; - default: - dev_err(&dev->dev, "Invalid reset GPIO %d\n", - pdata->reset_gpio); - } - } else { - if (cpu_is_pxa27x()) - reset_gpio = 113; - } if (cpu_is_pxa25x() || cpu_is_pxa27x()) { pxa_gpio_mode(GPIO31_SYNC_AC97_MD); @@ -391,7 +330,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) if (cpu_is_pxa27x()) { /* Use GPIO 113 as AC97 Reset on Bulverde */ - set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); + pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); if (IS_ERR(ac97conf_clk)) { ret = PTR_ERR(ac97conf_clk); diff --git a/trunk/sound/arm/pxa2xx-ac97.c b/trunk/sound/arm/pxa2xx-ac97.c index 7ed100c80a5f..85cf591d4e11 100644 --- a/trunk/sound/arm/pxa2xx-ac97.c +++ b/trunk/sound/arm/pxa2xx-ac97.c @@ -173,9 +173,10 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) struct snd_ac97_template ac97_template; int ret; - ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, 0, &card); - if (ret < 0) + ret = -ENOMEM; + card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, + THIS_MODULE, 0); + if (!card) goto err; card->dev = &dev->dev; diff --git a/trunk/sound/arm/sa11xx-uda1341.c b/trunk/sound/arm/sa11xx-uda1341.c new file mode 100644 index 000000000000..1dcd51d81d10 --- /dev/null +++ b/trunk/sound/arm/sa11xx-uda1341.c @@ -0,0 +1,983 @@ +/* + * Driver for Philips UDA1341TS on Compaq iPAQ H3600 soundcard + * Copyright (C) 2002 Tomas Kasparek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License. + * + * History: + * + * 2002-03-13 Tomas Kasparek initial release - based on h3600-uda1341.c from OSS + * 2002-03-20 Tomas Kasparek playback over ALSA is working + * 2002-03-28 Tomas Kasparek playback over OSS emulation is working + * 2002-03-29 Tomas Kasparek basic capture is working (native ALSA) + * 2002-03-29 Tomas Kasparek capture is working (OSS emulation) + * 2002-04-04 Tomas Kasparek better rates handling (allow non-standard rates) + * 2003-02-14 Brian Avery fixed full duplex mode, other updates + * 2003-02-20 Tomas Kasparek merged updates by Brian (except HAL) + * 2003-04-19 Jaroslav Kysela recoded DMA stuff to follow 2.4.18rmk3-hh24 kernel + * working suspend and resume + * 2003-04-28 Tomas Kasparek updated work by Jaroslav to compile it under 2.5.x again + * merged HAL layer (patches from Brian) + */ + +/*************************************************************************************************** +* +* To understand what Alsa Drivers should be doing look at "Writing an Alsa Driver" by Takashi Iwai +* available in the Alsa doc section on the website +* +* A few notes to make things clearer. The UDA1341 is hooked up to Serial port 4 on the SA1100. +* We are using SSP mode to talk to the UDA1341. The UDA1341 bit & wordselect clocks are generated +* by this UART. Unfortunately, the clock only runs if the transmit buffer has something in it. +* So, if we are just recording, we feed the transmit DMA stream a bunch of 0x0000 so that the +* transmit buffer is full and the clock keeps going. The zeroes come from FLUSH_BASE_PHYS which +* is a mem loc that always decodes to 0's w/ no off chip access. +* +* Some alsa terminology: +* frame => num_channels * sample_size e.g stereo 16 bit is 2 * 16 = 32 bytes +* period => the least number of bytes that will generate an interrupt e.g. we have a 1024 byte +* buffer and 4 periods in the runtime structure this means we'll get an int every 256 +* bytes or 4 times per buffer. +* A number of the sizes are in frames rather than bytes, use frames_to_bytes and +* bytes_to_frames to convert. The easiest way to tell the units is to look at the +* type i.e. runtime-> buffer_size is in frames and its type is snd_pcm_uframes_t +* +* Notes about the pointer fxn: +* The pointer fxn needs to return the offset into the dma buffer in frames. +* Interrupts must be blocked before calling the dma_get_pos fxn to avoid race with interrupts. +* +* Notes about pause/resume +* Implementing this would be complicated so it's skipped. The problem case is: +* A full duplex connection is going, then play is paused. At this point you need to start xmitting +* 0's to keep the record active which means you cant just freeze the dma and resume it later you'd +* need to save off the dma info, and restore it properly on a resume. Yeach! +* +* Notes about transfer methods: +* The async write calls fail. I probably need to implement something else to support them? +* +***************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PM +#include +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#undef DEBUG_MODE +#undef DEBUG_FUNCTION_NAMES +#include + +/* + * FIXME: Is this enough as autodetection of 2.4.X-rmkY-hhZ kernels? + * We use DMA stuff from 2.4.18-rmk3-hh24 here to be able to compile this + * module for Familiar 0.6.1 + */ + +/* {{{ Type definitions */ + +MODULE_AUTHOR("Tomas Kasparek "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SA1100/SA1111 + UDA1341TS driver for ALSA"); +MODULE_SUPPORTED_DEVICE("{{UDA1341,iPAQ H3600 UDA1341TS}}"); + +static char *id; /* ID for this card */ + +module_param(id, charp, 0444); +MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard."); + +struct audio_stream { + char *id; /* identification string */ + int stream_id; /* numeric identification */ + dma_device_t dma_dev; /* device identifier for DMA */ +#ifdef HH_VERSION + dmach_t dmach; /* dma channel identification */ +#else + dma_regs_t *dma_regs; /* points to our DMA registers */ +#endif + unsigned int active:1; /* we are using this stream for transfer now */ + int period; /* current transfer period */ + int periods; /* current count of periods registerd in the DMA engine */ + int tx_spin; /* are we recoding - flag used to do DMA trans. for sync */ + unsigned int old_offset; + spinlock_t dma_lock; /* for locking in DMA operations (see dma-sa1100.c in the kernel) */ + struct snd_pcm_substream *stream; +}; + +struct sa11xx_uda1341 { + struct snd_card *card; + struct l3_client *uda1341; + struct snd_pcm *pcm; + long samplerate; + struct audio_stream s[2]; /* playback & capture */ +}; + +static unsigned int rates[] = { + 8000, 10666, 10985, 14647, + 16000, 21970, 22050, 24000, + 29400, 32000, 44100, 48000, +}; + +static struct snd_pcm_hw_constraint_list hw_constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, +}; + +static struct platform_device *device; + +/* }}} */ + +/* {{{ Clock and sample rate stuff */ + +/* + * Stop-gap solution until rest of hh.org HAL stuff is merged. + */ +#define GPIO_H3600_CLK_SET0 GPIO_GPIO (12) +#define GPIO_H3600_CLK_SET1 GPIO_GPIO (13) + +#ifdef CONFIG_SA1100_H3XXX +#define clr_sa11xx_uda1341_egpio(x) clr_h3600_egpio(x) +#define set_sa11xx_uda1341_egpio(x) set_h3600_egpio(x) +#else +#error This driver could serve H3x00 handhelds only! +#endif + +static void sa11xx_uda1341_set_audio_clock(long val) +{ + switch (val) { + case 24000: case 32000: case 48000: /* 00: 12.288 MHz */ + GPCR = GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1; + break; + + case 22050: case 29400: case 44100: /* 01: 11.2896 MHz */ + GPSR = GPIO_H3600_CLK_SET0; + GPCR = GPIO_H3600_CLK_SET1; + break; + + case 8000: case 10666: case 16000: /* 10: 4.096 MHz */ + GPCR = GPIO_H3600_CLK_SET0; + GPSR = GPIO_H3600_CLK_SET1; + break; + + case 10985: case 14647: case 21970: /* 11: 5.6245 MHz */ + GPSR = GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1; + break; + } +} + +static void sa11xx_uda1341_set_samplerate(struct sa11xx_uda1341 *sa11xx_uda1341, long rate) +{ + int clk_div = 0; + int clk=0; + + /* We don't want to mess with clocks when frames are in flight */ + Ser4SSCR0 &= ~SSCR0_SSE; + /* wait for any frame to complete */ + udelay(125); + + /* + * We have the following clock sources: + * 4.096 MHz, 5.6245 MHz, 11.2896 MHz, 12.288 MHz + * Those can be divided either by 256, 384 or 512. + * This makes up 12 combinations for the following samplerates... + */ + if (rate >= 48000) + rate = 48000; + else if (rate >= 44100) + rate = 44100; + else if (rate >= 32000) + rate = 32000; + else if (rate >= 29400) + rate = 29400; + else if (rate >= 24000) + rate = 24000; + else if (rate >= 22050) + rate = 22050; + else if (rate >= 21970) + rate = 21970; + else if (rate >= 16000) + rate = 16000; + else if (rate >= 14647) + rate = 14647; + else if (rate >= 10985) + rate = 10985; + else if (rate >= 10666) + rate = 10666; + else + rate = 8000; + + /* Set the external clock generator */ + + sa11xx_uda1341_set_audio_clock(rate); + + /* Select the clock divisor */ + switch (rate) { + case 8000: + case 10985: + case 22050: + case 24000: + clk = F512; + clk_div = SSCR0_SerClkDiv(16); + break; + case 16000: + case 21970: + case 44100: + case 48000: + clk = F256; + clk_div = SSCR0_SerClkDiv(8); + break; + case 10666: + case 14647: + case 29400: + case 32000: + clk = F384; + clk_div = SSCR0_SerClkDiv(12); + break; + } + + /* FMT setting should be moved away when other FMTs are added (FIXME) */ + l3_command(sa11xx_uda1341->uda1341, CMD_FORMAT, (void *)LSB16); + + l3_command(sa11xx_uda1341->uda1341, CMD_FS, (void *)clk); + Ser4SSCR0 = (Ser4SSCR0 & ~0xff00) + clk_div + SSCR0_SSE; + sa11xx_uda1341->samplerate = rate; +} + +/* }}} */ + +/* {{{ HW init and shutdown */ + +static void sa11xx_uda1341_audio_init(struct sa11xx_uda1341 *sa11xx_uda1341) +{ + unsigned long flags; + + /* Setup DMA stuff */ + sa11xx_uda1341->s[SNDRV_PCM_STREAM_PLAYBACK].id = "UDA1341 out"; + sa11xx_uda1341->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id = SNDRV_PCM_STREAM_PLAYBACK; + sa11xx_uda1341->s[SNDRV_PCM_STREAM_PLAYBACK].dma_dev = DMA_Ser4SSPWr; + + sa11xx_uda1341->s[SNDRV_PCM_STREAM_CAPTURE].id = "UDA1341 in"; + sa11xx_uda1341->s[SNDRV_PCM_STREAM_CAPTURE].stream_id = SNDRV_PCM_STREAM_CAPTURE; + sa11xx_uda1341->s[SNDRV_PCM_STREAM_CAPTURE].dma_dev = DMA_Ser4SSPRd; + + /* Initialize the UDA1341 internal state */ + + /* Setup the uarts */ + local_irq_save(flags); + GAFR |= (GPIO_SSP_CLK); + GPDR &= ~(GPIO_SSP_CLK); + Ser4SSCR0 = 0; + Ser4SSCR0 = SSCR0_DataSize(16) + SSCR0_TI + SSCR0_SerClkDiv(8); + Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk; + Ser4SSCR0 |= SSCR0_SSE; + local_irq_restore(flags); + + /* Enable the audio power */ + + clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET); + set_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON); + set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE); + + /* Wait for the UDA1341 to wake up */ + mdelay(1); //FIXME - was removed by Perex - Why? + + /* Initialize the UDA1341 internal state */ + l3_open(sa11xx_uda1341->uda1341); + + /* external clock configuration (after l3_open - regs must be initialized */ + sa11xx_uda1341_set_samplerate(sa11xx_uda1341, sa11xx_uda1341->samplerate); + + /* Wait for the UDA1341 to wake up */ + set_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET); + mdelay(1); + + /* make the left and right channels unswapped (flip the WS latch) */ + Ser4SSDR = 0; + + clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE); +} + +static void sa11xx_uda1341_audio_shutdown(struct sa11xx_uda1341 *sa11xx_uda1341) +{ + /* mute on */ + set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE); + + /* disable the audio power and all signals leading to the audio chip */ + l3_close(sa11xx_uda1341->uda1341); + Ser4SSCR0 = 0; + clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET); + + /* power off and mute off */ + /* FIXME - is muting off necesary??? */ + + clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON); + clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE); +} + +/* }}} */ + +/* {{{ DMA staff */ + +/* + * these are the address and sizes used to fill the xmit buffer + * so we can get a clock in record only mode + */ +#define FORCE_CLOCK_ADDR (dma_addr_t)FLUSH_BASE_PHYS +#define FORCE_CLOCK_SIZE 4096 // was 2048 + +// FIXME Why this value exactly - wrote comment +#define DMA_BUF_SIZE 8176 /* <= MAX_DMA_SIZE from asm/arch-sa1100/dma.h */ + +#ifdef HH_VERSION + +static int audio_dma_request(struct audio_stream *s, void (*callback)(void *, int)) +{ + int ret; + + ret = sa1100_request_dma(&s->dmach, s->id, s->dma_dev); + if (ret < 0) { + printk(KERN_ERR "unable to grab audio dma 0x%x\n", s->dma_dev); + return ret; + } + sa1100_dma_set_callback(s->dmach, callback); + return 0; +} + +static inline void audio_dma_free(struct audio_stream *s) +{ + sa1100_free_dma(s->dmach); + s->dmach = -1; +} + +#else + +static int audio_dma_request(struct audio_stream *s, void (*callback)(void *)) +{ + int ret; + + ret = sa1100_request_dma(s->dma_dev, s->id, callback, s, &s->dma_regs); + if (ret < 0) + printk(KERN_ERR "unable to grab audio dma 0x%x\n", s->dma_dev); + return ret; +} + +static void audio_dma_free(struct audio_stream *s) +{ + sa1100_free_dma(s->dma_regs); + s->dma_regs = 0; +} + +#endif + +static u_int audio_get_dma_pos(struct audio_stream *s) +{ + struct snd_pcm_substream *substream = s->stream; + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned int offset; + unsigned long flags; + dma_addr_t addr; + + // this must be called w/ interrupts locked out see dma-sa1100.c in the kernel + spin_lock_irqsave(&s->dma_lock, flags); +#ifdef HH_VERSION + sa1100_dma_get_current(s->dmach, NULL, &addr); +#else + addr = sa1100_get_dma_pos((s)->dma_regs); +#endif + offset = addr - runtime->dma_addr; + spin_unlock_irqrestore(&s->dma_lock, flags); + + offset = bytes_to_frames(runtime,offset); + if (offset >= runtime->buffer_size) + offset = 0; + + return offset; +} + +/* + * this stops the dma and clears the dma ptrs + */ +static void audio_stop_dma(struct audio_stream *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->dma_lock, flags); + s->active = 0; + s->period = 0; + /* this stops the dma channel and clears the buffer ptrs */ +#ifdef HH_VERSION + sa1100_dma_flush_all(s->dmach); +#else + sa1100_clear_dma(s->dma_regs); +#endif + spin_unlock_irqrestore(&s->dma_lock, flags); +} + +static void audio_process_dma(struct audio_stream *s) +{ + struct snd_pcm_substream *substream = s->stream; + struct snd_pcm_runtime *runtime; + unsigned int dma_size; + unsigned int offset; + int ret; + + /* we are requested to process synchronization DMA transfer */ + if (s->tx_spin) { + if (snd_BUG_ON(s->stream_id != SNDRV_PCM_STREAM_PLAYBACK)) + return; + /* fill the xmit dma buffers and return */ +#ifdef HH_VERSION + sa1100_dma_set_spin(s->dmach, FORCE_CLOCK_ADDR, FORCE_CLOCK_SIZE); +#else + while (1) { + ret = sa1100_start_dma(s->dma_regs, FORCE_CLOCK_ADDR, FORCE_CLOCK_SIZE); + if (ret) + return; + } +#endif + return; + } + + /* must be set here - only valid for running streams, not for forced_clock dma fills */ + runtime = substream->runtime; + while (s->active && s->periods < runtime->periods) { + dma_size = frames_to_bytes(runtime, runtime->period_size); + if (s->old_offset) { + /* a little trick, we need resume from old position */ + offset = frames_to_bytes(runtime, s->old_offset - 1); + s->old_offset = 0; + s->periods = 0; + s->period = offset / dma_size; + offset %= dma_size; + dma_size = dma_size - offset; + if (!dma_size) + continue; /* special case */ + } else { + offset = dma_size * s->period; + snd_BUG_ON(dma_size > DMA_BUF_SIZE); + } +#ifdef HH_VERSION + ret = sa1100_dma_queue_buffer(s->dmach, s, runtime->dma_addr + offset, dma_size); + if (ret) + return; //FIXME +#else + ret = sa1100_start_dma((s)->dma_regs, runtime->dma_addr + offset, dma_size); + if (ret) { + printk(KERN_ERR "audio_process_dma: cannot queue DMA buffer (%i)\n", ret); + return; + } +#endif + + s->period++; + s->period %= runtime->periods; + s->periods++; + } +} + +#ifdef HH_VERSION +static void audio_dma_callback(void *data, int size) +#else +static void audio_dma_callback(void *data) +#endif +{ + struct audio_stream *s = data; + + /* + * If we are getting a callback for an active stream then we inform + * the PCM middle layer we've finished a period + */ + if (s->active) + snd_pcm_period_elapsed(s->stream); + + spin_lock(&s->dma_lock); + if (!s->tx_spin && s->periods > 0) + s->periods--; + audio_process_dma(s); + spin_unlock(&s->dma_lock); +} + +/* }}} */ + +/* {{{ PCM setting */ + +/* {{{ trigger & timer */ + +static int snd_sa11xx_uda1341_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); + int stream_id = substream->pstr->stream; + struct audio_stream *s = &chip->s[stream_id]; + struct audio_stream *s1 = &chip->s[stream_id ^ 1]; + int err = 0; + + /* note local interrupts are already disabled in the midlevel code */ + spin_lock(&s->dma_lock); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* now we need to make sure a record only stream has a clock */ + if (stream_id == SNDRV_PCM_STREAM_CAPTURE && !s1->active) { + /* we need to force fill the xmit DMA with zeros */ + s1->tx_spin = 1; + audio_process_dma(s1); + } + /* this case is when you were recording then you turn on a + * playback stream so we stop (also clears it) the dma first, + * clear the sync flag and then we let it turned on + */ + else { + s->tx_spin = 0; + } + + /* requested stream startup */ + s->active = 1; + audio_process_dma(s); + break; + case SNDRV_PCM_TRIGGER_STOP: + /* requested stream shutdown */ + audio_stop_dma(s); + + /* + * now we need to make sure a record only stream has a clock + * so if we're stopping a playback with an active capture + * we need to turn the 0 fill dma on for the xmit side + */ + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK && s1->active) { + /* we need to force fill the xmit DMA with zeros */ + s->tx_spin = 1; + audio_process_dma(s); + } + /* + * we killed a capture only stream, so we should also kill + * the zero fill transmit + */ + else { + if (s1->tx_spin) { + s1->tx_spin = 0; + audio_stop_dma(s1); + } + } + + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + s->active = 0; +#ifdef HH_VERSION + sa1100_dma_stop(s->dmach); +#else + //FIXME - DMA API +#endif + s->old_offset = audio_get_dma_pos(s) + 1; +#ifdef HH_VERSION + sa1100_dma_flush_all(s->dmach); +#else + //FIXME - DMA API +#endif + s->periods = 0; + break; + case SNDRV_PCM_TRIGGER_RESUME: + s->active = 1; + s->tx_spin = 0; + audio_process_dma(s); + if (stream_id == SNDRV_PCM_STREAM_CAPTURE && !s1->active) { + s1->tx_spin = 1; + audio_process_dma(s1); + } + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: +#ifdef HH_VERSION + sa1100_dma_stop(s->dmach); +#else + //FIXME - DMA API +#endif + s->active = 0; + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { + if (s1->active) { + s->tx_spin = 1; + s->old_offset = audio_get_dma_pos(s) + 1; +#ifdef HH_VERSION + sa1100_dma_flush_all(s->dmach); +#else + //FIXME - DMA API +#endif + audio_process_dma(s); + } + } else { + if (s1->tx_spin) { + s1->tx_spin = 0; +#ifdef HH_VERSION + sa1100_dma_flush_all(s1->dmach); +#else + //FIXME - DMA API +#endif + } + } + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + s->active = 1; + if (s->old_offset) { + s->tx_spin = 0; + audio_process_dma(s); + break; + } + if (stream_id == SNDRV_PCM_STREAM_CAPTURE && !s1->active) { + s1->tx_spin = 1; + audio_process_dma(s1); + } +#ifdef HH_VERSION + sa1100_dma_resume(s->dmach); +#else + //FIXME - DMA API +#endif + break; + default: + err = -EINVAL; + break; + } + spin_unlock(&s->dma_lock); + return err; +} + +static int snd_sa11xx_uda1341_prepare(struct snd_pcm_substream *substream) +{ + struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct audio_stream *s = &chip->s[substream->pstr->stream]; + + /* set requested samplerate */ + sa11xx_uda1341_set_samplerate(chip, runtime->rate); + + /* set requestd format when available */ + /* set FMT here !!! FIXME */ + + s->period = 0; + s->periods = 0; + + return 0; +} + +static snd_pcm_uframes_t snd_sa11xx_uda1341_pointer(struct snd_pcm_substream *substream) +{ + struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); + return audio_get_dma_pos(&chip->s[substream->pstr->stream]); +} + +/* }}} */ + +static struct snd_pcm_hardware snd_sa11xx_uda1341_capture = +{ + .info = (SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_KNOT), + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 64*1024, + .period_bytes_min = 64, + .period_bytes_max = DMA_BUF_SIZE, + .periods_min = 2, + .periods_max = 255, + .fifo_size = 0, +}; + +static struct snd_pcm_hardware snd_sa11xx_uda1341_playback = +{ + .info = (SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_KNOT), + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 64*1024, + .period_bytes_min = 64, + .period_bytes_max = DMA_BUF_SIZE, + .periods_min = 2, + .periods_max = 255, + .fifo_size = 0, +}; + +static int snd_card_sa11xx_uda1341_open(struct snd_pcm_substream *substream) +{ + struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int stream_id = substream->pstr->stream; + int err; + + chip->s[stream_id].stream = substream; + + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) + runtime->hw = snd_sa11xx_uda1341_playback; + else + runtime->hw = snd_sa11xx_uda1341_capture; + if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) + return err; + if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0) + return err; + + return 0; +} + +static int snd_card_sa11xx_uda1341_close(struct snd_pcm_substream *substream) +{ + struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); + + chip->s[substream->pstr->stream].stream = NULL; + return 0; +} + +/* {{{ HW params & free */ + +static int snd_sa11xx_uda1341_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + + return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); +} + +static int snd_sa11xx_uda1341_hw_free(struct snd_pcm_substream *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + +/* }}} */ + +static struct snd_pcm_ops snd_card_sa11xx_uda1341_playback_ops = { + .open = snd_card_sa11xx_uda1341_open, + .close = snd_card_sa11xx_uda1341_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_sa11xx_uda1341_hw_params, + .hw_free = snd_sa11xx_uda1341_hw_free, + .prepare = snd_sa11xx_uda1341_prepare, + .trigger = snd_sa11xx_uda1341_trigger, + .pointer = snd_sa11xx_uda1341_pointer, +}; + +static struct snd_pcm_ops snd_card_sa11xx_uda1341_capture_ops = { + .open = snd_card_sa11xx_uda1341_open, + .close = snd_card_sa11xx_uda1341_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_sa11xx_uda1341_hw_params, + .hw_free = snd_sa11xx_uda1341_hw_free, + .prepare = snd_sa11xx_uda1341_prepare, + .trigger = snd_sa11xx_uda1341_trigger, + .pointer = snd_sa11xx_uda1341_pointer, +}; + +static int __init snd_card_sa11xx_uda1341_pcm(struct sa11xx_uda1341 *sa11xx_uda1341, int device) +{ + struct snd_pcm *pcm; + int err; + + if ((err = snd_pcm_new(sa11xx_uda1341->card, "UDA1341 PCM", device, 1, 1, &pcm)) < 0) + return err; + + /* + * this sets up our initial buffers and sets the dma_type to isa. + * isa works but I'm not sure why (or if) it's the right choice + * this may be too large, trying it for now + */ + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_isa_data(), + 64*1024, 64*1024); + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_sa11xx_uda1341_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_sa11xx_uda1341_capture_ops); + pcm->private_data = sa11xx_uda1341; + pcm->info_flags = 0; + strcpy(pcm->name, "UDA1341 PCM"); + + sa11xx_uda1341_audio_init(sa11xx_uda1341); + + /* setup DMA controller */ + audio_dma_request(&sa11xx_uda1341->s[SNDRV_PCM_STREAM_PLAYBACK], audio_dma_callback); + audio_dma_request(&sa11xx_uda1341->s[SNDRV_PCM_STREAM_CAPTURE], audio_dma_callback); + + sa11xx_uda1341->pcm = pcm; + + return 0; +} + +/* }}} */ + +/* {{{ module init & exit */ + +#ifdef CONFIG_PM + +static int snd_sa11xx_uda1341_suspend(struct platform_device *devptr, + pm_message_t state) +{ + struct snd_card *card = platform_get_drvdata(devptr); + struct sa11xx_uda1341 *chip = card->private_data; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + snd_pcm_suspend_all(chip->pcm); +#ifdef HH_VERSION + sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach); + sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach); +#else + //FIXME +#endif + l3_command(chip->uda1341, CMD_SUSPEND, NULL); + sa11xx_uda1341_audio_shutdown(chip); + + return 0; +} + +static int snd_sa11xx_uda1341_resume(struct platform_device *devptr) +{ + struct snd_card *card = platform_get_drvdata(devptr); + struct sa11xx_uda1341 *chip = card->private_data; + + sa11xx_uda1341_audio_init(chip); + l3_command(chip->uda1341, CMD_RESUME, NULL); +#ifdef HH_VERSION + sa1100_dma_wakeup(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach); + sa1100_dma_wakeup(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach); +#else + //FIXME +#endif + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif /* COMFIG_PM */ + +void snd_sa11xx_uda1341_free(struct snd_card *card) +{ + struct sa11xx_uda1341 *chip = card->private_data; + + audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]); + audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]); +} + +static int __devinit sa11xx_uda1341_probe(struct platform_device *devptr) +{ + int err; + struct snd_card *card; + struct sa11xx_uda1341 *chip; + + /* register the soundcard */ + card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct sa11xx_uda1341)); + if (card == NULL) + return -ENOMEM; + + chip = card->private_data; + spin_lock_init(&chip->s[0].dma_lock); + spin_lock_init(&chip->s[1].dma_lock); + + card->private_free = snd_sa11xx_uda1341_free; + chip->card = card; + chip->samplerate = AUDIO_RATE_DEFAULT; + + // mixer + if ((err = snd_chip_uda1341_mixer_new(card, &chip->uda1341))) + goto nodev; + + // PCM + if ((err = snd_card_sa11xx_uda1341_pcm(chip, 0)) < 0) + goto nodev; + + strcpy(card->driver, "UDA1341"); + strcpy(card->shortname, "H3600 UDA1341TS"); + sprintf(card->longname, "Compaq iPAQ H3600 with Philips UDA1341TS"); + + snd_card_set_dev(card, &devptr->dev); + + if ((err = snd_card_register(card)) == 0) { + printk( KERN_INFO "iPAQ audio support initialized\n" ); + platform_set_drvdata(devptr, card); + return 0; + } + + nodev: + snd_card_free(card); + return err; +} + +static int __devexit sa11xx_uda1341_remove(struct platform_device *devptr) +{ + snd_card_free(platform_get_drvdata(devptr)); + platform_set_drvdata(devptr, NULL); + return 0; +} + +#define SA11XX_UDA1341_DRIVER "sa11xx_uda1341" + +static struct platform_driver sa11xx_uda1341_driver = { + .probe = sa11xx_uda1341_probe, + .remove = __devexit_p(sa11xx_uda1341_remove), +#ifdef CONFIG_PM + .suspend = snd_sa11xx_uda1341_suspend, + .resume = snd_sa11xx_uda1341_resume, +#endif + .driver = { + .name = SA11XX_UDA1341_DRIVER, + }, +}; + +static int __init sa11xx_uda1341_init(void) +{ + int err; + + if (!machine_is_h3xxx()) + return -ENODEV; + if ((err = platform_driver_register(&sa11xx_uda1341_driver)) < 0) + return err; + device = platform_device_register_simple(SA11XX_UDA1341_DRIVER, -1, NULL, 0); + if (!IS_ERR(device)) { + if (platform_get_drvdata(device)) + return 0; + platform_device_unregister(device); + err = -ENODEV; + } else + err = PTR_ERR(device); + platform_driver_unregister(&sa11xx_uda1341_driver); + return err; +} + +static void __exit sa11xx_uda1341_exit(void) +{ + platform_device_unregister(device); + platform_driver_unregister(&sa11xx_uda1341_driver); +} + +module_init(sa11xx_uda1341_init); +module_exit(sa11xx_uda1341_exit); + +/* }}} */ + +/* + * Local variables: + * indent-tabs-mode: t + * End: + */ diff --git a/trunk/sound/atmel/Kconfig b/trunk/sound/atmel/Kconfig deleted file mode 100644 index 6c228a91940d..000000000000 --- a/trunk/sound/atmel/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -menu "Atmel devices (AVR32 and AT91)" - depends on AVR32 || ARCH_AT91 - -config SND_ATMEL_ABDAC - tristate "Atmel Audio Bitstream DAC (ABDAC) driver" - select SND_PCM - depends on DW_DMAC && AVR32 - help - ALSA sound driver for the Atmel Audio Bitstream DAC (ABDAC). - -config SND_ATMEL_AC97C - tristate "Atmel AC97 Controller (AC97C) driver" - select SND_PCM - select SND_AC97_CODEC - depends on DW_DMAC && AVR32 - help - ALSA sound driver for the Atmel AC97 controller. - -endmenu diff --git a/trunk/sound/atmel/Makefile b/trunk/sound/atmel/Makefile deleted file mode 100644 index 219dcfac6086..000000000000 --- a/trunk/sound/atmel/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -snd-atmel-abdac-objs := abdac.o -snd-atmel-ac97c-objs := ac97c.o - -obj-$(CONFIG_SND_ATMEL_ABDAC) += snd-atmel-abdac.o -obj-$(CONFIG_SND_ATMEL_AC97C) += snd-atmel-ac97c.o diff --git a/trunk/sound/atmel/abdac.c b/trunk/sound/atmel/abdac.c deleted file mode 100644 index 28b3c7f7cfe6..000000000000 --- a/trunk/sound/atmel/abdac.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * Driver for the Atmel on-chip Audio Bitstream DAC (ABDAC) - * - * Copyright (C) 2006-2009 Atmel Corporation - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* DAC register offsets */ -#define DAC_DATA 0x0000 -#define DAC_CTRL 0x0008 -#define DAC_INT_MASK 0x000c -#define DAC_INT_EN 0x0010 -#define DAC_INT_DIS 0x0014 -#define DAC_INT_CLR 0x0018 -#define DAC_INT_STATUS 0x001c - -/* Bitfields in CTRL */ -#define DAC_SWAP_OFFSET 30 -#define DAC_SWAP_SIZE 1 -#define DAC_EN_OFFSET 31 -#define DAC_EN_SIZE 1 - -/* Bitfields in INT_MASK/INT_EN/INT_DIS/INT_STATUS/INT_CLR */ -#define DAC_UNDERRUN_OFFSET 28 -#define DAC_UNDERRUN_SIZE 1 -#define DAC_TX_READY_OFFSET 29 -#define DAC_TX_READY_SIZE 1 - -/* Bit manipulation macros */ -#define DAC_BIT(name) \ - (1 << DAC_##name##_OFFSET) -#define DAC_BF(name, value) \ - (((value) & ((1 << DAC_##name##_SIZE) - 1)) \ - << DAC_##name##_OFFSET) -#define DAC_BFEXT(name, value) \ - (((value) >> DAC_##name##_OFFSET) \ - & ((1 << DAC_##name##_SIZE) - 1)) -#define DAC_BFINS(name, value, old) \ - (((old) & ~(((1 << DAC_##name##_SIZE) - 1) \ - << DAC_##name##_OFFSET)) \ - | DAC_BF(name, value)) - -/* Register access macros */ -#define dac_readl(port, reg) \ - __raw_readl((port)->regs + DAC_##reg) -#define dac_writel(port, reg, value) \ - __raw_writel((value), (port)->regs + DAC_##reg) - -/* - * ABDAC supports a maximum of 6 different rates from a generic clock. The - * generic clock has a power of two divider, which gives 6 steps from 192 kHz - * to 5112 Hz. - */ -#define MAX_NUM_RATES 6 -/* ALSA seems to use rates between 192000 Hz and 5112 Hz. */ -#define RATE_MAX 192000 -#define RATE_MIN 5112 - -enum { - DMA_READY = 0, -}; - -struct atmel_abdac_dma { - struct dma_chan *chan; - struct dw_cyclic_desc *cdesc; -}; - -struct atmel_abdac { - struct clk *pclk; - struct clk *sample_clk; - struct platform_device *pdev; - struct atmel_abdac_dma dma; - - struct snd_pcm_hw_constraint_list constraints_rates; - struct snd_pcm_substream *substream; - struct snd_card *card; - struct snd_pcm *pcm; - - void __iomem *regs; - unsigned long flags; - unsigned int rates[MAX_NUM_RATES]; - unsigned int rates_num; - int irq; -}; - -#define get_dac(card) ((struct atmel_abdac *)(card)->private_data) - -/* This function is called by the DMA driver. */ -static void atmel_abdac_dma_period_done(void *arg) -{ - struct atmel_abdac *dac = arg; - snd_pcm_period_elapsed(dac->substream); -} - -static int atmel_abdac_prepare_dma(struct atmel_abdac *dac, - struct snd_pcm_substream *substream, - enum dma_data_direction direction) -{ - struct dma_chan *chan = dac->dma.chan; - struct dw_cyclic_desc *cdesc; - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long buffer_len, period_len; - - /* - * We don't do DMA on "complex" transfers, i.e. with - * non-halfword-aligned buffers or lengths. - */ - if (runtime->dma_addr & 1 || runtime->buffer_size & 1) { - dev_dbg(&dac->pdev->dev, "too complex transfer\n"); - return -EINVAL; - } - - buffer_len = frames_to_bytes(runtime, runtime->buffer_size); - period_len = frames_to_bytes(runtime, runtime->period_size); - - cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len, - period_len, DMA_TO_DEVICE); - if (IS_ERR(cdesc)) { - dev_dbg(&dac->pdev->dev, "could not prepare cyclic DMA\n"); - return PTR_ERR(cdesc); - } - - cdesc->period_callback = atmel_abdac_dma_period_done; - cdesc->period_callback_param = dac; - - dac->dma.cdesc = cdesc; - - set_bit(DMA_READY, &dac->flags); - - return 0; -} - -static struct snd_pcm_hardware atmel_abdac_hw = { - .info = (SNDRV_PCM_INFO_MMAP - | SNDRV_PCM_INFO_MMAP_VALID - | SNDRV_PCM_INFO_INTERLEAVED - | SNDRV_PCM_INFO_BLOCK_TRANSFER - | SNDRV_PCM_INFO_RESUME - | SNDRV_PCM_INFO_PAUSE), - .formats = (SNDRV_PCM_FMTBIT_S16_BE), - .rates = (SNDRV_PCM_RATE_KNOT), - .rate_min = RATE_MIN, - .rate_max = RATE_MAX, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = 64 * 4096, - .period_bytes_min = 4096, - .period_bytes_max = 4096, - .periods_min = 4, - .periods_max = 64, -}; - -static int atmel_abdac_open(struct snd_pcm_substream *substream) -{ - struct atmel_abdac *dac = snd_pcm_substream_chip(substream); - - dac->substream = substream; - atmel_abdac_hw.rate_max = dac->rates[dac->rates_num - 1]; - atmel_abdac_hw.rate_min = dac->rates[0]; - substream->runtime->hw = atmel_abdac_hw; - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &dac->constraints_rates); -} - -static int atmel_abdac_close(struct snd_pcm_substream *substream) -{ - struct atmel_abdac *dac = snd_pcm_substream_chip(substream); - dac->substream = NULL; - return 0; -} - -static int atmel_abdac_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct atmel_abdac *dac = snd_pcm_substream_chip(substream); - int retval; - - retval = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (retval < 0) - return retval; - /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ - if (retval == 1) - if (test_and_clear_bit(DMA_READY, &dac->flags)) - dw_dma_cyclic_free(dac->dma.chan); - - return retval; -} - -static int atmel_abdac_hw_free(struct snd_pcm_substream *substream) -{ - struct atmel_abdac *dac = snd_pcm_substream_chip(substream); - if (test_and_clear_bit(DMA_READY, &dac->flags)) - dw_dma_cyclic_free(dac->dma.chan); - return snd_pcm_lib_free_pages(substream); -} - -static int atmel_abdac_prepare(struct snd_pcm_substream *substream) -{ - struct atmel_abdac *dac = snd_pcm_substream_chip(substream); - int retval; - - retval = clk_set_rate(dac->sample_clk, 256 * substream->runtime->rate); - if (retval) - return retval; - - if (!test_bit(DMA_READY, &dac->flags)) - retval = atmel_abdac_prepare_dma(dac, substream, DMA_TO_DEVICE); - - return retval; -} - -static int atmel_abdac_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct atmel_abdac *dac = snd_pcm_substream_chip(substream); - int retval = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ - case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ - case SNDRV_PCM_TRIGGER_START: - clk_enable(dac->sample_clk); - retval = dw_dma_cyclic_start(dac->dma.chan); - if (retval) - goto out; - dac_writel(dac, CTRL, DAC_BIT(EN)); - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ - case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ - case SNDRV_PCM_TRIGGER_STOP: - dw_dma_cyclic_stop(dac->dma.chan); - dac_writel(dac, DATA, 0); - dac_writel(dac, CTRL, 0); - clk_disable(dac->sample_clk); - break; - default: - retval = -EINVAL; - break; - } -out: - return retval; -} - -static snd_pcm_uframes_t -atmel_abdac_pointer(struct snd_pcm_substream *substream) -{ - struct atmel_abdac *dac = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_uframes_t frames; - unsigned long bytes; - - bytes = dw_dma_get_src_addr(dac->dma.chan); - bytes -= runtime->dma_addr; - - frames = bytes_to_frames(runtime, bytes); - if (frames >= runtime->buffer_size) - frames -= runtime->buffer_size; - - return frames; -} - -static irqreturn_t abdac_interrupt(int irq, void *dev_id) -{ - struct atmel_abdac *dac = dev_id; - u32 status; - - status = dac_readl(dac, INT_STATUS); - if (status & DAC_BIT(UNDERRUN)) { - dev_err(&dac->pdev->dev, "underrun detected\n"); - dac_writel(dac, INT_CLR, DAC_BIT(UNDERRUN)); - } else { - dev_err(&dac->pdev->dev, "spurious interrupt (status=0x%x)\n", - status); - dac_writel(dac, INT_CLR, status); - } - - return IRQ_HANDLED; -} - -static struct snd_pcm_ops atmel_abdac_ops = { - .open = atmel_abdac_open, - .close = atmel_abdac_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = atmel_abdac_hw_params, - .hw_free = atmel_abdac_hw_free, - .prepare = atmel_abdac_prepare, - .trigger = atmel_abdac_trigger, - .pointer = atmel_abdac_pointer, -}; - -static int __devinit atmel_abdac_pcm_new(struct atmel_abdac *dac) -{ - struct snd_pcm_hardware hw = atmel_abdac_hw; - struct snd_pcm *pcm; - int retval; - - retval = snd_pcm_new(dac->card, dac->card->shortname, - dac->pdev->id, 1, 0, &pcm); - if (retval) - return retval; - - strcpy(pcm->name, dac->card->shortname); - pcm->private_data = dac; - pcm->info_flags = 0; - dac->pcm = pcm; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &atmel_abdac_ops); - - retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - &dac->pdev->dev, hw.periods_min * hw.period_bytes_min, - hw.buffer_bytes_max); - - return retval; -} - -static bool filter(struct dma_chan *chan, void *slave) -{ - struct dw_dma_slave *dws = slave; - - if (dws->dma_dev == chan->device->dev) { - chan->private = dws; - return true; - } else - return false; -} - -static int set_sample_rates(struct atmel_abdac *dac) -{ - long new_rate = RATE_MAX; - int retval = -EINVAL; - int index = 0; - - /* we start at 192 kHz and work our way down to 5112 Hz */ - while (new_rate >= RATE_MIN && index < (MAX_NUM_RATES + 1)) { - new_rate = clk_round_rate(dac->sample_clk, 256 * new_rate); - if (new_rate < 0) - break; - /* make sure we are below the ABDAC clock */ - if (new_rate <= clk_get_rate(dac->pclk)) { - dac->rates[index] = new_rate / 256; - index++; - } - /* divide by 256 and then by two to get next rate */ - new_rate /= 256 * 2; - } - - if (index) { - int i; - - /* reverse array, smallest go first */ - for (i = 0; i < (index / 2); i++) { - unsigned int tmp = dac->rates[index - 1 - i]; - dac->rates[index - 1 - i] = dac->rates[i]; - dac->rates[i] = tmp; - } - - dac->constraints_rates.count = index; - dac->constraints_rates.list = dac->rates; - dac->constraints_rates.mask = 0; - dac->rates_num = index; - - retval = 0; - } - - return retval; -} - -static int __devinit atmel_abdac_probe(struct platform_device *pdev) -{ - struct snd_card *card; - struct atmel_abdac *dac; - struct resource *regs; - struct atmel_abdac_pdata *pdata; - struct clk *pclk; - struct clk *sample_clk; - int retval; - int irq; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_dbg(&pdev->dev, "no memory resource\n"); - return -ENXIO; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_dbg(&pdev->dev, "could not get IRQ number\n"); - return irq; - } - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_dbg(&pdev->dev, "no platform data\n"); - return -ENXIO; - } - - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) { - dev_dbg(&pdev->dev, "no peripheral clock\n"); - return PTR_ERR(pclk); - } - sample_clk = clk_get(&pdev->dev, "sample_clk"); - if (IS_ERR(pclk)) { - dev_dbg(&pdev->dev, "no sample clock\n"); - retval = PTR_ERR(pclk); - goto out_put_pclk; - } - clk_enable(pclk); - - retval = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, sizeof(struct atmel_abdac), &card); - if (retval) { - dev_dbg(&pdev->dev, "could not create sound card device\n"); - goto out_put_sample_clk; - } - - dac = get_dac(card); - - dac->irq = irq; - dac->card = card; - dac->pclk = pclk; - dac->sample_clk = sample_clk; - dac->pdev = pdev; - - retval = set_sample_rates(dac); - if (retval < 0) { - dev_dbg(&pdev->dev, "could not set supported rates\n"); - goto out_free_card; - } - - dac->regs = ioremap(regs->start, regs->end - regs->start + 1); - if (!dac->regs) { - dev_dbg(&pdev->dev, "could not remap register memory\n"); - goto out_free_card; - } - - /* make sure the DAC is silent and disabled */ - dac_writel(dac, DATA, 0); - dac_writel(dac, CTRL, 0); - - retval = request_irq(irq, abdac_interrupt, 0, "abdac", dac); - if (retval) { - dev_dbg(&pdev->dev, "could not request irq\n"); - goto out_unmap_regs; - } - - snd_card_set_dev(card, &pdev->dev); - - if (pdata->dws.dma_dev) { - struct dw_dma_slave *dws = &pdata->dws; - dma_cap_mask_t mask; - - dws->tx_reg = regs->start + DAC_DATA; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - dac->dma.chan = dma_request_channel(mask, filter, dws); - } - if (!pdata->dws.dma_dev || !dac->dma.chan) { - dev_dbg(&pdev->dev, "DMA not available\n"); - retval = -ENODEV; - goto out_unset_card_dev; - } - - strcpy(card->driver, "Atmel ABDAC"); - strcpy(card->shortname, "Atmel ABDAC"); - sprintf(card->longname, "Atmel Audio Bitstream DAC"); - - retval = atmel_abdac_pcm_new(dac); - if (retval) { - dev_dbg(&pdev->dev, "could not register ABDAC pcm device\n"); - goto out_release_dma; - } - - retval = snd_card_register(card); - if (retval) { - dev_dbg(&pdev->dev, "could not register sound card\n"); - goto out_release_dma; - } - - platform_set_drvdata(pdev, card); - - dev_info(&pdev->dev, "Atmel ABDAC at 0x%p using %s\n", - dac->regs, dac->dma.chan->dev->device.bus_id); - - return retval; - -out_release_dma: - dma_release_channel(dac->dma.chan); - dac->dma.chan = NULL; -out_unset_card_dev: - snd_card_set_dev(card, NULL); - free_irq(irq, dac); -out_unmap_regs: - iounmap(dac->regs); -out_free_card: - snd_card_free(card); -out_put_sample_clk: - clk_put(sample_clk); - clk_disable(pclk); -out_put_pclk: - clk_put(pclk); - return retval; -} - -#ifdef CONFIG_PM -static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg) -{ - struct snd_card *card = platform_get_drvdata(pdev); - struct atmel_abdac *dac = card->private_data; - - dw_dma_cyclic_stop(dac->dma.chan); - clk_disable(dac->sample_clk); - clk_disable(dac->pclk); - - return 0; -} - -static int atmel_abdac_resume(struct platform_device *pdev) -{ - struct snd_card *card = platform_get_drvdata(pdev); - struct atmel_abdac *dac = card->private_data; - - clk_enable(dac->pclk); - clk_enable(dac->sample_clk); - if (test_bit(DMA_READY, &dac->flags)) - dw_dma_cyclic_start(dac->dma.chan); - - return 0; -} -#else -#define atmel_abdac_suspend NULL -#define atmel_abdac_resume NULL -#endif - -static int __devexit atmel_abdac_remove(struct platform_device *pdev) -{ - struct snd_card *card = platform_get_drvdata(pdev); - struct atmel_abdac *dac = get_dac(card); - - clk_put(dac->sample_clk); - clk_disable(dac->pclk); - clk_put(dac->pclk); - - dma_release_channel(dac->dma.chan); - dac->dma.chan = NULL; - snd_card_set_dev(card, NULL); - iounmap(dac->regs); - free_irq(dac->irq, dac); - snd_card_free(card); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver atmel_abdac_driver = { - .remove = __devexit_p(atmel_abdac_remove), - .driver = { - .name = "atmel_abdac", - }, - .suspend = atmel_abdac_suspend, - .resume = atmel_abdac_resume, -}; - -static int __init atmel_abdac_init(void) -{ - return platform_driver_probe(&atmel_abdac_driver, - atmel_abdac_probe); -} -module_init(atmel_abdac_init); - -static void __exit atmel_abdac_exit(void) -{ - platform_driver_unregister(&atmel_abdac_driver); -} -module_exit(atmel_abdac_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Driver for Atmel Audio Bitstream DAC (ABDAC)"); -MODULE_AUTHOR("Hans-Christian Egtvedt "); diff --git a/trunk/sound/atmel/ac97c.c b/trunk/sound/atmel/ac97c.c deleted file mode 100644 index dd72e00e5ae1..000000000000 --- a/trunk/sound/atmel/ac97c.c +++ /dev/null @@ -1,932 +0,0 @@ -/* - * Driver for the Atmel AC97C controller - * - * Copyright (C) 2005-2009 Atmel Corporation - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "ac97c.h" - -enum { - DMA_TX_READY = 0, - DMA_RX_READY, - DMA_TX_CHAN_PRESENT, - DMA_RX_CHAN_PRESENT, -}; - -/* Serialize access to opened variable */ -static DEFINE_MUTEX(opened_mutex); - -struct atmel_ac97c_dma { - struct dma_chan *rx_chan; - struct dma_chan *tx_chan; -}; - -struct atmel_ac97c { - struct clk *pclk; - struct platform_device *pdev; - struct atmel_ac97c_dma dma; - - struct snd_pcm_substream *playback_substream; - struct snd_pcm_substream *capture_substream; - struct snd_card *card; - struct snd_pcm *pcm; - struct snd_ac97 *ac97; - struct snd_ac97_bus *ac97_bus; - - u64 cur_format; - unsigned int cur_rate; - unsigned long flags; - /* Serialize access to opened variable */ - spinlock_t lock; - void __iomem *regs; - int opened; - int reset_pin; -}; - -#define get_chip(card) ((struct atmel_ac97c *)(card)->private_data) - -#define ac97c_writel(chip, reg, val) \ - __raw_writel((val), (chip)->regs + AC97C_##reg) -#define ac97c_readl(chip, reg) \ - __raw_readl((chip)->regs + AC97C_##reg) - -/* This function is called by the DMA driver. */ -static void atmel_ac97c_dma_playback_period_done(void *arg) -{ - struct atmel_ac97c *chip = arg; - snd_pcm_period_elapsed(chip->playback_substream); -} - -static void atmel_ac97c_dma_capture_period_done(void *arg) -{ - struct atmel_ac97c *chip = arg; - snd_pcm_period_elapsed(chip->capture_substream); -} - -static int atmel_ac97c_prepare_dma(struct atmel_ac97c *chip, - struct snd_pcm_substream *substream, - enum dma_data_direction direction) -{ - struct dma_chan *chan; - struct dw_cyclic_desc *cdesc; - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long buffer_len, period_len; - - /* - * We don't do DMA on "complex" transfers, i.e. with - * non-halfword-aligned buffers or lengths. - */ - if (runtime->dma_addr & 1 || runtime->buffer_size & 1) { - dev_dbg(&chip->pdev->dev, "too complex transfer\n"); - return -EINVAL; - } - - if (direction == DMA_TO_DEVICE) - chan = chip->dma.tx_chan; - else - chan = chip->dma.rx_chan; - - buffer_len = frames_to_bytes(runtime, runtime->buffer_size); - period_len = frames_to_bytes(runtime, runtime->period_size); - - cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len, - period_len, direction); - if (IS_ERR(cdesc)) { - dev_dbg(&chip->pdev->dev, "could not prepare cyclic DMA\n"); - return PTR_ERR(cdesc); - } - - if (direction == DMA_TO_DEVICE) { - cdesc->period_callback = atmel_ac97c_dma_playback_period_done; - set_bit(DMA_TX_READY, &chip->flags); - } else { - cdesc->period_callback = atmel_ac97c_dma_capture_period_done; - set_bit(DMA_RX_READY, &chip->flags); - } - - cdesc->period_callback_param = chip; - - return 0; -} - -static struct snd_pcm_hardware atmel_ac97c_hw = { - .info = (SNDRV_PCM_INFO_MMAP - | SNDRV_PCM_INFO_MMAP_VALID - | SNDRV_PCM_INFO_INTERLEAVED - | SNDRV_PCM_INFO_BLOCK_TRANSFER - | SNDRV_PCM_INFO_JOINT_DUPLEX - | SNDRV_PCM_INFO_RESUME - | SNDRV_PCM_INFO_PAUSE), - .formats = (SNDRV_PCM_FMTBIT_S16_BE - | SNDRV_PCM_FMTBIT_S16_LE), - .rates = (SNDRV_PCM_RATE_CONTINUOUS), - .rate_min = 4000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = 64 * 4096, - .period_bytes_min = 4096, - .period_bytes_max = 4096, - .periods_min = 4, - .periods_max = 64, -}; - -static int atmel_ac97c_playback_open(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - - mutex_lock(&opened_mutex); - chip->opened++; - runtime->hw = atmel_ac97c_hw; - if (chip->cur_rate) { - runtime->hw.rate_min = chip->cur_rate; - runtime->hw.rate_max = chip->cur_rate; - } - if (chip->cur_format) - runtime->hw.formats = (1ULL << chip->cur_format); - mutex_unlock(&opened_mutex); - chip->playback_substream = substream; - return 0; -} - -static int atmel_ac97c_capture_open(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - - mutex_lock(&opened_mutex); - chip->opened++; - runtime->hw = atmel_ac97c_hw; - if (chip->cur_rate) { - runtime->hw.rate_min = chip->cur_rate; - runtime->hw.rate_max = chip->cur_rate; - } - if (chip->cur_format) - runtime->hw.formats = (1ULL << chip->cur_format); - mutex_unlock(&opened_mutex); - chip->capture_substream = substream; - return 0; -} - -static int atmel_ac97c_playback_close(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - - mutex_lock(&opened_mutex); - chip->opened--; - if (!chip->opened) { - chip->cur_rate = 0; - chip->cur_format = 0; - } - mutex_unlock(&opened_mutex); - - chip->playback_substream = NULL; - - return 0; -} - -static int atmel_ac97c_capture_close(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - - mutex_lock(&opened_mutex); - chip->opened--; - if (!chip->opened) { - chip->cur_rate = 0; - chip->cur_format = 0; - } - mutex_unlock(&opened_mutex); - - chip->capture_substream = NULL; - - return 0; -} - -static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - int retval; - - retval = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (retval < 0) - return retval; - /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ - if (retval == 1) - if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) - dw_dma_cyclic_free(chip->dma.tx_chan); - - /* Set restrictions to params. */ - mutex_lock(&opened_mutex); - chip->cur_rate = params_rate(hw_params); - chip->cur_format = params_format(hw_params); - mutex_unlock(&opened_mutex); - - return retval; -} - -static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - int retval; - - retval = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (retval < 0) - return retval; - /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ - if (retval == 1) - if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) - dw_dma_cyclic_free(chip->dma.rx_chan); - - /* Set restrictions to params. */ - mutex_lock(&opened_mutex); - chip->cur_rate = params_rate(hw_params); - chip->cur_format = params_format(hw_params); - mutex_unlock(&opened_mutex); - - return retval; -} - -static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) - dw_dma_cyclic_free(chip->dma.tx_chan); - return snd_pcm_lib_free_pages(substream); -} - -static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) - dw_dma_cyclic_free(chip->dma.rx_chan); - return snd_pcm_lib_free_pages(substream); -} - -static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long word = 0; - int retval; - - /* assign channels to AC97C channel A */ - switch (runtime->channels) { - case 1: - word |= AC97C_CH_ASSIGN(PCM_LEFT, A); - break; - case 2: - word |= AC97C_CH_ASSIGN(PCM_LEFT, A) - | AC97C_CH_ASSIGN(PCM_RIGHT, A); - break; - default: - /* TODO: support more than two channels */ - return -EINVAL; - break; - } - ac97c_writel(chip, OCA, word); - - /* configure sample format and size */ - word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; - - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_LE: - word |= AC97C_CMR_CEM_LITTLE; - break; - case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ - default: - word &= ~(AC97C_CMR_CEM_LITTLE); - break; - } - - ac97c_writel(chip, CAMR, word); - - /* set variable rate if needed */ - if (runtime->rate != 48000) { - word = ac97c_readl(chip, MR); - word |= AC97C_MR_VRA; - ac97c_writel(chip, MR, word); - } else { - word = ac97c_readl(chip, MR); - word &= ~(AC97C_MR_VRA); - ac97c_writel(chip, MR, word); - } - - retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, - runtime->rate); - if (retval) - dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", - runtime->rate); - - if (!test_bit(DMA_TX_READY, &chip->flags)) - retval = atmel_ac97c_prepare_dma(chip, substream, - DMA_TO_DEVICE); - - return retval; -} - -static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long word = 0; - int retval; - - /* assign channels to AC97C channel A */ - switch (runtime->channels) { - case 1: - word |= AC97C_CH_ASSIGN(PCM_LEFT, A); - break; - case 2: - word |= AC97C_CH_ASSIGN(PCM_LEFT, A) - | AC97C_CH_ASSIGN(PCM_RIGHT, A); - break; - default: - /* TODO: support more than two channels */ - return -EINVAL; - break; - } - ac97c_writel(chip, ICA, word); - - /* configure sample format and size */ - word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; - - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_LE: - word |= AC97C_CMR_CEM_LITTLE; - break; - case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ - default: - word &= ~(AC97C_CMR_CEM_LITTLE); - break; - } - - ac97c_writel(chip, CAMR, word); - - /* set variable rate if needed */ - if (runtime->rate != 48000) { - word = ac97c_readl(chip, MR); - word |= AC97C_MR_VRA; - ac97c_writel(chip, MR, word); - } else { - word = ac97c_readl(chip, MR); - word &= ~(AC97C_MR_VRA); - ac97c_writel(chip, MR, word); - } - - retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, - runtime->rate); - if (retval) - dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", - runtime->rate); - - if (!test_bit(DMA_RX_READY, &chip->flags)) - retval = atmel_ac97c_prepare_dma(chip, substream, - DMA_FROM_DEVICE); - - return retval; -} - -static int -atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - unsigned long camr; - int retval = 0; - - camr = ac97c_readl(chip, CAMR); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ - case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ - case SNDRV_PCM_TRIGGER_START: - retval = dw_dma_cyclic_start(chip->dma.tx_chan); - if (retval) - goto out; - camr |= AC97C_CMR_CENA; - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ - case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ - case SNDRV_PCM_TRIGGER_STOP: - dw_dma_cyclic_stop(chip->dma.tx_chan); - if (chip->opened <= 1) - camr &= ~AC97C_CMR_CENA; - break; - default: - retval = -EINVAL; - goto out; - } - - ac97c_writel(chip, CAMR, camr); -out: - return retval; -} - -static int -atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - unsigned long camr; - int retval = 0; - - camr = ac97c_readl(chip, CAMR); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ - case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ - case SNDRV_PCM_TRIGGER_START: - retval = dw_dma_cyclic_start(chip->dma.rx_chan); - if (retval) - goto out; - camr |= AC97C_CMR_CENA; - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ - case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ - case SNDRV_PCM_TRIGGER_STOP: - dw_dma_cyclic_stop(chip->dma.rx_chan); - if (chip->opened <= 1) - camr &= ~AC97C_CMR_CENA; - break; - default: - retval = -EINVAL; - break; - } - - ac97c_writel(chip, CAMR, camr); -out: - return retval; -} - -static snd_pcm_uframes_t -atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_uframes_t frames; - unsigned long bytes; - - bytes = dw_dma_get_src_addr(chip->dma.tx_chan); - bytes -= runtime->dma_addr; - - frames = bytes_to_frames(runtime, bytes); - if (frames >= runtime->buffer_size) - frames -= runtime->buffer_size; - return frames; -} - -static snd_pcm_uframes_t -atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream) -{ - struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_uframes_t frames; - unsigned long bytes; - - bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); - bytes -= runtime->dma_addr; - - frames = bytes_to_frames(runtime, bytes); - if (frames >= runtime->buffer_size) - frames -= runtime->buffer_size; - return frames; -} - -static struct snd_pcm_ops atmel_ac97_playback_ops = { - .open = atmel_ac97c_playback_open, - .close = atmel_ac97c_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = atmel_ac97c_playback_hw_params, - .hw_free = atmel_ac97c_playback_hw_free, - .prepare = atmel_ac97c_playback_prepare, - .trigger = atmel_ac97c_playback_trigger, - .pointer = atmel_ac97c_playback_pointer, -}; - -static struct snd_pcm_ops atmel_ac97_capture_ops = { - .open = atmel_ac97c_capture_open, - .close = atmel_ac97c_capture_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = atmel_ac97c_capture_hw_params, - .hw_free = atmel_ac97c_capture_hw_free, - .prepare = atmel_ac97c_capture_prepare, - .trigger = atmel_ac97c_capture_trigger, - .pointer = atmel_ac97c_capture_pointer, -}; - -static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip) -{ - struct snd_pcm *pcm; - struct snd_pcm_hardware hw = atmel_ac97c_hw; - int capture, playback, retval; - - capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags); - playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags); - - retval = snd_pcm_new(chip->card, chip->card->shortname, - chip->pdev->id, playback, capture, &pcm); - if (retval) - return retval; - - if (capture) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &atmel_ac97_capture_ops); - if (playback) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &atmel_ac97_playback_ops); - - retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - &chip->pdev->dev, hw.periods_min * hw.period_bytes_min, - hw.buffer_bytes_max); - if (retval) - return retval; - - pcm->private_data = chip; - pcm->info_flags = 0; - strcpy(pcm->name, chip->card->shortname); - chip->pcm = pcm; - - return 0; -} - -static int atmel_ac97c_mixer_new(struct atmel_ac97c *chip) -{ - struct snd_ac97_template template; - memset(&template, 0, sizeof(template)); - template.private_data = chip; - return snd_ac97_mixer(chip->ac97_bus, &template, &chip->ac97); -} - -static void atmel_ac97c_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - struct atmel_ac97c *chip = get_chip(ac97); - unsigned long word; - int timeout = 40; - - word = (reg & 0x7f) << 16 | val; - - do { - if (ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) { - ac97c_writel(chip, COTHR, word); - return; - } - udelay(1); - } while (--timeout); - - dev_dbg(&chip->pdev->dev, "codec write timeout\n"); -} - -static unsigned short atmel_ac97c_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - struct atmel_ac97c *chip = get_chip(ac97); - unsigned long word; - int timeout = 40; - int write = 10; - - word = (0x80 | (reg & 0x7f)) << 16; - - if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0) - ac97c_readl(chip, CORHR); - -retry_write: - timeout = 40; - - do { - if ((ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) != 0) { - ac97c_writel(chip, COTHR, word); - goto read_reg; - } - udelay(10); - } while (--timeout); - - if (!--write) - goto timed_out; - goto retry_write; - -read_reg: - do { - if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0) { - unsigned short val = ac97c_readl(chip, CORHR); - return val; - } - udelay(10); - } while (--timeout); - - if (!--write) - goto timed_out; - goto retry_write; - -timed_out: - dev_dbg(&chip->pdev->dev, "codec read timeout\n"); - return 0xffff; -} - -static bool filter(struct dma_chan *chan, void *slave) -{ - struct dw_dma_slave *dws = slave; - - if (dws->dma_dev == chan->device->dev) { - chan->private = dws; - return true; - } else - return false; -} - -static void atmel_ac97c_reset(struct atmel_ac97c *chip) -{ - ac97c_writel(chip, MR, AC97C_MR_WRST); - - if (gpio_is_valid(chip->reset_pin)) { - gpio_set_value(chip->reset_pin, 0); - /* AC97 v2.2 specifications says minimum 1 us. */ - udelay(10); - gpio_set_value(chip->reset_pin, 1); - } - - udelay(1); - ac97c_writel(chip, MR, AC97C_MR_ENA); -} - -static int __devinit atmel_ac97c_probe(struct platform_device *pdev) -{ - struct snd_card *card; - struct atmel_ac97c *chip; - struct resource *regs; - struct ac97c_platform_data *pdata; - struct clk *pclk; - static struct snd_ac97_bus_ops ops = { - .write = atmel_ac97c_write, - .read = atmel_ac97c_read, - }; - int retval; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_dbg(&pdev->dev, "no memory resource\n"); - return -ENXIO; - } - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_dbg(&pdev->dev, "no platform data\n"); - return -ENXIO; - } - - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) { - dev_dbg(&pdev->dev, "no peripheral clock\n"); - return PTR_ERR(pclk); - } - clk_enable(pclk); - - retval = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, sizeof(struct atmel_ac97c), &card); - if (retval) { - dev_dbg(&pdev->dev, "could not create sound card device\n"); - goto err_snd_card_new; - } - - chip = get_chip(card); - - spin_lock_init(&chip->lock); - - strcpy(card->driver, "Atmel AC97C"); - strcpy(card->shortname, "Atmel AC97C"); - sprintf(card->longname, "Atmel AC97 controller"); - - chip->card = card; - chip->pclk = pclk; - chip->pdev = pdev; - chip->regs = ioremap(regs->start, regs->end - regs->start + 1); - - if (!chip->regs) { - dev_dbg(&pdev->dev, "could not remap register memory\n"); - goto err_ioremap; - } - - if (gpio_is_valid(pdata->reset_pin)) { - if (gpio_request(pdata->reset_pin, "reset_pin")) { - dev_dbg(&pdev->dev, "reset pin not available\n"); - chip->reset_pin = -ENODEV; - } else { - gpio_direction_output(pdata->reset_pin, 1); - chip->reset_pin = pdata->reset_pin; - } - } - - snd_card_set_dev(card, &pdev->dev); - - retval = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus); - if (retval) { - dev_dbg(&pdev->dev, "could not register on ac97 bus\n"); - goto err_ac97_bus; - } - - atmel_ac97c_reset(chip); - - retval = atmel_ac97c_mixer_new(chip); - if (retval) { - dev_dbg(&pdev->dev, "could not register ac97 mixer\n"); - goto err_ac97_bus; - } - - if (pdata->rx_dws.dma_dev) { - struct dw_dma_slave *dws = &pdata->rx_dws; - dma_cap_mask_t mask; - - dws->rx_reg = regs->start + AC97C_CARHR + 2; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - chip->dma.rx_chan = dma_request_channel(mask, filter, dws); - - dev_info(&chip->pdev->dev, "using %s for DMA RX\n", - chip->dma.rx_chan->dev->device.bus_id); - set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); - } - - if (pdata->tx_dws.dma_dev) { - struct dw_dma_slave *dws = &pdata->tx_dws; - dma_cap_mask_t mask; - - dws->tx_reg = regs->start + AC97C_CATHR + 2; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - chip->dma.tx_chan = dma_request_channel(mask, filter, dws); - - dev_info(&chip->pdev->dev, "using %s for DMA TX\n", - chip->dma.tx_chan->dev->device.bus_id); - set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); - } - - if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && - !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { - dev_dbg(&pdev->dev, "DMA not available\n"); - retval = -ENODEV; - goto err_dma; - } - - retval = atmel_ac97c_pcm_new(chip); - if (retval) { - dev_dbg(&pdev->dev, "could not register ac97 pcm device\n"); - goto err_dma; - } - - retval = snd_card_register(card); - if (retval) { - dev_dbg(&pdev->dev, "could not register sound card\n"); - goto err_ac97_bus; - } - - platform_set_drvdata(pdev, card); - - dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p\n", - chip->regs); - - return 0; - -err_dma: - if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) - dma_release_channel(chip->dma.rx_chan); - if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) - dma_release_channel(chip->dma.tx_chan); - clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); - clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); - chip->dma.rx_chan = NULL; - chip->dma.tx_chan = NULL; -err_ac97_bus: - snd_card_set_dev(card, NULL); - - if (gpio_is_valid(chip->reset_pin)) - gpio_free(chip->reset_pin); - - iounmap(chip->regs); -err_ioremap: - snd_card_free(card); -err_snd_card_new: - clk_disable(pclk); - clk_put(pclk); - return retval; -} - -#ifdef CONFIG_PM -static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg) -{ - struct snd_card *card = platform_get_drvdata(pdev); - struct atmel_ac97c *chip = card->private_data; - - if (test_bit(DMA_RX_READY, &chip->flags)) - dw_dma_cyclic_stop(chip->dma.rx_chan); - if (test_bit(DMA_TX_READY, &chip->flags)) - dw_dma_cyclic_stop(chip->dma.tx_chan); - clk_disable(chip->pclk); - - return 0; -} - -static int atmel_ac97c_resume(struct platform_device *pdev) -{ - struct snd_card *card = platform_get_drvdata(pdev); - struct atmel_ac97c *chip = card->private_data; - - clk_enable(chip->pclk); - if (test_bit(DMA_RX_READY, &chip->flags)) - dw_dma_cyclic_start(chip->dma.rx_chan); - if (test_bit(DMA_TX_READY, &chip->flags)) - dw_dma_cyclic_start(chip->dma.tx_chan); - - return 0; -} -#else -#define atmel_ac97c_suspend NULL -#define atmel_ac97c_resume NULL -#endif - -static int __devexit atmel_ac97c_remove(struct platform_device *pdev) -{ - struct snd_card *card = platform_get_drvdata(pdev); - struct atmel_ac97c *chip = get_chip(card); - - if (gpio_is_valid(chip->reset_pin)) - gpio_free(chip->reset_pin); - - clk_disable(chip->pclk); - clk_put(chip->pclk); - iounmap(chip->regs); - - if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) - dma_release_channel(chip->dma.rx_chan); - if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) - dma_release_channel(chip->dma.tx_chan); - clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); - clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); - chip->dma.rx_chan = NULL; - chip->dma.tx_chan = NULL; - - snd_card_set_dev(card, NULL); - snd_card_free(card); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver atmel_ac97c_driver = { - .remove = __devexit_p(atmel_ac97c_remove), - .driver = { - .name = "atmel_ac97c", - }, - .suspend = atmel_ac97c_suspend, - .resume = atmel_ac97c_resume, -}; - -static int __init atmel_ac97c_init(void) -{ - return platform_driver_probe(&atmel_ac97c_driver, - atmel_ac97c_probe); -} -module_init(atmel_ac97c_init); - -static void __exit atmel_ac97c_exit(void) -{ - platform_driver_unregister(&atmel_ac97c_driver); -} -module_exit(atmel_ac97c_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Driver for Atmel AC97 controller"); -MODULE_AUTHOR("Hans-Christian Egtvedt "); diff --git a/trunk/sound/atmel/ac97c.h b/trunk/sound/atmel/ac97c.h deleted file mode 100644 index c17bd5825980..000000000000 --- a/trunk/sound/atmel/ac97c.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Register definitions for the Atmel AC97C controller - * - * Copyright (C) 2005-2009 Atmel Corporation - * - * 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. - */ -#ifndef __SOUND_ATMEL_AC97C_H -#define __SOUND_ATMEL_AC97C_H - -#define AC97C_MR 0x08 -#define AC97C_ICA 0x10 -#define AC97C_OCA 0x14 -#define AC97C_CARHR 0x20 -#define AC97C_CATHR 0x24 -#define AC97C_CASR 0x28 -#define AC97C_CAMR 0x2c -#define AC97C_CBRHR 0x30 -#define AC97C_CBTHR 0x34 -#define AC97C_CBSR 0x38 -#define AC97C_CBMR 0x3c -#define AC97C_CORHR 0x40 -#define AC97C_COTHR 0x44 -#define AC97C_COSR 0x48 -#define AC97C_COMR 0x4c -#define AC97C_SR 0x50 -#define AC97C_IER 0x54 -#define AC97C_IDR 0x58 -#define AC97C_IMR 0x5c -#define AC97C_VERSION 0xfc - -#define AC97C_CATPR PDC_TPR -#define AC97C_CATCR PDC_TCR -#define AC97C_CATNPR PDC_TNPR -#define AC97C_CATNCR PDC_TNCR -#define AC97C_CARPR PDC_RPR -#define AC97C_CARCR PDC_RCR -#define AC97C_CARNPR PDC_RNPR -#define AC97C_CARNCR PDC_RNCR -#define AC97C_PTCR PDC_PTCR - -#define AC97C_MR_ENA (1 << 0) -#define AC97C_MR_WRST (1 << 1) -#define AC97C_MR_VRA (1 << 2) - -#define AC97C_CSR_TXRDY (1 << 0) -#define AC97C_CSR_UNRUN (1 << 2) -#define AC97C_CSR_RXRDY (1 << 4) -#define AC97C_CSR_ENDTX (1 << 10) -#define AC97C_CSR_ENDRX (1 << 14) - -#define AC97C_CMR_SIZE_20 (0 << 16) -#define AC97C_CMR_SIZE_18 (1 << 16) -#define AC97C_CMR_SIZE_16 (2 << 16) -#define AC97C_CMR_SIZE_10 (3 << 16) -#define AC97C_CMR_CEM_LITTLE (1 << 18) -#define AC97C_CMR_CEM_BIG (0 << 18) -#define AC97C_CMR_CENA (1 << 21) -#define AC97C_CMR_DMAEN (1 << 22) - -#define AC97C_SR_CAEVT (1 << 3) - -#define AC97C_CH_ASSIGN(slot, channel) \ - (AC97C_CHANNEL_##channel << (3 * (AC97_SLOT_##slot - 3))) -#define AC97C_CHANNEL_NONE 0x0 -#define AC97C_CHANNEL_A 0x1 -#define AC97C_CHANNEL_B 0x2 - -#endif /* __SOUND_ATMEL_AC97C_H */ diff --git a/trunk/sound/core/hwdep.c b/trunk/sound/core/hwdep.c index a70ee7f1ed98..195cafc5a553 100644 --- a/trunk/sound/core/hwdep.c +++ b/trunk/sound/core/hwdep.c @@ -99,6 +99,9 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) if (hw == NULL) return -ENODEV; + if (!hw->ops.open) + return -ENXIO; + if (!try_module_get(hw->card->module)) return -EFAULT; @@ -110,10 +113,6 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) err = -EBUSY; break; } - if (!hw->ops.open) { - err = 0; - break; - } err = hw->ops.open(hw, file); if (err >= 0) break; @@ -152,7 +151,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) static int snd_hwdep_release(struct inode *inode, struct file * file) { - int err = 0; + int err = -ENXIO; struct snd_hwdep *hw = file->private_data; struct module *mod = hw->card->module; diff --git a/trunk/sound/core/init.c b/trunk/sound/core/init.c index fd56afe846ed..0d5520c415d3 100644 --- a/trunk/sound/core/init.c +++ b/trunk/sound/core/init.c @@ -121,44 +121,31 @@ static inline int init_info_for_card(struct snd_card *card) #endif /** - * snd_card_create - create and initialize a soundcard structure + * snd_card_new - create and initialize a soundcard structure * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] * @xid: card identification (ASCII string) * @module: top level module for locking * @extra_size: allocate this extra size after the main soundcard structure - * @card_ret: the pointer to store the created card instance * * Creates and initializes a soundcard structure. * - * The function allocates snd_card instance via kzalloc with the given - * space for the driver to use freely. The allocated struct is stored - * in the given card_ret pointer. - * - * Returns zero if successful or a negative error code. + * Returns kmallocated snd_card structure. Creates the ALSA control interface + * (which is blocked until snd_card_register function is called). */ -int snd_card_create(int idx, const char *xid, - struct module *module, int extra_size, - struct snd_card **card_ret) +struct snd_card *snd_card_new(int idx, const char *xid, + struct module *module, int extra_size) { struct snd_card *card; int err, idx2; - if (snd_BUG_ON(!card_ret)) - return -EINVAL; - *card_ret = NULL; - if (extra_size < 0) extra_size = 0; card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL); - if (!card) - return -ENOMEM; + if (card == NULL) + return NULL; if (xid) { - if (!snd_info_check_reserved_words(xid)) { - snd_printk(KERN_ERR - "given id string '%s' is reserved.\n", xid); - err = -EBUSY; + if (!snd_info_check_reserved_words(xid)) goto __error; - } strlcpy(card->id, xid, sizeof(card->id)); } err = 0; @@ -208,7 +195,6 @@ int snd_card_create(int idx, const char *xid, INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->ctl_files); spin_lock_init(&card->files_lock); - INIT_LIST_HEAD(&card->files_list); init_waitqueue_head(&card->shutdown_sleep); #ifdef CONFIG_PM mutex_init(&card->power_lock); @@ -216,28 +202,26 @@ int snd_card_create(int idx, const char *xid, #endif /* the control interface cannot be accessed from the user space until */ /* snd_cards_bitmask and snd_cards are set with snd_card_register */ - err = snd_ctl_create(card); - if (err < 0) { - snd_printk(KERN_ERR "unable to register control minors\n"); + if ((err = snd_ctl_create(card)) < 0) { + snd_printd("unable to register control minors\n"); goto __error; } - err = snd_info_card_create(card); - if (err < 0) { - snd_printk(KERN_ERR "unable to create card info\n"); + if ((err = snd_info_card_create(card)) < 0) { + snd_printd("unable to create card info\n"); goto __error_ctl; } if (extra_size > 0) card->private_data = (char *)card + sizeof(struct snd_card); - *card_ret = card; - return 0; + return card; __error_ctl: snd_device_free_all(card, SNDRV_DEV_CMD_PRE); __error: kfree(card); - return err; + return NULL; } -EXPORT_SYMBOL(snd_card_create); + +EXPORT_SYMBOL(snd_card_new); /* return non-zero if a card is already locked */ int snd_card_locked(int card) @@ -275,7 +259,6 @@ static int snd_disconnect_release(struct inode *inode, struct file *file) list_for_each_entry(_df, &shutdown_files, shutdown_list) { if (_df->file == file) { df = _df; - list_del_init(&df->shutdown_list); break; } } @@ -364,7 +347,8 @@ int snd_card_disconnect(struct snd_card *card) /* phase 2: replace file->f_op with special dummy operations */ spin_lock(&card->files_lock); - list_for_each_entry(mfile, &card->files_list, list) { + mfile = card->files; + while (mfile) { file = mfile->file; /* it's critical part, use endless loop */ @@ -377,6 +361,8 @@ int snd_card_disconnect(struct snd_card *card) mfile->file->f_op = &snd_shutdown_f_ops; fops_get(mfile->file->f_op); + + mfile = mfile->next; } spin_unlock(&card->files_lock); @@ -456,7 +442,7 @@ int snd_card_free_when_closed(struct snd_card *card) return ret; spin_lock(&card->files_lock); - if (list_empty(&card->files_list)) + if (card->files == NULL) free_now = 1; else card->free_on_last_close = 1; @@ -476,7 +462,7 @@ int snd_card_free(struct snd_card *card) return ret; /* wait, until all devices are ready for the free operation */ - wait_event(card->shutdown_sleep, list_empty(&card->files_list)); + wait_event(card->shutdown_sleep, card->files == NULL); snd_card_do_free(card); return 0; } @@ -823,13 +809,15 @@ int snd_card_file_add(struct snd_card *card, struct file *file) return -ENOMEM; mfile->file = file; mfile->disconnected_f_op = NULL; + mfile->next = NULL; spin_lock(&card->files_lock); if (card->shutdown) { spin_unlock(&card->files_lock); kfree(mfile); return -ENODEV; } - list_add(&mfile->list, &card->files_list); + mfile->next = card->files; + card->files = mfile; spin_unlock(&card->files_lock); return 0; } @@ -851,20 +839,29 @@ EXPORT_SYMBOL(snd_card_file_add); */ int snd_card_file_remove(struct snd_card *card, struct file *file) { - struct snd_monitor_file *mfile, *found = NULL; + struct snd_monitor_file *mfile, *pfile = NULL; int last_close = 0; spin_lock(&card->files_lock); - list_for_each_entry(mfile, &card->files_list, list) { + mfile = card->files; + while (mfile) { if (mfile->file == file) { - list_del(&mfile->list); - if (mfile->disconnected_f_op) - fops_put(mfile->disconnected_f_op); - found = mfile; + if (pfile) + pfile->next = mfile->next; + else + card->files = mfile->next; break; } + pfile = mfile; + mfile = mfile->next; + } + if (mfile && mfile->disconnected_f_op) { + fops_put(mfile->disconnected_f_op); + spin_lock(&shutdown_lock); + list_del(&mfile->shutdown_list); + spin_unlock(&shutdown_lock); } - if (list_empty(&card->files_list)) + if (card->files == NULL) last_close = 1; spin_unlock(&card->files_lock); if (last_close) { @@ -872,11 +869,11 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) if (card->free_on_last_close) snd_card_do_free(card); } - if (!found) { + if (!mfile) { snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); return -ENOENT; } - kfree(found); + kfree(mfile); return 0; } diff --git a/trunk/sound/core/jack.c b/trunk/sound/core/jack.c index c8254c667c62..077a85262c1c 100644 --- a/trunk/sound/core/jack.c +++ b/trunk/sound/core/jack.c @@ -23,14 +23,6 @@ #include #include -static int jack_types[] = { - SW_HEADPHONE_INSERT, - SW_MICROPHONE_INSERT, - SW_LINEOUT_INSERT, - SW_JACK_PHYSICAL_INSERT, - SW_VIDEOOUT_INSERT, -}; - static int snd_jack_dev_free(struct snd_device *device) { struct snd_jack *jack = device->device_data; @@ -87,7 +79,6 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, { struct snd_jack *jack; int err; - int i; static struct snd_device_ops ops = { .dev_free = snd_jack_dev_free, .dev_register = snd_jack_dev_register, @@ -109,10 +100,18 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, jack->type = type; - for (i = 0; i < ARRAY_SIZE(jack_types); i++) - if (type & (1 << i)) - input_set_capability(jack->input_dev, EV_SW, - jack_types[i]); + if (type & SND_JACK_HEADPHONE) + input_set_capability(jack->input_dev, EV_SW, + SW_HEADPHONE_INSERT); + if (type & SND_JACK_LINEOUT) + input_set_capability(jack->input_dev, EV_SW, + SW_LINEOUT_INSERT); + if (type & SND_JACK_MICROPHONE) + input_set_capability(jack->input_dev, EV_SW, + SW_MICROPHONE_INSERT); + if (type & SND_JACK_MECHANICAL) + input_set_capability(jack->input_dev, EV_SW, + SW_JACK_PHYSICAL_INSERT); err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); if (err < 0) @@ -155,17 +154,21 @@ EXPORT_SYMBOL(snd_jack_set_parent); */ void snd_jack_report(struct snd_jack *jack, int status) { - int i; - if (!jack) return; - for (i = 0; i < ARRAY_SIZE(jack_types); i++) { - int testbit = 1 << i; - if (jack->type & testbit) - input_report_switch(jack->input_dev, jack_types[i], - status & testbit); - } + if (jack->type & SND_JACK_HEADPHONE) + input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT, + status & SND_JACK_HEADPHONE); + if (jack->type & SND_JACK_LINEOUT) + input_report_switch(jack->input_dev, SW_LINEOUT_INSERT, + status & SND_JACK_LINEOUT); + if (jack->type & SND_JACK_MICROPHONE) + input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT, + status & SND_JACK_MICROPHONE); + if (jack->type & SND_JACK_MECHANICAL) + input_report_switch(jack->input_dev, SW_JACK_PHYSICAL_INSERT, + status & SND_JACK_MECHANICAL); input_sync(jack->input_dev); } diff --git a/trunk/sound/core/misc.c b/trunk/sound/core/misc.c index a9710e0c97af..38524f615d94 100644 --- a/trunk/sound/core/misc.c +++ b/trunk/sound/core/misc.c @@ -95,14 +95,12 @@ snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list) { const struct snd_pci_quirk *q; - for (q = list; q->subvendor; q++) { - if (q->subvendor != pci->subsystem_vendor) - continue; - if (!q->subdevice || - (pci->subsystem_device & q->subdevice_mask) == q->subdevice) + for (q = list; q->subvendor; q++) + if (q->subvendor == pci->subsystem_vendor && + (!q->subdevice || q->subdevice == pci->subsystem_device)) return q; - } return NULL; } + EXPORT_SYMBOL(snd_pci_quirk_lookup); #endif diff --git a/trunk/sound/core/oss/mixer_oss.c b/trunk/sound/core/oss/mixer_oss.c index e570649184e2..4690b8b5681f 100644 --- a/trunk/sound/core/oss/mixer_oss.c +++ b/trunk/sound/core/oss/mixer_oss.c @@ -692,9 +692,6 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer, snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right); - } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) { - snd_mixer_oss_put_volume1_vol(fmixer, pslot, - slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right); } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) { snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right); } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) { diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index 2864cefb773c..0a1798eafb0b 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -1160,11 +1160,9 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { #ifdef OSS_DEBUG if (runtime->status->state == SNDRV_PCM_STATE_XRUN) - printk(KERN_DEBUG "pcm_oss: write: " - "recovering from XRUN\n"); + printk("pcm_oss: write: recovering from XRUN\n"); else - printk(KERN_DEBUG "pcm_oss: write: " - "recovering from SUSPEND\n"); + printk("pcm_oss: write: recovering from SUSPEND\n"); #endif ret = snd_pcm_oss_prepare(substream); if (ret < 0) @@ -1198,11 +1196,9 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { #ifdef OSS_DEBUG if (runtime->status->state == SNDRV_PCM_STATE_XRUN) - printk(KERN_DEBUG "pcm_oss: read: " - "recovering from XRUN\n"); + printk("pcm_oss: read: recovering from XRUN\n"); else - printk(KERN_DEBUG "pcm_oss: read: " - "recovering from SUSPEND\n"); + printk("pcm_oss: read: recovering from SUSPEND\n"); #endif ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); if (ret < 0) @@ -1246,11 +1242,9 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { #ifdef OSS_DEBUG if (runtime->status->state == SNDRV_PCM_STATE_XRUN) - printk(KERN_DEBUG "pcm_oss: writev: " - "recovering from XRUN\n"); + printk("pcm_oss: writev: recovering from XRUN\n"); else - printk(KERN_DEBUG "pcm_oss: writev: " - "recovering from SUSPEND\n"); + printk("pcm_oss: writev: recovering from SUSPEND\n"); #endif ret = snd_pcm_oss_prepare(substream); if (ret < 0) @@ -1284,11 +1278,9 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void * runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { #ifdef OSS_DEBUG if (runtime->status->state == SNDRV_PCM_STATE_XRUN) - printk(KERN_DEBUG "pcm_oss: readv: " - "recovering from XRUN\n"); + printk("pcm_oss: readv: recovering from XRUN\n"); else - printk(KERN_DEBUG "pcm_oss: readv: " - "recovering from SUSPEND\n"); + printk("pcm_oss: readv: recovering from SUSPEND\n"); #endif ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); if (ret < 0) @@ -1541,7 +1533,7 @@ static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size) init_waitqueue_entry(&wait, current); add_wait_queue(&runtime->sleep, &wait); #ifdef OSS_DEBUG - printk(KERN_DEBUG "sync1: size = %li\n", size); + printk("sync1: size = %li\n", size); #endif while (1) { result = snd_pcm_oss_write2(substream, runtime->oss.buffer, size, 1); @@ -1598,7 +1590,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) mutex_lock(&runtime->oss.params_lock); if (runtime->oss.buffer_used > 0) { #ifdef OSS_DEBUG - printk(KERN_DEBUG "sync: buffer_used\n"); + printk("sync: buffer_used\n"); #endif size = (8 * (runtime->oss.period_bytes - runtime->oss.buffer_used) + 7) / width; snd_pcm_format_set_silence(format, @@ -1611,7 +1603,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) } } else if (runtime->oss.period_ptr > 0) { #ifdef OSS_DEBUG - printk(KERN_DEBUG "sync: period_ptr\n"); + printk("sync: period_ptr\n"); #endif size = runtime->oss.period_bytes - runtime->oss.period_ptr; snd_pcm_format_set_silence(format, @@ -1960,7 +1952,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr int err, cmd; #ifdef OSS_DEBUG - printk(KERN_DEBUG "pcm_oss: trigger = 0x%x\n", trigger); + printk("pcm_oss: trigger = 0x%x\n", trigger); #endif psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; @@ -2178,9 +2170,7 @@ static int snd_pcm_oss_get_space(struct snd_pcm_oss_file *pcm_oss_file, int stre } #ifdef OSS_DEBUG - printk(KERN_DEBUG "pcm_oss: space: bytes = %i, fragments = %i, " - "fragstotal = %i, fragsize = %i\n", - info.bytes, info.fragments, info.fragstotal, info.fragsize); + printk("pcm_oss: space: bytes = %i, fragments = %i, fragstotal = %i, fragsize = %i\n", info.bytes, info.fragments, info.fragstotal, info.fragsize); #endif if (copy_to_user(_info, &info, sizeof(info))) return -EFAULT; @@ -2483,7 +2473,7 @@ static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long if (((cmd >> 8) & 0xff) != 'P') return -EINVAL; #ifdef OSS_DEBUG - printk(KERN_DEBUG "pcm_oss: ioctl = 0x%x\n", cmd); + printk("pcm_oss: ioctl = 0x%x\n", cmd); #endif switch (cmd) { case SNDCTL_DSP_RESET: @@ -2637,8 +2627,7 @@ static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t coun #else { ssize_t res = snd_pcm_oss_read1(substream, buf, count); - printk(KERN_DEBUG "pcm_oss: read %li bytes " - "(returned %li bytes)\n", (long)count, (long)res); + printk("pcm_oss: read %li bytes (returned %li bytes)\n", (long)count, (long)res); return res; } #endif @@ -2657,8 +2646,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size substream->f_flags = file->f_flags & O_NONBLOCK; result = snd_pcm_oss_write1(substream, buf, count); #ifdef OSS_DEBUG - printk(KERN_DEBUG "pcm_oss: write %li bytes (wrote %li bytes)\n", - (long)count, (long)result); + printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); #endif return result; } @@ -2732,7 +2720,7 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) int err; #ifdef OSS_DEBUG - printk(KERN_DEBUG "pcm_oss: mmap begin\n"); + printk("pcm_oss: mmap begin\n"); #endif pcm_oss_file = file->private_data; switch ((area->vm_flags & (VM_READ | VM_WRITE))) { @@ -2782,8 +2770,7 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) runtime->silence_threshold = 0; runtime->silence_size = 0; #ifdef OSS_DEBUG - printk(KERN_DEBUG "pcm_oss: mmap ok, bytes = 0x%x\n", - runtime->oss.mmap_bytes); + printk("pcm_oss: mmap ok, bytes = 0x%x\n", runtime->oss.mmap_bytes); #endif /* In mmap mode we never stop */ runtime->stop_threshold = runtime->boundary; @@ -2885,7 +2872,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, setup = kmalloc(sizeof(*setup), GFP_KERNEL); if (! setup) { buffer->error = -ENOMEM; - mutex_unlock(&pstr->oss.setup_mutex); + mutex_lock(&pstr->oss.setup_mutex); return; } if (pstr->oss.setup_list == NULL) @@ -2899,7 +2886,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, if (! template.task_name) { kfree(setup); buffer->error = -ENOMEM; - mutex_unlock(&pstr->oss.setup_mutex); + mutex_lock(&pstr->oss.setup_mutex); return; } } diff --git a/trunk/sound/core/oss/pcm_plugin.h b/trunk/sound/core/oss/pcm_plugin.h index b9afab603711..ca2f4c39be46 100644 --- a/trunk/sound/core/oss/pcm_plugin.h +++ b/trunk/sound/core/oss/pcm_plugin.h @@ -176,9 +176,9 @@ static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_ #endif #ifdef PLUGIN_DEBUG -#define pdprintf(fmt, args...) printk(KERN_DEBUG "plugin: " fmt, ##args) +#define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args) #else -#define pdprintf(fmt, args...) +#define pdprintf( fmt, args... ) #endif #endif /* __PCM_PLUGIN_H */ diff --git a/trunk/sound/core/pcm.c b/trunk/sound/core/pcm.c index 145931a9ff30..192a433a2403 100644 --- a/trunk/sound/core/pcm.c +++ b/trunk/sound/core/pcm.c @@ -667,6 +667,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) spin_lock_init(&substream->self_group.lock); INIT_LIST_HEAD(&substream->self_group.substreams); list_add_tail(&substream->link_list, &substream->self_group.substreams); + spin_lock_init(&substream->timer_lock); atomic_set(&substream->mmap_count, 0); prev = substream; } @@ -691,7 +692,7 @@ EXPORT_SYMBOL(snd_pcm_new_stream); * * Returns zero if successful, or a negative error code on failure. */ -int snd_pcm_new(struct snd_card *card, const char *id, int device, +int snd_pcm_new(struct snd_card *card, char *id, int device, int playback_count, int capture_count, struct snd_pcm ** rpcm) { diff --git a/trunk/sound/core/pcm_lib.c b/trunk/sound/core/pcm_lib.c index fbb2e391591e..921691080f35 100644 --- a/trunk/sound/core/pcm_lib.c +++ b/trunk/sound/core/pcm_lib.c @@ -125,32 +125,23 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram } } -#ifdef CONFIG_SND_PCM_XRUN_DEBUG -#define xrun_debug(substream) ((substream)->pstr->xrun_debug) -#else -#define xrun_debug(substream) 0 -#endif - -#define dump_stack_on_xrun(substream) do { \ - if (xrun_debug(substream) > 1) \ - dump_stack(); \ - } while (0) - static void xrun(struct snd_pcm_substream *substream) { snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - if (xrun_debug(substream)) { +#ifdef CONFIG_SND_PCM_XRUN_DEBUG + if (substream->pstr->xrun_debug) { snd_printd(KERN_DEBUG "XRUN: pcmC%dD%d%c\n", substream->pcm->card->number, substream->pcm->device, substream->stream ? 'c' : 'p'); - dump_stack_on_xrun(substream); + if (substream->pstr->xrun_debug > 1) + dump_stack(); } +#endif } -static snd_pcm_uframes_t -snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, - struct snd_pcm_runtime *runtime) +static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, + struct snd_pcm_runtime *runtime) { snd_pcm_uframes_t pos; @@ -159,21 +150,17 @@ snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, pos = substream->ops->pointer(substream); if (pos == SNDRV_PCM_POS_XRUN) return pos; /* XRUN */ +#ifdef CONFIG_SND_DEBUG if (pos >= runtime->buffer_size) { - if (printk_ratelimit()) { - snd_printd(KERN_ERR "BUG: stream = %i, pos = 0x%lx, " - "buffer size = 0x%lx, period size = 0x%lx\n", - substream->stream, pos, runtime->buffer_size, - runtime->period_size); - } - pos = 0; + snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size); } +#endif pos -= pos % runtime->min_align; return pos; } -static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, - struct snd_pcm_runtime *runtime) +static inline int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, + struct snd_pcm_runtime *runtime) { snd_pcm_uframes_t avail; @@ -195,21 +182,11 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, return 0; } -#define hw_ptr_error(substream, fmt, args...) \ - do { \ - if (xrun_debug(substream)) { \ - if (printk_ratelimit()) { \ - snd_printd("PCM: " fmt, ##args); \ - } \ - dump_stack_on_xrun(substream); \ - } \ - } while (0) - -static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) +static inline int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t pos; - snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt, hw_base; + snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt; snd_pcm_sframes_t delta; pos = snd_pcm_update_hw_ptr_pos(substream, runtime); @@ -217,53 +194,36 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) xrun(substream); return -EPIPE; } - hw_base = runtime->hw_ptr_base; - new_hw_ptr = hw_base + pos; + if (runtime->period_size == runtime->buffer_size) + goto __next_buf; + new_hw_ptr = runtime->hw_ptr_base + pos; hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size; - delta = new_hw_ptr - hw_ptr_interrupt; - if (hw_ptr_interrupt >= runtime->boundary) { - hw_ptr_interrupt -= runtime->boundary; - if (hw_base < runtime->boundary / 2) - /* hw_base was already lapped; recalc delta */ - delta = new_hw_ptr - hw_ptr_interrupt; - } - if (delta < 0) { - delta += runtime->buffer_size; - if (delta < 0) { - hw_ptr_error(substream, - "Unexpected hw_pointer value " - "(stream=%i, pos=%ld, intr_ptr=%ld)\n", - substream->stream, (long)pos, - (long)hw_ptr_interrupt); - /* rebase to interrupt position */ - hw_base = new_hw_ptr = hw_ptr_interrupt; - /* align hw_base to buffer_size */ - hw_base -= hw_base % runtime->buffer_size; - delta = 0; - } else { - hw_base += runtime->buffer_size; - if (hw_base >= runtime->boundary) - hw_base = 0; - new_hw_ptr = hw_base + pos; + + delta = hw_ptr_interrupt - new_hw_ptr; + if (delta > 0) { + if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { +#ifdef CONFIG_SND_PCM_XRUN_DEBUG + if (runtime->periods > 1 && substream->pstr->xrun_debug) { + snd_printd(KERN_ERR "Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); + if (substream->pstr->xrun_debug > 1) + dump_stack(); + } +#endif + return 0; } + __next_buf: + runtime->hw_ptr_base += runtime->buffer_size; + if (runtime->hw_ptr_base == runtime->boundary) + runtime->hw_ptr_base = 0; + new_hw_ptr = runtime->hw_ptr_base + pos; } - if (delta > runtime->period_size) { - hw_ptr_error(substream, - "Lost interrupts? " - "(stream=%i, delta=%ld, intr_ptr=%ld)\n", - substream->stream, (long)delta, - (long)hw_ptr_interrupt); - /* rebase hw_ptr_interrupt */ - hw_ptr_interrupt = - new_hw_ptr - new_hw_ptr % runtime->period_size; - } + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && runtime->silence_size > 0) snd_pcm_playback_silence(substream, new_hw_ptr); - runtime->hw_ptr_base = hw_base; runtime->status->hw_ptr = new_hw_ptr; - runtime->hw_ptr_interrupt = hw_ptr_interrupt; + runtime->hw_ptr_interrupt = new_hw_ptr - new_hw_ptr % runtime->period_size; return snd_pcm_update_hw_ptr_post(substream, runtime); } @@ -273,7 +233,7 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t pos; - snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base; + snd_pcm_uframes_t old_hw_ptr, new_hw_ptr; snd_pcm_sframes_t delta; old_hw_ptr = runtime->status->hw_ptr; @@ -282,38 +242,29 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) xrun(substream); return -EPIPE; } - hw_base = runtime->hw_ptr_base; - new_hw_ptr = hw_base + pos; - - delta = new_hw_ptr - old_hw_ptr; - if (delta < 0) { - delta += runtime->buffer_size; - if (delta < 0) { - hw_ptr_error(substream, - "Unexpected hw_pointer value [2] " - "(stream=%i, pos=%ld, old_ptr=%ld)\n", - substream->stream, (long)pos, - (long)old_hw_ptr); + new_hw_ptr = runtime->hw_ptr_base + pos; + + delta = old_hw_ptr - new_hw_ptr; + if (delta > 0) { + if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { +#ifdef CONFIG_SND_PCM_XRUN_DEBUG + if (runtime->periods > 2 && substream->pstr->xrun_debug) { + snd_printd(KERN_ERR "Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); + if (substream->pstr->xrun_debug > 1) + dump_stack(); + } +#endif return 0; } - hw_base += runtime->buffer_size; - if (hw_base >= runtime->boundary) - hw_base = 0; - new_hw_ptr = hw_base + pos; - } - if (delta > runtime->period_size && runtime->periods > 1) { - hw_ptr_error(substream, - "hw_ptr skipping! " - "(pos=%ld, delta=%ld, period=%ld)\n", - (long)pos, (long)delta, - (long)runtime->period_size); - return 0; + runtime->hw_ptr_base += runtime->buffer_size; + if (runtime->hw_ptr_base == runtime->boundary) + runtime->hw_ptr_base = 0; + new_hw_ptr = runtime->hw_ptr_base + pos; } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && runtime->silence_size > 0) snd_pcm_playback_silence(substream, new_hw_ptr); - runtime->hw_ptr_base = hw_base; runtime->status->hw_ptr = new_hw_ptr; return snd_pcm_update_hw_ptr_post(substream, runtime); diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index d9b8f5379428..a789efc9df39 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -186,7 +186,7 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, if (!(params->rmask & (1 << k))) continue; #ifdef RULES_DEBUG - printk(KERN_DEBUG "%s = ", snd_pcm_hw_param_names[k]); + printk("%s = ", snd_pcm_hw_param_names[k]); printk("%04x%04x%04x%04x -> ", m->bits[3], m->bits[2], m->bits[1], m->bits[0]); #endif changed = snd_mask_refine(m, constrs_mask(constrs, k)); @@ -206,7 +206,7 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, if (!(params->rmask & (1 << k))) continue; #ifdef RULES_DEBUG - printk(KERN_DEBUG "%s = ", snd_pcm_hw_param_names[k]); + printk("%s = ", snd_pcm_hw_param_names[k]); if (i->empty) printk("empty"); else @@ -251,7 +251,7 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, if (!doit) continue; #ifdef RULES_DEBUG - printk(KERN_DEBUG "Rule %d [%p]: ", k, r->func); + printk("Rule %d [%p]: ", k, r->func); if (r->var >= 0) { printk("%s = ", snd_pcm_hw_param_names[r->var]); if (hw_is_mask(r->var)) { diff --git a/trunk/sound/core/pcm_timer.c b/trunk/sound/core/pcm_timer.c index ca8068b63d6c..2c89c04f2916 100644 --- a/trunk/sound/core/pcm_timer.c +++ b/trunk/sound/core/pcm_timer.c @@ -85,19 +85,25 @@ static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer) static int snd_pcm_timer_start(struct snd_timer * timer) { + unsigned long flags; struct snd_pcm_substream *substream; substream = snd_timer_chip(timer); + spin_lock_irqsave(&substream->timer_lock, flags); substream->timer_running = 1; + spin_unlock_irqrestore(&substream->timer_lock, flags); return 0; } static int snd_pcm_timer_stop(struct snd_timer * timer) { + unsigned long flags; struct snd_pcm_substream *substream; substream = snd_timer_chip(timer); + spin_lock_irqsave(&substream->timer_lock, flags); substream->timer_running = 0; + spin_unlock_irqrestore(&substream->timer_lock, flags); return 0; } diff --git a/trunk/sound/core/rawmidi.c b/trunk/sound/core/rawmidi.c index 473247c8e6d3..002777ba336a 100644 --- a/trunk/sound/core/rawmidi.c +++ b/trunk/sound/core/rawmidi.c @@ -224,143 +224,156 @@ int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream) return 0; } -/* look for an available substream for the given stream direction; - * if a specific subdevice is given, try to assign it - */ -static int assign_substream(struct snd_rawmidi *rmidi, int subdevice, - int stream, int mode, - struct snd_rawmidi_substream **sub_ret) -{ - struct snd_rawmidi_substream *substream; - struct snd_rawmidi_str *s = &rmidi->streams[stream]; - static unsigned int info_flags[2] = { - [SNDRV_RAWMIDI_STREAM_OUTPUT] = SNDRV_RAWMIDI_INFO_OUTPUT, - [SNDRV_RAWMIDI_STREAM_INPUT] = SNDRV_RAWMIDI_INFO_INPUT, - }; - - if (!(rmidi->info_flags & info_flags[stream])) - return -ENXIO; - if (subdevice >= 0 && subdevice >= s->substream_count) - return -ENODEV; - if (s->substream_opened >= s->substream_count) - return -EAGAIN; - - list_for_each_entry(substream, &s->substreams, list) { - if (substream->opened) { - if (stream == SNDRV_RAWMIDI_STREAM_INPUT || - !(mode & SNDRV_RAWMIDI_LFLG_APPEND)) - continue; - } - if (subdevice < 0 || subdevice == substream->number) { - *sub_ret = substream; - return 0; - } - } - return -EAGAIN; -} - -/* open and do ref-counting for the given substream */ -static int open_substream(struct snd_rawmidi *rmidi, - struct snd_rawmidi_substream *substream, - int mode) -{ - int err; - - err = snd_rawmidi_runtime_create(substream); - if (err < 0) - return err; - err = substream->ops->open(substream); - if (err < 0) - return err; - substream->opened = 1; - if (substream->use_count++ == 0) - substream->active_sensing = 1; - if (mode & SNDRV_RAWMIDI_LFLG_APPEND) - substream->append = 1; - rmidi->streams[substream->stream].substream_opened++; - return 0; -} - -static void close_substream(struct snd_rawmidi *rmidi, - struct snd_rawmidi_substream *substream, - int cleanup); - -static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode, - struct snd_rawmidi_file *rfile) +int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, + int mode, struct snd_rawmidi_file * rfile) { + struct snd_rawmidi *rmidi; + struct list_head *list1, *list2; struct snd_rawmidi_substream *sinput = NULL, *soutput = NULL; + struct snd_rawmidi_runtime *input = NULL, *output = NULL; int err; - rfile->input = rfile->output = NULL; + if (rfile) + rfile->input = rfile->output = NULL; + mutex_lock(®ister_mutex); + rmidi = snd_rawmidi_search(card, device); + mutex_unlock(®ister_mutex); + if (rmidi == NULL) { + err = -ENODEV; + goto __error1; + } + if (!try_module_get(rmidi->card->module)) { + err = -EFAULT; + goto __error1; + } + if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) + mutex_lock(&rmidi->open_mutex); if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { - err = assign_substream(rmidi, subdevice, - SNDRV_RAWMIDI_STREAM_INPUT, - mode, &sinput); - if (err < 0) + if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) { + err = -ENXIO; + goto __error; + } + if (subdevice >= 0 && (unsigned int)subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_count) { + err = -ENODEV; + goto __error; + } + if (rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_opened >= + rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_count) { + err = -EAGAIN; goto __error; + } } if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) { - err = assign_substream(rmidi, subdevice, - SNDRV_RAWMIDI_STREAM_OUTPUT, - mode, &soutput); - if (err < 0) + if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT)) { + err = -ENXIO; goto __error; + } + if (subdevice >= 0 && (unsigned int)subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_count) { + err = -ENODEV; + goto __error; + } + if (rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened >= + rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_count) { + err = -EAGAIN; + goto __error; + } } - - if (sinput) { - err = open_substream(rmidi, sinput, mode); - if (err < 0) + list1 = rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams.next; + while (1) { + if (list1 == &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { + sinput = NULL; + if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { + err = -EAGAIN; + goto __error; + } + break; + } + sinput = list_entry(list1, struct snd_rawmidi_substream, list); + if ((mode & SNDRV_RAWMIDI_LFLG_INPUT) && sinput->opened) + goto __nexti; + if (subdevice < 0 || (subdevice >= 0 && subdevice == sinput->number)) + break; + __nexti: + list1 = list1->next; + } + list2 = rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams.next; + while (1) { + if (list2 == &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { + soutput = NULL; + if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) { + err = -EAGAIN; + goto __error; + } + break; + } + soutput = list_entry(list2, struct snd_rawmidi_substream, list); + if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) { + if (mode & SNDRV_RAWMIDI_LFLG_APPEND) { + if (soutput->opened && !soutput->append) + goto __nexto; + } else { + if (soutput->opened) + goto __nexto; + } + } + if (subdevice < 0 || (subdevice >= 0 && subdevice == soutput->number)) + break; + __nexto: + list2 = list2->next; + } + if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { + if ((err = snd_rawmidi_runtime_create(sinput)) < 0) + goto __error; + input = sinput->runtime; + if ((err = sinput->ops->open(sinput)) < 0) goto __error; + sinput->opened = 1; + rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_opened++; + } else { + sinput = NULL; } - if (soutput) { - err = open_substream(rmidi, soutput, mode); - if (err < 0) { - if (sinput) - close_substream(rmidi, sinput, 0); + if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) { + if (soutput->opened) + goto __skip_output; + if ((err = snd_rawmidi_runtime_create(soutput)) < 0) { + if (mode & SNDRV_RAWMIDI_LFLG_INPUT) + sinput->ops->close(sinput); + goto __error; + } + output = soutput->runtime; + if ((err = soutput->ops->open(soutput)) < 0) { + if (mode & SNDRV_RAWMIDI_LFLG_INPUT) + sinput->ops->close(sinput); goto __error; } + __skip_output: + soutput->opened = 1; + if (mode & SNDRV_RAWMIDI_LFLG_APPEND) + soutput->append = 1; + if (soutput->use_count++ == 0) + soutput->active_sensing = 1; + rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened++; + } else { + soutput = NULL; + } + if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) + mutex_unlock(&rmidi->open_mutex); + if (rfile) { + rfile->rmidi = rmidi; + rfile->input = sinput; + rfile->output = soutput; } - - rfile->rmidi = rmidi; - rfile->input = sinput; - rfile->output = soutput; return 0; __error: - if (sinput && sinput->runtime) + if (input != NULL) snd_rawmidi_runtime_free(sinput); - if (soutput && soutput->runtime) + if (output != NULL) snd_rawmidi_runtime_free(soutput); - return err; -} - -/* called from sound/core/seq/seq_midi.c */ -int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, - int mode, struct snd_rawmidi_file * rfile) -{ - struct snd_rawmidi *rmidi; - int err; - - if (snd_BUG_ON(!rfile)) - return -EINVAL; - - mutex_lock(®ister_mutex); - rmidi = snd_rawmidi_search(card, device); - if (rmidi == NULL) { - mutex_unlock(®ister_mutex); - return -ENODEV; - } - if (!try_module_get(rmidi->card->module)) { - mutex_unlock(®ister_mutex); - return -ENXIO; - } - mutex_unlock(®ister_mutex); - - mutex_lock(&rmidi->open_mutex); - err = rawmidi_open_priv(rmidi, subdevice, mode, rfile); - mutex_unlock(&rmidi->open_mutex); - if (err < 0) - module_put(rmidi->card->module); + module_put(rmidi->card->module); + if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) + mutex_unlock(&rmidi->open_mutex); + __error1: return err; } @@ -372,13 +385,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) unsigned short fflags; int err; struct snd_rawmidi *rmidi; - struct snd_rawmidi_file *rawmidi_file = NULL; + struct snd_rawmidi_file *rawmidi_file; wait_queue_t wait; struct snd_ctl_file *kctl; - if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) - return -EINVAL; /* invalid combination */ - if (maj == snd_major) { rmidi = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_RAWMIDI); @@ -392,25 +402,24 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) if (rmidi == NULL) return -ENODEV; - - if (!try_module_get(rmidi->card->module)) - return -ENXIO; - - mutex_lock(&rmidi->open_mutex); + if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) + return -EINVAL; /* invalid combination */ card = rmidi->card; err = snd_card_file_add(card, file); if (err < 0) - goto __error_card; + return -ENODEV; fflags = snd_rawmidi_file_flags(file); if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */ fflags |= SNDRV_RAWMIDI_LFLG_APPEND; + fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK; rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL); if (rawmidi_file == NULL) { - err = -ENOMEM; - goto __error; + snd_card_file_remove(card, file); + return -ENOMEM; } init_waitqueue_entry(&wait, current); add_wait_queue(&rmidi->open_wait, &wait); + mutex_lock(&rmidi->open_mutex); while (1) { subdevice = -1; read_lock(&card->ctl_files_rwlock); @@ -422,7 +431,8 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) } } read_unlock(&card->ctl_files_rwlock); - err = rawmidi_open_priv(rmidi, subdevice, fflags, rawmidi_file); + err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device, + subdevice, fflags, rawmidi_file); if (err >= 0) break; if (err == -EAGAIN) { @@ -441,89 +451,67 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) break; } } - remove_wait_queue(&rmidi->open_wait, &wait); - if (err < 0) { - kfree(rawmidi_file); - goto __error; - } #ifdef CONFIG_SND_OSSEMUL if (rawmidi_file->input && rawmidi_file->input->runtime) rawmidi_file->input->runtime->oss = (maj == SOUND_MAJOR); if (rawmidi_file->output && rawmidi_file->output->runtime) rawmidi_file->output->runtime->oss = (maj == SOUND_MAJOR); #endif - file->private_data = rawmidi_file; - mutex_unlock(&rmidi->open_mutex); - return 0; - - __error: - snd_card_file_remove(card, file); - __error_card: + remove_wait_queue(&rmidi->open_wait, &wait); + if (err >= 0) { + file->private_data = rawmidi_file; + } else { + snd_card_file_remove(card, file); + kfree(rawmidi_file); + } mutex_unlock(&rmidi->open_mutex); - module_put(rmidi->card->module); return err; } -static void close_substream(struct snd_rawmidi *rmidi, - struct snd_rawmidi_substream *substream, - int cleanup) +int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) { - rmidi->streams[substream->stream].substream_opened--; - if (--substream->use_count) - return; + struct snd_rawmidi *rmidi; + struct snd_rawmidi_substream *substream; + struct snd_rawmidi_runtime *runtime; - if (cleanup) { - if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT) - snd_rawmidi_input_trigger(substream, 0); - else { + if (snd_BUG_ON(!rfile)) + return -ENXIO; + rmidi = rfile->rmidi; + mutex_lock(&rmidi->open_mutex); + if (rfile->input != NULL) { + substream = rfile->input; + rfile->input = NULL; + runtime = substream->runtime; + snd_rawmidi_input_trigger(substream, 0); + substream->ops->close(substream); + if (runtime->private_free != NULL) + runtime->private_free(substream); + snd_rawmidi_runtime_free(substream); + substream->opened = 0; + rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_opened--; + } + if (rfile->output != NULL) { + substream = rfile->output; + rfile->output = NULL; + if (--substream->use_count == 0) { + runtime = substream->runtime; if (substream->active_sensing) { unsigned char buf = 0xfe; - /* sending single active sensing message - * to shut the device up - */ + /* sending single active sensing message to shut the device up */ snd_rawmidi_kernel_write(substream, &buf, 1); } if (snd_rawmidi_drain_output(substream) == -ERESTARTSYS) snd_rawmidi_output_trigger(substream, 0); + substream->ops->close(substream); + if (runtime->private_free != NULL) + runtime->private_free(substream); + snd_rawmidi_runtime_free(substream); + substream->opened = 0; + substream->append = 0; } + rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--; } - substream->ops->close(substream); - if (substream->runtime->private_free) - substream->runtime->private_free(substream); - snd_rawmidi_runtime_free(substream); - substream->opened = 0; - substream->append = 0; -} - -static void rawmidi_release_priv(struct snd_rawmidi_file *rfile) -{ - struct snd_rawmidi *rmidi; - - rmidi = rfile->rmidi; - mutex_lock(&rmidi->open_mutex); - if (rfile->input) { - close_substream(rmidi, rfile->input, 1); - rfile->input = NULL; - } - if (rfile->output) { - close_substream(rmidi, rfile->output, 1); - rfile->output = NULL; - } - rfile->rmidi = NULL; mutex_unlock(&rmidi->open_mutex); - wake_up(&rmidi->open_wait); -} - -/* called from sound/core/seq/seq_midi.c */ -int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile) -{ - struct snd_rawmidi *rmidi; - - if (snd_BUG_ON(!rfile)) - return -ENXIO; - - rmidi = rfile->rmidi; - rawmidi_release_priv(rfile); module_put(rmidi->card->module); return 0; } @@ -532,14 +520,15 @@ static int snd_rawmidi_release(struct inode *inode, struct file *file) { struct snd_rawmidi_file *rfile; struct snd_rawmidi *rmidi; + int err; rfile = file->private_data; + err = snd_rawmidi_kernel_release(rfile); rmidi = rfile->rmidi; - rawmidi_release_priv(rfile); + wake_up(&rmidi->open_wait); kfree(rfile); snd_card_file_remove(rmidi->card, file); - module_put(rmidi->card->module); - return 0; + return err; } static int snd_rawmidi_info(struct snd_rawmidi_substream *substream, diff --git a/trunk/sound/core/seq/oss/seq_oss_device.h b/trunk/sound/core/seq/oss/seq_oss_device.h index c0154a959d55..bf8d2b4cb15e 100644 --- a/trunk/sound/core/seq/oss/seq_oss_device.h +++ b/trunk/sound/core/seq/oss/seq_oss_device.h @@ -181,7 +181,7 @@ char *enabled_str(int bool); /* for debug */ #ifdef SNDRV_SEQ_OSS_DEBUG extern int seq_oss_debug; -#define debug_printk(x) do { if (seq_oss_debug > 0) snd_printd x; } while (0) +#define debug_printk(x) do { if (seq_oss_debug > 0) snd_printk x; } while (0) #else #define debug_printk(x) /**/ #endif diff --git a/trunk/sound/core/seq/seq_prioq.c b/trunk/sound/core/seq/seq_prioq.c index 29896ab23403..0101a8b99b73 100644 --- a/trunk/sound/core/seq/seq_prioq.c +++ b/trunk/sound/core/seq/seq_prioq.c @@ -321,8 +321,7 @@ void snd_seq_prioq_leave(struct snd_seq_prioq * f, int client, int timestamp) freeprev = cell; } else { #if 0 - printk(KERN_DEBUG "type = %i, source = %i, dest = %i, " - "client = %i\n", + printk("type = %i, source = %i, dest = %i, client = %i\n", cell->event.type, cell->event.source.client, cell->event.dest.client, diff --git a/trunk/sound/core/sgbuf.c b/trunk/sound/core/sgbuf.c index 4e7ec2b49873..d4564edd61d7 100644 --- a/trunk/sound/core/sgbuf.c +++ b/trunk/sound/core/sgbuf.c @@ -38,10 +38,6 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) if (! sgbuf) return -EINVAL; - if (dmab->area) - vunmap(dmab->area); - dmab->area = NULL; - tmpb.dev.type = SNDRV_DMA_TYPE_DEV; tmpb.dev.dev = sgbuf->dev; for (i = 0; i < sgbuf->pages; i++) { @@ -52,6 +48,9 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT; snd_dma_free_pages(&tmpb); } + if (dmab->area) + vunmap(dmab->area); + dmab->area = NULL; kfree(sgbuf->table); kfree(sgbuf->page_table); diff --git a/trunk/sound/core/vmaster.c b/trunk/sound/core/vmaster.c index 257624bd1997..4cc57f902e2c 100644 --- a/trunk/sound/core/vmaster.c +++ b/trunk/sound/core/vmaster.c @@ -50,38 +50,18 @@ struct link_slave { struct link_master *master; struct link_ctl_info info; int vals[2]; /* current values */ - unsigned int flags; struct snd_kcontrol slave; /* the copy of original control entry */ }; -static int slave_update(struct link_slave *slave) -{ - struct snd_ctl_elem_value *uctl; - int err, ch; - - uctl = kmalloc(sizeof(*uctl), GFP_KERNEL); - if (!uctl) - return -ENOMEM; - uctl->id = slave->slave.id; - err = slave->slave.get(&slave->slave, uctl); - for (ch = 0; ch < slave->info.count; ch++) - slave->vals[ch] = uctl->value.integer.value[ch]; - kfree(uctl); - return 0; -} - /* get the slave ctl info and save the initial values */ static int slave_init(struct link_slave *slave) { struct snd_ctl_elem_info *uinfo; - int err; + struct snd_ctl_elem_value *uctl; + int err, ch; - if (slave->info.count) { - /* already initialized */ - if (slave->flags & SND_CTL_SLAVE_NEED_UPDATE) - return slave_update(slave); - return 0; - } + if (slave->info.count) + return 0; /* already initialized */ uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL); if (!uinfo) @@ -105,7 +85,15 @@ static int slave_init(struct link_slave *slave) slave->info.max_val = uinfo->value.integer.max; kfree(uinfo); - return slave_update(slave); + uctl = kmalloc(sizeof(*uctl), GFP_KERNEL); + if (!uctl) + return -ENOMEM; + uctl->id = slave->slave.id; + err = slave->slave.get(&slave->slave, uctl); + for (ch = 0; ch < slave->info.count; ch++) + slave->vals[ch] = uctl->value.integer.value[ch]; + kfree(uctl); + return 0; } /* initialize master volume */ @@ -241,8 +229,7 @@ static void slave_free(struct snd_kcontrol *kcontrol) * - logarithmic volume control (dB level), no linear volume * - master can only attenuate the volume, no gain */ -int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, - unsigned int flags) +int snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave) { struct link_master *master_link = snd_kcontrol_chip(master); struct link_slave *srec; @@ -254,7 +241,6 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, srec->slave = *slave; memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); srec->master = master_link; - srec->flags = flags; /* override callbacks */ slave->info = slave_info; @@ -268,7 +254,8 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, list_add_tail(&srec->list, &master_link->slaves); return 0; } -EXPORT_SYMBOL(_snd_ctl_add_slave); + +EXPORT_SYMBOL(snd_ctl_add_slave); /* * ctl callbacks for master controls @@ -340,20 +327,8 @@ static void master_free(struct snd_kcontrol *kcontrol) } -/** - * snd_ctl_make_virtual_master - Create a virtual master control - * @name: name string of the control element to create - * @tlv: optional TLV int array for dB information - * - * Creates a virtual matster control with the given name string. - * Returns the created control element, or NULL for errors (ENOMEM). - * - * After creating a vmaster element, you can add the slave controls - * via snd_ctl_add_slave() or snd_ctl_add_slave_uncached(). - * - * The optional argument @tlv can be used to specify the TLV information - * for dB scale of the master control. It should be a single element - * with #SNDRV_CTL_TLVT_DB_SCALE type, and should be the max 0dB. +/* + * Create a virtual master control with the given name */ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, const unsigned int *tlv) @@ -392,4 +367,5 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, return kctl; } + EXPORT_SYMBOL(snd_ctl_make_virtual_master); diff --git a/trunk/sound/drivers/dummy.c b/trunk/sound/drivers/dummy.c index 54239d2e0997..73be7e14a603 100644 --- a/trunk/sound/drivers/dummy.c +++ b/trunk/sound/drivers/dummy.c @@ -588,10 +588,10 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr) int idx, err; int dev = devptr->id; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_dummy), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_dummy)); + if (card == NULL) + return -ENOMEM; dummy = card->private_data; dummy->card = card; for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) { diff --git a/trunk/sound/drivers/ml403-ac97cr.c b/trunk/sound/drivers/ml403-ac97cr.c index 1950ffce2b54..7783843ca9ae 100644 --- a/trunk/sound/drivers/ml403-ac97cr.c +++ b/trunk/sound/drivers/ml403-ac97cr.c @@ -1279,9 +1279,9 @@ static int __devinit snd_ml403_ac97cr_probe(struct platform_device *pfdev) if (!enable[dev]) return -ENOENT; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; err = snd_ml403_ac97cr_create(card, pfdev, &ml403_ac97cr); if (err < 0) { PDEBUG(INIT_FAILURE, "probe(): create failed!\n"); diff --git a/trunk/sound/drivers/mpu401/mpu401.c b/trunk/sound/drivers/mpu401/mpu401.c index 149d05a8202d..5b996f3faba5 100644 --- a/trunk/sound/drivers/mpu401/mpu401.c +++ b/trunk/sound/drivers/mpu401/mpu401.c @@ -73,9 +73,9 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard) snd_printk(KERN_ERR "the uart_enter option is obsolete; remove it\n"); *rcard = NULL; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "MPU-401 UART"); strcpy(card->shortname, card->driver); sprintf(card->longname, "%s at %#lx, ", card->shortname, port[dev]); diff --git a/trunk/sound/drivers/mtpav.c b/trunk/sound/drivers/mtpav.c index 2f8f295d6b0c..48b64e6b2670 100644 --- a/trunk/sound/drivers/mtpav.c +++ b/trunk/sound/drivers/mtpav.c @@ -303,10 +303,8 @@ static void snd_mtpav_output_port_write(struct mtpav *mtp_card, snd_mtpav_send_byte(mtp_card, 0xf5); snd_mtpav_send_byte(mtp_card, portp->hwport); - /* - snd_printk(KERN_DEBUG "new outport: 0x%x\n", - (unsigned int) portp->hwport); - */ + //snd_printk("new outport: 0x%x\n", (unsigned int) portp->hwport); + if (!(outbyte & 0x80) && portp->running_status) snd_mtpav_send_byte(mtp_card, portp->running_status); } @@ -542,7 +540,7 @@ static void snd_mtpav_read_bytes(struct mtpav *mcrd) u8 sbyt = snd_mtpav_getreg(mcrd, SREG); - /* printk(KERN_DEBUG "snd_mtpav_read_bytes() sbyt: 0x%x\n", sbyt); */ + //printk("snd_mtpav_read_bytes() sbyt: 0x%x\n", sbyt); if (!(sbyt & SIGS_BYTE)) return; @@ -587,12 +585,12 @@ static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id) static int __devinit snd_mtpav_get_ISA(struct mtpav * mcard) { if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) { - snd_printk(KERN_ERR "MTVAP port 0x%lx is busy\n", port); + snd_printk("MTVAP port 0x%lx is busy\n", port); return -EBUSY; } mcard->port = port; if (request_irq(irq, snd_mtpav_irqh, IRQF_DISABLED, "MOTU MTPAV", mcard)) { - snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq); + snd_printk("MTVAP IRQ %d busy\n", irq); return -EBUSY; } mcard->irq = irq; @@ -698,9 +696,9 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev) int err; struct mtpav *mtp_card; - err = snd_card_create(index, id, THIS_MODULE, sizeof(*mtp_card), &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, sizeof(*mtp_card)); + if (! card) + return -ENOMEM; mtp_card = card->private_data; spin_lock_init(&mtp_card->spinlock); diff --git a/trunk/sound/drivers/mts64.c b/trunk/sound/drivers/mts64.c index 9284829bf927..87ba1ddc0115 100644 --- a/trunk/sound/drivers/mts64.c +++ b/trunk/sound/drivers/mts64.c @@ -957,10 +957,10 @@ static int __devinit snd_mts64_probe(struct platform_device *pdev) if ((err = snd_mts64_probe_port(p)) < 0) return err; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) { + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) { snd_printd("Cannot create card\n"); - return err; + return -ENOMEM; } strcpy(card->driver, DRIVER_NAME); strcpy(card->shortname, "ESI " CARD_NAME); @@ -1015,7 +1015,7 @@ static int __devinit snd_mts64_probe(struct platform_device *pdev) goto __err; } - snd_printk(KERN_INFO "ESI Miditerminal 4140 on 0x%lx\n", p->base); + snd_printk("ESI Miditerminal 4140 on 0x%lx\n", p->base); return 0; __err: diff --git a/trunk/sound/drivers/opl3/opl3_lib.c b/trunk/sound/drivers/opl3/opl3_lib.c index 6e31e46ca393..780582340fef 100644 --- a/trunk/sound/drivers/opl3/opl3_lib.c +++ b/trunk/sound/drivers/opl3/opl3_lib.c @@ -302,7 +302,7 @@ void snd_opl3_interrupt(struct snd_hwdep * hw) opl3 = hw->private_data; status = inb(opl3->l_port); #if 0 - snd_printk(KERN_DEBUG "AdLib IRQ status = 0x%x\n", status); + snd_printk("AdLib IRQ status = 0x%x\n", status); #endif if (!(status & 0x80)) return; diff --git a/trunk/sound/drivers/opl3/opl3_midi.c b/trunk/sound/drivers/opl3/opl3_midi.c index 6e7d09ae0e82..16feafa2c51e 100644 --- a/trunk/sound/drivers/opl3/opl3_midi.c +++ b/trunk/sound/drivers/opl3/opl3_midi.c @@ -125,7 +125,7 @@ static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) { int i; char *str = "x.24"; - printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice); + printk("time %.5i: %s [%.2i]: ", opl3->use_time, s, voice); for (i = 0; i < opl3->max_voices; i++) printk("%c", *(str + opl3->voices[i].state + 1)); printk("\n"); @@ -218,7 +218,7 @@ static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op, for (i = 0; i < END; i++) { if (best[i].voice >= 0) { #ifdef DEBUG_ALLOC - printk(KERN_DEBUG "%s %iop allocation on voice %i\n", + printk("%s %iop allocation on voice %i\n", alloc_type[i], instr_4op ? 4 : 2, best[i].voice); #endif @@ -317,7 +317,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) opl3 = p; #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG "Note on, ch %i, inst %i, note %i, vel %i\n", + snd_printk("Note on, ch %i, inst %i, note %i, vel %i\n", chan->number, chan->midi_program, note, vel); #endif @@ -372,7 +372,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) return; } #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG " --> OPL%i instrument: %s\n", + snd_printk(" --> OPL%i instrument: %s\n", instr_4op ? 3 : 2, patch->name); #endif /* in SYNTH mode, application takes care of voices */ @@ -431,7 +431,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) } #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG " --> setting OPL3 connection: 0x%x\n", + snd_printk(" --> setting OPL3 connection: 0x%x\n", opl3->connection_reg); #endif /* @@ -466,7 +466,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) /* Program the FM voice characteristics */ for (i = 0; i < (instr_4op ? 4 : 2); i++) { #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG " --> programming operator %i\n", i); + snd_printk(" --> programming operator %i\n", i); #endif op_offset = snd_opl3_regmap[voice_offset][i]; @@ -546,7 +546,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) blocknum |= OPL3_KEYON_BIT; #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG " --> trigger voice %i\n", voice); + snd_printk(" --> trigger voice %i\n", voice); #endif /* Set OPL3 KEYON_BLOCK register of requested voice */ opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); @@ -602,7 +602,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) prg = extra_prg - 1; } #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG " *** allocating extra program\n"); + snd_printk(" *** allocating extra program\n"); #endif goto __extra_prg; } @@ -633,7 +633,7 @@ static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice) /* kill voice */ #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG " --> kill voice %i\n", voice); + snd_printk(" --> kill voice %i\n", voice); #endif opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); /* clear Key ON bit */ @@ -670,7 +670,7 @@ void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan opl3 = p; #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG "Note off, ch %i, inst %i, note %i\n", + snd_printk("Note off, ch %i, inst %i, note %i\n", chan->number, chan->midi_program, note); #endif @@ -709,7 +709,7 @@ void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *cha opl3 = p; #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG "Key pressure, ch#: %i, inst#: %i\n", + snd_printk("Key pressure, ch#: %i, inst#: %i\n", chan->number, chan->midi_program); #endif } @@ -723,7 +723,7 @@ void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan) opl3 = p; #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG "Terminate note, ch#: %i, inst#: %i\n", + snd_printk("Terminate note, ch#: %i, inst#: %i\n", chan->number, chan->midi_program); #endif } @@ -812,7 +812,7 @@ void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan) opl3 = p; #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG "Controller, TYPE = %i, ch#: %i, inst#: %i\n", + snd_printk("Controller, TYPE = %i, ch#: %i, inst#: %i\n", type, chan->number, chan->midi_program); #endif @@ -849,7 +849,7 @@ void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, opl3 = p; #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG "NRPN, ch#: %i, inst#: %i\n", + snd_printk("NRPN, ch#: %i, inst#: %i\n", chan->number, chan->midi_program); #endif } @@ -864,6 +864,6 @@ void snd_opl3_sysex(void *p, unsigned char *buf, int len, opl3 = p; #ifdef DEBUG_MIDI - snd_printk(KERN_DEBUG "SYSEX\n"); + snd_printk("SYSEX\n"); #endif } diff --git a/trunk/sound/drivers/opl3/opl3_oss.c b/trunk/sound/drivers/opl3/opl3_oss.c index a54b1dc5cc78..9a2271dc046a 100644 --- a/trunk/sound/drivers/opl3/opl3_oss.c +++ b/trunk/sound/drivers/opl3/opl3_oss.c @@ -220,14 +220,14 @@ static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, return -EINVAL; if (count < (int)sizeof(sbi)) { - snd_printk(KERN_ERR "FM Error: Patch record too short\n"); + snd_printk("FM Error: Patch record too short\n"); return -EINVAL; } if (copy_from_user(&sbi, buf, sizeof(sbi))) return -EFAULT; if (sbi.channel < 0 || sbi.channel >= SBFM_MAXINSTR) { - snd_printk(KERN_ERR "FM Error: Invalid instrument number %d\n", + snd_printk("FM Error: Invalid instrument number %d\n", sbi.channel); return -EINVAL; } @@ -254,9 +254,7 @@ static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, opl3 = arg->private_data; switch (cmd) { case SNDCTL_FM_LOAD_INSTR: - snd_printk(KERN_ERR "OPL3: " - "Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. " - "Fix the program.\n"); + snd_printk("OPL3: Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. Fix the program.\n"); return -EINVAL; case SNDCTL_SYNTH_MEMAVL: diff --git a/trunk/sound/drivers/opl3/opl3_synth.c b/trunk/sound/drivers/opl3/opl3_synth.c index 6d57b6441dec..962bb9c8b9c8 100644 --- a/trunk/sound/drivers/opl3/opl3_synth.c +++ b/trunk/sound/drivers/opl3/opl3_synth.c @@ -168,7 +168,7 @@ int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file, #ifdef CONFIG_SND_DEBUG default: - snd_printk(KERN_WARNING "unknown IOCTL: 0x%x\n", cmd); + snd_printk("unknown IOCTL: 0x%x\n", cmd); #endif } return -ENOTTY; diff --git a/trunk/sound/drivers/pcsp/pcsp.c b/trunk/sound/drivers/pcsp/pcsp.c index b60cef257b58..a4049eb94d35 100644 --- a/trunk/sound/drivers/pcsp/pcsp.c +++ b/trunk/sound/drivers/pcsp/pcsp.c @@ -57,7 +57,7 @@ static int __devinit snd_pcsp_create(struct snd_card *card) else min_div = MAX_DIV; #if PCSP_DEBUG - printk(KERN_DEBUG "PCSP: lpj=%li, min_div=%i, res=%li\n", + printk("PCSP: lpj=%li, min_div=%i, res=%li\n", loops_per_jiffy, min_div, tp.tv_nsec); #endif @@ -98,9 +98,9 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev) hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); pcsp_chip.timer.function = pcsp_do_timer; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (!card) + return -ENOMEM; err = snd_pcsp_create(card); if (err < 0) { diff --git a/trunk/sound/drivers/portman2x4.c b/trunk/sound/drivers/portman2x4.c index 60158e2e0eaf..b1c047ec19af 100644 --- a/trunk/sound/drivers/portman2x4.c +++ b/trunk/sound/drivers/portman2x4.c @@ -746,10 +746,10 @@ static int __devinit snd_portman_probe(struct platform_device *pdev) if ((err = snd_portman_probe_port(p)) < 0) return err; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) { + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) { snd_printd("Cannot create card\n"); - return err; + return -ENOMEM; } strcpy(card->driver, DRIVER_NAME); strcpy(card->shortname, CARD_NAME); diff --git a/trunk/sound/drivers/serial-u16550.c b/trunk/sound/drivers/serial-u16550.c index b2b6d50c9425..d8aab9da97c2 100644 --- a/trunk/sound/drivers/serial-u16550.c +++ b/trunk/sound/drivers/serial-u16550.c @@ -241,8 +241,7 @@ static void snd_uart16550_io_loop(struct snd_uart16550 * uart) snd_rawmidi_receive(uart->midi_input[substream], &c, 1); if (status & UART_LSR_OE) - snd_printk(KERN_WARNING - "%s: Overrun on device at 0x%lx\n", + snd_printk("%s: Overrun on device at 0x%lx\n", uart->rmidi->name, uart->base); } @@ -637,8 +636,7 @@ static int snd_uart16550_output_byte(struct snd_uart16550 *uart, } } else { if (!snd_uart16550_write_buffer(uart, midi_byte)) { - snd_printk(KERN_WARNING - "%s: Buffer overrun on device at 0x%lx\n", + snd_printk("%s: Buffer overrun on device at 0x%lx\n", uart->rmidi->name, uart->base); return 0; } @@ -817,8 +815,7 @@ static int __devinit snd_uart16550_create(struct snd_card *card, if (irq >= 0 && irq != SNDRV_AUTO_IRQ) { if (request_irq(irq, snd_uart16550_interrupt, IRQF_DISABLED, "Serial MIDI", uart)) { - snd_printk(KERN_WARNING - "irq %d busy. Using Polling.\n", irq); + snd_printk("irq %d busy. Using Polling.\n", irq); } else { uart->irq = irq; } @@ -922,29 +919,26 @@ static int __devinit snd_serial_probe(struct platform_device *devptr) case SNDRV_SERIAL_GENERIC: break; default: - snd_printk(KERN_ERR - "Adaptor type is out of range 0-%d (%d)\n", + snd_printk("Adaptor type is out of range 0-%d (%d)\n", SNDRV_SERIAL_MAX_ADAPTOR, adaptor[dev]); return -ENODEV; } if (outs[dev] < 1 || outs[dev] > SNDRV_SERIAL_MAX_OUTS) { - snd_printk(KERN_ERR - "Count of outputs is out of range 1-%d (%d)\n", + snd_printk("Count of outputs is out of range 1-%d (%d)\n", SNDRV_SERIAL_MAX_OUTS, outs[dev]); return -ENODEV; } if (ins[dev] < 1 || ins[dev] > SNDRV_SERIAL_MAX_INS) { - snd_printk(KERN_ERR - "Count of inputs is out of range 1-%d (%d)\n", + snd_printk("Count of inputs is out of range 1-%d (%d)\n", SNDRV_SERIAL_MAX_INS, ins[dev]); return -ENODEV; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "Serial"); strcpy(card->shortname, "Serial MIDI (UART16550A)"); diff --git a/trunk/sound/drivers/virmidi.c b/trunk/sound/drivers/virmidi.c index 0e631c3221e3..f79e3614079d 100644 --- a/trunk/sound/drivers/virmidi.c +++ b/trunk/sound/drivers/virmidi.c @@ -90,17 +90,15 @@ static int __devinit snd_virmidi_probe(struct platform_device *devptr) int idx, err; int dev = devptr->id; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_virmidi), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_virmidi)); + if (card == NULL) + return -ENOMEM; vmidi = (struct snd_card_virmidi *)card->private_data; vmidi->card = card; if (midi_devs[dev] > MAX_MIDI_DEVICES) { - snd_printk(KERN_WARNING - "too much midi devices for virmidi %d: " - "force to use %d\n", dev, MAX_MIDI_DEVICES); + snd_printk("too much midi devices for virmidi %d: force to use %d\n", dev, MAX_MIDI_DEVICES); midi_devs[dev] = MAX_MIDI_DEVICES; } for (idx = 0; idx < midi_devs[dev]; idx++) { diff --git a/trunk/sound/drivers/vx/vx_core.c b/trunk/sound/drivers/vx/vx_core.c index 19c6e376c7c7..14e3354be43a 100644 --- a/trunk/sound/drivers/vx/vx_core.c +++ b/trunk/sound/drivers/vx/vx_core.c @@ -688,8 +688,7 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp) image = dsp->data + i; /* Wait DSP ready for a new read */ if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) { - printk(KERN_ERR - "dsp loading error at position %d\n", i); + printk("dsp loading error at position %d\n", i); return err; } cptr = image; diff --git a/trunk/sound/drivers/vx/vx_hwdep.c b/trunk/sound/drivers/vx/vx_hwdep.c index 46df8817c18f..8d6362e2d4c9 100644 --- a/trunk/sound/drivers/vx/vx_hwdep.c +++ b/trunk/sound/drivers/vx/vx_hwdep.c @@ -119,6 +119,16 @@ void snd_vx_free_firmware(struct vx_core *chip) #else /* old style firmware loading */ +static int vx_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + +static int vx_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + static int vx_hwdep_dsp_status(struct snd_hwdep *hw, struct snd_hwdep_dsp_status *info) { @@ -233,6 +243,8 @@ int snd_vx_setup_firmware(struct vx_core *chip) hw->iface = SNDRV_HWDEP_IFACE_VX; hw->private_data = chip; + hw->ops.open = vx_hwdep_open; + hw->ops.release = vx_hwdep_release; hw->ops.dsp_status = vx_hwdep_dsp_status; hw->ops.dsp_load = vx_hwdep_dsp_load; hw->exclusive = 1; diff --git a/trunk/sound/drivers/vx/vx_uer.c b/trunk/sound/drivers/vx/vx_uer.c index b0560fec6bba..0e1ba9b47904 100644 --- a/trunk/sound/drivers/vx/vx_uer.c +++ b/trunk/sound/drivers/vx/vx_uer.c @@ -103,7 +103,7 @@ static void vx_write_one_cbit(struct vx_core *chip, int index, int val) * returns the frequency of UER, or 0 if not sync, * or a negative error code. */ -static int vx_read_uer_status(struct vx_core *chip, unsigned int *mode) +static int vx_read_uer_status(struct vx_core *chip, int *mode) { int val, freq; diff --git a/trunk/sound/i2c/Makefile b/trunk/sound/i2c/Makefile index 36879bf88700..37970666a453 100644 --- a/trunk/sound/i2c/Makefile +++ b/trunk/sound/i2c/Makefile @@ -7,6 +7,8 @@ snd-i2c-objs := i2c.o snd-cs8427-objs := cs8427.o snd-tea6330t-objs := tea6330t.o +obj-$(CONFIG_L3) += l3/ + obj-$(CONFIG_SND) += other/ # Toplevel Module Dependency diff --git a/trunk/sound/i2c/l3/Makefile b/trunk/sound/i2c/l3/Makefile new file mode 100644 index 000000000000..49455b8dcc04 --- /dev/null +++ b/trunk/sound/i2c/l3/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for ALSA +# + +snd-uda1341-objs := uda1341.o + +# Module Dependency +obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-uda1341.o diff --git a/trunk/sound/i2c/l3/uda1341.c b/trunk/sound/i2c/l3/uda1341.c new file mode 100644 index 000000000000..9840eb43648d --- /dev/null +++ b/trunk/sound/i2c/l3/uda1341.c @@ -0,0 +1,935 @@ +/* + * Philips UDA1341 mixer device driver + * Copyright (c) 2002 Tomas Kasparek + * + * Portions are Copyright (C) 2000 Lernout & Hauspie Speech Products, N.V. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + * + * History: + * + * 2002-03-13 Tomas Kasparek initial release - based on uda1341.c from OSS + * 2002-03-28 Tomas Kasparek basic mixer is working (volume, bass, treble) + * 2002-03-30 Tomas Kasparek proc filesystem support, complete mixer and DSP + * features support + * 2002-04-12 Tomas Kasparek proc interface update, code cleanup + * 2002-05-12 Tomas Kasparek another code cleanup + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include + +/* {{{ HW regs definition */ + +#define STAT0 0x00 +#define STAT1 0x80 +#define STAT_MASK 0x80 + +#define DATA0_0 0x00 +#define DATA0_1 0x40 +#define DATA0_2 0x80 +#define DATA_MASK 0xc0 + +#define IS_DATA0(x) ((x) >= data0_0 && (x) <= data0_2) +#define IS_DATA1(x) ((x) == data1) +#define IS_STATUS(x) ((x) == stat0 || (x) == stat1) +#define IS_EXTEND(x) ((x) >= ext0 && (x) <= ext6) + +/* }}} */ + + +static const char *peak_names[] = { + "before", + "after", +}; + +static const char *filter_names[] = { + "flat", + "min", + "min", + "max", +}; + +static const char *mixer_names[] = { + "double differential", + "input channel 1 (line in)", + "input channel 2 (microphone)", + "digital mixer", +}; + +static const char *deemp_names[] = { + "none", + "32 kHz", + "44.1 kHz", + "48 kHz", +}; + +enum uda1341_regs_names { + stat0, + stat1, + data0_0, + data0_1, + data0_2, + data1, + ext0, + ext1, + ext2, + empty, + ext4, + ext5, + ext6, + uda1341_reg_last, +}; + +static const char *uda1341_reg_names[] = { + "stat 0 ", + "stat 1 ", + "data 00", + "data 01", + "data 02", + "data 1 ", + "ext 0", + "ext 1", + "ext 2", + "empty", + "ext 4", + "ext 5", + "ext 6", +}; + +static const int uda1341_enum_items[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, //peak - before/after + 4, //deemp - none/32/44.1/48 + 0, + 4, //filter - flat/min/min/max + 0, 0, 0, + 4, //mixer - differ/line/mic/mixer + 0, 0, 0, 0, 0, +}; + +static const char ** uda1341_enum_names[] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + peak_names, //peak - before/after + deemp_names, //deemp - none/32/44.1/48 + NULL, + filter_names, //filter - flat/min/min/max + NULL, NULL, NULL, + mixer_names, //mixer - differ/line/mic/mixer + NULL, NULL, NULL, NULL, NULL, +}; + +typedef int uda1341_cfg[CMD_LAST]; + +struct uda1341 { + int (*write) (struct l3_client *uda1341, unsigned short reg, unsigned short val); + int (*read) (struct l3_client *uda1341, unsigned short reg); + unsigned char regs[uda1341_reg_last]; + int active; + spinlock_t reg_lock; + struct snd_card *card; + uda1341_cfg cfg; +#ifdef CONFIG_PM + unsigned char suspend_regs[uda1341_reg_last]; + uda1341_cfg suspend_cfg; +#endif +}; + +/* transfer 8bit integer into string with binary representation */ +static void int2str_bin8(uint8_t val, char *buf) +{ + const int size = sizeof(val) * 8; + int i; + + for (i= 0; i < size; i++){ + *(buf++) = (val >> (size - 1)) ? '1' : '0'; + val <<= 1; + } + *buf = '\0'; //end the string with zero +} + +/* {{{ HW manipulation routines */ + +static int snd_uda1341_codec_write(struct l3_client *clnt, unsigned short reg, unsigned short val) +{ + struct uda1341 *uda = clnt->driver_data; + unsigned char buf[2] = { 0xc0, 0xe0 }; // for EXT addressing + int err = 0; + + uda->regs[reg] = val; + + if (uda->active) { + if (IS_DATA0(reg)) { + err = l3_write(clnt, UDA1341_DATA0, (const unsigned char *)&val, 1); + } else if (IS_DATA1(reg)) { + err = l3_write(clnt, UDA1341_DATA1, (const unsigned char *)&val, 1); + } else if (IS_STATUS(reg)) { + err = l3_write(clnt, UDA1341_STATUS, (const unsigned char *)&val, 1); + } else if (IS_EXTEND(reg)) { + buf[0] |= (reg - ext0) & 0x7; //EXT address + buf[1] |= val; //EXT data + err = l3_write(clnt, UDA1341_DATA0, (const unsigned char *)buf, 2); + } + } else + printk(KERN_ERR "UDA1341 codec not active!\n"); + return err; +} + +static int snd_uda1341_codec_read(struct l3_client *clnt, unsigned short reg) +{ + unsigned char val; + int err; + + err = l3_read(clnt, reg, &val, 1); + if (err == 1) + // use just 6bits - the rest is address of the reg + return val & 63; + return err < 0 ? err : -EIO; +} + +static inline int snd_uda1341_valid_reg(struct l3_client *clnt, unsigned short reg) +{ + return reg < uda1341_reg_last; +} + +static int snd_uda1341_update_bits(struct l3_client *clnt, unsigned short reg, + unsigned short mask, unsigned short shift, + unsigned short value, int flush) +{ + int change; + unsigned short old, new; + struct uda1341 *uda = clnt->driver_data; + +#if 0 + printk(KERN_DEBUG "update_bits: reg: %s mask: %d shift: %d val: %d\n", + uda1341_reg_names[reg], mask, shift, value); +#endif + + if (!snd_uda1341_valid_reg(clnt, reg)) + return -EINVAL; + spin_lock(&uda->reg_lock); + old = uda->regs[reg]; + new = (old & ~(mask << shift)) | (value << shift); + change = old != new; + if (change) { + if (flush) uda->write(clnt, reg, new); + uda->regs[reg] = new; + } + spin_unlock(&uda->reg_lock); + return change; +} + +static int snd_uda1341_cfg_write(struct l3_client *clnt, unsigned short what, + unsigned short value, int flush) +{ + struct uda1341 *uda = clnt->driver_data; + int ret = 0; +#ifdef CONFIG_PM + int reg; +#endif + +#if 0 + printk(KERN_DEBUG "cfg_write what: %d value: %d\n", what, value); +#endif + + uda->cfg[what] = value; + + switch(what) { + case CMD_RESET: + ret = snd_uda1341_update_bits(clnt, data0_2, 1, 2, 1, flush); // MUTE + ret = snd_uda1341_update_bits(clnt, stat0, 1, 6, 1, flush); // RESET + ret = snd_uda1341_update_bits(clnt, stat0, 1, 6, 0, flush); // RESTORE + uda->cfg[CMD_RESET]=0; + break; + case CMD_FS: + ret = snd_uda1341_update_bits(clnt, stat0, 3, 4, value, flush); + break; + case CMD_FORMAT: + ret = snd_uda1341_update_bits(clnt, stat0, 7, 1, value, flush); + break; + case CMD_OGAIN: + ret = snd_uda1341_update_bits(clnt, stat1, 1, 6, value, flush); + break; + case CMD_IGAIN: + ret = snd_uda1341_update_bits(clnt, stat1, 1, 5, value, flush); + break; + case CMD_DAC: + ret = snd_uda1341_update_bits(clnt, stat1, 1, 0, value, flush); + break; + case CMD_ADC: + ret = snd_uda1341_update_bits(clnt, stat1, 1, 1, value, flush); + break; + case CMD_VOLUME: + ret = snd_uda1341_update_bits(clnt, data0_0, 63, 0, value, flush); + break; + case CMD_BASS: + ret = snd_uda1341_update_bits(clnt, data0_1, 15, 2, value, flush); + break; + case CMD_TREBBLE: + ret = snd_uda1341_update_bits(clnt, data0_1, 3, 0, value, flush); + break; + case CMD_PEAK: + ret = snd_uda1341_update_bits(clnt, data0_2, 1, 5, value, flush); + break; + case CMD_DEEMP: + ret = snd_uda1341_update_bits(clnt, data0_2, 3, 3, value, flush); + break; + case CMD_MUTE: + ret = snd_uda1341_update_bits(clnt, data0_2, 1, 2, value, flush); + break; + case CMD_FILTER: + ret = snd_uda1341_update_bits(clnt, data0_2, 3, 0, value, flush); + break; + case CMD_CH1: + ret = snd_uda1341_update_bits(clnt, ext0, 31, 0, value, flush); + break; + case CMD_CH2: + ret = snd_uda1341_update_bits(clnt, ext1, 31, 0, value, flush); + break; + case CMD_MIC: + ret = snd_uda1341_update_bits(clnt, ext2, 7, 2, value, flush); + break; + case CMD_MIXER: + ret = snd_uda1341_update_bits(clnt, ext2, 3, 0, value, flush); + break; + case CMD_AGC: + ret = snd_uda1341_update_bits(clnt, ext4, 1, 4, value, flush); + break; + case CMD_IG: + ret = snd_uda1341_update_bits(clnt, ext4, 3, 0, value & 0x3, flush); + ret = snd_uda1341_update_bits(clnt, ext5, 31, 0, value >> 2, flush); + break; + case CMD_AGC_TIME: + ret = snd_uda1341_update_bits(clnt, ext6, 7, 2, value, flush); + break; + case CMD_AGC_LEVEL: + ret = snd_uda1341_update_bits(clnt, ext6, 3, 0, value, flush); + break; +#ifdef CONFIG_PM + case CMD_SUSPEND: + for (reg = stat0; reg < uda1341_reg_last; reg++) + uda->suspend_regs[reg] = uda->regs[reg]; + for (reg = 0; reg < CMD_LAST; reg++) + uda->suspend_cfg[reg] = uda->cfg[reg]; + break; + case CMD_RESUME: + for (reg = stat0; reg < uda1341_reg_last; reg++) + snd_uda1341_codec_write(clnt, reg, uda->suspend_regs[reg]); + for (reg = 0; reg < CMD_LAST; reg++) + uda->cfg[reg] = uda->suspend_cfg[reg]; + break; +#endif + default: + ret = -EINVAL; + break; + } + + if (!uda->active) + printk(KERN_ERR "UDA1341 codec not active!\n"); + return ret; +} + +/* }}} */ + +/* {{{ Proc interface */ +#ifdef CONFIG_PROC_FS + +static const char *format_names[] = { + "I2S-bus", + "LSB 16bits", + "LSB 18bits", + "LSB 20bits", + "MSB", + "in LSB 16bits/out MSB", + "in LSB 18bits/out MSB", + "in LSB 20bits/out MSB", +}; + +static const char *fs_names[] = { + "512*fs", + "384*fs", + "256*fs", + "Unused - bad value!", +}; + +static const char* bass_values[][16] = { + {"0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", + "0 dB", "0 dB", "0 dB", "0 dB", "undefined", }, //flat + {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB", + "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min + {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB", + "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min + {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "20 dB", + "22 dB", "24 dB", "24 dB", "24 dB", "undefined",}, // max +}; + +static const char *mic_sens_value[] = { + "-3 dB", "0 dB", "3 dB", "9 dB", "15 dB", "21 dB", "27 dB", "not used", +}; + +static const unsigned short AGC_atime[] = { + 11, 16, 11, 16, 21, 11, 16, 21, +}; + +static const unsigned short AGC_dtime[] = { + 100, 100, 200, 200, 200, 400, 400, 400, +}; + +static const char *AGC_level[] = { + "-9.0", "-11.5", "-15.0", "-17.5", +}; + +static const char *ig_small_value[] = { + "-3.0", "-2.5", "-2.0", "-1.5", "-1.0", "-0.5", +}; + +/* + * this was computed as peak_value[i] = pow((63-i)*1.42,1.013) + * + * UDA1341 datasheet on page 21: Peak value (dB) = (Peak level - 63.5)*5*log2 + * There is an table with these values [level]=value: [3]=-90.31, [7]=-84.29 + * [61]=-2.78, [62] = -1.48, [63] = 0.0 + * I tried to compute it, but using but even using logarithm with base either 10 or 2 + * i was'n able to get values in the table from the formula. So I constructed another + * formula (see above) to interpolate the values as good as possible. If there is some + * mistake, please contact me on tomas.kasparek@seznam.cz. Thanks. + * UDA1341TS datasheet is available at: + * http://www-us9.semiconductors.com/acrobat/datasheets/UDA1341TS_3.pdf + */ +static const char *peak_value[] = { + "-INF dB", "N.A.", "N.A", "90.31 dB", "N.A.", "N.A.", "N.A.", "-84.29 dB", + "-82.65 dB", "-81.13 dB", "-79.61 dB", "-78.09 dB", "-76.57 dB", "-75.05 dB", "-73.53 dB", + "-72.01 dB", "-70.49 dB", "-68.97 dB", "-67.45 dB", "-65.93 dB", "-64.41 dB", "-62.90 dB", + "-61.38 dB", "-59.86 dB", "-58.35 dB", "-56.83 dB", "-55.32 dB", "-53.80 dB", "-52.29 dB", + "-50.78 dB", "-49.26 dB", "-47.75 dB", "-46.24 dB", "-44.73 dB", "-43.22 dB", "-41.71 dB", + "-40.20 dB", "-38.69 dB", "-37.19 dB", "-35.68 dB", "-34.17 dB", "-32.67 dB", "-31.17 dB", + "-29.66 dB", "-28.16 dB", "-26.66 dB", "-25.16 dB", "-23.66 dB", "-22.16 dB", "-20.67 dB", + "-19.17 dB", "-17.68 dB", "-16.19 dB", "-14.70 dB", "-13.21 dB", "-11.72 dB", "-10.24 dB", + "-8.76 dB", "-7.28 dB", "-5.81 dB", "-4.34 dB", "-2.88 dB", "-1.43 dB", "0.00 dB", +}; + +static void snd_uda1341_proc_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct l3_client *clnt = entry->private_data; + struct uda1341 *uda = clnt->driver_data; + int peak; + + peak = snd_uda1341_codec_read(clnt, UDA1341_DATA1); + if (peak < 0) + peak = 0; + + snd_iprintf(buffer, "%s\n\n", uda->card->longname); + + // for information about computed values see UDA1341TS datasheet pages 15 - 21 + snd_iprintf(buffer, "DAC power : %s\n", uda->cfg[CMD_DAC] ? "on" : "off"); + snd_iprintf(buffer, "ADC power : %s\n", uda->cfg[CMD_ADC] ? "on" : "off"); + snd_iprintf(buffer, "Clock frequency : %s\n", fs_names[uda->cfg[CMD_FS]]); + snd_iprintf(buffer, "Data format : %s\n\n", format_names[uda->cfg[CMD_FORMAT]]); + + snd_iprintf(buffer, "Filter mode : %s\n", filter_names[uda->cfg[CMD_FILTER]]); + snd_iprintf(buffer, "Mixer mode : %s\n", mixer_names[uda->cfg[CMD_MIXER]]); + snd_iprintf(buffer, "De-emphasis : %s\n", deemp_names[uda->cfg[CMD_DEEMP]]); + snd_iprintf(buffer, "Peak detection pos. : %s\n", uda->cfg[CMD_PEAK] ? "after" : "before"); + snd_iprintf(buffer, "Peak value : %s\n\n", peak_value[peak]); + + snd_iprintf(buffer, "Automatic Gain Ctrl : %s\n", uda->cfg[CMD_AGC] ? "on" : "off"); + snd_iprintf(buffer, "AGC attack time : %d ms\n", AGC_atime[uda->cfg[CMD_AGC_TIME]]); + snd_iprintf(buffer, "AGC decay time : %d ms\n", AGC_dtime[uda->cfg[CMD_AGC_TIME]]); + snd_iprintf(buffer, "AGC output level : %s dB\n\n", AGC_level[uda->cfg[CMD_AGC_LEVEL]]); + + snd_iprintf(buffer, "Mute : %s\n", uda->cfg[CMD_MUTE] ? "on" : "off"); + + if (uda->cfg[CMD_VOLUME] == 0) + snd_iprintf(buffer, "Volume : 0 dB\n"); + else if (uda->cfg[CMD_VOLUME] < 62) + snd_iprintf(buffer, "Volume : %d dB\n", -1*uda->cfg[CMD_VOLUME] +1); + else + snd_iprintf(buffer, "Volume : -INF dB\n"); + snd_iprintf(buffer, "Bass : %s\n", bass_values[uda->cfg[CMD_FILTER]][uda->cfg[CMD_BASS]]); + snd_iprintf(buffer, "Trebble : %d dB\n", uda->cfg[CMD_FILTER] ? 2*uda->cfg[CMD_TREBBLE] : 0); + snd_iprintf(buffer, "Input Gain (6dB) : %s\n", uda->cfg[CMD_IGAIN] ? "on" : "off"); + snd_iprintf(buffer, "Output Gain (6dB) : %s\n", uda->cfg[CMD_OGAIN] ? "on" : "off"); + snd_iprintf(buffer, "Mic sensitivity : %s\n", mic_sens_value[uda->cfg[CMD_MIC]]); + + + if(uda->cfg[CMD_CH1] < 31) + snd_iprintf(buffer, "Mixer gain channel 1: -%d.%c dB\n", + ((uda->cfg[CMD_CH1] >> 1) * 3) + (uda->cfg[CMD_CH1] & 1), + uda->cfg[CMD_CH1] & 1 ? '5' : '0'); + else + snd_iprintf(buffer, "Mixer gain channel 1: -INF dB\n"); + if(uda->cfg[CMD_CH2] < 31) + snd_iprintf(buffer, "Mixer gain channel 2: -%d.%c dB\n", + ((uda->cfg[CMD_CH2] >> 1) * 3) + (uda->cfg[CMD_CH2] & 1), + uda->cfg[CMD_CH2] & 1 ? '5' : '0'); + else + snd_iprintf(buffer, "Mixer gain channel 2: -INF dB\n"); + + if(uda->cfg[CMD_IG] > 5) + snd_iprintf(buffer, "Input Amp. Gain ch 2: %d.%c dB\n", + (uda->cfg[CMD_IG] >> 1) -3, uda->cfg[CMD_IG] & 1 ? '5' : '0'); + else + snd_iprintf(buffer, "Input Amp. Gain ch 2: %s dB\n", ig_small_value[uda->cfg[CMD_IG]]); +} + +static void snd_uda1341_proc_regs_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct l3_client *clnt = entry->private_data; + struct uda1341 *uda = clnt->driver_data; + int reg; + char buf[12]; + + for (reg = 0; reg < uda1341_reg_last; reg ++) { + if (reg == empty) + continue; + int2str_bin8(uda->regs[reg], buf); + snd_iprintf(buffer, "%s = %s\n", uda1341_reg_names[reg], buf); + } + + int2str_bin8(snd_uda1341_codec_read(clnt, UDA1341_DATA1), buf); + snd_iprintf(buffer, "DATA1 = %s\n", buf); +} +#endif /* CONFIG_PROC_FS */ + +static void __devinit snd_uda1341_proc_init(struct snd_card *card, struct l3_client *clnt) +{ + struct snd_info_entry *entry; + + if (! snd_card_proc_new(card, "uda1341", &entry)) + snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_read); + if (! snd_card_proc_new(card, "uda1341-regs", &entry)) + snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_regs_read); +} + +/* }}} */ + +/* {{{ Mixer controls setting */ + +/* {{{ UDA1341 single functions */ + +#define UDA1341_SINGLE(xname, where, reg, shift, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_uda1341_info_single, \ + .get = snd_uda1341_get_single, .put = snd_uda1341_put_single, \ + .private_value = where | (reg << 5) | (shift << 9) | (mask << 12) | (invert << 18) \ +} + +static int snd_uda1341_info_single(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int mask = (kcontrol->private_value >> 12) & 63; + + uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mask; + return 0; +} + +static int snd_uda1341_get_single(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct l3_client *clnt = snd_kcontrol_chip(kcontrol); + struct uda1341 *uda = clnt->driver_data; + int where = kcontrol->private_value & 31; + int mask = (kcontrol->private_value >> 12) & 63; + int invert = (kcontrol->private_value >> 18) & 1; + + ucontrol->value.integer.value[0] = uda->cfg[where]; + if (invert) + ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; + + return 0; +} + +static int snd_uda1341_put_single(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct l3_client *clnt = snd_kcontrol_chip(kcontrol); + struct uda1341 *uda = clnt->driver_data; + int where = kcontrol->private_value & 31; + int reg = (kcontrol->private_value >> 5) & 15; + int shift = (kcontrol->private_value >> 9) & 7; + int mask = (kcontrol->private_value >> 12) & 63; + int invert = (kcontrol->private_value >> 18) & 1; + unsigned short val; + + val = (ucontrol->value.integer.value[0] & mask); + if (invert) + val = mask - val; + + uda->cfg[where] = val; + return snd_uda1341_update_bits(clnt, reg, mask, shift, val, FLUSH); +} + +/* }}} */ + +/* {{{ UDA1341 enum functions */ + +#define UDA1341_ENUM(xname, where, reg, shift, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_uda1341_info_enum, \ + .get = snd_uda1341_get_enum, .put = snd_uda1341_put_enum, \ + .private_value = where | (reg << 5) | (shift << 9) | (mask << 12) | (invert << 18) \ +} + +static int snd_uda1341_info_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int where = kcontrol->private_value & 31; + const char **texts; + + // this register we don't handle this way + if (!uda1341_enum_items[where]) + return -EINVAL; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = uda1341_enum_items[where]; + + if (uinfo->value.enumerated.item >= uda1341_enum_items[where]) + uinfo->value.enumerated.item = uda1341_enum_items[where] - 1; + + texts = uda1341_enum_names[where]; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + +static int snd_uda1341_get_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct l3_client *clnt = snd_kcontrol_chip(kcontrol); + struct uda1341 *uda = clnt->driver_data; + int where = kcontrol->private_value & 31; + + ucontrol->value.enumerated.item[0] = uda->cfg[where]; + return 0; +} + +static int snd_uda1341_put_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct l3_client *clnt = snd_kcontrol_chip(kcontrol); + struct uda1341 *uda = clnt->driver_data; + int where = kcontrol->private_value & 31; + int reg = (kcontrol->private_value >> 5) & 15; + int shift = (kcontrol->private_value >> 9) & 7; + int mask = (kcontrol->private_value >> 12) & 63; + + uda->cfg[where] = (ucontrol->value.enumerated.item[0] & mask); + + return snd_uda1341_update_bits(clnt, reg, mask, shift, uda->cfg[where], FLUSH); +} + +/* }}} */ + +/* {{{ UDA1341 2regs functions */ + +#define UDA1341_2REGS(xname, where, reg_1, reg_2, shift_1, shift_2, mask_1, mask_2, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_uda1341_info_2regs, \ + .get = snd_uda1341_get_2regs, .put = snd_uda1341_put_2regs, \ + .private_value = where | (reg_1 << 5) | (reg_2 << 9) | (shift_1 << 13) | (shift_2 << 16) | \ + (mask_1 << 19) | (mask_2 << 25) | (invert << 31) \ +} + + +static int snd_uda1341_info_2regs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int mask_1 = (kcontrol->private_value >> 19) & 63; + int mask_2 = (kcontrol->private_value >> 25) & 63; + int mask; + + mask = (mask_2 + 1) * (mask_1 + 1) - 1; + uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mask; + return 0; +} + +static int snd_uda1341_get_2regs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct l3_client *clnt = snd_kcontrol_chip(kcontrol); + struct uda1341 *uda = clnt->driver_data; + int where = kcontrol->private_value & 31; + int mask_1 = (kcontrol->private_value >> 19) & 63; + int mask_2 = (kcontrol->private_value >> 25) & 63; + int invert = (kcontrol->private_value >> 31) & 1; + int mask; + + mask = (mask_2 + 1) * (mask_1 + 1) - 1; + + ucontrol->value.integer.value[0] = uda->cfg[where]; + if (invert) + ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; + return 0; +} + +static int snd_uda1341_put_2regs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct l3_client *clnt = snd_kcontrol_chip(kcontrol); + struct uda1341 *uda = clnt->driver_data; + int where = kcontrol->private_value & 31; + int reg_1 = (kcontrol->private_value >> 5) & 15; + int reg_2 = (kcontrol->private_value >> 9) & 15; + int shift_1 = (kcontrol->private_value >> 13) & 7; + int shift_2 = (kcontrol->private_value >> 16) & 7; + int mask_1 = (kcontrol->private_value >> 19) & 63; + int mask_2 = (kcontrol->private_value >> 25) & 63; + int invert = (kcontrol->private_value >> 31) & 1; + int mask; + unsigned short val1, val2, val; + + val = ucontrol->value.integer.value[0]; + + mask = (mask_2 + 1) * (mask_1 + 1) - 1; + + val1 = val & mask_1; + val2 = (val / (mask_1 + 1)) & mask_2; + + if (invert) { + val1 = mask_1 - val1; + val2 = mask_2 - val2; + } + + uda->cfg[where] = invert ? mask - val : val; + + //FIXME - return value + snd_uda1341_update_bits(clnt, reg_1, mask_1, shift_1, val1, FLUSH); + return snd_uda1341_update_bits(clnt, reg_2, mask_2, shift_2, val2, FLUSH); +} + +/* }}} */ + +static struct snd_kcontrol_new snd_uda1341_controls[] = { + UDA1341_SINGLE("Master Playback Switch", CMD_MUTE, data0_2, 2, 1, 1), + UDA1341_SINGLE("Master Playback Volume", CMD_VOLUME, data0_0, 0, 63, 1), + + UDA1341_SINGLE("Bass Playback Volume", CMD_BASS, data0_1, 2, 15, 0), + UDA1341_SINGLE("Treble Playback Volume", CMD_TREBBLE, data0_1, 0, 3, 0), + + UDA1341_SINGLE("Input Gain Switch", CMD_IGAIN, stat1, 5, 1, 0), + UDA1341_SINGLE("Output Gain Switch", CMD_OGAIN, stat1, 6, 1, 0), + + UDA1341_SINGLE("Mixer Gain Channel 1 Volume", CMD_CH1, ext0, 0, 31, 1), + UDA1341_SINGLE("Mixer Gain Channel 2 Volume", CMD_CH2, ext1, 0, 31, 1), + + UDA1341_SINGLE("Mic Sensitivity Volume", CMD_MIC, ext2, 2, 7, 0), + + UDA1341_SINGLE("AGC Output Level", CMD_AGC_LEVEL, ext6, 0, 3, 0), + UDA1341_SINGLE("AGC Time Constant", CMD_AGC_TIME, ext6, 2, 7, 0), + UDA1341_SINGLE("AGC Time Constant Switch", CMD_AGC, ext4, 4, 1, 0), + + UDA1341_SINGLE("DAC Power", CMD_DAC, stat1, 0, 1, 0), + UDA1341_SINGLE("ADC Power", CMD_ADC, stat1, 1, 1, 0), + + UDA1341_ENUM("Peak detection", CMD_PEAK, data0_2, 5, 1, 0), + UDA1341_ENUM("De-emphasis", CMD_DEEMP, data0_2, 3, 3, 0), + UDA1341_ENUM("Mixer mode", CMD_MIXER, ext2, 0, 3, 0), + UDA1341_ENUM("Filter mode", CMD_FILTER, data0_2, 0, 3, 0), + + UDA1341_2REGS("Gain Input Amplifier Gain (channel 2)", CMD_IG, ext4, ext5, 0, 0, 3, 31, 0), +}; + +static void uda1341_free(struct l3_client *clnt) +{ + l3_detach_client(clnt); // calls kfree for driver_data (struct uda1341) + kfree(clnt); +} + +static int uda1341_dev_free(struct snd_device *device) +{ + struct l3_client *clnt = device->device_data; + uda1341_free(clnt); + return 0; +} + +int __init snd_chip_uda1341_mixer_new(struct snd_card *card, struct l3_client **clntp) +{ + static struct snd_device_ops ops = { + .dev_free = uda1341_dev_free, + }; + struct l3_client *clnt; + int idx, err; + + if (snd_BUG_ON(!card)) + return -EINVAL; + + clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); + if (clnt == NULL) + return -ENOMEM; + + if ((err = l3_attach_client(clnt, "l3-bit-sa1100-gpio", UDA1341_ALSA_NAME))) { + kfree(clnt); + return err; + } + + for (idx = 0; idx < ARRAY_SIZE(snd_uda1341_controls); idx++) { + if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_uda1341_controls[idx], clnt))) < 0) { + uda1341_free(clnt); + return err; + } + } + + if ((err = snd_device_new(card, SNDRV_DEV_CODEC, clnt, &ops)) < 0) { + uda1341_free(clnt); + return err; + } + + *clntp = clnt; + strcpy(card->mixername, "UDA1341TS Mixer"); + ((struct uda1341 *)clnt->driver_data)->card = card; + + snd_uda1341_proc_init(card, clnt); + + return 0; +} + +/* }}} */ + +/* {{{ L3 operations */ + +static int uda1341_attach(struct l3_client *clnt) +{ + struct uda1341 *uda; + + uda = kzalloc(sizeof(*uda), 0, GFP_KERNEL); + if (!uda) + return -ENOMEM; + + /* init fixed parts of my copy of registers */ + uda->regs[stat0] = STAT0; + uda->regs[stat1] = STAT1; + + uda->regs[data0_0] = DATA0_0; + uda->regs[data0_1] = DATA0_1; + uda->regs[data0_2] = DATA0_2; + + uda->write = snd_uda1341_codec_write; + uda->read = snd_uda1341_codec_read; + + spin_lock_init(&uda->reg_lock); + + clnt->driver_data = uda; + return 0; +} + +static void uda1341_detach(struct l3_client *clnt) +{ + kfree(clnt->driver_data); +} + +static int +uda1341_command(struct l3_client *clnt, int cmd, void *arg) +{ + if (cmd != CMD_READ_REG) + return snd_uda1341_cfg_write(clnt, cmd, (int) arg, FLUSH); + + return snd_uda1341_codec_read(clnt, (int) arg); +} + +static int uda1341_open(struct l3_client *clnt) +{ + struct uda1341 *uda = clnt->driver_data; + + uda->active = 1; + + /* init default configuration */ + snd_uda1341_cfg_write(clnt, CMD_RESET, 0, REGS_ONLY); + snd_uda1341_cfg_write(clnt, CMD_FS, F256, FLUSH); // unknown state after reset + snd_uda1341_cfg_write(clnt, CMD_FORMAT, LSB16, FLUSH); // unknown state after reset + snd_uda1341_cfg_write(clnt, CMD_OGAIN, ON, FLUSH); // default off after reset + snd_uda1341_cfg_write(clnt, CMD_IGAIN, ON, FLUSH); // default off after reset + snd_uda1341_cfg_write(clnt, CMD_DAC, ON, FLUSH); // ??? default value after reset + snd_uda1341_cfg_write(clnt, CMD_ADC, ON, FLUSH); // ??? default value after reset + snd_uda1341_cfg_write(clnt, CMD_VOLUME, 20, FLUSH); // default 0dB after reset + snd_uda1341_cfg_write(clnt, CMD_BASS, 0, REGS_ONLY); // default value after reset + snd_uda1341_cfg_write(clnt, CMD_TREBBLE, 0, REGS_ONLY); // default value after reset + snd_uda1341_cfg_write(clnt, CMD_PEAK, AFTER, REGS_ONLY);// default value after reset + snd_uda1341_cfg_write(clnt, CMD_DEEMP, NONE, REGS_ONLY);// default value after reset + //at this moment should be QMUTED by h3600_audio_init + snd_uda1341_cfg_write(clnt, CMD_MUTE, OFF, REGS_ONLY); // default value after reset + snd_uda1341_cfg_write(clnt, CMD_FILTER, MAX, FLUSH); // defaul flat after reset + snd_uda1341_cfg_write(clnt, CMD_CH1, 31, FLUSH); // default value after reset + snd_uda1341_cfg_write(clnt, CMD_CH2, 4, FLUSH); // default value after reset + snd_uda1341_cfg_write(clnt, CMD_MIC, 4, FLUSH); // default 0dB after reset + snd_uda1341_cfg_write(clnt, CMD_MIXER, MIXER, FLUSH); // default doub.dif.mode + snd_uda1341_cfg_write(clnt, CMD_AGC, OFF, FLUSH); // default value after reset + snd_uda1341_cfg_write(clnt, CMD_IG, 0, FLUSH); // unknown state after reset + snd_uda1341_cfg_write(clnt, CMD_AGC_TIME, 0, FLUSH); // default value after reset + snd_uda1341_cfg_write(clnt, CMD_AGC_LEVEL, 0, FLUSH); // default value after reset + + return 0; +} + +static void uda1341_close(struct l3_client *clnt) +{ + struct uda1341 *uda = clnt->driver_data; + + uda->active = 0; +} + +/* }}} */ + +/* {{{ Module and L3 initialization */ + +static struct l3_ops uda1341_ops = { + .open = uda1341_open, + .command = uda1341_command, + .close = uda1341_close, +}; + +static struct l3_driver uda1341_driver = { + .name = UDA1341_ALSA_NAME, + .attach_client = uda1341_attach, + .detach_client = uda1341_detach, + .ops = &uda1341_ops, + .owner = THIS_MODULE, +}; + +static int __init uda1341_init(void) +{ + return l3_add_driver(&uda1341_driver); +} + +static void __exit uda1341_exit(void) +{ + l3_del_driver(&uda1341_driver); +} + +module_init(uda1341_init); +module_exit(uda1341_exit); + +MODULE_AUTHOR("Tomas Kasparek "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Philips UDA1341 CODEC driver for ALSA"); +MODULE_SUPPORTED_DEVICE("{{UDA1341,UDA1341TS}}"); + +EXPORT_SYMBOL(snd_chip_uda1341_mixer_new); + +/* }}} */ + +/* + * Local variables: + * indent-tabs-mode: t + * End: + */ diff --git a/trunk/sound/isa/Kconfig b/trunk/sound/isa/Kconfig index 4e06bbd9298d..ce0aa044e274 100644 --- a/trunk/sound/isa/Kconfig +++ b/trunk/sound/isa/Kconfig @@ -56,8 +56,8 @@ config SND_AD1848 Say Y here to include support for AD1848 (Analog Devices) or CS4248 (Cirrus Logic - Crystal Semiconductors) chips. - For newer chips from Cirrus Logic, use the CS4231 or CS4232+ - drivers. + For newer chips from Cirrus Logic, use the CS4231, CS4232 or + CS4236+ drivers. To compile this driver as a module, choose M here: the module will be called snd-ad1848. @@ -94,8 +94,6 @@ config SND_CMI8330 tristate "C-Media CMI8330" select SND_WSS_LIB select SND_SB16_DSP - select SND_OPL3_LIB - select SND_MPU401_UART help Say Y here to include support for soundcards based on the C-Media CMI8330 chip. @@ -114,15 +112,26 @@ config SND_CS4231 To compile this driver as a module, choose M here: the module will be called snd-cs4231. +config SND_CS4232 + tristate "Generic Cirrus Logic CS4232 driver" + select SND_OPL3_LIB + select SND_MPU401_UART + select SND_WSS_LIB + help + Say Y here to include support for CS4232 chips from Cirrus + Logic - Crystal Semiconductors. + + To compile this driver as a module, choose M here: the module + will be called snd-cs4232. + config SND_CS4236 - tristate "Generic Cirrus Logic CS4232/CS4236+ driver" + tristate "Generic Cirrus Logic CS4236+ driver" select SND_OPL3_LIB select SND_MPU401_UART select SND_WSS_LIB help - Say Y to include support for CS4232,CS4235,CS4236,CS4237B, - CS4238B,CS4239 chips from Cirrus Logic - Crystal - Semiconductors. + Say Y to include support for CS4235,CS4236,CS4237B,CS4238B, + CS4239 chips from Cirrus Logic - Crystal Semiconductors. To compile this driver as a module, choose M here: the module will be called snd-cs4236. diff --git a/trunk/sound/isa/ad1816a/ad1816a.c b/trunk/sound/isa/ad1816a/ad1816a.c index bbcbf92a8ebe..77524244a846 100644 --- a/trunk/sound/isa/ad1816a/ad1816a.c +++ b/trunk/sound/isa/ad1816a/ad1816a.c @@ -156,12 +156,10 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard struct snd_card_ad1816a *acard; struct snd_ad1816a *chip; struct snd_opl3 *opl3; - struct snd_timer *timer; - error = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_ad1816a), &card); - if (error < 0) - return error; + if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_ad1816a))) == NULL) + return -ENOMEM; acard = (struct snd_card_ad1816a *)card->private_data; if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) { @@ -196,12 +194,6 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard return error; } - error = snd_ad1816a_timer(chip, 0, &timer); - if (error < 0) { - snd_card_free(card); - return error; - } - if (mpu_port[dev] > 0) { if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, mpu_port[dev], 0, mpu_irq[dev], IRQF_DISABLED, @@ -215,8 +207,11 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard OPL3_HW_AUTO, 0, &opl3) < 0) { printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx.\n", fm_port[dev], fm_port[dev] + 2); } else { - error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); - if (error < 0) { + if ((error = snd_opl3_timer_new(opl3, 1, 2)) < 0) { + snd_card_free(card); + return error; + } + if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { snd_card_free(card); return error; } diff --git a/trunk/sound/isa/ad1816a/ad1816a_lib.c b/trunk/sound/isa/ad1816a/ad1816a_lib.c index 05aef8b97e96..3bfca7c59baf 100644 --- a/trunk/sound/isa/ad1816a/ad1816a_lib.c +++ b/trunk/sound/isa/ad1816a/ad1816a_lib.c @@ -37,7 +37,7 @@ static inline int snd_ad1816a_busy_wait(struct snd_ad1816a *chip) if (inb(AD1816A_REG(AD1816A_CHIP_STATUS)) & AD1816A_READY) return 0; - snd_printk(KERN_WARNING "chip busy.\n"); + snd_printk("chip busy.\n"); return -EBUSY; } @@ -196,7 +196,7 @@ static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what, spin_unlock(&chip->lock); break; default: - snd_printk(KERN_WARNING "invalid trigger mode 0x%x.\n", what); + snd_printk("invalid trigger mode 0x%x.\n", what); error = -EINVAL; } @@ -377,6 +377,7 @@ static struct snd_pcm_hardware snd_ad1816a_capture = { .fifo_size = 0, }; +#if 0 /* not used now */ static int snd_ad1816a_timer_close(struct snd_timer *timer) { struct snd_ad1816a *chip = snd_timer_chip(timer); @@ -441,6 +442,8 @@ static struct snd_timer_hardware snd_ad1816a_timer_table = { .start = snd_ad1816a_timer_start, .stop = snd_ad1816a_timer_stop, }; +#endif /* not used now */ + static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream) { @@ -565,7 +568,7 @@ static const char __devinit *snd_ad1816a_chip_id(struct snd_ad1816a *chip) case AD1816A_HW_AD1815: return "AD1815"; case AD1816A_HW_AD18MAX10: return "AD18max10"; default: - snd_printk(KERN_WARNING "Unknown chip version %d:%d.\n", + snd_printk("Unknown chip version %d:%d.\n", chip->version, chip->hardware); return "AD1816A - unknown"; } @@ -684,6 +687,7 @@ int __devinit snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_p return 0; } +#if 0 /* not used now */ int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd_timer **rtimer) { struct snd_timer *timer; @@ -705,6 +709,7 @@ int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd *rtimer = timer; return 0; } +#endif /* not used now */ /* * diff --git a/trunk/sound/isa/ad1848/ad1848.c b/trunk/sound/isa/ad1848/ad1848.c index 4beeb6f98e0e..223a6c038819 100644 --- a/trunk/sound/isa/ad1848/ad1848.c +++ b/trunk/sound/isa/ad1848/ad1848.c @@ -91,9 +91,9 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) struct snd_pcm *pcm; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); - if (error < 0) - return error; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], -1, thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT, diff --git a/trunk/sound/isa/adlib.c b/trunk/sound/isa/adlib.c index 7465ae036e0b..374b7177e111 100644 --- a/trunk/sound/isa/adlib.c +++ b/trunk/sound/isa/adlib.c @@ -53,10 +53,10 @@ static int __devinit snd_adlib_probe(struct device *dev, unsigned int n) struct snd_opl3 *opl3; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); - if (error < 0) { + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) { dev_err(dev, "could not create card\n"); - return error; + return -EINVAL; } card->private_data = request_region(port[n], 4, CRD_NAME); diff --git a/trunk/sound/isa/als100.c b/trunk/sound/isa/als100.c index 5fd52e4d7079..f1ce30f379c9 100644 --- a/trunk/sound/isa/als100.c +++ b/trunk/sound/isa/als100.c @@ -163,10 +163,9 @@ static int __devinit snd_card_als100_probe(int dev, struct snd_card_als100 *acard; struct snd_opl3 *opl3; - error = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_als100), &card); - if (error < 0) - return error; + if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_als100))) == NULL) + return -ENOMEM; acard = card->private_data; if ((error = snd_card_als100_pnp(dev, acard, pcard, pid))) { diff --git a/trunk/sound/isa/azt2320.c b/trunk/sound/isa/azt2320.c index f7aa637b0d18..3e74d1a3928e 100644 --- a/trunk/sound/isa/azt2320.c +++ b/trunk/sound/isa/azt2320.c @@ -184,10 +184,9 @@ static int __devinit snd_card_azt2320_probe(int dev, struct snd_wss *chip; struct snd_opl3 *opl3; - error = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_azt2320), &card); - if (error < 0) - return error; + if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_azt2320))) == NULL) + return -ENOMEM; acard = (struct snd_card_azt2320 *)card->private_data; if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) { diff --git a/trunk/sound/isa/cmi8330.c b/trunk/sound/isa/cmi8330.c index de83608719ea..e49aec700a55 100644 --- a/trunk/sound/isa/cmi8330.c +++ b/trunk/sound/isa/cmi8330.c @@ -31,11 +31,11 @@ * To quickly load the module, * * modprobe -a snd-cmi8330 sbport=0x220 sbirq=5 sbdma8=1 - * sbdma16=5 wssport=0x530 wssirq=11 wssdma=0 fmport=0x388 + * sbdma16=5 wssport=0x530 wssirq=11 wssdma=0 * * This card has two mixers and two PCM devices. I've cheesed it such * that recording and playback can be done through the same device. - * The driver "magically" routes the capturing to the CMI8330 codec, + * The driver "magically" routes the capturing to the AD1848 codec, * and playback to the SB16 codec. This allows for full-duplex mode * to some extent. * The utilities in alsa-utils are aware of both devices, so passing @@ -51,8 +51,6 @@ #include #include #include -#include -#include #include #include @@ -81,9 +79,6 @@ static int sbdma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; static int wssirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; static int wssdma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; -static long fmport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; -static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; -static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard."); @@ -112,12 +107,6 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver."); module_param_array(wssdma, int, NULL, 0444); MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); -module_param_array(fmport, long, NULL, 0444); -MODULE_PARM_DESC(fmport, "FM port # for CMI8330 driver."); -module_param_array(mpuport, long, NULL, 0444); -MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330 driver."); -module_param_array(mpuirq, int, NULL, 0444); -MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330 MPU-401 port."); #ifdef CONFIG_PNP static int isa_registered; static int pnp_registered; @@ -160,7 +149,6 @@ struct snd_cmi8330 { #ifdef CONFIG_PNP struct pnp_dev *cap; struct pnp_dev *play; - struct pnp_dev *mpu; #endif struct snd_card *card; struct snd_wss *wss; @@ -177,7 +165,7 @@ struct snd_cmi8330 { #ifdef CONFIG_PNP static struct pnp_card_device_id snd_cmi8330_pnpids[] = { - { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, + { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" } } }, { .id = "" } }; @@ -231,10 +219,8 @@ WSS_SINGLE("3D Control - Switch", 0, CMI8330_RMUX3D, 5, 1, 1), WSS_SINGLE("PC Speaker Playback Volume", 0, CMI8330_OUTPUTVOL, 3, 3, 0), -WSS_DOUBLE("FM Playback Switch", 0, - CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -WSS_DOUBLE("FM Playback Volume", 0, - CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), +WSS_SINGLE("FM Playback Switch", 0, + CMI8330_RECMUX, 3, 1, 1), WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0, CMI8330_RMUX3D, 7, 1, 1), WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0, @@ -337,21 +323,16 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, if (acard->play == NULL) return -EBUSY; - acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL); - if (acard->play == NULL) - return -EBUSY; - pdev = acard->cap; err = pnp_activate_dev(pdev); if (err < 0) { - snd_printk(KERN_ERR "CMI8330/C3D PnP configure failure\n"); + snd_printk(KERN_ERR "CMI8330/C3D (AD1848) PnP configure failure\n"); return -EBUSY; } wssport[dev] = pnp_port_start(pdev, 0); wssdma[dev] = pnp_dma(pdev, 0); wssirq[dev] = pnp_irq(pdev, 0); - fmport[dev] = pnp_port_start(pdev, 1); /* allocate SB16 resources */ pdev = acard->play; @@ -366,17 +347,6 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, sbdma16[dev] = pnp_dma(pdev, 1); sbirq[dev] = pnp_irq(pdev, 0); - /* allocate MPU-401 resources */ - pdev = acard->mpu; - - err = pnp_activate_dev(pdev); - if (err < 0) { - snd_printk(KERN_ERR - "CMI8330/C3D (MPU-401) PnP configure failure\n"); - return -EBUSY; - } - mpuport[dev] = pnp_port_start(pdev, 0); - mpuirq[dev] = pnp_irq(pdev, 0); return 0; } #endif @@ -497,29 +467,26 @@ static int snd_cmi8330_resume(struct snd_card *card) #define PFX "cmi8330: " -static int snd_cmi8330_card_new(int dev, struct snd_card **cardp) +static struct snd_card *snd_cmi8330_card_new(int dev) { struct snd_card *card; struct snd_cmi8330 *acard; - int err; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_cmi8330), &card); - if (err < 0) { + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_cmi8330)); + if (card == NULL) { snd_printk(KERN_ERR PFX "could not get a new card\n"); - return err; + return NULL; } acard = card->private_data; acard->card = card; - *cardp = card; - return 0; + return card; } static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) { struct snd_cmi8330 *acard; int i, err; - struct snd_opl3 *opl3; acard = card->private_data; err = snd_wss_create(card, wssport[dev] + 4, -1, @@ -527,11 +494,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) wssdma[dev], -1, WSS_HW_DETECT, 0, &acard->wss); if (err < 0) { - snd_printk(KERN_ERR PFX "(CMI8330) device busy??\n"); + snd_printk(KERN_ERR PFX "(AD1848) device busy??\n"); return err; } if (acard->wss->hardware != WSS_HW_CMI8330) { - snd_printk(KERN_ERR PFX "(CMI8330) not found during probe\n"); + snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n"); return -ENODEV; } @@ -563,27 +530,6 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) snd_printk(KERN_ERR PFX "failed to create pcms\n"); return err; } - if (fmport[dev] != SNDRV_AUTO_PORT) { - if (snd_opl3_create(card, - fmport[dev], fmport[dev] + 2, - OPL3_HW_AUTO, 0, &opl3) < 0) { - snd_printk(KERN_ERR PFX - "no OPL device at 0x%lx-0x%lx ?\n", - fmport[dev], fmport[dev] + 2); - } else { - err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); - if (err < 0) - return err; - } - } - - if (mpuport[dev] != SNDRV_AUTO_PORT) { - if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, - mpuport[dev], 0, mpuirq[dev], - IRQF_DISABLED, NULL) < 0) - printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", - mpuport[dev]); - } strcpy(card->driver, "CMI8330/C3D"); strcpy(card->shortname, "C-Media CMI8330/C3D"); @@ -618,9 +564,9 @@ static int __devinit snd_cmi8330_isa_probe(struct device *pdev, struct snd_card *card; int err; - err = snd_cmi8330_card_new(dev, &card); - if (err < 0) - return err; + card = snd_cmi8330_card_new(dev); + if (! card) + return -ENOMEM; snd_card_set_dev(card, pdev); if ((err = snd_cmi8330_probe(card, dev)) < 0) { snd_card_free(card); @@ -682,9 +628,9 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, if (dev >= SNDRV_CARDS) return -ENODEV; - res = snd_cmi8330_card_new(dev, &card); - if (res < 0) - return res; + card = snd_cmi8330_card_new(dev); + if (! card) + return -ENOMEM; if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) { snd_printk(KERN_ERR PFX "PnP detection failed\n"); snd_card_free(card); diff --git a/trunk/sound/isa/cs423x/Makefile b/trunk/sound/isa/cs423x/Makefile index 6d397e8d54ac..5870ca21ab59 100644 --- a/trunk/sound/isa/cs423x/Makefile +++ b/trunk/sound/isa/cs423x/Makefile @@ -3,11 +3,13 @@ # Copyright (c) 2001 by Jaroslav Kysela # +snd-cs4236-lib-objs := cs4236_lib.o snd-cs4231-objs := cs4231.o -snd-cs4236-objs := cs4236.o cs4236_lib.o +snd-cs4232-objs := cs4232.o +snd-cs4236-objs := cs4236.o # Toplevel Module Dependency obj-$(CONFIG_SND_CS4231) += snd-cs4231.o -obj-$(CONFIG_SND_CS4236) += snd-cs4236.o - +obj-$(CONFIG_SND_CS4232) += snd-cs4232.o +obj-$(CONFIG_SND_CS4236) += snd-cs4236.o snd-cs4236-lib.o diff --git a/trunk/sound/isa/cs423x/cs4231.c b/trunk/sound/isa/cs423x/cs4231.c index cb9153e75b82..f019d449e2d6 100644 --- a/trunk/sound/isa/cs423x/cs4231.c +++ b/trunk/sound/isa/cs423x/cs4231.c @@ -95,9 +95,9 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) struct snd_pcm *pcm; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); - if (error < 0) - return error; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n], WSS_HW_DETECT, 0, &chip); diff --git a/trunk/sound/isa/cs423x/cs4232.c b/trunk/sound/isa/cs423x/cs4232.c new file mode 100644 index 000000000000..9fad2e6c0c2c --- /dev/null +++ b/trunk/sound/isa/cs423x/cs4232.c @@ -0,0 +1,2 @@ +#define CS4232 +#include "cs4236.c" diff --git a/trunk/sound/isa/cs423x/cs4236.c b/trunk/sound/isa/cs423x/cs4236.c index a076a6ce8071..019c9401663e 100644 --- a/trunk/sound/isa/cs423x/cs4236.c +++ b/trunk/sound/isa/cs423x/cs4236.c @@ -33,14 +33,17 @@ MODULE_AUTHOR("Jaroslav Kysela "); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Cirrus Logic CS4232-9"); +#ifdef CS4232 +MODULE_DESCRIPTION("Cirrus Logic CS4232"); MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000}," "{Turtle Beach,Tropez Plus}," "{SIC CrystalWave 32}," "{Hewlett Packard,Omnibook 5500}," "{TerraTec,Maestro 32/96}," - "{Philips,PCA70PS}}," - "{{Crystal Semiconductors,CS4235}," + "{Philips,PCA70PS}}"); +#else +MODULE_DESCRIPTION("Cirrus Logic CS4235-9"); +MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235}," "{Crystal Semiconductors,CS4236}," "{Crystal Semiconductors,CS4237}," "{Crystal Semiconductors,CS4238}," @@ -67,11 +70,15 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000}," "{Typhoon Soundsystem,CS4236B}," "{Turtle Beach,Malibu}," "{Unknown,Digital PC 5000 Onboard}}"); +#endif -MODULE_ALIAS("snd_cs4232"); - -#define IDENT "CS4232+" -#define DEV_NAME "cs4232+" +#ifdef CS4232 +#define IDENT "CS4232" +#define DEV_NAME "cs4232" +#else +#define IDENT "CS4236+" +#define DEV_NAME "cs4236" +#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -121,7 +128,9 @@ MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); #ifdef CONFIG_PNP static int isa_registered; static int pnpc_registered; +#ifdef CS4232 static int pnp_registered; +#endif #endif /* CONFIG_PNP */ struct snd_card_cs4236 { @@ -136,10 +145,11 @@ struct snd_card_cs4236 { #ifdef CONFIG_PNP +#ifdef CS4232 /* * PNP BIOS */ -static const struct pnp_device_id snd_cs423x_pnpbiosids[] = { +static const struct pnp_device_id snd_cs4232_pnpbiosids[] = { { .id = "CSC0100" }, { .id = "CSC0000" }, /* Guillemot Turtlebeach something appears to be cs4232 compatible @@ -147,8 +157,10 @@ static const struct pnp_device_id snd_cs423x_pnpbiosids[] = { { .id = "GIM0100" }, { .id = "" } }; -MODULE_DEVICE_TABLE(pnp, snd_cs423x_pnpbiosids); +MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpbiosids); +#endif /* CS4232 */ +#ifdef CS4232 #define CS423X_ISAPNP_DRIVER "cs4232_isapnp" static struct pnp_card_device_id snd_cs423x_pnpids[] = { /* Philips PCA70PS */ @@ -167,6 +179,12 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = { { .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, /* Netfinity 3000 on-board soundcard */ { .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC010f" } } }, + /* --- */ + { .id = "" } /* end */ +}; +#else /* CS4236 */ +#define CS423X_ISAPNP_DRIVER "cs4236_isapnp" +static struct pnp_card_device_id snd_cs423x_pnpids[] = { /* Intel Marlin Spike Motherboard - CS4235 */ { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, /* Intel Marlin Spike Motherboard (#2) - CS4235 */ @@ -248,6 +266,7 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = { /* --- */ { .id = "" } /* end */ }; +#endif MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids); @@ -304,19 +323,17 @@ static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev) return 0; } -static int __devinit snd_card_cs423x_pnp(int dev, struct snd_card_cs4236 *acard, - struct pnp_dev *pdev, - struct pnp_dev *cdev) +#ifdef CS4232 +static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard, + struct pnp_dev *pdev) { acard->wss = pdev; if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0) return -EBUSY; - if (cdev) - cport[dev] = pnp_port_start(cdev, 0); - else - cport[dev] = -1; + cport[dev] = -1; return 0; } +#endif static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard, struct pnp_card_link *card, @@ -365,18 +382,16 @@ static void snd_card_cs4236_free(struct snd_card *card) release_and_free_resource(acard->res_sb_port); } -static int snd_cs423x_card_new(int dev, struct snd_card **cardp) +static struct snd_card *snd_cs423x_card_new(int dev) { struct snd_card *card; - int err; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_cs4236), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_cs4236)); + if (card == NULL) + return NULL; card->private_free = snd_card_cs4236_free; - *cardp = card; - return 0; + return card; } static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) @@ -394,39 +409,40 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) return -EBUSY; } +#ifdef CS4232 err = snd_wss_create(card, port[dev], cport[dev], irq[dev], dma1[dev], dma2[dev], - WSS_HW_DETECT3, 0, &chip); + WSS_HW_DETECT, 0, &chip); if (err < 0) return err; - if (chip->hardware & WSS_HW_CS4236B_MASK) { - snd_wss_free(chip); - err = snd_cs4236_create(card, - port[dev], cport[dev], - irq[dev], dma1[dev], dma2[dev], - WSS_HW_DETECT, 0, &chip); - if (err < 0) - return err; - acard->chip = chip; - - err = snd_cs4236_pcm(chip, 0, &pcm); - if (err < 0) - return err; - - err = snd_cs4236_mixer(chip); - if (err < 0) - return err; - } else { - acard->chip = chip; - err = snd_wss_pcm(chip, 0, &pcm); - if (err < 0) - return err; - - err = snd_wss_mixer(chip); - if (err < 0) - return err; - } + acard->chip = chip; + + err = snd_wss_pcm(chip, 0, &pcm); + if (err < 0) + return err; + + err = snd_wss_mixer(chip); + if (err < 0) + return err; + +#else /* CS4236 */ + err = snd_cs4236_create(card, + port[dev], cport[dev], + irq[dev], dma1[dev], dma2[dev], + WSS_HW_DETECT, 0, &chip); + if (err < 0) + return err; + acard->chip = chip; + + err = snd_cs4236_pcm(chip, 0, &pcm); + if (err < 0) + return err; + + err = snd_cs4236_mixer(chip); + if (err < 0) + return err; +#endif strcpy(card->driver, pcm->name); strcpy(card->shortname, pcm->name); sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", @@ -496,9 +512,9 @@ static int __devinit snd_cs423x_isa_probe(struct device *pdev, struct snd_card *card; int err; - err = snd_cs423x_card_new(dev, &card); - if (err < 0) - return err; + card = snd_cs423x_card_new(dev); + if (! card) + return -ENOMEM; snd_card_set_dev(card, pdev); if ((err = snd_cs423x_probe(card, dev)) < 0) { snd_card_free(card); @@ -561,14 +577,13 @@ static struct isa_driver cs423x_isa_driver = { #ifdef CONFIG_PNP -static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, +#ifdef CS4232 +static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, const struct pnp_device_id *id) { static int dev; int err; struct snd_card *card; - struct pnp_dev *cdev; - char cid[PNP_ID_LEN]; if (pnp_device_is_isapnp(pdev)) return -ENOENT; /* we have another procedure - card */ @@ -579,19 +594,10 @@ static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, if (dev >= SNDRV_CARDS) return -ENODEV; - /* prepare second id */ - strcpy(cid, pdev->id[0].id); - cid[5] = '1'; - cdev = NULL; - list_for_each_entry(cdev, &(pdev->protocol->devices), protocol_list) { - if (!strcmp(cdev->id[0].id, cid)) - break; - } - err = snd_cs423x_card_new(dev, &card); - if (err < 0) - return err; - err = snd_card_cs423x_pnp(dev, card->private_data, pdev, cdev); - if (err < 0) { + card = snd_cs423x_card_new(dev); + if (! card) + return -ENOMEM; + if ((err = snd_card_cs4232_pnp(dev, card->private_data, pdev)) < 0) { printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); snd_card_free(card); return err; @@ -606,34 +612,35 @@ static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, return 0; } -static void __devexit snd_cs423x_pnp_remove(struct pnp_dev *pdev) +static void __devexit snd_cs4232_pnp_remove(struct pnp_dev * pdev) { snd_card_free(pnp_get_drvdata(pdev)); pnp_set_drvdata(pdev, NULL); } #ifdef CONFIG_PM -static int snd_cs423x_pnp_suspend(struct pnp_dev *pdev, pm_message_t state) +static int snd_cs4232_pnp_suspend(struct pnp_dev *pdev, pm_message_t state) { return snd_cs423x_suspend(pnp_get_drvdata(pdev)); } -static int snd_cs423x_pnp_resume(struct pnp_dev *pdev) +static int snd_cs4232_pnp_resume(struct pnp_dev *pdev) { return snd_cs423x_resume(pnp_get_drvdata(pdev)); } #endif -static struct pnp_driver cs423x_pnp_driver = { - .name = "cs423x-pnpbios", - .id_table = snd_cs423x_pnpbiosids, - .probe = snd_cs423x_pnpbios_detect, - .remove = __devexit_p(snd_cs423x_pnp_remove), +static struct pnp_driver cs4232_pnp_driver = { + .name = "cs4232-pnpbios", + .id_table = snd_cs4232_pnpbiosids, + .probe = snd_cs4232_pnpbios_detect, + .remove = __devexit_p(snd_cs4232_pnp_remove), #ifdef CONFIG_PM - .suspend = snd_cs423x_pnp_suspend, - .resume = snd_cs423x_pnp_resume, + .suspend = snd_cs4232_pnp_suspend, + .resume = snd_cs4232_pnp_resume, #endif }; +#endif /* CS4232 */ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) @@ -649,9 +656,9 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, if (dev >= SNDRV_CARDS) return -ENODEV; - res = snd_cs423x_card_new(dev, &card); - if (res < 0) - return res; + card = snd_cs423x_card_new(dev); + if (! card) + return -ENOMEM; if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) { printk(KERN_ERR "isapnp detection failed and probing for " IDENT " is not supported\n"); @@ -707,14 +714,18 @@ static int __init alsa_card_cs423x_init(void) #ifdef CONFIG_PNP if (!err) isa_registered = 1; - err = pnp_register_driver(&cs423x_pnp_driver); +#ifdef CS4232 + err = pnp_register_driver(&cs4232_pnp_driver); if (!err) pnp_registered = 1; +#endif err = pnp_register_card_driver(&cs423x_pnpc_driver); if (!err) pnpc_registered = 1; +#ifdef CS4232 if (pnp_registered) err = 0; +#endif if (isa_registered) err = 0; #endif @@ -726,8 +737,10 @@ static void __exit alsa_card_cs423x_exit(void) #ifdef CONFIG_PNP if (pnpc_registered) pnp_unregister_card_driver(&cs423x_pnpc_driver); +#ifdef CS4232 if (pnp_registered) - pnp_unregister_driver(&cs423x_pnp_driver); + pnp_unregister_driver(&cs4232_pnp_driver); +#endif if (isa_registered) #endif isa_unregister_driver(&cs423x_isa_driver); diff --git a/trunk/sound/isa/cs423x/cs4236_lib.c b/trunk/sound/isa/cs423x/cs4236_lib.c index 38835f31298b..6a85fdc53b60 100644 --- a/trunk/sound/isa/cs423x/cs4236_lib.c +++ b/trunk/sound/isa/cs423x/cs4236_lib.c @@ -88,6 +88,10 @@ #include #include +MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_DESCRIPTION("Routines for control of CS4235/4236B/4237B/4238B/4239 chips"); +MODULE_LICENSE("GPL"); + /* * */ @@ -282,8 +286,7 @@ int snd_cs4236_create(struct snd_card *card, if (hardware == WSS_HW_DETECT) hardware = WSS_HW_DETECT3; if (cport < 0x100) { - snd_printk(KERN_ERR "please, specify control port " - "for CS4236+ chips\n"); + snd_printk("please, specify control port for CS4236+ chips\n"); return -ENODEV; } err = snd_wss_create(card, port, cport, @@ -292,8 +295,7 @@ int snd_cs4236_create(struct snd_card *card, return err; if (!(chip->hardware & WSS_HW_CS4236B_MASK)) { - snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers " - "not available, hardware=0x%x\n", chip->hardware); + snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware); snd_device_free(card, chip); return -ENODEV; } @@ -301,19 +303,16 @@ int snd_cs4236_create(struct snd_card *card, { int idx; for (idx = 0; idx < 8; idx++) - snd_printk(KERN_DEBUG "CD%i = 0x%x\n", - idx, inb(chip->cport + idx)); + snd_printk("CD%i = 0x%x\n", idx, inb(chip->cport + idx)); for (idx = 0; idx < 9; idx++) - snd_printk(KERN_DEBUG "C%i = 0x%x\n", - idx, snd_cs4236_ctrl_in(chip, idx)); + snd_printk("C%i = 0x%x\n", idx, snd_cs4236_ctrl_in(chip, idx)); } #endif ver1 = snd_cs4236_ctrl_in(chip, 1); ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION); snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2); if (ver1 != ver2) { - snd_printk(KERN_ERR "CS4236+ chip detected, but " - "control port 0x%lx is not valid\n", cport); + snd_printk("CS4236+ chip detected, but control port 0x%lx is not valid\n", cport); snd_device_free(card, chip); return -ENODEV; } @@ -884,8 +883,7 @@ static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct sn spin_lock_irqsave(&chip->reg_lock, flags); ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0; #if 0 - printk(KERN_DEBUG "get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, " - "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", + printk("get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", snd_wss_in(chip, CS4231_ALT_FEATURE_1), snd_cs4236_ctrl_in(chip, 3), snd_cs4236_ctrl_in(chip, 4), @@ -922,8 +920,7 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn mutex_unlock(&chip->mce_mutex); #if 0 - printk(KERN_DEBUG "set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, " - "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", + printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", snd_wss_in(chip, CS4231_ALT_FEATURE_1), snd_cs4236_ctrl_in(chip, 3), snd_cs4236_ctrl_in(chip, 4), @@ -1018,3 +1015,23 @@ int snd_cs4236_mixer(struct snd_wss *chip) } return 0; } + +EXPORT_SYMBOL(snd_cs4236_create); +EXPORT_SYMBOL(snd_cs4236_pcm); +EXPORT_SYMBOL(snd_cs4236_mixer); + +/* + * INIT part + */ + +static int __init alsa_cs4236_init(void) +{ + return 0; +} + +static void __exit alsa_cs4236_exit(void) +{ +} + +module_init(alsa_cs4236_init) +module_exit(alsa_cs4236_exit) diff --git a/trunk/sound/isa/dt019x.c b/trunk/sound/isa/dt019x.c index 80f5b1af9be8..a0242c3b613e 100644 --- a/trunk/sound/isa/dt019x.c +++ b/trunk/sound/isa/dt019x.c @@ -150,10 +150,9 @@ static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, struct snd_card_dt019x *acard; struct snd_opl3 *opl3; - error = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_dt019x), &card); - if (error < 0) - return error; + if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_dt019x))) == NULL) + return -ENOMEM; acard = card->private_data; snd_card_set_dev(card, &pcard->card->dev); diff --git a/trunk/sound/isa/es1688/es1688.c b/trunk/sound/isa/es1688/es1688.c index 442b081cafb7..b46377139cf8 100644 --- a/trunk/sound/isa/es1688/es1688.c +++ b/trunk/sound/isa/es1688/es1688.c @@ -49,7 +49,6 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ -static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ @@ -66,8 +65,6 @@ MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(mpu_port, long, NULL, 0444); MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -module_param_array(fm_port, long, NULL, 0444); -MODULE_PARM_DESC(fm_port, "FM port # for ES1688 driver."); MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(mpu_irq, int, NULL, 0444); MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); @@ -125,9 +122,9 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) struct snd_pcm *pcm; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); - if (error < 0) - return error; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; error = snd_es1688_legacy_create(card, dev, n, &chip); if (error < 0) @@ -146,19 +143,13 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, chip->irq, chip->dma8); - if (fm_port[n] == SNDRV_AUTO_PORT) - fm_port[n] = port[n]; /* share the same port */ - - if (fm_port[n] > 0) { - if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, - OPL3_HW_OPL3, 0, &opl3) < 0) - dev_warn(dev, - "opl3 not detected at 0x%lx\n", fm_port[n]); - else { - error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); - if (error < 0) - goto out; - } + if (snd_opl3_create(card, chip->port, chip->port + 2, + OPL3_HW_OPL3, 0, &opl3) < 0) + dev_warn(dev, "opl3 not detected at 0x%lx\n", chip->port); + else { + error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); + if (error < 0) + goto out; } if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ && diff --git a/trunk/sound/isa/es1688/es1688_lib.c b/trunk/sound/isa/es1688/es1688_lib.c index 4c6e14f87f2d..4fbb508a817f 100644 --- a/trunk/sound/isa/es1688/es1688_lib.c +++ b/trunk/sound/isa/es1688/es1688_lib.c @@ -45,7 +45,7 @@ static int snd_es1688_dsp_command(struct snd_es1688 *chip, unsigned char val) return 1; } #ifdef CONFIG_SND_DEBUG - printk(KERN_DEBUG "snd_es1688_dsp_command: timeout (0x%x)\n", val); + printk("snd_es1688_dsp_command: timeout (0x%x)\n", val); #endif return 0; } @@ -167,16 +167,13 @@ static int snd_es1688_probe(struct snd_es1688 *chip) hw = ES1688_HW_AUTO; switch (chip->version & 0xfff0) { case 0x4880: - snd_printk(KERN_ERR "[0x%lx] ESS: AudioDrive ES488 detected, " - "but driver is in another place\n", chip->port); + snd_printk("[0x%lx] ESS: AudioDrive ES488 detected, but driver is in another place\n", chip->port); return -ENODEV; case 0x6880: hw = (chip->version & 0x0f) >= 8 ? ES1688_HW_1688 : ES1688_HW_688; break; default: - snd_printk(KERN_ERR "[0x%lx] ESS: unknown AudioDrive chip " - "with version 0x%x (Jazz16 soundcard?)\n", - chip->port, chip->version); + snd_printk("[0x%lx] ESS: unknown AudioDrive chip with version 0x%x (Jazz16 soundcard?)\n", chip->port, chip->version); return -ENODEV; } @@ -226,7 +223,7 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable) } } #if 0 - snd_printk(KERN_DEBUG "mpu cfg = 0x%x\n", cfg); + snd_printk("mpu cfg = 0x%x\n", cfg); #endif spin_lock_irqsave(&chip->reg_lock, flags); snd_es1688_mixer_write(chip, 0x40, cfg); @@ -240,9 +237,7 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable) cfg = 0xf0; /* enable only DMA counter interrupt */ irq_bits = irqs[chip->irq & 0x0f]; if (irq_bits < 0) { - snd_printk(KERN_ERR "[0x%lx] ESS: bad IRQ %d " - "for ES1688 chip!!\n", - chip->port, chip->irq); + snd_printk("[0x%lx] ESS: bad IRQ %d for ES1688 chip!!\n", chip->port, chip->irq); #if 0 irq_bits = 0; cfg = 0x10; @@ -255,8 +250,7 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable) cfg = 0xf0; /* extended mode DMA enable */ dma = chip->dma8; if (dma > 3 || dma == 2) { - snd_printk(KERN_ERR "[0x%lx] ESS: bad DMA channel %d " - "for ES1688 chip!!\n", chip->port, dma); + snd_printk("[0x%lx] ESS: bad DMA channel %d for ES1688 chip!!\n", chip->port, dma); #if 0 dma_bits = 0; cfg = 0x00; /* disable all DMA */ @@ -347,9 +341,8 @@ static int snd_es1688_trigger(struct snd_es1688 *chip, int cmd, unsigned char va return -EINVAL; /* something is wrong */ } #if 0 - printk(KERN_DEBUG "trigger: val = 0x%x, value = 0x%x\n", val, value); - printk(KERN_DEBUG "trigger: pointer = 0x%x\n", - snd_dma_pointer(chip->dma8, chip->dma_size)); + printk("trigger: val = 0x%x, value = 0x%x\n", val, value); + printk("trigger: pointer = 0x%x\n", snd_dma_pointer(chip->dma8, chip->dma_size)); #endif snd_es1688_write(chip, 0xb8, (val & 0xf0) | value); spin_unlock(&chip->reg_lock); diff --git a/trunk/sound/isa/es18xx.c b/trunk/sound/isa/es18xx.c index 8cfbff73a835..90498e4ca260 100644 --- a/trunk/sound/isa/es18xx.c +++ b/trunk/sound/isa/es18xx.c @@ -2125,10 +2125,10 @@ static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard, #define is_isapnp_selected(dev) 0 #endif -static int snd_es18xx_card_new(int dev, struct snd_card **cardp) +static struct snd_card *snd_es18xx_card_new(int dev) { - return snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_audiodrive), cardp); + return snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_audiodrive)); } static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) @@ -2197,9 +2197,9 @@ static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr) struct snd_card *card; int err; - err = snd_es18xx_card_new(dev, &card); - if (err < 0) - return err; + card = snd_es18xx_card_new(dev); + if (! card) + return -ENOMEM; snd_card_set_dev(card, devptr); if ((err = snd_audiodrive_probe(card, dev)) < 0) { snd_card_free(card); @@ -2303,9 +2303,9 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, if (dev >= SNDRV_CARDS) return -ENODEV; - err = snd_es18xx_card_new(dev, &card); - if (err < 0) - return err; + card = snd_es18xx_card_new(dev); + if (! card) + return -ENOMEM; if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) { snd_card_free(card); return err; @@ -2362,9 +2362,9 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard, if (dev >= SNDRV_CARDS) return -ENODEV; - res = snd_es18xx_card_new(dev, &card); - if (res < 0) - return res; + card = snd_es18xx_card_new(dev); + if (! card) + return -ENOMEM; if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) { snd_card_free(card); diff --git a/trunk/sound/isa/gus/gus_dma.c b/trunk/sound/isa/gus/gus_dma.c index 36c27c832360..f45f6116c77a 100644 --- a/trunk/sound/isa/gus/gus_dma.c +++ b/trunk/sound/isa/gus/gus_dma.c @@ -45,8 +45,7 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus, unsigned char dma_cmd; unsigned int address_high; - snd_printdd("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n", - addr, buf_addr, count); + // snd_printk("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n", addr, (long) buf, count); if (gus->gf1.dma1 > 3) { if (gus->gf1.enh_mode) { @@ -78,8 +77,7 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus, snd_gf1_dma_ack(gus); snd_dma_program(gus->gf1.dma1, buf_addr, count, dma_cmd & SNDRV_GF1_DMA_READ ? DMA_MODE_READ : DMA_MODE_WRITE); #if 0 - snd_printk(KERN_DEBUG "address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n", - address << 1, count, dma_cmd); + snd_printk("address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n", address << 1, count, dma_cmd); #endif spin_lock_irqsave(&gus->reg_lock, flags); if (gus->gf1.enh_mode) { @@ -144,9 +142,7 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus) snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd); kfree(block); #if 0 - snd_printd(KERN_DEBUG "program dma (IRQ) - " - "addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", - block->addr, block->buf_addr, block->count, block->cmd); + printk("program dma (IRQ) - addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", addr, (long) buffer, count, cmd); #endif } @@ -207,16 +203,13 @@ int snd_gf1_dma_transfer_block(struct snd_gus_card * gus, } *block = *__block; block->next = NULL; - - snd_printdd("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", - block->addr, (long) block->buffer, block->count, - block->cmd); - - snd_printdd("gus->gf1.dma_data_pcm_last = 0x%lx\n", - (long)gus->gf1.dma_data_pcm_last); - snd_printdd("gus->gf1.dma_data_pcm = 0x%lx\n", - (long)gus->gf1.dma_data_pcm); - +#if 0 + printk("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", block->addr, (long) block->buffer, block->count, block->cmd); +#endif +#if 0 + printk("gus->gf1.dma_data_pcm_last = 0x%lx\n", (long)gus->gf1.dma_data_pcm_last); + printk("gus->gf1.dma_data_pcm = 0x%lx\n", (long)gus->gf1.dma_data_pcm); +#endif spin_lock_irqsave(&gus->dma_lock, flags); if (synth) { if (gus->gf1.dma_data_synth_last) { diff --git a/trunk/sound/isa/gus/gus_irq.c b/trunk/sound/isa/gus/gus_irq.c index 2055aff71b50..041894ddd014 100644 --- a/trunk/sound/isa/gus/gus_irq.c +++ b/trunk/sound/isa/gus/gus_irq.c @@ -41,7 +41,7 @@ irqreturn_t snd_gus_interrupt(int irq, void *dev_id) if (status == 0) return IRQ_RETVAL(handled); handled = 1; - /* snd_printk(KERN_DEBUG "IRQ: status = 0x%x\n", status); */ + // snd_printk("IRQ: status = 0x%x\n", status); if (status & 0x02) { STAT_ADD(gus->gf1.interrupt_stat_midi_in); if (gus->gf1.interrupt_handler_midi_in) @@ -65,9 +65,7 @@ irqreturn_t snd_gus_interrupt(int irq, void *dev_id) continue; /* multi request */ already |= _current_; /* mark request */ #if 0 - printk(KERN_DEBUG "voice = %i, voice_status = 0x%x, " - "voice_verify = %i\n", - voice, voice_status, inb(GUSP(gus, GF1PAGE))); + printk("voice = %i, voice_status = 0x%x, voice_verify = %i\n", voice, voice_status, inb(GUSP(gus, GF1PAGE))); #endif pvoice = &gus->gf1.voices[voice]; if (pvoice->use) { diff --git a/trunk/sound/isa/gus/gus_pcm.c b/trunk/sound/isa/gus/gus_pcm.c index edb11eefdfe3..38510aeb21c6 100644 --- a/trunk/sound/isa/gus/gus_pcm.c +++ b/trunk/sound/isa/gus/gus_pcm.c @@ -82,10 +82,7 @@ static int snd_gf1_pcm_block_change(struct snd_pcm_substream *substream, count += offset & 31; offset &= ~31; - /* - snd_printk(KERN_DEBUG "block change - offset = 0x%x, count = 0x%x\n", - offset, count); - */ + // snd_printk("block change - offset = 0x%x, count = 0x%x\n", offset, count); memset(&block, 0, sizeof(block)); block.cmd = SNDRV_GF1_DMA_IRQ; if (snd_pcm_format_unsigned(runtime->format)) @@ -138,11 +135,7 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream) curr = begin + (pcmp->bpos * pcmp->block_size) / runtime->channels; end = curr + (pcmp->block_size / runtime->channels); end -= snd_pcm_format_width(runtime->format) == 16 ? 2 : 1; - /* - snd_printk(KERN_DEBUG "init: curr=0x%x, begin=0x%x, end=0x%x, " - "ctrl=0x%x, ramp=0x%x, rate=0x%x\n", - curr, begin, end, voice_ctrl, ramp_ctrl, rate); - */ + // snd_printk("init: curr=0x%x, begin=0x%x, end=0x%x, ctrl=0x%x, ramp=0x%x, rate=0x%x\n", curr, begin, end, voice_ctrl, ramp_ctrl, rate); pan = runtime->channels == 2 ? (!voice ? 1 : 14) : 8; vol = !voice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right; spin_lock_irqsave(&gus->reg_lock, flags); @@ -212,11 +205,9 @@ static void snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus, ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03; #if 0 snd_gf1_select_voice(gus, pvoice->number); - printk(KERN_DEBUG "position = 0x%x\n", - (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); + printk("position = 0x%x\n", (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); snd_gf1_select_voice(gus, pcmp->pvoices[1]->number); - printk(KERN_DEBUG "position = 0x%x\n", - (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); + printk("position = 0x%x\n", (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); snd_gf1_select_voice(gus, pvoice->number); #endif pcmp->bpos++; @@ -308,11 +299,7 @@ static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf, unsigned int len; unsigned long flags; - /* - printk(KERN_DEBUG - "poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n", - (int)buf, pos, count, gus->gf1.port); - */ + // printk("poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n", (int)buf, pos, count, gus->gf1.port); while (count > 0) { len = count; if (len > 512) /* limit, to allow IRQ */ @@ -693,8 +680,7 @@ static int snd_gf1_pcm_playback_open(struct snd_pcm_substream *substream) runtime->private_free = snd_gf1_pcm_playback_free; #if 0 - printk(KERN_DEBUG "playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n", - (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer); + printk("playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n", (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer); #endif if ((err = snd_gf1_dma_init(gus)) < 0) return err; diff --git a/trunk/sound/isa/gus/gus_uart.c b/trunk/sound/isa/gus/gus_uart.c index 21cc42e4c4be..f0af3f79b08b 100644 --- a/trunk/sound/isa/gus/gus_uart.c +++ b/trunk/sound/isa/gus/gus_uart.c @@ -129,14 +129,8 @@ static int snd_gf1_uart_input_open(struct snd_rawmidi_substream *substream) } spin_unlock_irqrestore(&gus->uart_cmd_lock, flags); #if 0 - snd_printk(KERN_DEBUG - "read init - enable = %i, cmd = 0x%x, stat = 0x%x\n", - gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus)); - snd_printk(KERN_DEBUG - "[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x " - "(page = 0x%x)\n", - gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100), - inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102)); + snd_printk("read init - enable = %i, cmd = 0x%x, stat = 0x%x\n", gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus)); + snd_printk("[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x (page = 0x%x)\n", gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100), inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102)); #endif return 0; } diff --git a/trunk/sound/isa/gus/gusclassic.c b/trunk/sound/isa/gus/gusclassic.c index 086b8f0e0f94..426532a4d730 100644 --- a/trunk/sound/isa/gus/gusclassic.c +++ b/trunk/sound/isa/gus/gusclassic.c @@ -148,9 +148,9 @@ static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n) struct snd_gus_card *gus; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); - if (error < 0) - return error; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; if (pcm_channels[n] < 2) pcm_channels[n] = 2; diff --git a/trunk/sound/isa/gus/gusextreme.c b/trunk/sound/isa/gus/gusextreme.c index 180a8dea6bd9..7ad4c3b41a84 100644 --- a/trunk/sound/isa/gus/gusextreme.c +++ b/trunk/sound/isa/gus/gusextreme.c @@ -241,9 +241,9 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) struct snd_opl3 *opl3; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); - if (error < 0) - return error; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; if (mpu_port[n] == SNDRV_AUTO_PORT) mpu_port[n] = 0; diff --git a/trunk/sound/isa/gus/gusmax.c b/trunk/sound/isa/gus/gusmax.c index f26eac8d8110..f94c1976e632 100644 --- a/trunk/sound/isa/gus/gusmax.c +++ b/trunk/sound/isa/gus/gusmax.c @@ -214,10 +214,10 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) struct snd_wss *wss; struct snd_gusmax *maxcard; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_gusmax), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_gusmax)); + if (card == NULL) + return -ENOMEM; card->private_free = snd_gusmax_free; maxcard = (struct snd_gusmax *)card->private_data; maxcard->card = card; diff --git a/trunk/sound/isa/gus/interwave.c b/trunk/sound/isa/gus/interwave.c index 534a6eced2b8..5faecfb602d3 100644 --- a/trunk/sound/isa/gus/interwave.c +++ b/trunk/sound/isa/gus/interwave.c @@ -170,7 +170,7 @@ static void snd_interwave_i2c_setlines(struct snd_i2c_bus *bus, int ctrl, int da unsigned long port = bus->private_value; #if 0 - printk(KERN_DEBUG "i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data); + printk("i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data); #endif outb((data << 1) | ctrl, port); udelay(10); @@ -183,7 +183,7 @@ static int snd_interwave_i2c_getclockline(struct snd_i2c_bus *bus) res = inb(port) & 1; #if 0 - printk(KERN_DEBUG "i2c_getclockline - 0x%lx -> %i\n", port, res); + printk("i2c_getclockline - 0x%lx -> %i\n", port, res); #endif return res; } @@ -197,7 +197,7 @@ static int snd_interwave_i2c_getdataline(struct snd_i2c_bus *bus, int ack) udelay(10); res = (inb(port) & 2) >> 1; #if 0 - printk(KERN_DEBUG "i2c_getdataline - 0x%lx -> %i\n", port, res); + printk("i2c_getdataline - 0x%lx -> %i\n", port, res); #endif return res; } @@ -342,8 +342,7 @@ static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *s snd_gf1_poke(gus, local, d); snd_gf1_poke(gus, local + 1, d + 1); #if 0 - printk(KERN_DEBUG "d = 0x%x, local = 0x%x, " - "local + 1 = 0x%x, idx << 22 = 0x%x\n", + printk("d = 0x%x, local = 0x%x, local + 1 = 0x%x, idx << 22 = 0x%x\n", d, snd_gf1_peek(gus, local), snd_gf1_peek(gus, local + 1), @@ -357,8 +356,7 @@ static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *s } } #if 0 - printk(KERN_DEBUG "sizes: %i %i %i %i\n", - sizes[0], sizes[1], sizes[2], sizes[3]); + printk("sizes: %i %i %i %i\n", sizes[0], sizes[1], sizes[2], sizes[3]); #endif } @@ -412,12 +410,12 @@ static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus) lmct = (psizes[3] << 24) | (psizes[2] << 16) | (psizes[1] << 8) | psizes[0]; #if 0 - printk(KERN_DEBUG "lmct = 0x%08x\n", lmct); + printk("lmct = 0x%08x\n", lmct); #endif for (i = 0; i < ARRAY_SIZE(lmc); i++) if (lmct == lmc[i]) { #if 0 - printk(KERN_DEBUG "found !!! %i\n", i); + printk("found !!! %i\n", i); #endif snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i); snd_interwave_bank_sizes(gus, psizes); @@ -628,22 +626,20 @@ static void snd_interwave_free(struct snd_card *card) free_irq(iwcard->irq, (void *)iwcard); } -static int snd_interwave_card_new(int dev, struct snd_card **cardp) +static struct snd_card *snd_interwave_card_new(int dev) { struct snd_card *card; struct snd_interwave *iwcard; - int err; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_interwave), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_interwave)); + if (card == NULL) + return NULL; iwcard = card->private_data; iwcard->card = card; iwcard->irq = -1; card->private_free = snd_interwave_free; - *cardp = card; - return 0; + return card; } static int __devinit snd_interwave_probe(struct snd_card *card, int dev) @@ -782,9 +778,9 @@ static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr) struct snd_card *card; int err; - err = snd_interwave_card_new(dev, &card); - if (err < 0) - return err; + card = snd_interwave_card_new(dev); + if (! card) + return -ENOMEM; snd_card_set_dev(card, devptr); if ((err = snd_interwave_probe(card, dev)) < 0) { @@ -880,9 +876,9 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, if (dev >= SNDRV_CARDS) return -ENODEV; - res = snd_interwave_card_new(dev, &card); - if (res < 0) - return res; + card = snd_interwave_card_new(dev); + if (! card) + return -ENOMEM; if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) { snd_card_free(card); diff --git a/trunk/sound/isa/opl3sa2.c b/trunk/sound/isa/opl3sa2.c index 9c5fce31f06b..58c972b2af03 100644 --- a/trunk/sound/isa/opl3sa2.c +++ b/trunk/sound/isa/opl3sa2.c @@ -179,13 +179,12 @@ static unsigned char __snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char unsigned char result; #if 0 outb(0x1d, port); /* password */ - printk(KERN_DEBUG "read [0x%lx] = 0x%x\n", port, inb(port)); + printk("read [0x%lx] = 0x%x\n", port, inb(port)); #endif outb(reg, chip->port); /* register */ result = inb(chip->port + 1); #if 0 - printk(KERN_DEBUG "read [0x%lx] = 0x%x [0x%x]\n", - port, result, inb(port)); + printk("read [0x%lx] = 0x%x [0x%x]\n", port, result, inb(port)); #endif return result; } @@ -234,10 +233,7 @@ static int __devinit snd_opl3sa2_detect(struct snd_card *card) snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port); return -EBUSY; } - /* - snd_printk(KERN_DEBUG "REG 0A = 0x%x\n", - snd_opl3sa2_read(chip, 0x0a)); - */ + // snd_printk("REG 0A = 0x%x\n", snd_opl3sa2_read(chip, 0x0a)); chip->version = 0; tmp = snd_opl3sa2_read(chip, OPL3SA2_MISC); if (tmp == 0xff) { @@ -554,27 +550,21 @@ static int __devinit snd_opl3sa2_mixer(struct snd_card *card) #ifdef CONFIG_PM static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) { - if (card) { - struct snd_opl3sa2 *chip = card->private_data; + struct snd_opl3sa2 *chip = card->private_data; - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - chip->wss->suspend(chip->wss); - /* power down */ - snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); - } + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + chip->wss->suspend(chip->wss); + /* power down */ + snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); return 0; } static int snd_opl3sa2_resume(struct snd_card *card) { - struct snd_opl3sa2 *chip; + struct snd_opl3sa2 *chip = card->private_data; int i; - if (!card) - return 0; - - chip = card->private_data; /* power up */ snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0); @@ -627,24 +617,21 @@ static void snd_opl3sa2_free(struct snd_card *card) release_and_free_resource(chip->res_port); } -static int snd_opl3sa2_card_new(int dev, struct snd_card **cardp) +static struct snd_card *snd_opl3sa2_card_new(int dev) { struct snd_card *card; struct snd_opl3sa2 *chip; - int err; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_opl3sa2), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_opl3sa2)); + if (card == NULL) + return NULL; strcpy(card->driver, "OPL3SA2"); strcpy(card->shortname, "Yamaha OPL3-SA2"); chip = card->private_data; spin_lock_init(&chip->reg_lock); chip->irq = -1; card->private_free = snd_opl3sa2_free; - *cardp = card; - return 0; + return card; } static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) @@ -736,9 +723,9 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, if (dev >= SNDRV_CARDS) return -ENODEV; - err = snd_opl3sa2_card_new(dev, &card); - if (err < 0) - return err; + card = snd_opl3sa2_card_new(dev); + if (! card) + return -ENOMEM; if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { snd_card_free(card); return err; @@ -802,9 +789,9 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard, if (dev >= SNDRV_CARDS) return -ENODEV; - err = snd_opl3sa2_card_new(dev, &card); - if (err < 0) - return err; + card = snd_opl3sa2_card_new(dev); + if (! card) + return -ENOMEM; if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { snd_card_free(card); return err; @@ -883,9 +870,9 @@ static int __devinit snd_opl3sa2_isa_probe(struct device *pdev, struct snd_card *card; int err; - err = snd_opl3sa2_card_new(dev, &card); - if (err < 0) - return err; + card = snd_opl3sa2_card_new(dev); + if (! card) + return -ENOMEM; snd_card_set_dev(card, pdev); if ((err = snd_opl3sa2_probe(card, dev)) < 0) { snd_card_free(card); diff --git a/trunk/sound/isa/opti9xx/miro.c b/trunk/sound/isa/opti9xx/miro.c index 02e30d7c6a93..440755cc0013 100644 --- a/trunk/sound/isa/opti9xx/miro.c +++ b/trunk/sound/isa/opti9xx/miro.c @@ -1228,10 +1228,9 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n) struct snd_pcm *pcm; struct snd_rawmidi *rmidi; - error = snd_card_create(index, id, THIS_MODULE, - sizeof(struct snd_miro), &card); - if (error < 0) - return error; + if (!(card = snd_card_new(index, id, THIS_MODULE, + sizeof(struct snd_miro)))) + return -ENOMEM; card->private_free = snd_card_miro_free; miro = card->private_data; diff --git a/trunk/sound/isa/opti9xx/opti92x-ad1848.c b/trunk/sound/isa/opti9xx/opti92x-ad1848.c index 5cd555325b9d..19706b0d8497 100644 --- a/trunk/sound/isa/opti9xx/opti92x-ad1848.c +++ b/trunk/sound/isa/opti9xx/opti92x-ad1848.c @@ -252,7 +252,7 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, #endif /* OPTi93X */ default: - snd_printk(KERN_ERR "chip %d not supported\n", hardware); + snd_printk("chip %d not supported\n", hardware); return -ENODEV; } return 0; @@ -294,7 +294,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip, #endif /* OPTi93X */ default: - snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); + snd_printk("chip %d not supported\n", chip->hardware); } spin_unlock_irqrestore(&chip->lock, flags); @@ -336,7 +336,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, #endif /* OPTi93X */ default: - snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); + snd_printk("chip %d not supported\n", chip->hardware); } spin_unlock_irqrestore(&chip->lock, flags); @@ -412,7 +412,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) #endif /* OPTi93X */ default: - snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); + snd_printk("chip %d not supported\n", chip->hardware); return -EINVAL; } @@ -430,8 +430,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) wss_base_bits = 0x02; break; default: - snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", - chip->wss_base); + snd_printk("WSS port 0x%lx not valid\n", chip->wss_base); goto __skip_base; } snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); @@ -456,7 +455,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) irq_bits = 0x04; break; default: - snd_printk(KERN_WARNING "WSS irq # %d not valid\n", chip->irq); + snd_printk("WSS irq # %d not valid\n", chip->irq); goto __skip_resources; } @@ -471,14 +470,13 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) dma_bits = 0x03; break; default: - snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", - chip->dma1); + snd_printk("WSS dma1 # %d not valid\n", chip->dma1); goto __skip_resources; } #if defined(CS4231) || defined(OPTi93X) if (chip->dma1 == chip->dma2) { - snd_printk(KERN_ERR "don't want to share dmas\n"); + snd_printk("don't want to share dmas\n"); return -EBUSY; } @@ -487,8 +485,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) case 1: break; default: - snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", - chip->dma2); + snd_printk("WSS dma2 # %d not valid\n", chip->dma2); goto __skip_resources; } dma_bits |= 0x04; @@ -519,8 +516,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) mpu_port_bits = 0x00; break; default: - snd_printk(KERN_WARNING - "MPU-401 port 0x%lx not valid\n", + snd_printk("MPU-401 port 0x%lx not valid\n", chip->mpu_port); goto __skip_mpu; } @@ -539,7 +535,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) mpu_irq_bits = 0x01; break; default: - snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n", + snd_printk("MPU-401 irq # %d not valid\n", chip->mpu_irq); goto __skip_mpu; } @@ -730,7 +726,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) if (chip->wss_base == SNDRV_AUTO_PORT) { chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4); if (chip->wss_base < 0) { - snd_printk(KERN_ERR "unable to find a free WSS port\n"); + snd_printk("unable to find a free WSS port\n"); return -EBUSY; } } @@ -819,8 +815,14 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) chip->fm_port, chip->fm_port + 4 - 1); } if (opl3) { - error = snd_opl3_hwdep_new(opl3, 0, 1, &synth); - if (error < 0) +#ifdef CS4231 + const int t1dev = 1; +#else + const int t1dev = 0; +#endif + if ((error = snd_opl3_timer_new(opl3, t1dev, t1dev+1)) < 0) + return error; + if ((error = snd_opl3_hwdep_new(opl3, 0, 1, &synth)) < 0) return error; } } @@ -828,18 +830,15 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) return snd_card_register(card); } -static int snd_opti9xx_card_new(struct snd_card **cardp) +static struct snd_card *snd_opti9xx_card_new(void) { struct snd_card *card; - int err; - err = snd_card_create(index, id, THIS_MODULE, - sizeof(struct snd_opti9xx), &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, sizeof(struct snd_opti9xx)); + if (! card) + return NULL; card->private_free = snd_card_opti9xx_free; - *cardp = card; - return 0; + return card; } static int __devinit snd_opti9xx_isa_match(struct device *devptr, @@ -898,15 +897,15 @@ static int __devinit snd_opti9xx_isa_probe(struct device *devptr, #if defined(CS4231) || defined(OPTi93X) if (dma2 == SNDRV_AUTO_DMA) { if ((dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4])) < 0) { - snd_printk(KERN_ERR "unable to find a free DMA2\n"); + snd_printk("unable to find a free DMA2\n"); return -EBUSY; } } #endif - error = snd_opti9xx_card_new(&card); - if (error < 0) - return error; + card = snd_opti9xx_card_new(); + if (! card) + return -ENOMEM; if ((error = snd_card_opti9xx_detect(card, card->private_data)) < 0) { snd_card_free(card); @@ -951,9 +950,9 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, return -EBUSY; if (! isapnp) return -ENODEV; - error = snd_opti9xx_card_new(&card); - if (error < 0) - return error; + card = snd_opti9xx_card_new(); + if (! card) + return -ENOMEM; chip = card->private_data; hw = snd_card_opti9xx_pnp(chip, pcard, pid); diff --git a/trunk/sound/isa/sb/es968.c b/trunk/sound/isa/sb/es968.c index cafc3a7316a8..c8c8e214c843 100644 --- a/trunk/sound/isa/sb/es968.c +++ b/trunk/sound/isa/sb/es968.c @@ -108,10 +108,9 @@ static int __devinit snd_card_es968_probe(int dev, struct snd_card *card; struct snd_card_es968 *acard; - error = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_es968), &card); - if (error < 0) - return error; + if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_es968))) == NULL) + return -ENOMEM; acard = card->private_data; if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { snd_card_free(card); diff --git a/trunk/sound/isa/sb/sb16.c b/trunk/sound/isa/sb/sb16.c index 519c36346dec..2c201f78ce50 100644 --- a/trunk/sound/isa/sb/sb16.c +++ b/trunk/sound/isa/sb/sb16.c @@ -324,18 +324,14 @@ static void snd_sb16_free(struct snd_card *card) #define is_isapnp_selected(dev) 0 #endif -static int snd_sb16_card_new(int dev, struct snd_card **cardp) +static struct snd_card *snd_sb16_card_new(int dev) { - struct snd_card *card; - int err; - - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_sb16), &card); - if (err < 0) - return err; + struct snd_card *card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_sb16)); + if (card == NULL) + return NULL; card->private_free = snd_sb16_free; - *cardp = card; - return 0; + return card; } static int __devinit snd_sb16_probe(struct snd_card *card, int dev) @@ -493,9 +489,9 @@ static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev) struct snd_card *card; int err; - err = snd_sb16_card_new(dev, &card); - if (err < 0) - return err; + card = snd_sb16_card_new(dev); + if (! card) + return -ENOMEM; acard = card->private_data; /* non-PnP FM port address is hardwired with base port address */ @@ -614,9 +610,9 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, for ( ; dev < SNDRV_CARDS; dev++) { if (!enable[dev] || !isapnp[dev]) continue; - res = snd_sb16_card_new(dev, &card); - if (res < 0) - return res; + card = snd_sb16_card_new(dev); + if (! card) + return -ENOMEM; snd_card_set_dev(card, &pcard->card->dev); if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 || (res = snd_sb16_probe(card, dev)) < 0) { diff --git a/trunk/sound/isa/sb/sb8.c b/trunk/sound/isa/sb/sb8.c index 3cd57ee54660..ea06877be4b1 100644 --- a/trunk/sound/isa/sb/sb8.c +++ b/trunk/sound/isa/sb/sb8.c @@ -103,10 +103,10 @@ static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev) struct snd_opl3 *opl3; int err; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_sb8), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_sb8)); + if (card == NULL) + return -ENOMEM; acard = card->private_data; card->private_free = snd_sb8_free; diff --git a/trunk/sound/isa/sc6000.c b/trunk/sound/isa/sc6000.c index 782010608ef4..ca35924dc3b3 100644 --- a/trunk/sound/isa/sc6000.c +++ b/trunk/sound/isa/sc6000.c @@ -489,9 +489,9 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) char __iomem *vmss_port; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (!card) + return -ENOMEM; if (xirq == SNDRV_AUTO_IRQ) { xirq = snd_legacy_find_free_irq(possible_irqs); @@ -576,6 +576,10 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) snd_printk(KERN_ERR PFX "no OPL device at 0x%x-0x%x ?\n", 0x388, 0x388 + 2); } else { + err = snd_opl3_timer_new(opl3, 0, 1); + if (err < 0) + goto err_unmap2; + err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); if (err < 0) goto err_unmap2; diff --git a/trunk/sound/isa/sgalaxy.c b/trunk/sound/isa/sgalaxy.c index 6fe27b9d9440..2c7503bf1271 100644 --- a/trunk/sound/isa/sgalaxy.c +++ b/trunk/sound/isa/sgalaxy.c @@ -243,9 +243,9 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) struct snd_card *card; struct snd_wss *chip; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; xirq = irq[dev]; if (xirq == SNDRV_AUTO_IRQ) { diff --git a/trunk/sound/isa/sscape.c b/trunk/sound/isa/sscape.c index 4025fb558c50..48a16d865834 100644 --- a/trunk/sound/isa/sscape.c +++ b/trunk/sound/isa/sscape.c @@ -1357,10 +1357,10 @@ static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) struct soundscape *sscape; int ret; - ret = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct soundscape), &card); - if (ret < 0) - return ret; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct soundscape)); + if (!card) + return -ENOMEM; sscape = get_card_soundscape(card); sscape->type = SSCAPE; @@ -1462,10 +1462,10 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, * Create a new ALSA sound card entry, in anticipation * of detecting our hardware ... */ - ret = snd_card_create(index[idx], id[idx], THIS_MODULE, - sizeof(struct soundscape), &card); - if (ret < 0) - return ret; + card = snd_card_new(index[idx], id[idx], THIS_MODULE, + sizeof(struct soundscape)); + if (!card) + return -ENOMEM; sscape = get_card_soundscape(card); diff --git a/trunk/sound/isa/wavefront/wavefront.c b/trunk/sound/isa/wavefront/wavefront.c index a34ae7b1f7d0..4c095bc7c729 100644 --- a/trunk/sound/isa/wavefront/wavefront.c +++ b/trunk/sound/isa/wavefront/wavefront.c @@ -338,16 +338,15 @@ snd_wavefront_free(struct snd_card *card) } } -static int snd_wavefront_card_new(int dev, struct snd_card **cardp) +static struct snd_card *snd_wavefront_card_new(int dev) { struct snd_card *card; snd_wavefront_card_t *acard; - int err; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(snd_wavefront_card_t), &card); - if (err < 0) - return err; + card = snd_card_new (index[dev], id[dev], THIS_MODULE, + sizeof(snd_wavefront_card_t)); + if (card == NULL) + return NULL; acard = card->private_data; acard->wavefront.irq = -1; @@ -358,8 +357,7 @@ static int snd_wavefront_card_new(int dev, struct snd_card **cardp) acard->wavefront.card = card; card->private_free = snd_wavefront_free; - *cardp = card; - return 0; + return card; } static int __devinit @@ -553,11 +551,11 @@ static int __devinit snd_wavefront_isa_match(struct device *pdev, return 0; #endif if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify CS4232 port\n"); + snd_printk("specify CS4232 port\n"); return 0; } if (ics2115_port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify ICS2115 port\n"); + snd_printk("specify ICS2115 port\n"); return 0; } return 1; @@ -569,9 +567,9 @@ static int __devinit snd_wavefront_isa_probe(struct device *pdev, struct snd_card *card; int err; - err = snd_wavefront_card_new(dev, &card); - if (err < 0) - return err; + card = snd_wavefront_card_new(dev); + if (! card) + return -ENOMEM; snd_card_set_dev(card, pdev); if ((err = snd_wavefront_probe(card, dev)) < 0) { snd_card_free(card); @@ -618,9 +616,9 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, if (dev >= SNDRV_CARDS) return -ENODEV; - res = snd_wavefront_card_new(dev, &card); - if (res < 0) - return res; + card = snd_wavefront_card_new(dev); + if (! card) + return -ENOMEM; if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) { if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { diff --git a/trunk/sound/isa/wavefront/wavefront_synth.c b/trunk/sound/isa/wavefront/wavefront_synth.c index beb312cca75b..4c410820a994 100644 --- a/trunk/sound/isa/wavefront/wavefront_synth.c +++ b/trunk/sound/isa/wavefront/wavefront_synth.c @@ -633,7 +633,7 @@ wavefront_get_sample_status (snd_wavefront_t *dev, int assume_rom) wbuf[1] = i >> 7; if (snd_wavefront_cmd (dev, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) { - snd_printk(KERN_WARNING "cannot identify sample " + snd_printk("cannot identify sample " "type of slot %d\n", i); dev->sample_status[i] = WF_ST_EMPTY; continue; diff --git a/trunk/sound/isa/wss/wss_lib.c b/trunk/sound/isa/wss/wss_lib.c index ac27832b2c6f..3d6c5f2838af 100644 --- a/trunk/sound/isa/wss/wss_lib.c +++ b/trunk/sound/isa/wss/wss_lib.c @@ -219,8 +219,7 @@ void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value) snd_wss_wait(chip); #ifdef CONFIG_SND_DEBUG if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk(KERN_DEBUG "out: auto calibration time out " - "- reg = 0x%x, value = 0x%x\n", reg, value); + snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); #endif wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); wss_outb(chip, CS4231P(REG), value); @@ -236,8 +235,7 @@ unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg) snd_wss_wait(chip); #ifdef CONFIG_SND_DEBUG if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk(KERN_DEBUG "in: auto calibration time out " - "- reg = 0x%x\n", reg); + snd_printk("in: auto calibration time out - reg = 0x%x\n", reg); #endif wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); mb(); @@ -254,7 +252,7 @@ void snd_cs4236_ext_out(struct snd_wss *chip, unsigned char reg, wss_outb(chip, CS4231P(REG), val); chip->eimage[CS4236_REG(reg)] = val; #if 0 - printk(KERN_DEBUG "ext out : reg = 0x%x, val = 0x%x\n", reg, val); + printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val); #endif } EXPORT_SYMBOL(snd_cs4236_ext_out); @@ -270,8 +268,7 @@ unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg) { unsigned char res; res = wss_inb(chip, CS4231P(REG)); - printk(KERN_DEBUG "ext in : reg = 0x%x, val = 0x%x\n", - reg, res); + printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res); return res; } #endif @@ -397,16 +394,13 @@ void snd_wss_mce_up(struct snd_wss *chip) snd_wss_wait(chip); #ifdef CONFIG_SND_DEBUG if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk(KERN_DEBUG - "mce_up - auto calibration time out (0)\n"); + snd_printk("mce_up - auto calibration time out (0)\n"); #endif spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit |= CS4231_MCE; timeout = wss_inb(chip, CS4231P(REGSEL)); if (timeout == 0x80) - snd_printk(KERN_DEBUG "mce_up [0x%lx]: " - "serious init problem - codec still busy\n", - chip->port); + snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); if (!(timeout & CS4231_MCE)) wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); @@ -425,9 +419,7 @@ void snd_wss_mce_down(struct snd_wss *chip) #ifdef CONFIG_SND_DEBUG if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk(KERN_DEBUG "mce_down [0x%lx] - " - "auto calibration time out (0)\n", - (long)CS4231P(REGSEL)); + snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL)); #endif spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit &= ~CS4231_MCE; @@ -435,9 +427,7 @@ void snd_wss_mce_down(struct snd_wss *chip) wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); spin_unlock_irqrestore(&chip->reg_lock, flags); if (timeout == 0x80) - snd_printk(KERN_DEBUG "mce_down [0x%lx]: " - "serious init problem - codec still busy\n", - chip->port); + snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & hw_mask)) return; @@ -575,7 +565,7 @@ static unsigned char snd_wss_get_format(struct snd_wss *chip, if (channels > 1) rformat |= CS4231_STEREO; #if 0 - snd_printk(KERN_DEBUG "get_format: 0x%x (mode=0x%x)\n", format, mode); + snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode); #endif return rformat; } @@ -784,7 +774,7 @@ static void snd_wss_init(struct snd_wss *chip) snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE - snd_printk(KERN_DEBUG "init: (1)\n"); + snd_printk("init: (1)\n"); #endif snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); @@ -799,7 +789,7 @@ static void snd_wss_init(struct snd_wss *chip) snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE - snd_printk(KERN_DEBUG "init: (2)\n"); + snd_printk("init: (2)\n"); #endif snd_wss_mce_up(chip); @@ -810,7 +800,7 @@ static void snd_wss_init(struct snd_wss *chip) snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE - snd_printk(KERN_DEBUG "init: (3) - afei = 0x%x\n", + snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]); #endif @@ -827,7 +817,7 @@ static void snd_wss_init(struct snd_wss *chip) snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE - snd_printk(KERN_DEBUG "init: (4)\n"); + snd_printk("init: (4)\n"); #endif snd_wss_mce_up(chip); @@ -839,7 +829,7 @@ static void snd_wss_init(struct snd_wss *chip) snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE - snd_printk(KERN_DEBUG "init: (5)\n"); + snd_printk("init: (5)\n"); #endif } @@ -1288,8 +1278,7 @@ static int snd_wss_probe(struct snd_wss *chip) } else if (rev == 0x03) { chip->hardware = WSS_HW_CS4236B; } else { - snd_printk(KERN_ERR - "unknown CS chip with version 0x%x\n", rev); + snd_printk("unknown CS chip with version 0x%x\n", rev); return -ENODEV; /* unknown CS4231 chip? */ } } @@ -1353,10 +1342,7 @@ static int snd_wss_probe(struct snd_wss *chip) case 6: break; default: - snd_printk(KERN_WARNING - "unknown CS4235 chip " - "(enhanced version = 0x%x)\n", - id); + snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id); } } else if ((id & 0x1f) == 0x0b) { /* CS4236/B */ switch (id >> 5) { @@ -1367,10 +1353,7 @@ static int snd_wss_probe(struct snd_wss *chip) chip->hardware = WSS_HW_CS4236B; break; default: - snd_printk(KERN_WARNING - "unknown CS4236 chip " - "(enhanced version = 0x%x)\n", - id); + snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id); } } else if ((id & 0x1f) == 0x08) { /* CS4237B */ chip->hardware = WSS_HW_CS4237B; @@ -1381,10 +1364,7 @@ static int snd_wss_probe(struct snd_wss *chip) case 7: break; default: - snd_printk(KERN_WARNING - "unknown CS4237B chip " - "(enhanced version = 0x%x)\n", - id); + snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id); } } else if ((id & 0x1f) == 0x09) { /* CS4238B */ chip->hardware = WSS_HW_CS4238B; @@ -1394,10 +1374,7 @@ static int snd_wss_probe(struct snd_wss *chip) case 7: break; default: - snd_printk(KERN_WARNING - "unknown CS4238B chip " - "(enhanced version = 0x%x)\n", - id); + snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id); } } else if ((id & 0x1f) == 0x1e) { /* CS4239 */ chip->hardware = WSS_HW_CS4239; @@ -1407,15 +1384,10 @@ static int snd_wss_probe(struct snd_wss *chip) case 6: break; default: - snd_printk(KERN_WARNING - "unknown CS4239 chip " - "(enhanced version = 0x%x)\n", - id); + snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id); } } else { - snd_printk(KERN_WARNING - "unknown CS4236/CS423xB chip " - "(enhanced version = 0x%x)\n", id); + snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id); } } } @@ -1646,8 +1618,7 @@ static void snd_wss_resume(struct snd_wss *chip) wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); spin_unlock_irqrestore(&chip->reg_lock, flags); if (timeout == 0x80) - snd_printk(KERN_ERR "down [0x%lx]: serious init problem " - "- codec still busy\n", chip->port); + snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) { return; @@ -1657,7 +1628,7 @@ static void snd_wss_resume(struct snd_wss *chip) } #endif /* CONFIG_PM */ -int snd_wss_free(struct snd_wss *chip) +static int snd_wss_free(struct snd_wss *chip) { release_and_free_resource(chip->res_port); release_and_free_resource(chip->res_cport); @@ -1680,7 +1651,6 @@ int snd_wss_free(struct snd_wss *chip) kfree(chip); return 0; } -EXPORT_SYMBOL(snd_wss_free); static int snd_wss_dev_free(struct snd_device *device) { @@ -1850,8 +1820,7 @@ int snd_wss_create(struct snd_card *card, #if 0 if (chip->hardware & WSS_HW_CS4232_MASK) { if (chip->res_cport == NULL) - snd_printk(KERN_ERR "CS4232 control port features are " - "not accessible\n"); + snd_printk("CS4232 control port features are not accessible\n"); } #endif diff --git a/trunk/sound/mips/au1x00.c b/trunk/sound/mips/au1x00.c index 3e763d6a5d67..1881cec11e78 100644 --- a/trunk/sound/mips/au1x00.c +++ b/trunk/sound/mips/au1x00.c @@ -636,10 +636,9 @@ au1000_init(void) struct snd_card *card; struct snd_au1000 *au1000; - err = snd_card_create(-1, "AC97", THIS_MODULE, - sizeof(struct snd_au1000), &card); - if (err < 0) - return err; + card = snd_card_new(-1, "AC97", THIS_MODULE, sizeof(struct snd_au1000)); + if (card == NULL) + return -ENOMEM; card->private_free = snd_au1000_free; au1000 = card->private_data; @@ -679,7 +678,7 @@ au1000_init(void) return err; } - printk(KERN_INFO "ALSA AC97: Driver Initialized\n"); + printk( KERN_INFO "ALSA AC97: Driver Initialized\n" ); au1000_card = card; return 0; } diff --git a/trunk/sound/mips/hal2.c b/trunk/sound/mips/hal2.c index c52691c2fc46..db495be01861 100644 --- a/trunk/sound/mips/hal2.c +++ b/trunk/sound/mips/hal2.c @@ -878,9 +878,9 @@ static int __devinit hal2_probe(struct platform_device *pdev) struct snd_hal2 *chip; int err; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; err = hal2_create(card, &chip); if (err < 0) { diff --git a/trunk/sound/mips/sgio2audio.c b/trunk/sound/mips/sgio2audio.c index 66f3b48ceafc..4c63504348dc 100644 --- a/trunk/sound/mips/sgio2audio.c +++ b/trunk/sound/mips/sgio2audio.c @@ -936,9 +936,9 @@ static int __devinit snd_sgio2audio_probe(struct platform_device *pdev) struct snd_sgio2audio *chip; int err; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; err = snd_sgio2audio_create(card, &chip); if (err < 0) { diff --git a/trunk/sound/parisc/harmony.c b/trunk/sound/parisc/harmony.c index 6055fd6d3b38..41f870f8a11d 100644 --- a/trunk/sound/parisc/harmony.c +++ b/trunk/sound/parisc/harmony.c @@ -975,9 +975,9 @@ snd_harmony_probe(struct parisc_device *padev) struct snd_card *card; struct snd_harmony *h; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; err = snd_harmony_create(card, padev, &h); if (err < 0) diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 44f2381b0aed..e2b843b4f9d0 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -143,7 +143,6 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x43525970, 0xfffffff8, "CS4202", NULL, NULL }, { 0x43585421, 0xffffffff, "HSD11246", NULL, NULL }, // SmartMC II { 0x43585428, 0xfffffff8, "Cx20468", patch_conexant, NULL }, // SmartAMC fixme: the mask might be different -{ 0x43585430, 0xffffffff, "Cx20468-31", patch_conexant, NULL }, { 0x43585431, 0xffffffff, "Cx20551", patch_cx20551, NULL }, { 0x44543031, 0xfffffff0, "DT0398", NULL, NULL }, { 0x454d4328, 0xffffffff, "EM28028", NULL, NULL }, // same as TR28028? @@ -1644,10 +1643,7 @@ static int snd_ac97_modem_build(struct snd_card *card, struct snd_ac97 * ac97) { int err, idx; - /* - printk(KERN_DEBUG "AC97_GPIO_CFG = %x\n", - snd_ac97_read(ac97,AC97_GPIO_CFG)); - */ + //printk("AC97_GPIO_CFG = %x\n",snd_ac97_read(ac97,AC97_GPIO_CFG)); snd_ac97_write(ac97, AC97_GPIO_CFG, 0xffff & ~(AC97_GPIO_LINE1_OH)); snd_ac97_write(ac97, AC97_GPIO_POLARITY, 0xffff & ~(AC97_GPIO_LINE1_OH)); snd_ac97_write(ac97, AC97_GPIO_STICKY, 0xffff); diff --git a/trunk/sound/pci/ad1889.c b/trunk/sound/pci/ad1889.c index d1f242bd0ac5..a7f38e63303f 100644 --- a/trunk/sound/pci/ad1889.c +++ b/trunk/sound/pci/ad1889.c @@ -995,10 +995,10 @@ snd_ad1889_probe(struct pci_dev *pci, } /* (2) */ - err = snd_card_create(index[devno], id[devno], THIS_MODULE, 0, &card); + card = snd_card_new(index[devno], id[devno], THIS_MODULE, 0); /* XXX REVISIT: we can probably allocate chip in this call */ - if (err < 0) - return err; + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "AD1889"); strcpy(card->shortname, "Analog Devices AD1889"); diff --git a/trunk/sound/pci/ak4531_codec.c b/trunk/sound/pci/ak4531_codec.c index fd135e3d8a84..0f819ddb3ebf 100644 --- a/trunk/sound/pci/ak4531_codec.c +++ b/trunk/sound/pci/ak4531_codec.c @@ -51,8 +51,7 @@ static void snd_ak4531_dump(struct snd_ak4531 *ak4531) int idx; for (idx = 0; idx < 0x19; idx++) - printk(KERN_DEBUG "ak4531 0x%x: 0x%x\n", - idx, ak4531->regs[idx]); + printk("ak4531 0x%x: 0x%x\n", idx, ak4531->regs[idx]); } #endif diff --git a/trunk/sound/pci/ali5451/ali5451.c b/trunk/sound/pci/ali5451/ali5451.c index 4edf270a7809..1a0fd65ec280 100644 --- a/trunk/sound/pci/ali5451/ali5451.c +++ b/trunk/sound/pci/ali5451/ali5451.c @@ -2142,7 +2142,7 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) { int err; - snd_ali_printk("resources allocation ...\n"); + snd_ali_printk("resouces allocation ...\n"); err = pci_request_regions(codec->pci, "ALI 5451"); if (err < 0) return err; @@ -2154,7 +2154,7 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) return -EBUSY; } codec->irq = codec->pci->irq; - snd_ali_printk("resources allocated.\n"); + snd_ali_printk("resouces allocated.\n"); return 0; } static int snd_ali_dev_free(struct snd_device *device) @@ -2307,9 +2307,9 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, snd_ali_printk("probe ...\n"); - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (!card) + return -ENOMEM; err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); if (err < 0) diff --git a/trunk/sound/pci/als300.c b/trunk/sound/pci/als300.c index 009b4c8225a5..8df6824b51cd 100644 --- a/trunk/sound/pci/als300.c +++ b/trunk/sound/pci/als300.c @@ -91,7 +91,7 @@ #define DEBUG_PLAY_REC 0 #if DEBUG_CALLS -#define snd_als300_dbgcalls(format, args...) printk(KERN_DEBUG format, ##args) +#define snd_als300_dbgcalls(format, args...) printk(format, ##args) #define snd_als300_dbgcallenter() printk(KERN_ERR "--> %s\n", __func__) #define snd_als300_dbgcallleave() printk(KERN_ERR "<-- %s\n", __func__) #else @@ -812,10 +812,10 @@ static int __devinit snd_als300_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (err < 0) - return err; + if (card == NULL) + return -ENOMEM; chip_type = pci_id->driver_data; diff --git a/trunk/sound/pci/als4000.c b/trunk/sound/pci/als4000.c index 542a0c65a92c..ba570053d4d5 100644 --- a/trunk/sound/pci/als4000.c +++ b/trunk/sound/pci/als4000.c @@ -889,13 +889,12 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO); pci_set_master(pci); - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(*acard) /* private_data: acard */, - &card); - if (err < 0) { + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(*acard) /* private_data: acard */); + if (card == NULL) { pci_release_regions(pci); pci_disable_device(pci); - return err; + return -ENOMEM; } acard = card->private_data; diff --git a/trunk/sound/pci/atiixp.c b/trunk/sound/pci/atiixp.c index 9ce8548c03e4..226fe8237d31 100644 --- a/trunk/sound/pci/atiixp.c +++ b/trunk/sound/pci/atiixp.c @@ -1645,9 +1645,9 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci, struct atiixp *chip; int err; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA"); strcpy(card->shortname, "ATI IXP"); diff --git a/trunk/sound/pci/atiixp_modem.c b/trunk/sound/pci/atiixp_modem.c index c3136cccc559..0e6e5cc1c501 100644 --- a/trunk/sound/pci/atiixp_modem.c +++ b/trunk/sound/pci/atiixp_modem.c @@ -1288,9 +1288,9 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci, struct atiixp_modem *chip; int err; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "ATIIXP-MODEM"); strcpy(card->shortname, "ATI IXP Modem"); diff --git a/trunk/sound/pci/au88x0/au88x0.c b/trunk/sound/pci/au88x0/au88x0.c index 9ec122383eef..a36d4d1fd419 100644 --- a/trunk/sound/pci/au88x0/au88x0.c +++ b/trunk/sound/pci/au88x0/au88x0.c @@ -250,9 +250,9 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) return -ENOENT; } // (2) - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; // (3) if ((err = snd_vortex_create(card, pci, &chip)) < 0) { diff --git a/trunk/sound/pci/au88x0/au88x0_a3d.c b/trunk/sound/pci/au88x0/au88x0_a3d.c index f4aa8ff6f5f9..649849e540d3 100644 --- a/trunk/sound/pci/au88x0/au88x0_a3d.c +++ b/trunk/sound/pci/au88x0/au88x0_a3d.c @@ -462,10 +462,9 @@ static void a3dsrc_ZeroSliceIO(a3dsrc_t * a) /* Reset Single A3D source. */ static void a3dsrc_ZeroState(a3dsrc_t * a) { - /* - printk(KERN_DEBUG "vortex: ZeroState slice: %d, source %d\n", - a->slice, a->source); - */ + + //printk("vortex: ZeroState slice: %d, source %d\n", a->slice, a->source); + a3dsrc_SetAtmosState(a, 0, 0, 0, 0); a3dsrc_SetHrtfState(a, A3dHrirZeros, A3dHrirZeros); a3dsrc_SetItdDline(a, A3dItdDlineZeros); diff --git a/trunk/sound/pci/au88x0/au88x0_core.c b/trunk/sound/pci/au88x0/au88x0_core.c index 3906f5afe27a..b070e5714514 100644 --- a/trunk/sound/pci/au88x0/au88x0_core.c +++ b/trunk/sound/pci/au88x0/au88x0_core.c @@ -1135,10 +1135,7 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, snd_pcm_sgbuf_get_addr(dma->substream, 0)); break; } - /* - printk(KERN_DEBUG "vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", - dma->cfg0, dma->cfg1); - */ + //printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1); hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG0 + (adbdma << 3), dma->cfg0); hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG1 + (adbdma << 3), dma->cfg1); @@ -1962,7 +1959,7 @@ vortex_connect_codecplay(vortex_t * vortex, int en, unsigned char mixers[]) ADB_CODECOUT(0 + 4)); vortex_connection_mix_adb(vortex, en, 0x11, mixers[3], ADB_CODECOUT(1 + 4)); - /* printk(KERN_DEBUG "SDAC detected "); */ + //printk("SDAC detected "); } #else // Use plain direct output to codec. @@ -2016,11 +2013,7 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype) resmap[restype] |= (1 << i); else vortex->dma_adb[i].resources[restype] |= (1 << i); - /* - printk(KERN_DEBUG - "vortex: ResManager: type %d out %d\n", - restype, i); - */ + //printk("vortex: ResManager: type %d out %d\n", restype, i); return i; } } @@ -2031,11 +2024,7 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype) for (i = 0; i < qty; i++) { if (resmap[restype] & (1 << i)) { resmap[restype] &= ~(1 << i); - /* - printk(KERN_DEBUG - "vortex: ResManager: type %d in %d\n", - restype, i); - */ + //printk("vortex: ResManager: type %d in %d\n",restype, i); return i; } } @@ -2800,7 +2789,7 @@ vortex_translateformat(vortex_t * vortex, char bits, char nch, int encod) { int a, this_194; - if ((bits != 8) && (bits != 16)) + if ((bits != 8) || (bits != 16)) return -1; switch (encod) { diff --git a/trunk/sound/pci/au88x0/au88x0_synth.c b/trunk/sound/pci/au88x0/au88x0_synth.c index 2805e34bd41d..978b856f5621 100644 --- a/trunk/sound/pci/au88x0/au88x0_synth.c +++ b/trunk/sound/pci/au88x0/au88x0_synth.c @@ -213,59 +213,38 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, switch (reg) { /* Voice specific parameters */ case 0: /* running */ - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", - WT_RUN(wt), (int)val); - */ + //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_RUN(wt), (int)val); hwwrite(vortex->mmio, WT_RUN(wt), val); return 0xc; break; case 1: /* param 0 */ - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", - WT_PARM(wt,0), (int)val); - */ + //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_PARM(wt,0), (int)val); hwwrite(vortex->mmio, WT_PARM(wt, 0), val); return 0xc; break; case 2: /* param 1 */ - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", - WT_PARM(wt,1), (int)val); - */ + //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_PARM(wt,1), (int)val); hwwrite(vortex->mmio, WT_PARM(wt, 1), val); return 0xc; break; case 3: /* param 2 */ - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", - WT_PARM(wt,2), (int)val); - */ + //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_PARM(wt,2), (int)val); hwwrite(vortex->mmio, WT_PARM(wt, 2), val); return 0xc; break; case 4: /* param 3 */ - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", - WT_PARM(wt,3), (int)val); - */ + //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_PARM(wt,3), (int)val); hwwrite(vortex->mmio, WT_PARM(wt, 3), val); return 0xc; break; case 6: /* mute */ - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", - WT_MUTE(wt), (int)val); - */ + //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_MUTE(wt), (int)val); hwwrite(vortex->mmio, WT_MUTE(wt), val); return 0xc; break; case 0xb: { /* delay */ - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", - WT_DELAY(wt,0), (int)val); - */ + //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", WT_DELAY(wt,0), (int)val); hwwrite(vortex->mmio, WT_DELAY(wt, 3), val); hwwrite(vortex->mmio, WT_DELAY(wt, 2), val); hwwrite(vortex->mmio, WT_DELAY(wt, 1), val); @@ -293,9 +272,7 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, return 0; break; } - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", ecx, (int)val); - */ + //printk("vortex: WT SetReg(0x%x) = 0x%08x\n", ecx, (int)val); hwwrite(vortex->mmio, ecx, val); return 1; } diff --git a/trunk/sound/pci/aw2/aw2-alsa.c b/trunk/sound/pci/aw2/aw2-alsa.c index 8eea29fc42fe..c7c54e7748e9 100644 --- a/trunk/sound/pci/aw2/aw2-alsa.c +++ b/trunk/sound/pci/aw2/aw2-alsa.c @@ -368,9 +368,9 @@ static int __devinit snd_aw2_probe(struct pci_dev *pci, } /* (2) Create card instance */ - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; /* (3) Create main component */ err = snd_aw2_create(card, pci, &chip); diff --git a/trunk/sound/pci/azt3328.c b/trunk/sound/pci/azt3328.c index e9e9b5821d41..333007c523a1 100644 --- a/trunk/sound/pci/azt3328.c +++ b/trunk/sound/pci/azt3328.c @@ -211,25 +211,25 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}"); #endif #if DEBUG_MIXER -#define snd_azf3328_dbgmixer(format, args...) printk(KERN_DEBUG format, ##args) +#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args) #else #define snd_azf3328_dbgmixer(format, args...) #endif #if DEBUG_PLAY_REC -#define snd_azf3328_dbgplay(format, args...) printk(KERN_DEBUG format, ##args) +#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args) #else #define snd_azf3328_dbgplay(format, args...) #endif #if DEBUG_MISC -#define snd_azf3328_dbgtimer(format, args...) printk(KERN_DEBUG format, ##args) +#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args) #else #define snd_azf3328_dbgtimer(format, args...) #endif #if DEBUG_GAME -#define snd_azf3328_dbggame(format, args...) printk(KERN_DEBUG format, ##args) +#define snd_azf3328_dbggame(format, args...) printk(KERN_ERR format, ##args) #else #define snd_azf3328_dbggame(format, args...) #endif @@ -2216,9 +2216,9 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "AZF3328"); strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); diff --git a/trunk/sound/pci/bt87x.c b/trunk/sound/pci/bt87x.c index a299340519df..1aa1c0402540 100644 --- a/trunk/sound/pci/bt87x.c +++ b/trunk/sound/pci/bt87x.c @@ -888,9 +888,9 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (!card) + return -ENOMEM; err = snd_bt87x_create(card, pci, &chip); if (err < 0) diff --git a/trunk/sound/pci/ca0106/ca0106_main.c b/trunk/sound/pci/ca0106/ca0106_main.c index df757575798a..0e62205d4081 100644 --- a/trunk/sound/pci/ca0106/ca0106_main.c +++ b/trunk/sound/pci/ca0106/ca0106_main.c @@ -255,14 +255,6 @@ static struct snd_ca0106_details ca0106_chip_details[] = { .gpio_type = 2, .i2c_adc = 1, .spi_dac = 1 } , - /* Giga-byte GA-G1975X mobo - * Novell bnc#395807 - */ - /* FIXME: the GPIO and I2C setting aren't tested well */ - { .serial = 0x1458a006, - .name = "Giga-byte GA-G1975X", - .gpio_type = 1, - .i2c_adc = 1 }, /* Shuttle XPC SD31P which has an onboard Creative Labs * Sound Blaster Live! 24-bit EAX * high-definition 7.1 audio processor". @@ -412,9 +404,7 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, } tmp = reg << 25 | value << 16; - /* - snd_printk(KERN_DEBUG "I2C-write:reg=0x%x, value=0x%x\n", reg, value); - */ + // snd_printk("I2C-write:reg=0x%x, value=0x%x\n", reg, value); /* Not sure what this I2C channel controls. */ /* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */ @@ -432,7 +422,7 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, /* Wait till the transaction ends */ while (1) { status = snd_ca0106_ptr_read(emu, I2C_A, 0); - /*snd_printk(KERN_DEBUG "I2C:status=0x%x\n", status);*/ + //snd_printk("I2C:status=0x%x\n", status); timeout++; if ((status & I2C_A_ADC_START) == 0) break; @@ -531,10 +521,7 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr channel->number = channel_id; channel->use = 1; - /* - printk(KERN_DEBUG "open:channel_id=%d, chip=%p, channel=%p\n", - channel_id, chip, channel); - */ + //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); //channel->interrupt = snd_ca0106_pcm_channel_interrupt; channel->epcm = epcm; if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) @@ -627,10 +614,7 @@ static int snd_ca0106_pcm_open_capture_channel(struct snd_pcm_substream *substre channel->number = channel_id; channel->use = 1; - /* - printk(KERN_DEBUG "open:channel_id=%d, chip=%p, channel=%p\n", - channel_id, chip, channel); - */ + //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); //channel->interrupt = snd_ca0106_pcm_channel_interrupt; channel->epcm = epcm; if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) @@ -721,20 +705,9 @@ static int snd_ca0106_pcm_prepare_playback(struct snd_pcm_substream *substream) u32 reg71; int i; -#if 0 /* debug */ - snd_printk(KERN_DEBUG - "prepare:channel_number=%d, rate=%d, format=0x%x, " - "channels=%d, buffer_size=%ld, period_size=%ld, " - "periods=%u, frames_to_bytes=%d\n", - channel, runtime->rate, runtime->format, - runtime->channels, runtime->buffer_size, - runtime->period_size, runtime->periods, - frames_to_bytes(runtime, 1)); - snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, table_base=%p\n", - runtime->dma_addr, runtime->dma_area, table_base); - snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n", - emu->buffer.addr, emu->buffer.area, emu->buffer.bytes); -#endif /* debug */ + //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1)); + //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base); + //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes); /* Rate can be set per channel. */ /* reg40 control host to fifo */ /* reg71 controls DAC rate. */ @@ -826,20 +799,9 @@ static int snd_ca0106_pcm_prepare_capture(struct snd_pcm_substream *substream) u32 reg71_set = 0; u32 reg71; -#if 0 /* debug */ - snd_printk(KERN_DEBUG - "prepare:channel_number=%d, rate=%d, format=0x%x, " - "channels=%d, buffer_size=%ld, period_size=%ld, " - "periods=%u, frames_to_bytes=%d\n", - channel, runtime->rate, runtime->format, - runtime->channels, runtime->buffer_size, - runtime->period_size, runtime->periods, - frames_to_bytes(runtime, 1)); - snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, table_base=%p\n", - runtime->dma_addr, runtime->dma_area, table_base); - snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n", - emu->buffer.addr, emu->buffer.area, emu->buffer.bytes); -#endif /* debug */ + //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1)); + //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base); + //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes); /* reg71 controls ADC rate. */ switch (runtime->rate) { case 44100: @@ -884,14 +846,7 @@ static int snd_ca0106_pcm_prepare_capture(struct snd_pcm_substream *substream) } - /* - printk(KERN_DEBUG - "prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, " - "buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n", - channel, runtime->rate, runtime->format, runtime->channels, - runtime->buffer_size, runtime->period_size, - frames_to_bytes(runtime, 1)); - */ + //printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1)); snd_ca0106_ptr_write(emu, 0x13, channel, 0); snd_ca0106_ptr_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); snd_ca0106_ptr_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes @@ -933,13 +888,13 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, runtime = s->runtime; epcm = runtime->private_data; channel = epcm->channel_id; - /* snd_printk(KERN_DEBUG "channel=%d\n", channel); */ + /* snd_printk("channel=%d\n",channel); */ epcm->running = running; basic |= (0x1 << channel); extended |= (0x10 << channel); snd_pcm_trigger_done(s, substream); } - /* snd_printk(KERN_DEBUG "basic=0x%x, extended=0x%x\n",basic, extended); */ + /* snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); */ switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -1017,13 +972,8 @@ snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream) ptr=ptr2; if (ptr >= runtime->buffer_size) ptr -= runtime->buffer_size; - /* - printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, " - "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", - ptr1, ptr2, ptr, (int)runtime->buffer_size, - (int)runtime->period_size, (int)runtime->frame_bits, - (int)runtime->rate); - */ + //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate); + return ptr; } @@ -1045,13 +995,8 @@ snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream) ptr=ptr2; if (ptr >= runtime->buffer_size) ptr -= runtime->buffer_size; - /* - printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, " - "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", - ptr1, ptr2, ptr, (int)runtime->buffer_size, - (int)runtime->period_size, (int)runtime->frame_bits, - (int)runtime->rate); - */ + //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate); + return ptr; } @@ -1236,12 +1181,8 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id) return IRQ_NONE; stat76 = snd_ca0106_ptr_read(chip, EXTENDED_INT, 0); - /* - snd_printk(KERN_DEBUG "interrupt status = 0x%08x, stat76=0x%08x\n", - status, stat76); - snd_printk(KERN_DEBUG "ptr=0x%08x\n", - snd_ca0106_ptr_read(chip, PLAYBACK_POINTER, 0)); - */ + //snd_printk("interrupt status = 0x%08x, stat76=0x%08x\n", status, stat76); + //snd_printk("ptr=0x%08x\n",snd_ca0106_ptr_read(chip, PLAYBACK_POINTER, 0)); mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */ for(i = 0; i < 4; i++) { pchannel = &(chip->playback_channels[i]); @@ -1529,7 +1470,7 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume) int size, n; size = ARRAY_SIZE(i2c_adc_init); - /* snd_printk(KERN_DEBUG "I2C:array size=0x%x\n", size); */ + /* snd_printk("I2C:array size=0x%x\n", size); */ for (n = 0; n < size; n++) snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]); @@ -1766,9 +1707,9 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; err = snd_ca0106_create(dev, card, pci, &chip); if (err < 0) diff --git a/trunk/sound/pci/cmipci.c b/trunk/sound/pci/cmipci.c index c7899c32aba1..1a74ca62c314 100644 --- a/trunk/sound/pci/cmipci.c +++ b/trunk/sound/pci/cmipci.c @@ -3272,9 +3272,9 @@ static int __devinit snd_cmipci_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; switch (pci->device) { case PCI_DEVICE_ID_CMEDIA_CM8738: diff --git a/trunk/sound/pci/cs4281.c b/trunk/sound/pci/cs4281.c index f6286f84a221..192e7842e181 100644 --- a/trunk/sound/pci/cs4281.c +++ b/trunk/sound/pci/cs4281.c @@ -834,11 +834,7 @@ static snd_pcm_uframes_t snd_cs4281_pointer(struct snd_pcm_substream *substream) struct cs4281_dma *dma = runtime->private_data; struct cs4281 *chip = snd_pcm_substream_chip(substream); - /* - printk(KERN_DEBUG "DCC = 0x%x, buffer_size = 0x%x, jiffies = %li\n", - snd_cs4281_peekBA0(chip, dma->regDCC), runtime->buffer_size, - jiffies); - */ + // printk("DCC = 0x%x, buffer_size = 0x%x, jiffies = %li\n", snd_cs4281_peekBA0(chip, dma->regDCC), runtime->buffer_size, jiffies); return runtime->buffer_size - snd_cs4281_peekBA0(chip, dma->regDCC) - 1; } @@ -1929,9 +1925,9 @@ static int __devinit snd_cs4281_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_cs4281_create(card, pci, &chip, dual_codec[dev])) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/cs46xx/cs46xx.c b/trunk/sound/pci/cs46xx/cs46xx.c index c9b3e3d48cbc..e876b3263e46 100644 --- a/trunk/sound/pci/cs46xx/cs46xx.c +++ b/trunk/sound/pci/cs46xx/cs46xx.c @@ -88,9 +88,9 @@ static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_cs46xx_create(card, pci, external_amp[dev], thinkpad[dev], &chip)) < 0) { diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.c b/trunk/sound/pci/cs46xx/cs46xx_lib.c index 1be96ead4244..8ab07aa63652 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.c +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.c @@ -194,7 +194,7 @@ static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip, * ACSDA = Status Data Register = 474h */ #if 0 - printk(KERN_DEBUG "e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg, + printk("e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg, snd_cs46xx_peekBA0(chip, BA0_ACSDA), snd_cs46xx_peekBA0(chip, BA0_ACCAD)); #endif @@ -428,8 +428,8 @@ static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) } if(status & SERBST_WBSY) { - snd_printk(KERN_ERR "cs46xx: failure waiting for " - "FIFO command to complete\n"); + snd_printk( KERN_ERR "cs46xx: failure waiting for FIFO command to complete\n"); + return -EINVAL; } diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.h b/trunk/sound/pci/cs46xx/cs46xx_lib.h index 4eb55aa33612..018a7de56017 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.h +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.h @@ -62,11 +62,7 @@ static inline void snd_cs46xx_poke(struct snd_cs46xx *chip, unsigned long reg, u unsigned int bank = reg >> 16; unsigned int offset = reg & 0xffff; - /* - if (bank == 0) - printk(KERN_DEBUG "snd_cs46xx_poke: %04X - %08X\n", - reg >> 2,val); - */ + /*if (bank == 0) printk("snd_cs46xx_poke: %04X - %08X\n",reg >> 2,val); */ writel(val, chip->region.idx[bank+1].remap_addr + offset); } diff --git a/trunk/sound/pci/cs5530.c b/trunk/sound/pci/cs5530.c index dc464321d0f3..6dea5b5cc774 100644 --- a/trunk/sound/pci/cs5530.c +++ b/trunk/sound/pci/cs5530.c @@ -258,10 +258,10 @@ static int __devinit snd_cs5530_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (err < 0) - return err; + if (card == NULL) + return -ENOMEM; err = snd_cs5530_create(card, pci, &chip); if (err < 0) { diff --git a/trunk/sound/pci/cs5535audio/cs5535audio.c b/trunk/sound/pci/cs5535audio/cs5535audio.c index c89ed1f5bc2b..826e6dec2e97 100644 --- a/trunk/sound/pci/cs5535audio/cs5535audio.c +++ b/trunk/sound/pci/cs5535audio/cs5535audio.c @@ -312,7 +312,7 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card, if (request_irq(pci->irq, snd_cs5535audio_interrupt, IRQF_SHARED, "CS5535 Audio", cs5535au)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + snd_printk("unable to grab IRQ %d\n", pci->irq); err = -EBUSY; goto sndfail; } @@ -353,9 +353,9 @@ static int __devinit snd_cs5535audio_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0) goto probefail_out; diff --git a/trunk/sound/pci/echoaudio/echo3g_dsp.c b/trunk/sound/pci/echoaudio/echo3g_dsp.c index 57967e580571..417e25add82b 100644 --- a/trunk/sound/pci/echoaudio/echo3g_dsp.c +++ b/trunk/sound/pci/echoaudio/echo3g_dsp.c @@ -56,7 +56,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) } chip->comm_page->e3g_frq_register = - cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2); + __constant_cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2); chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; diff --git a/trunk/sound/pci/echoaudio/echoaudio.c b/trunk/sound/pci/echoaudio/echoaudio.c index 9d015a76eb69..4b70ea1e4c9f 100644 --- a/trunk/sound/pci/echoaudio/echoaudio.c +++ b/trunk/sound/pci/echoaudio/echoaudio.c @@ -950,6 +950,8 @@ static int __devinit snd_echo_new_pcm(struct echoaudio *chip) Control interface ******************************************************************************/ +#ifndef ECHOCARD_HAS_VMIXER + /******************* PCM output volume *******************/ static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -1001,18 +1003,6 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol, return changed; } -#ifdef ECHOCARD_HAS_VMIXER -/* On Vmixer cards this one controls the line-out volume */ -static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { - .name = "Line Playback Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = snd_echo_output_gain_info, - .get = snd_echo_output_gain_get, - .put = snd_echo_output_gain_put, - .tlv = {.p = db_scale_output_gain}, -}; -#else static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { .name = "PCM Playback Volume", .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1022,6 +1012,7 @@ static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { .put = snd_echo_output_gain_put, .tlv = {.p = db_scale_output_gain}, }; + #endif @@ -1997,9 +1988,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, DE_INIT(("Echoaudio driver starting...\n")); i = 0; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; snd_card_set_dev(card, &pci->dev); @@ -2037,8 +2028,6 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, #ifdef ECHOCARD_HAS_VMIXER snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_output_gain, chip))) < 0) - goto ctl_error; if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) goto ctl_error; #else diff --git a/trunk/sound/pci/echoaudio/echoaudio_3g.c b/trunk/sound/pci/echoaudio/echoaudio_3g.c index e32a74897921..c3736bbd819e 100644 --- a/trunk/sound/pci/echoaudio/echoaudio_3g.c +++ b/trunk/sound/pci/echoaudio/echoaudio_3g.c @@ -40,7 +40,8 @@ static int check_asic_status(struct echoaudio *chip) if (wait_handshake(chip)) return -EIO; - chip->comm_page->ext_box_status = cpu_to_le32(E3G_ASIC_NOT_LOADED); + chip->comm_page->ext_box_status = + __constant_cpu_to_le32(E3G_ASIC_NOT_LOADED); chip->asic_loaded = FALSE; clear_handshake(chip); send_vector(chip, DSP_VC_TEST_ASIC); diff --git a/trunk/sound/pci/echoaudio/echoaudio_dsp.c b/trunk/sound/pci/echoaudio/echoaudio_dsp.c index 4df51ef5e095..be0e18192de3 100644 --- a/trunk/sound/pci/echoaudio/echoaudio_dsp.c +++ b/trunk/sound/pci/echoaudio/echoaudio_dsp.c @@ -926,11 +926,11 @@ static int init_dsp_comm_page(struct echoaudio *chip) /* Init the comm page */ chip->comm_page->comm_size = - cpu_to_le32(sizeof(struct comm_page)); + __constant_cpu_to_le32(sizeof(struct comm_page)); chip->comm_page->handshake = 0xffffffff; chip->comm_page->midi_out_free_count = - cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); - chip->comm_page->sample_rate = cpu_to_le32(44100); + __constant_cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); + chip->comm_page->sample_rate = __constant_cpu_to_le32(44100); chip->sample_rate = 44100; /* Set line levels so we don't blast any inputs on startup */ diff --git a/trunk/sound/pci/echoaudio/gina20_dsp.c b/trunk/sound/pci/echoaudio/gina20_dsp.c index 3f1e7475faea..db6c952e9d7f 100644 --- a/trunk/sound/pci/echoaudio/gina20_dsp.c +++ b/trunk/sound/pci/echoaudio/gina20_dsp.c @@ -208,10 +208,10 @@ static int set_professional_spdif(struct echoaudio *chip, char prof) DE_ACT(("set_professional_spdif %d\n", prof)); if (prof) chip->comm_page->flags |= - cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); else chip->comm_page->flags &= - ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); chip->professional_spdif = prof; return update_flags(chip); } diff --git a/trunk/sound/pci/echoaudio/layla20_dsp.c b/trunk/sound/pci/echoaudio/layla20_dsp.c index 83750e9fd7b4..ede75c6ca0fb 100644 --- a/trunk/sound/pci/echoaudio/layla20_dsp.c +++ b/trunk/sound/pci/echoaudio/layla20_dsp.c @@ -284,10 +284,10 @@ static int set_professional_spdif(struct echoaudio *chip, char prof) DE_ACT(("set_professional_spdif %d\n", prof)); if (prof) chip->comm_page->flags |= - cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); else chip->comm_page->flags &= - ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); chip->professional_spdif = prof; return update_flags(chip); } diff --git a/trunk/sound/pci/echoaudio/mia_dsp.c b/trunk/sound/pci/echoaudio/mia_dsp.c index 3eca16cb7f71..227386602f9b 100644 --- a/trunk/sound/pci/echoaudio/mia_dsp.c +++ b/trunk/sound/pci/echoaudio/mia_dsp.c @@ -222,10 +222,10 @@ static int set_professional_spdif(struct echoaudio *chip, char prof) DE_ACT(("set_professional_spdif %d\n", prof)); if (prof) chip->comm_page->flags |= - cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); else chip->comm_page->flags &= - ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); chip->professional_spdif = prof; return update_flags(chip); } diff --git a/trunk/sound/pci/echoaudio/midi.c b/trunk/sound/pci/echoaudio/midi.c index a953d142cb4b..77bf2a83d997 100644 --- a/trunk/sound/pci/echoaudio/midi.c +++ b/trunk/sound/pci/echoaudio/midi.c @@ -44,10 +44,10 @@ static int enable_midi_input(struct echoaudio *chip, char enable) if (enable) { chip->mtc_state = MIDI_IN_STATE_NORMAL; chip->comm_page->flags |= - cpu_to_le32(DSP_FLAG_MIDI_INPUT); + __constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT); } else chip->comm_page->flags &= - ~cpu_to_le32(DSP_FLAG_MIDI_INPUT); + ~__constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT); clear_handshake(chip); return send_vector(chip, DSP_VC_UPDATE_FLAGS); diff --git a/trunk/sound/pci/emu10k1/emu10k1.c b/trunk/sound/pci/emu10k1/emu10k1.c index c7f3b994101c..8354c1a83312 100644 --- a/trunk/sound/pci/emu10k1/emu10k1.c +++ b/trunk/sound/pci/emu10k1/emu10k1.c @@ -114,9 +114,9 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if (max_buffer_size[dev] < 32) max_buffer_size[dev] = 32; else if (max_buffer_size[dev] > 1024) diff --git a/trunk/sound/pci/emu10k1/emu10k1x.c b/trunk/sound/pci/emu10k1/emu10k1x.c index 31542adc6b7e..5ff4dbb62dad 100644 --- a/trunk/sound/pci/emu10k1/emu10k1x.c +++ b/trunk/sound/pci/emu10k1/emu10k1x.c @@ -1544,9 +1544,9 @@ static int __devinit snd_emu10k1x_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index 18f4d1e98c46..9bf95367c882 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -584,8 +584,7 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531, unsigned long end_time = jiffies + HZ / 10; #if 0 - printk(KERN_DEBUG - "CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n", + printk("CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n", reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC)); #endif do { @@ -2410,9 +2409,9 @@ static int __devinit snd_audiopci_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_ensoniq_create(card, pci, &ensoniq)) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/es1938.c b/trunk/sound/pci/es1938.c index dd63b132fb8e..4cd9a1faaecc 100644 --- a/trunk/sound/pci/es1938.c +++ b/trunk/sound/pci/es1938.c @@ -1673,22 +1673,18 @@ static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id) status = inb(SLIO_REG(chip, IRQCONTROL)); #if 0 - printk(KERN_DEBUG "Es1938debug - interrupt status: =0x%x\n", status); + printk("Es1938debug - interrupt status: =0x%x\n", status); #endif /* AUDIO 1 */ if (status & 0x10) { #if 0 - printk(KERN_DEBUG - "Es1938debug - AUDIO channel 1 interrupt\n"); - printk(KERN_DEBUG - "Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n", + printk("Es1938debug - AUDIO channel 1 interrupt\n"); + printk("Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n", inw(SLDM_REG(chip, DMACOUNT))); - printk(KERN_DEBUG - "Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n", + printk("Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n", inl(SLDM_REG(chip, DMAADDR))); - printk(KERN_DEBUG - "Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n", + printk("Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n", inl(SLDM_REG(chip, DMASTATUS))); #endif /* clear irq */ @@ -1703,13 +1699,10 @@ static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id) /* AUDIO 2 */ if (status & 0x20) { #if 0 - printk(KERN_DEBUG - "Es1938debug - AUDIO channel 2 interrupt\n"); - printk(KERN_DEBUG - "Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n", + printk("Es1938debug - AUDIO channel 2 interrupt\n"); + printk("Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n", inw(SLIO_REG(chip, AUDIO2DMACOUNT))); - printk(KERN_DEBUG - "Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n", + printk("Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n", inl(SLIO_REG(chip, AUDIO2DMAADDR))); #endif @@ -1806,9 +1799,9 @@ static int __devinit snd_es1938_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; for (idx = 0; idx < 5; idx++) { if (pci_resource_start(pci, idx) == 0 || !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) { diff --git a/trunk/sound/pci/es1968.c b/trunk/sound/pci/es1968.c index dc97e8116141..e9c3794bbcb8 100644 --- a/trunk/sound/pci/es1968.c +++ b/trunk/sound/pci/es1968.c @@ -2645,9 +2645,9 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (!card) + return -ENOMEM; if (total_bufsize[dev] < 128) total_bufsize[dev] = 128; diff --git a/trunk/sound/pci/fm801.c b/trunk/sound/pci/fm801.c index 60cdb9e0b68d..c129f9e2072c 100644 --- a/trunk/sound/pci/fm801.c +++ b/trunk/sound/pci/fm801.c @@ -1468,9 +1468,9 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) { snd_card_free(card); return err; diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 3683978324e8..5e909e0da04b 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -2059,31 +2059,26 @@ static int __devinit check_position_fix(struct azx *chip, int fix) { const struct snd_pci_quirk *q; - switch (fix) { - case POS_FIX_LPIB: - case POS_FIX_POSBUF: - return fix; - } - - /* Check VIA/ATI HD Audio Controller exist */ - switch (chip->driver_type) { - case AZX_DRIVER_VIA: - case AZX_DRIVER_ATI: + /* Check VIA HD Audio Controller exist */ + if (chip->pci->vendor == PCI_VENDOR_ID_VIA && + chip->pci->device == VIA_HDAC_DEVICE_ID) { chip->via_dmapos_patch = 1; /* Use link position directly, avoid any transfer problem. */ return POS_FIX_LPIB; } chip->via_dmapos_patch = 0; - q = snd_pci_quirk_lookup(chip->pci, position_fix_list); - if (q) { - printk(KERN_INFO - "hda_intel: position_fix set to %d " - "for device %04x:%04x\n", - q->value, q->subvendor, q->subdevice); - return q->value; + if (fix == POS_FIX_AUTO) { + q = snd_pci_quirk_lookup(chip->pci, position_fix_list); + if (q) { + printk(KERN_INFO + "hda_intel: position_fix set to %d " + "for device %04x:%04x\n", + q->value, q->subvendor, q->subdevice); + return q->value; + } } - return POS_FIX_AUTO; + return fix; } /* @@ -2215,17 +2210,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, gcap = azx_readw(chip, GCAP); snd_printdd("chipset global capabilities = 0x%x\n", gcap); - /* ATI chips seems buggy about 64bit DMA addresses */ - if (chip->driver_type == AZX_DRIVER_ATI) - gcap &= ~0x01; - /* allow 64bit DMA address if supported by H/W */ if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK)) pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK); - else { - pci_set_dma_mask(pci, DMA_32BIT_MASK); - pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK); - } /* read number of streams from GCAP register instead of using * hardcoded value @@ -2347,10 +2334,10 @@ static int __devinit azx_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) { + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (!card) { snd_printk(KERN_ERR SFX "Error creating card!\n"); - return err; + return -ENOMEM; } err = azx_create(card, pci, dev, pci_id->driver_data, &chip); diff --git a/trunk/sound/pci/ice1712/ice1712.c b/trunk/sound/pci/ice1712/ice1712.c index bab1c700f497..58d7cda03de5 100644 --- a/trunk/sound/pci/ice1712/ice1712.c +++ b/trunk/sound/pci/ice1712/ice1712.c @@ -2648,9 +2648,9 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "ICE1712"); strcpy(card->shortname, "ICEnsemble ICE1712"); diff --git a/trunk/sound/pci/ice1712/ice1724.c b/trunk/sound/pci/ice1712/ice1724.c index 7ff36d3f0f44..bb8d8c766b9d 100644 --- a/trunk/sound/pci/ice1712/ice1724.c +++ b/trunk/sound/pci/ice1712/ice1724.c @@ -2456,9 +2456,9 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "ICE1724"); strcpy(card->shortname, "ICEnsemble ICE1724"); diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index 608655e9275e..e900cdc84849 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -3058,9 +3058,9 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, int err; struct shortname_table *name; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if (spdif_aclink < 0) spdif_aclink = check_default_spdif_aclink(pci); diff --git a/trunk/sound/pci/intel8x0m.c b/trunk/sound/pci/intel8x0m.c index 33a843c19316..93449e464566 100644 --- a/trunk/sound/pci/intel8x0m.c +++ b/trunk/sound/pci/intel8x0m.c @@ -1269,9 +1269,9 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci, int err; struct shortname_table *name; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "ICH-MODEM"); strcpy(card->shortname, "Intel ICH"); diff --git a/trunk/sound/pci/korg1212/korg1212.c b/trunk/sound/pci/korg1212/korg1212.c index 8b79969034be..5f8006b42750 100644 --- a/trunk/sound/pci/korg1212/korg1212.c +++ b/trunk/sound/pci/korg1212/korg1212.c @@ -2443,9 +2443,9 @@ snd_korg1212_probe(struct pci_dev *pci, dev++; return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/maestro3.c b/trunk/sound/pci/maestro3.c index 70141548f251..59bbaf8f3e5b 100644 --- a/trunk/sound/pci/maestro3.c +++ b/trunk/sound/pci/maestro3.c @@ -2691,9 +2691,9 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; switch (pci->device) { case PCI_DEVICE_ID_ESS_ALLEGRO: diff --git a/trunk/sound/pci/mixart/mixart.c b/trunk/sound/pci/mixart/mixart.c index c1eb84a14c42..f23a73577c22 100644 --- a/trunk/sound/pci/mixart/mixart.c +++ b/trunk/sound/pci/mixart/mixart.c @@ -607,7 +607,6 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs, /* set the format to the board */ err = mixart_set_format(stream, format); if(err < 0) { - mutex_unlock(&mgr->setup_mutex); return err; } @@ -1366,12 +1365,12 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, else idx = index[dev] + i; snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i); - err = snd_card_create(idx, tmpid, THIS_MODULE, 0, &card); + card = snd_card_new(idx, tmpid, THIS_MODULE, 0); - if (err < 0) { + if (! card) { snd_printk(KERN_ERR "cannot allocate the card %d\n", i); snd_mixart_free(mgr); - return err; + return -ENOMEM; } strcpy(card->driver, CARD_NAME); diff --git a/trunk/sound/pci/mixart/mixart_hwdep.c b/trunk/sound/pci/mixart/mixart_hwdep.c index 4cf4cd8c939c..3782b52bc0e8 100644 --- a/trunk/sound/pci/mixart/mixart_hwdep.c +++ b/trunk/sound/pci/mixart/mixart_hwdep.c @@ -345,8 +345,8 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw status_daught = readl_be( MIXART_MEM( mgr,MIXART_PSEUDOREG_DXLX_STATUS_OFFSET )); /* motherboard xilinx status 5 will say that the board is performing a reset */ - if (status_xilinx == 5) { - snd_printk(KERN_ERR "miXart is resetting !\n"); + if( status_xilinx == 5 ) { + snd_printk( KERN_ERR "miXart is resetting !\n"); return -EAGAIN; /* try again later */ } @@ -354,14 +354,13 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw case MIXART_MOTHERBOARD_XLX_INDEX: /* xilinx already loaded ? */ - if (status_xilinx == 4) { - snd_printk(KERN_DEBUG "xilinx is already loaded !\n"); + if( status_xilinx == 4 ) { + snd_printk( KERN_DEBUG "xilinx is already loaded !\n"); return 0; } /* the status should be 0 == "idle" */ - if (status_xilinx != 0) { - snd_printk(KERN_ERR "xilinx load error ! status = %d\n", - status_xilinx); + if( status_xilinx != 0 ) { + snd_printk( KERN_ERR "xilinx load error ! status = %d\n", status_xilinx); return -EIO; /* modprob -r may help ? */ } @@ -390,23 +389,21 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw case MIXART_MOTHERBOARD_ELF_INDEX: - if (status_elf == 4) { - snd_printk(KERN_DEBUG "elf file already loaded !\n"); + if( status_elf == 4 ) { + snd_printk( KERN_DEBUG "elf file already loaded !\n"); return 0; } /* the status should be 0 == "idle" */ - if (status_elf != 0) { - snd_printk(KERN_ERR "elf load error ! status = %d\n", - status_elf); + if( status_elf != 0 ) { + snd_printk( KERN_ERR "elf load error ! status = %d\n", status_elf); return -EIO; /* modprob -r may help ? */ } /* wait for xilinx status == 4 */ err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET, 1, 4, 500); /* 5sec */ if (err < 0) { - snd_printk(KERN_ERR "xilinx was not loaded or " - "could not be started\n"); + snd_printk( KERN_ERR "xilinx was not loaded or could not be started\n"); return err; } @@ -427,7 +424,7 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw /* wait for elf status == 4 */ err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET, 1, 4, 300); /* 3sec */ if (err < 0) { - snd_printk(KERN_ERR "elf could not be started\n"); + snd_printk( KERN_ERR "elf could not be started\n"); return err; } @@ -440,16 +437,15 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw default: /* elf and xilinx should be loaded */ - if (status_elf != 4 || status_xilinx != 4) { - printk(KERN_ERR "xilinx or elf not " - "successfully loaded\n"); + if( (status_elf != 4) || (status_xilinx != 4) ) { + printk( KERN_ERR "xilinx or elf not successfully loaded\n"); return -EIO; /* modprob -r may help ? */ } /* wait for daughter detection != 0 */ err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DBRD_PRESENCE_OFFSET, 0, 0, 30); /* 300msec */ if (err < 0) { - snd_printk(KERN_ERR "error starting elf file\n"); + snd_printk( KERN_ERR "error starting elf file\n"); return err; } @@ -464,9 +460,8 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw return -EINVAL; /* daughter should be idle */ - if (status_daught != 0) { - printk(KERN_ERR "daughter load error ! status = %d\n", - status_daught); + if( status_daught != 0 ) { + printk( KERN_ERR "daughter load error ! status = %d\n", status_daught); return -EIO; /* modprob -r may help ? */ } @@ -485,7 +480,7 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw /* wait for status == 2 */ err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET, 1, 2, 30); /* 300msec */ if (err < 0) { - snd_printk(KERN_ERR "daughter board load error\n"); + snd_printk( KERN_ERR "daughter board load error\n"); return err; } @@ -507,8 +502,7 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw /* wait for daughter status == 3 */ err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET, 1, 3, 300); /* 3sec */ if (err < 0) { - snd_printk(KERN_ERR - "daughter board could not be initialised\n"); + snd_printk( KERN_ERR "daughter board could not be initialised\n"); return err; } @@ -518,7 +512,7 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw /* first communication with embedded */ err = mixart_first_init(mgr); if (err < 0) { - snd_printk(KERN_ERR "miXart could not be set up\n"); + snd_printk( KERN_ERR "miXart could not be set up\n"); return err; } @@ -587,6 +581,16 @@ MODULE_FIRMWARE("mixart/miXart8AES.xlx"); /* miXart hwdep interface id string */ #define SND_MIXART_HWDEP_ID "miXart Loader" +static int mixart_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + +static int mixart_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + static int mixart_hwdep_dsp_status(struct snd_hwdep *hw, struct snd_hwdep_dsp_status *info) { @@ -639,6 +643,8 @@ int snd_mixart_setup_firmware(struct mixart_mgr *mgr) hw->iface = SNDRV_HWDEP_IFACE_MIXART; hw->private_data = mgr; + hw->ops.open = mixart_hwdep_open; + hw->ops.release = mixart_hwdep_release; hw->ops.dsp_status = mixart_hwdep_dsp_status; hw->ops.dsp_load = mixart_hwdep_dsp_load; hw->exclusive = 1; diff --git a/trunk/sound/pci/nm256/nm256.c b/trunk/sound/pci/nm256/nm256.c index 522a040855d4..50c9f8a05082 100644 --- a/trunk/sound/pci/nm256/nm256.c +++ b/trunk/sound/pci/nm256/nm256.c @@ -1668,9 +1668,9 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, } } - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; switch (pci->device) { case PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO: diff --git a/trunk/sound/pci/oxygen/oxygen_lib.c b/trunk/sound/pci/oxygen/oxygen_lib.c index 9c81e0b05113..84f481d41efa 100644 --- a/trunk/sound/pci/oxygen/oxygen_lib.c +++ b/trunk/sound/pci/oxygen/oxygen_lib.c @@ -459,10 +459,10 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, struct oxygen *chip; int err; - err = snd_card_create(index, id, model->owner, - sizeof(*chip) + model->model_data_size, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, model->owner, + sizeof *chip + model->model_data_size); + if (!card) + return -ENOMEM; chip = card->private_data; chip->card = card; diff --git a/trunk/sound/pci/pcxhr/pcxhr.c b/trunk/sound/pci/pcxhr/pcxhr.c index 7f95459c8b1f..27cf2c28d113 100644 --- a/trunk/sound/pci/pcxhr/pcxhr.c +++ b/trunk/sound/pci/pcxhr/pcxhr.c @@ -1510,12 +1510,12 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : card_name, i); - err = snd_card_create(idx, tmpid, THIS_MODULE, 0, &card); + card = snd_card_new(idx, tmpid, THIS_MODULE, 0); - if (err < 0) { + if (! card) { snd_printk(KERN_ERR "cannot allocate the card %d\n", i); pcxhr_free(mgr); - return err; + return -ENOMEM; } strcpy(card->driver, DRIVER_NAME); diff --git a/trunk/sound/pci/pcxhr/pcxhr_hwdep.c b/trunk/sound/pci/pcxhr/pcxhr_hwdep.c index 17cb1233a903..592743a298b0 100644 --- a/trunk/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/trunk/sound/pci/pcxhr/pcxhr_hwdep.c @@ -471,6 +471,16 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw, return 0; } +static int pcxhr_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + +static int pcxhr_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) { int err; @@ -485,6 +495,8 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) hw->iface = SNDRV_HWDEP_IFACE_PCXHR; hw->private_data = mgr; + hw->ops.open = pcxhr_hwdep_open; + hw->ops.release = pcxhr_hwdep_release; hw->ops.dsp_status = pcxhr_hwdep_dsp_status; hw->ops.dsp_load = pcxhr_hwdep_dsp_load; hw->exclusive = 1; diff --git a/trunk/sound/pci/riptide/riptide.c b/trunk/sound/pci/riptide/riptide.c index 6f1034417a02..3caacfb9d8e0 100644 --- a/trunk/sound/pci/riptide/riptide.c +++ b/trunk/sound/pci/riptide/riptide.c @@ -2102,9 +2102,9 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_riptide_create(card, pci, &chip)) < 0) { snd_card_free(card); return err; diff --git a/trunk/sound/pci/rme32.c b/trunk/sound/pci/rme32.c index d7b966e7c4cf..e7ef3a1a25a8 100644 --- a/trunk/sound/pci/rme32.c +++ b/trunk/sound/pci/rme32.c @@ -1941,10 +1941,9 @@ snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct rme32), &card); - if (err < 0) - return err; + if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct rme32))) == NULL) + return -ENOMEM; card->private_free = snd_rme32_card_free; rme32 = (struct rme32 *) card->private_data; rme32->card = card; diff --git a/trunk/sound/pci/rme96.c b/trunk/sound/pci/rme96.c index 55fb1c131f58..3fdd488d0975 100644 --- a/trunk/sound/pci/rme96.c +++ b/trunk/sound/pci/rme96.c @@ -2348,10 +2348,9 @@ snd_rme96_probe(struct pci_dev *pci, dev++; return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct rme96), &card); - if (err < 0) - return err; + if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct rme96))) == NULL) + return -ENOMEM; card->private_free = snd_rme96_card_free; rme96 = (struct rme96 *)card->private_data; rme96->card = card; diff --git a/trunk/sound/pci/rme9652/hdsp.c b/trunk/sound/pci/rme9652/hdsp.c index bacfdd12619b..44d0c15e2b71 100644 --- a/trunk/sound/pci/rme9652/hdsp.c +++ b/trunk/sound/pci/rme9652/hdsp.c @@ -4413,6 +4413,13 @@ static int snd_hdsp_capture_release(struct snd_pcm_substream *substream) return 0; } +static int snd_hdsp_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file) +{ + /* we have nothing to initialize but the call is required */ + return 0; +} + + /* helper functions for copying meter values */ static inline int copy_u32_le(void __user *dest, void __iomem *src) { @@ -4731,7 +4738,9 @@ static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp) hw->private_data = hdsp; strcpy(hw->name, "HDSP hwdep interface"); + hw->ops.open = snd_hdsp_hwdep_dummy_op; hw->ops.ioctl = snd_hdsp_hwdep_ioctl; + hw->ops.release = snd_hdsp_hwdep_dummy_op; return 0; } @@ -5149,10 +5158,8 @@ static int __devinit snd_hdsp_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct hdsp), &card); - if (err < 0) - return err; + if (!(card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct hdsp)))) + return -ENOMEM; hdsp = (struct hdsp *) card->private_data; card->private_free = snd_hdsp_card_free; diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index bac2dc0c5d85..71231cf1b2b0 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -4100,6 +4100,13 @@ static int snd_hdspm_capture_release(struct snd_pcm_substream *substream) return 0; } +static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep * hw, struct file *file) +{ + /* we have nothing to initialize but the call is required */ + return 0; +} + + static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg) { @@ -4206,7 +4213,9 @@ static int __devinit snd_hdspm_create_hwdep(struct snd_card *card, hw->private_data = hdspm; strcpy(hw->name, "HDSPM hwdep interface"); + hw->ops.open = snd_hdspm_hwdep_dummy_op; hw->ops.ioctl = snd_hdspm_hwdep_ioctl; + hw->ops.release = snd_hdspm_hwdep_dummy_op; return 0; } @@ -4494,10 +4503,10 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], - THIS_MODULE, sizeof(struct hdspm), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], + THIS_MODULE, sizeof(struct hdspm)); + if (!card) + return -ENOMEM; hdspm = card->private_data; card->private_free = snd_hdspm_card_free; diff --git a/trunk/sound/pci/rme9652/rme9652.c b/trunk/sound/pci/rme9652/rme9652.c index bc539abb2105..2570907134d7 100644 --- a/trunk/sound/pci/rme9652/rme9652.c +++ b/trunk/sound/pci/rme9652/rme9652.c @@ -2594,11 +2594,11 @@ static int __devinit snd_rme9652_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_rme9652), &card); + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_rme9652)); - if (err < 0) - return err; + if (!card) + return -ENOMEM; rme9652 = (struct snd_rme9652 *) card->private_data; card->private_free = snd_rme9652_card_free; diff --git a/trunk/sound/pci/sis7019.c b/trunk/sound/pci/sis7019.c index baf6d8e3dabc..df2007e3be7c 100644 --- a/trunk/sound/pci/sis7019.c +++ b/trunk/sound/pci/sis7019.c @@ -1387,8 +1387,9 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, if (!enable) goto error_out; - rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); - if (rc < 0) + rc = -ENOMEM; + card = snd_card_new(index, id, THIS_MODULE, sizeof(*sis)); + if (!card) goto error_out; strcpy(card->driver, "SiS7019"); diff --git a/trunk/sound/pci/sonicvibes.c b/trunk/sound/pci/sonicvibes.c index d989215f3556..cd408b86c839 100644 --- a/trunk/sound/pci/sonicvibes.c +++ b/trunk/sound/pci/sonicvibes.c @@ -273,8 +273,7 @@ static inline void snd_sonicvibes_setdmaa(struct sonicvibes * sonic, outl(count, sonic->dmaa_port + SV_DMA_COUNT0); outb(0x18, sonic->dmaa_port + SV_DMA_MODE); #if 0 - printk(KERN_DEBUG "program dmaa: addr = 0x%x, paddr = 0x%x\n", - addr, inl(sonic->dmaa_port + SV_DMA_ADDR0)); + printk("program dmaa: addr = 0x%x, paddr = 0x%x\n", addr, inl(sonic->dmaa_port + SV_DMA_ADDR0)); #endif } @@ -289,8 +288,7 @@ static inline void snd_sonicvibes_setdmac(struct sonicvibes * sonic, outl(count, sonic->dmac_port + SV_DMA_COUNT0); outb(0x14, sonic->dmac_port + SV_DMA_MODE); #if 0 - printk(KERN_DEBUG "program dmac: addr = 0x%x, paddr = 0x%x\n", - addr, inl(sonic->dmac_port + SV_DMA_ADDR0)); + printk("program dmac: addr = 0x%x, paddr = 0x%x\n", addr, inl(sonic->dmac_port + SV_DMA_ADDR0)); #endif } @@ -357,104 +355,71 @@ static unsigned char snd_sonicvibes_in(struct sonicvibes * sonic, unsigned char #if 0 static void snd_sonicvibes_debug(struct sonicvibes * sonic) { - printk(KERN_DEBUG - "SV REGS: INDEX = 0x%02x ", inb(SV_REG(sonic, INDEX))); + printk("SV REGS: INDEX = 0x%02x ", inb(SV_REG(sonic, INDEX))); printk(" STATUS = 0x%02x\n", inb(SV_REG(sonic, STATUS))); - printk(KERN_DEBUG - " 0x00: left input = 0x%02x ", snd_sonicvibes_in(sonic, 0x00)); + printk(" 0x00: left input = 0x%02x ", snd_sonicvibes_in(sonic, 0x00)); printk(" 0x20: synth rate low = 0x%02x\n", snd_sonicvibes_in(sonic, 0x20)); - printk(KERN_DEBUG - " 0x01: right input = 0x%02x ", snd_sonicvibes_in(sonic, 0x01)); + printk(" 0x01: right input = 0x%02x ", snd_sonicvibes_in(sonic, 0x01)); printk(" 0x21: synth rate high = 0x%02x\n", snd_sonicvibes_in(sonic, 0x21)); - printk(KERN_DEBUG - " 0x02: left AUX1 = 0x%02x ", snd_sonicvibes_in(sonic, 0x02)); + printk(" 0x02: left AUX1 = 0x%02x ", snd_sonicvibes_in(sonic, 0x02)); printk(" 0x22: ADC clock = 0x%02x\n", snd_sonicvibes_in(sonic, 0x22)); - printk(KERN_DEBUG - " 0x03: right AUX1 = 0x%02x ", snd_sonicvibes_in(sonic, 0x03)); + printk(" 0x03: right AUX1 = 0x%02x ", snd_sonicvibes_in(sonic, 0x03)); printk(" 0x23: ADC alt rate = 0x%02x\n", snd_sonicvibes_in(sonic, 0x23)); - printk(KERN_DEBUG - " 0x04: left CD = 0x%02x ", snd_sonicvibes_in(sonic, 0x04)); + printk(" 0x04: left CD = 0x%02x ", snd_sonicvibes_in(sonic, 0x04)); printk(" 0x24: ADC pll M = 0x%02x\n", snd_sonicvibes_in(sonic, 0x24)); - printk(KERN_DEBUG - " 0x05: right CD = 0x%02x ", snd_sonicvibes_in(sonic, 0x05)); + printk(" 0x05: right CD = 0x%02x ", snd_sonicvibes_in(sonic, 0x05)); printk(" 0x25: ADC pll N = 0x%02x\n", snd_sonicvibes_in(sonic, 0x25)); - printk(KERN_DEBUG - " 0x06: left line = 0x%02x ", snd_sonicvibes_in(sonic, 0x06)); + printk(" 0x06: left line = 0x%02x ", snd_sonicvibes_in(sonic, 0x06)); printk(" 0x26: Synth pll M = 0x%02x\n", snd_sonicvibes_in(sonic, 0x26)); - printk(KERN_DEBUG - " 0x07: right line = 0x%02x ", snd_sonicvibes_in(sonic, 0x07)); + printk(" 0x07: right line = 0x%02x ", snd_sonicvibes_in(sonic, 0x07)); printk(" 0x27: Synth pll N = 0x%02x\n", snd_sonicvibes_in(sonic, 0x27)); - printk(KERN_DEBUG - " 0x08: MIC = 0x%02x ", snd_sonicvibes_in(sonic, 0x08)); + printk(" 0x08: MIC = 0x%02x ", snd_sonicvibes_in(sonic, 0x08)); printk(" 0x28: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x28)); - printk(KERN_DEBUG - " 0x09: Game port = 0x%02x ", snd_sonicvibes_in(sonic, 0x09)); + printk(" 0x09: Game port = 0x%02x ", snd_sonicvibes_in(sonic, 0x09)); printk(" 0x29: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x29)); - printk(KERN_DEBUG - " 0x0a: left synth = 0x%02x ", snd_sonicvibes_in(sonic, 0x0a)); + printk(" 0x0a: left synth = 0x%02x ", snd_sonicvibes_in(sonic, 0x0a)); printk(" 0x2a: MPU401 = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2a)); - printk(KERN_DEBUG - " 0x0b: right synth = 0x%02x ", snd_sonicvibes_in(sonic, 0x0b)); + printk(" 0x0b: right synth = 0x%02x ", snd_sonicvibes_in(sonic, 0x0b)); printk(" 0x2b: drive ctrl = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2b)); - printk(KERN_DEBUG - " 0x0c: left AUX2 = 0x%02x ", snd_sonicvibes_in(sonic, 0x0c)); + printk(" 0x0c: left AUX2 = 0x%02x ", snd_sonicvibes_in(sonic, 0x0c)); printk(" 0x2c: SRS space = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2c)); - printk(KERN_DEBUG - " 0x0d: right AUX2 = 0x%02x ", snd_sonicvibes_in(sonic, 0x0d)); + printk(" 0x0d: right AUX2 = 0x%02x ", snd_sonicvibes_in(sonic, 0x0d)); printk(" 0x2d: SRS center = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2d)); - printk(KERN_DEBUG - " 0x0e: left analog = 0x%02x ", snd_sonicvibes_in(sonic, 0x0e)); + printk(" 0x0e: left analog = 0x%02x ", snd_sonicvibes_in(sonic, 0x0e)); printk(" 0x2e: wave source = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2e)); - printk(KERN_DEBUG - " 0x0f: right analog = 0x%02x ", snd_sonicvibes_in(sonic, 0x0f)); + printk(" 0x0f: right analog = 0x%02x ", snd_sonicvibes_in(sonic, 0x0f)); printk(" 0x2f: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2f)); - printk(KERN_DEBUG - " 0x10: left PCM = 0x%02x ", snd_sonicvibes_in(sonic, 0x10)); + printk(" 0x10: left PCM = 0x%02x ", snd_sonicvibes_in(sonic, 0x10)); printk(" 0x30: analog power = 0x%02x\n", snd_sonicvibes_in(sonic, 0x30)); - printk(KERN_DEBUG - " 0x11: right PCM = 0x%02x ", snd_sonicvibes_in(sonic, 0x11)); + printk(" 0x11: right PCM = 0x%02x ", snd_sonicvibes_in(sonic, 0x11)); printk(" 0x31: analog power = 0x%02x\n", snd_sonicvibes_in(sonic, 0x31)); - printk(KERN_DEBUG - " 0x12: DMA data format = 0x%02x ", snd_sonicvibes_in(sonic, 0x12)); + printk(" 0x12: DMA data format = 0x%02x ", snd_sonicvibes_in(sonic, 0x12)); printk(" 0x32: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x32)); - printk(KERN_DEBUG - " 0x13: P/C enable = 0x%02x ", snd_sonicvibes_in(sonic, 0x13)); + printk(" 0x13: P/C enable = 0x%02x ", snd_sonicvibes_in(sonic, 0x13)); printk(" 0x33: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x33)); - printk(KERN_DEBUG - " 0x14: U/D button = 0x%02x ", snd_sonicvibes_in(sonic, 0x14)); + printk(" 0x14: U/D button = 0x%02x ", snd_sonicvibes_in(sonic, 0x14)); printk(" 0x34: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x34)); - printk(KERN_DEBUG - " 0x15: revision = 0x%02x ", snd_sonicvibes_in(sonic, 0x15)); + printk(" 0x15: revision = 0x%02x ", snd_sonicvibes_in(sonic, 0x15)); printk(" 0x35: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x35)); - printk(KERN_DEBUG - " 0x16: ADC output ctrl = 0x%02x ", snd_sonicvibes_in(sonic, 0x16)); + printk(" 0x16: ADC output ctrl = 0x%02x ", snd_sonicvibes_in(sonic, 0x16)); printk(" 0x36: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x36)); - printk(KERN_DEBUG - " 0x17: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x17)); + printk(" 0x17: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x17)); printk(" 0x37: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x37)); - printk(KERN_DEBUG - " 0x18: DMA A upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x18)); + printk(" 0x18: DMA A upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x18)); printk(" 0x38: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x38)); - printk(KERN_DEBUG - " 0x19: DMA A lower cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x19)); + printk(" 0x19: DMA A lower cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x19)); printk(" 0x39: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x39)); - printk(KERN_DEBUG - " 0x1a: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x1a)); + printk(" 0x1a: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x1a)); printk(" 0x3a: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3a)); - printk(KERN_DEBUG - " 0x1b: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x1b)); + printk(" 0x1b: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x1b)); printk(" 0x3b: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3b)); - printk(KERN_DEBUG - " 0x1c: DMA C upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x1c)); + printk(" 0x1c: DMA C upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x1c)); printk(" 0x3c: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3c)); - printk(KERN_DEBUG - " 0x1d: DMA C upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x1d)); + printk(" 0x1d: DMA C upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x1d)); printk(" 0x3d: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3d)); - printk(KERN_DEBUG - " 0x1e: PCM rate low = 0x%02x ", snd_sonicvibes_in(sonic, 0x1e)); + printk(" 0x1e: PCM rate low = 0x%02x ", snd_sonicvibes_in(sonic, 0x1e)); printk(" 0x3e: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3e)); - printk(KERN_DEBUG - " 0x1f: PCM rate high = 0x%02x ", snd_sonicvibes_in(sonic, 0x1f)); + printk(" 0x1f: PCM rate high = 0x%02x ", snd_sonicvibes_in(sonic, 0x1f)); printk(" 0x3f: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3f)); } @@ -511,8 +476,8 @@ static void snd_sonicvibes_pll(unsigned int rate, *res_m = m; *res_n = n; #if 0 - printk(KERN_DEBUG "metric = %i, xm = %i, xn = %i\n", metric, xm, xn); - printk(KERN_DEBUG "pll: m = 0x%x, r = 0x%x, n = 0x%x\n", reg, m, r, n); + printk("metric = %i, xm = %i, xn = %i\n", metric, xm, xn); + printk("pll: m = 0x%x, r = 0x%x, n = 0x%x\n", reg, m, r, n); #endif } @@ -1458,9 +1423,9 @@ static int __devinit snd_sonic_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; for (idx = 0; idx < 5; idx++) { if (pci_resource_start(pci, idx) == 0 || !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) { diff --git a/trunk/sound/pci/trident/trident.c b/trunk/sound/pci/trident/trident.c index 21cef97d478d..d94b16ffb385 100644 --- a/trunk/sound/pci/trident/trident.c +++ b/trunk/sound/pci/trident/trident.c @@ -89,9 +89,9 @@ static int __devinit snd_trident_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_trident_create(card, pci, pcm_channels[dev], diff --git a/trunk/sound/pci/trident/trident_main.c b/trunk/sound/pci/trident/trident_main.c index a9da9c184660..c612b435ca2b 100644 --- a/trunk/sound/pci/trident/trident_main.c +++ b/trunk/sound/pci/trident/trident_main.c @@ -68,40 +68,40 @@ static void snd_trident_print_voice_regs(struct snd_trident *trident, int voice) { unsigned int val, tmp; - printk(KERN_DEBUG "Trident voice %i:\n", voice); + printk("Trident voice %i:\n", voice); outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR)); val = inl(TRID_REG(trident, CH_LBA)); - printk(KERN_DEBUG "LBA: 0x%x\n", val); + printk("LBA: 0x%x\n", val); val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC)); - printk(KERN_DEBUG "GVSel: %i\n", val >> 31); - printk(KERN_DEBUG "Pan: 0x%x\n", (val >> 24) & 0x7f); - printk(KERN_DEBUG "Vol: 0x%x\n", (val >> 16) & 0xff); - printk(KERN_DEBUG "CTRL: 0x%x\n", (val >> 12) & 0x0f); - printk(KERN_DEBUG "EC: 0x%x\n", val & 0x0fff); + printk("GVSel: %i\n", val >> 31); + printk("Pan: 0x%x\n", (val >> 24) & 0x7f); + printk("Vol: 0x%x\n", (val >> 16) & 0xff); + printk("CTRL: 0x%x\n", (val >> 12) & 0x0f); + printk("EC: 0x%x\n", val & 0x0fff); if (trident->device != TRIDENT_DEVICE_ID_NX) { val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS)); - printk(KERN_DEBUG "CSO: 0x%x\n", val >> 16); + printk("CSO: 0x%x\n", val >> 16); printk("Alpha: 0x%x\n", (val >> 4) & 0x0fff); - printk(KERN_DEBUG "FMS: 0x%x\n", val & 0x0f); + printk("FMS: 0x%x\n", val & 0x0f); val = inl(TRID_REG(trident, CH_DX_ESO_DELTA)); - printk(KERN_DEBUG "ESO: 0x%x\n", val >> 16); - printk(KERN_DEBUG "Delta: 0x%x\n", val & 0xffff); + printk("ESO: 0x%x\n", val >> 16); + printk("Delta: 0x%x\n", val & 0xffff); val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL)); } else { // TRIDENT_DEVICE_ID_NX val = inl(TRID_REG(trident, CH_NX_DELTA_CSO)); tmp = (val >> 24) & 0xff; - printk(KERN_DEBUG "CSO: 0x%x\n", val & 0x00ffffff); + printk("CSO: 0x%x\n", val & 0x00ffffff); val = inl(TRID_REG(trident, CH_NX_DELTA_ESO)); tmp |= (val >> 16) & 0xff00; - printk(KERN_DEBUG "Delta: 0x%x\n", tmp); - printk(KERN_DEBUG "ESO: 0x%x\n", val & 0x00ffffff); + printk("Delta: 0x%x\n", tmp); + printk("ESO: 0x%x\n", val & 0x00ffffff); val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL)); - printk(KERN_DEBUG "Alpha: 0x%x\n", val >> 20); - printk(KERN_DEBUG "FMS: 0x%x\n", (val >> 16) & 0x0f); + printk("Alpha: 0x%x\n", val >> 20); + printk("FMS: 0x%x\n", (val >> 16) & 0x0f); } - printk(KERN_DEBUG "FMC: 0x%x\n", (val >> 14) & 3); - printk(KERN_DEBUG "RVol: 0x%x\n", (val >> 7) & 0x7f); - printk(KERN_DEBUG "CVol: 0x%x\n", val & 0x7f); + printk("FMC: 0x%x\n", (val >> 14) & 3); + printk("RVol: 0x%x\n", (val >> 7) & 0x7f); + printk("CVol: 0x%x\n", val & 0x7f); } #endif @@ -496,17 +496,12 @@ void snd_trident_write_voice_regs(struct snd_trident * trident, outl(regs[4], TRID_REG(trident, CH_START + 16)); #if 0 - printk(KERN_DEBUG "written %i channel:\n", voice->number); - printk(KERN_DEBUG " regs[0] = 0x%x/0x%x\n", - regs[0], inl(TRID_REG(trident, CH_START + 0))); - printk(KERN_DEBUG " regs[1] = 0x%x/0x%x\n", - regs[1], inl(TRID_REG(trident, CH_START + 4))); - printk(KERN_DEBUG " regs[2] = 0x%x/0x%x\n", - regs[2], inl(TRID_REG(trident, CH_START + 8))); - printk(KERN_DEBUG " regs[3] = 0x%x/0x%x\n", - regs[3], inl(TRID_REG(trident, CH_START + 12))); - printk(KERN_DEBUG " regs[4] = 0x%x/0x%x\n", - regs[4], inl(TRID_REG(trident, CH_START + 16))); + printk("written %i channel:\n", voice->number); + printk(" regs[0] = 0x%x/0x%x\n", regs[0], inl(TRID_REG(trident, CH_START + 0))); + printk(" regs[1] = 0x%x/0x%x\n", regs[1], inl(TRID_REG(trident, CH_START + 4))); + printk(" regs[2] = 0x%x/0x%x\n", regs[2], inl(TRID_REG(trident, CH_START + 8))); + printk(" regs[3] = 0x%x/0x%x\n", regs[3], inl(TRID_REG(trident, CH_START + 12))); + printk(" regs[4] = 0x%x/0x%x\n", regs[4], inl(TRID_REG(trident, CH_START + 16))); #endif } @@ -588,7 +583,7 @@ static void snd_trident_write_vol_reg(struct snd_trident * trident, outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2)); break; case TRIDENT_DEVICE_ID_SI7018: - /* printk(KERN_DEBUG "voice->Vol = 0x%x\n", voice->Vol); */ + // printk("voice->Vol = 0x%x\n", voice->Vol); outw((voice->CTRL << 12) | voice->Vol, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC)); break; diff --git a/trunk/sound/pci/via82xx.c b/trunk/sound/pci/via82xx.c index 809b233dd4a3..1aafe956ee2b 100644 --- a/trunk/sound/pci/via82xx.c +++ b/trunk/sound/pci/via82xx.c @@ -466,10 +466,7 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre flag = VIA_TBL_BIT_FLAG; /* period boundary */ } else flag = 0; /* period continues to the next */ - /* - printk(KERN_DEBUG "via: tbl %d: at %d size %d " - "(rest %d)\n", idx, ofs, r, rest); - */ + // printk("via: tbl %d: at %d size %d (rest %d)\n", idx, ofs, r, rest); ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag); dev->idx_table[idx].offset = ofs; dev->idx_table[idx].size = r; @@ -2363,14 +2360,14 @@ static struct snd_pci_quirk dxs_whitelist[] __devinitdata = { SND_PCI_QUIRK(0x1019, 0x0996, "ESC Mobo", VIA_DXS_48K), SND_PCI_QUIRK(0x1019, 0x0a81, "ECS K7VTA3 v8.0", VIA_DXS_NO_VRA), SND_PCI_QUIRK(0x1019, 0x0a85, "ECS L7VMM2", VIA_DXS_NO_VRA), - SND_PCI_QUIRK_VENDOR(0x1019, "ESC K8", VIA_DXS_SRC), + SND_PCI_QUIRK(0x1019, 0, "ESC K8", VIA_DXS_SRC), SND_PCI_QUIRK(0x1019, 0xaa01, "ESC K8T890-A", VIA_DXS_SRC), SND_PCI_QUIRK(0x1025, 0x0033, "Acer Inspire 1353LM", VIA_DXS_NO_VRA), SND_PCI_QUIRK(0x1025, 0x0046, "Acer Aspire 1524 WLMi", VIA_DXS_SRC), - SND_PCI_QUIRK_VENDOR(0x1043, "ASUS A7/A8", VIA_DXS_NO_VRA), - SND_PCI_QUIRK_VENDOR(0x1071, "Diverse Notebook", VIA_DXS_NO_VRA), + SND_PCI_QUIRK(0x1043, 0, "ASUS A7/A8", VIA_DXS_NO_VRA), + SND_PCI_QUIRK(0x1071, 0, "Diverse Notebook", VIA_DXS_NO_VRA), SND_PCI_QUIRK(0x10cf, 0x118e, "FSC Laptop", VIA_DXS_ENABLE), - SND_PCI_QUIRK_VENDOR(0x1106, "ASRock", VIA_DXS_SRC), + SND_PCI_QUIRK(0x1106, 0, "ASRock", VIA_DXS_SRC), SND_PCI_QUIRK(0x1297, 0xa231, "Shuttle AK31v2", VIA_DXS_SRC), SND_PCI_QUIRK(0x1297, 0xa232, "Shuttle", VIA_DXS_SRC), SND_PCI_QUIRK(0x1297, 0xc160, "Shuttle Sk41G", VIA_DXS_SRC), @@ -2378,7 +2375,7 @@ static struct snd_pci_quirk dxs_whitelist[] __devinitdata = { SND_PCI_QUIRK(0x1462, 0x3800, "MSI KT266", VIA_DXS_ENABLE), SND_PCI_QUIRK(0x1462, 0x7120, "MSI KT4V", VIA_DXS_ENABLE), SND_PCI_QUIRK(0x1462, 0x7142, "MSI K8MM-V", VIA_DXS_ENABLE), - SND_PCI_QUIRK_VENDOR(0x1462, "MSI Mobo", VIA_DXS_SRC), + SND_PCI_QUIRK(0x1462, 0, "MSI Mobo", VIA_DXS_SRC), SND_PCI_QUIRK(0x147b, 0x1401, "ABIT KD7(-RAID)", VIA_DXS_ENABLE), SND_PCI_QUIRK(0x147b, 0x1411, "ABIT VA-20", VIA_DXS_ENABLE), SND_PCI_QUIRK(0x147b, 0x1413, "ABIT KV8 Pro", VIA_DXS_ENABLE), @@ -2392,11 +2389,11 @@ static struct snd_pci_quirk dxs_whitelist[] __devinitdata = { SND_PCI_QUIRK(0x161f, 0x2032, "m680x machines", VIA_DXS_48K), SND_PCI_QUIRK(0x1631, 0xe004, "PB EasyNote 3174", VIA_DXS_ENABLE), SND_PCI_QUIRK(0x1695, 0x3005, "EPoX EP-8K9A", VIA_DXS_ENABLE), - SND_PCI_QUIRK_VENDOR(0x1695, "EPoX mobo", VIA_DXS_SRC), - SND_PCI_QUIRK_VENDOR(0x16f3, "Jetway K8", VIA_DXS_SRC), - SND_PCI_QUIRK_VENDOR(0x1734, "FSC Laptop", VIA_DXS_SRC), + SND_PCI_QUIRK(0x1695, 0, "EPoX mobo", VIA_DXS_SRC), + SND_PCI_QUIRK(0x16f3, 0, "Jetway K8", VIA_DXS_SRC), + SND_PCI_QUIRK(0x1734, 0, "FSC Laptop", VIA_DXS_SRC), SND_PCI_QUIRK(0x1849, 0x3059, "ASRock K7VM2", VIA_DXS_NO_VRA), - SND_PCI_QUIRK_VENDOR(0x1849, "ASRock mobo", VIA_DXS_SRC), + SND_PCI_QUIRK(0x1849, 0, "ASRock mobo", VIA_DXS_SRC), SND_PCI_QUIRK(0x1919, 0x200a, "Soltek SL-K8", VIA_DXS_NO_VRA), SND_PCI_QUIRK(0x4005, 0x4710, "MSI K7T266", VIA_DXS_SRC), { } /* terminator */ @@ -2436,9 +2433,9 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci, unsigned int i; int err; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; card_type = pci_id->driver_data; switch (card_type) { diff --git a/trunk/sound/pci/via82xx_modem.c b/trunk/sound/pci/via82xx_modem.c index 0d54e3503c1e..5bd79d2a5a15 100644 --- a/trunk/sound/pci/via82xx_modem.c +++ b/trunk/sound/pci/via82xx_modem.c @@ -328,10 +328,7 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre flag = VIA_TBL_BIT_FLAG; /* period boundary */ } else flag = 0; /* period continues to the next */ - /* - printk(KERN_DEBUG "via: tbl %d: at %d size %d " - "(rest %d)\n", idx, ofs, r, rest); - */ + // printk("via: tbl %d: at %d size %d (rest %d)\n", idx, ofs, r, rest); ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag); dev->idx_table[idx].offset = ofs; dev->idx_table[idx].size = r; @@ -1170,9 +1167,9 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci, unsigned int i; int err; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; card_type = pci_id->driver_data; switch (card_type) { diff --git a/trunk/sound/pci/vx222/vx222.c b/trunk/sound/pci/vx222/vx222.c index fc9136c3e0d7..acc352f4a441 100644 --- a/trunk/sound/pci/vx222/vx222.c +++ b/trunk/sound/pci/vx222/vx222.c @@ -204,9 +204,9 @@ static int __devinit snd_vx222_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; switch ((int)pci_id->driver_data) { case VX_PCI_VX222_OLD: diff --git a/trunk/sound/pci/vx222/vx222_ops.c b/trunk/sound/pci/vx222/vx222_ops.c index c0efe4491116..7e87f398ff0b 100644 --- a/trunk/sound/pci/vx222/vx222_ops.c +++ b/trunk/sound/pci/vx222/vx222_ops.c @@ -107,9 +107,7 @@ static unsigned char vx2_inb(struct vx_core *chip, int offset) static void vx2_outb(struct vx_core *chip, int offset, unsigned char val) { outb(val, vx2_reg_addr(chip, offset)); - /* - printk(KERN_DEBUG "outb: %x -> %x\n", val, vx2_reg_addr(chip, offset)); - */ + //printk("outb: %x -> %x\n", val, vx2_reg_addr(chip, offset)); } /** @@ -128,9 +126,7 @@ static unsigned int vx2_inl(struct vx_core *chip, int offset) */ static void vx2_outl(struct vx_core *chip, int offset, unsigned int val) { - /* - printk(KERN_DEBUG "outl: %x -> %x\n", val, vx2_reg_addr(chip, offset)); - */ + // printk("outl: %x -> %x\n", val, vx2_reg_addr(chip, offset)); outl(val, vx2_reg_addr(chip, offset)); } diff --git a/trunk/sound/pci/ymfpci/ymfpci.c b/trunk/sound/pci/ymfpci/ymfpci.c index 4af66661f9b0..2631a554845e 100644 --- a/trunk/sound/pci/ymfpci/ymfpci.c +++ b/trunk/sound/pci/ymfpci/ymfpci.c @@ -187,9 +187,9 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; switch (pci_id->device) { case 0x0004: str = "YMF724"; model = "DS-1"; break; diff --git a/trunk/sound/pci/ymfpci/ymfpci_main.c b/trunk/sound/pci/ymfpci/ymfpci_main.c index 2f0925236a1b..90d0d62bd0b4 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_main.c +++ b/trunk/sound/pci/ymfpci/ymfpci_main.c @@ -318,12 +318,7 @@ static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_ ypcm->period_pos += delta; ypcm->last_pos = pos; if (ypcm->period_pos >= ypcm->period_size) { - /* - printk(KERN_DEBUG - "done - active_bank = 0x%x, start = 0x%x\n", - chip->active_bank, - voice->bank[chip->active_bank].start); - */ + // printk("done - active_bank = 0x%x, start = 0x%x\n", chip->active_bank, voice->bank[chip->active_bank].start); ypcm->period_pos %= ypcm->period_size; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(ypcm->substream); @@ -371,12 +366,7 @@ static void snd_ymfpci_pcm_capture_interrupt(struct snd_pcm_substream *substream ypcm->last_pos = pos; if (ypcm->period_pos >= ypcm->period_size) { ypcm->period_pos %= ypcm->period_size; - /* - printk(KERN_DEBUG - "done - active_bank = 0x%x, start = 0x%x\n", - chip->active_bank, - voice->bank[chip->active_bank].start); - */ + // printk("done - active_bank = 0x%x, start = 0x%x\n", chip->active_bank, voice->bank[chip->active_bank].start); spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(substream); spin_lock(&chip->reg_lock); diff --git a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c index 7dea74b71cf1..819aaaac432f 100644 --- a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -91,7 +91,7 @@ static int snd_pdacf_dev_free(struct snd_device *device) */ static int snd_pdacf_probe(struct pcmcia_device *link) { - int i, err; + int i; struct snd_pdacf *pdacf; struct snd_card *card; static struct snd_device_ops ops = { @@ -112,23 +112,20 @@ static int snd_pdacf_probe(struct pcmcia_device *link) return -ENODEV; /* disabled explicitly */ /* ok, create a card instance */ - err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card); - if (err < 0) { + card = snd_card_new(index[i], id[i], THIS_MODULE, 0); + if (card == NULL) { snd_printk(KERN_ERR "pdacf: cannot create a card instance\n"); - return err; + return -ENOMEM; } pdacf = snd_pdacf_create(card); - if (!pdacf) { - snd_card_free(card); - return -ENOMEM; - } + if (! pdacf) + return -EIO; - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops); - if (err < 0) { + if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) { kfree(pdacf); snd_card_free(card); - return err; + return -ENODEV; } snd_card_set_dev(card, &handle_to_dev(link)); diff --git a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_core.c index 5d2afa0b0ce4..dfa40b0ed86d 100644 --- a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_core.c +++ b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_core.c @@ -82,21 +82,14 @@ static void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned c #if 0 void pdacf_dump(struct snd_pdacf *chip) { - printk(KERN_DEBUG "PDAUDIOCF DUMP (0x%lx):\n", chip->port); - printk(KERN_DEBUG "WPD : 0x%x\n", - inw(chip->port + PDAUDIOCF_REG_WDP)); - printk(KERN_DEBUG "RDP : 0x%x\n", - inw(chip->port + PDAUDIOCF_REG_RDP)); - printk(KERN_DEBUG "TCR : 0x%x\n", - inw(chip->port + PDAUDIOCF_REG_TCR)); - printk(KERN_DEBUG "SCR : 0x%x\n", - inw(chip->port + PDAUDIOCF_REG_SCR)); - printk(KERN_DEBUG "ISR : 0x%x\n", - inw(chip->port + PDAUDIOCF_REG_ISR)); - printk(KERN_DEBUG "IER : 0x%x\n", - inw(chip->port + PDAUDIOCF_REG_IER)); - printk(KERN_DEBUG "AK_IFR : 0x%x\n", - inw(chip->port + PDAUDIOCF_REG_AK_IFR)); + printk("PDAUDIOCF DUMP (0x%lx):\n", chip->port); + printk("WPD : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_WDP)); + printk("RDP : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_RDP)); + printk("TCR : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_TCR)); + printk("SCR : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_SCR)); + printk("ISR : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_ISR)); + printk("IER : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_IER)); + printk("AK_IFR : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_AK_IFR)); } #endif diff --git a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c index dcd32201bc8c..ea903c8e90dd 100644 --- a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c +++ b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c @@ -269,7 +269,7 @@ void pdacf_tasklet(unsigned long private_data) rdp = inw(chip->port + PDAUDIOCF_REG_RDP); wdp = inw(chip->port + PDAUDIOCF_REG_WDP); - /* printk(KERN_DEBUG "TASKLET: rdp = %x, wdp = %x\n", rdp, wdp); */ + // printk("TASKLET: rdp = %x, wdp = %x\n", rdp, wdp); size = wdp - rdp; if (size < 0) size += 0x10000; @@ -321,5 +321,5 @@ void pdacf_tasklet(unsigned long private_data) spin_lock(&chip->reg_lock); } spin_unlock(&chip->reg_lock); - /* printk(KERN_DEBUG "TASKLET: end\n"); */ + // printk("TASKLET: end\n"); } diff --git a/trunk/sound/pcmcia/vx/vxpocket.c b/trunk/sound/pcmcia/vx/vxpocket.c index 7445cc8a47d3..706602a40600 100644 --- a/trunk/sound/pcmcia/vx/vxpocket.c +++ b/trunk/sound/pcmcia/vx/vxpocket.c @@ -130,26 +130,23 @@ static struct snd_vx_hardware vxp440_hw = { /* * create vxpocket instance */ -static int snd_vxpocket_new(struct snd_card *card, int ibl, - struct pcmcia_device *link, - struct snd_vxpocket **chip_ret) +static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl, + struct pcmcia_device *link) { struct vx_core *chip; struct snd_vxpocket *vxp; static struct snd_device_ops ops = { .dev_free = snd_vxpocket_dev_free, }; - int err; chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops, sizeof(struct snd_vxpocket) - sizeof(struct vx_core)); - if (!chip) - return -ENOMEM; + if (! chip) + return NULL; - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); - if (err < 0) { + if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) { kfree(chip); - return err; + return NULL; } chip->ibl.size = ibl; @@ -172,8 +169,7 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl, link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; - *chip_ret = vxp; - return 0; + return vxp; } @@ -296,7 +292,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) { struct snd_card *card; struct snd_vxpocket *vxp; - int i, err; + int i; /* find an empty slot from the card list */ for (i = 0; i < SNDRV_CARDS; i++) { @@ -311,16 +307,16 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) return -ENODEV; /* disabled explicitly */ /* ok, create a card instance */ - err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card); - if (err < 0) { + card = snd_card_new(index[i], id[i], THIS_MODULE, 0); + if (card == NULL) { snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); - return err; + return -ENOMEM; } - err = snd_vxpocket_new(card, ibl[i], p_dev, &vxp); - if (err < 0) { + vxp = snd_vxpocket_new(card, ibl[i], p_dev); + if (! vxp) { snd_card_free(card); - return err; + return -ENODEV; } card->private_data = vxp; diff --git a/trunk/sound/ppc/powermac.c b/trunk/sound/ppc/powermac.c index 2e18ed0ea899..c936225771ba 100644 --- a/trunk/sound/ppc/powermac.c +++ b/trunk/sound/ppc/powermac.c @@ -58,9 +58,9 @@ static int __init snd_pmac_probe(struct platform_device *devptr) char *name_ext; int err; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); - if (err < 0) - return err; + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; if ((err = snd_pmac_new(card, &chip)) < 0) goto __error; diff --git a/trunk/sound/ppc/snd_ps3.c b/trunk/sound/ppc/snd_ps3.c index f361c26506aa..ff321110ec02 100644 --- a/trunk/sound/ppc/snd_ps3.c +++ b/trunk/sound/ppc/snd_ps3.c @@ -969,9 +969,11 @@ static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) } /* create card instance */ - ret = snd_card_create(index, id, THIS_MODULE, 0, &the_card.card); - if (ret < 0) + the_card.card = snd_card_new(index, id, THIS_MODULE, 0); + if (!the_card.card) { + ret = -ENXIO; goto clean_irq; + } strcpy(the_card.card->driver, "PS3"); strcpy(the_card.card->shortname, "PS3"); diff --git a/trunk/sound/sh/aica.c b/trunk/sound/sh/aica.c index f551233c5a08..7c920f3e7fe3 100644 --- a/trunk/sound/sh/aica.c +++ b/trunk/sound/sh/aica.c @@ -609,11 +609,11 @@ static int __devinit snd_aica_probe(struct platform_device *devptr) dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL); if (unlikely(!dreamcastcard)) return -ENOMEM; - err = snd_card_create(index, SND_AICA_DRIVER, THIS_MODULE, 0, - &dreamcastcard->card); - if (unlikely(err < 0)) { + dreamcastcard->card = + snd_card_new(index, SND_AICA_DRIVER, THIS_MODULE, 0); + if (unlikely(!dreamcastcard->card)) { kfree(dreamcastcard); - return err; + return -ENODEV; } strcpy(dreamcastcard->card->driver, "snd_aica"); strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER); diff --git a/trunk/sound/soc/Kconfig b/trunk/sound/soc/Kconfig index 3d2bb6fc6dcc..ef025c66cc66 100644 --- a/trunk/sound/soc/Kconfig +++ b/trunk/sound/soc/Kconfig @@ -6,7 +6,6 @@ menuconfig SND_SOC tristate "ALSA for SoC audio support" select SND_PCM select AC97_BUS if SND_SOC_AC97_BUS - select SND_JACK if INPUT=y || INPUT=SND ---help--- If you want ASoC support, you should say Y here and also to the diff --git a/trunk/sound/soc/Makefile b/trunk/sound/soc/Makefile index 0237879fd412..86a9b1f5b0f3 100644 --- a/trunk/sound/soc/Makefile +++ b/trunk/sound/soc/Makefile @@ -1,4 +1,4 @@ -snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o +snd-soc-core-objs := soc-core.o soc-dapm.o obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += codecs/ diff --git a/trunk/sound/soc/atmel/atmel-pcm.c b/trunk/sound/soc/atmel/atmel-pcm.c index 9ef6b96373f5..3dcdc4e3cfa0 100644 --- a/trunk/sound/soc/atmel/atmel-pcm.c +++ b/trunk/sound/soc/atmel/atmel-pcm.c @@ -347,7 +347,7 @@ static int atmel_pcm_mmap(struct snd_pcm_substream *substream, vma->vm_end - vma->vm_start, vma->vm_page_prot); } -static struct snd_pcm_ops atmel_pcm_ops = { +struct snd_pcm_ops atmel_pcm_ops = { .open = atmel_pcm_open, .close = atmel_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/trunk/sound/soc/atmel/atmel_ssc_dai.c b/trunk/sound/soc/atmel/atmel_ssc_dai.c index e588e63f18d2..ff0054b76502 100644 --- a/trunk/sound/soc/atmel/atmel_ssc_dai.c +++ b/trunk/sound/soc/atmel/atmel_ssc_dai.c @@ -697,15 +697,6 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai) #define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops atmel_ssc_dai_ops = { - .startup = atmel_ssc_startup, - .shutdown = atmel_ssc_shutdown, - .prepare = atmel_ssc_prepare, - .hw_params = atmel_ssc_hw_params, - .set_fmt = atmel_ssc_set_dai_fmt, - .set_clkdiv = atmel_ssc_set_dai_clkdiv, -}; - struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = { { .name = "atmel-ssc0", .id = 0, @@ -721,7 +712,13 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = { .channels_max = 2, .rates = ATMEL_SSC_RATES, .formats = ATMEL_SSC_FORMATS,}, - .ops = &atmel_ssc_dai_ops, + .ops = { + .startup = atmel_ssc_startup, + .shutdown = atmel_ssc_shutdown, + .prepare = atmel_ssc_prepare, + .hw_params = atmel_ssc_hw_params, + .set_fmt = atmel_ssc_set_dai_fmt, + .set_clkdiv = atmel_ssc_set_dai_clkdiv,}, .private_data = &ssc_info[0], }, #if NUM_SSC_DEVICES == 3 @@ -739,7 +736,13 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = { .channels_max = 2, .rates = ATMEL_SSC_RATES, .formats = ATMEL_SSC_FORMATS,}, - .ops = &atmel_ssc_dai_ops, + .ops = { + .startup = atmel_ssc_startup, + .shutdown = atmel_ssc_shutdown, + .prepare = atmel_ssc_prepare, + .hw_params = atmel_ssc_hw_params, + .set_fmt = atmel_ssc_set_dai_fmt, + .set_clkdiv = atmel_ssc_set_dai_clkdiv,}, .private_data = &ssc_info[1], }, { .name = "atmel-ssc2", @@ -756,7 +759,13 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = { .channels_max = 2, .rates = ATMEL_SSC_RATES, .formats = ATMEL_SSC_FORMATS,}, - .ops = &atmel_ssc_dai_ops, + .ops = { + .startup = atmel_ssc_startup, + .shutdown = atmel_ssc_shutdown, + .prepare = atmel_ssc_prepare, + .hw_params = atmel_ssc_hw_params, + .set_fmt = atmel_ssc_set_dai_fmt, + .set_clkdiv = atmel_ssc_set_dai_clkdiv,}, .private_data = &ssc_info[2], }, #endif diff --git a/trunk/sound/soc/atmel/playpaq_wm8510.c b/trunk/sound/soc/atmel/playpaq_wm8510.c index 70657534e6b1..43dd8cee83c6 100644 --- a/trunk/sound/soc/atmel/playpaq_wm8510.c +++ b/trunk/sound/soc/atmel/playpaq_wm8510.c @@ -164,38 +164,38 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, */ switch (params_rate(params)) { case 48000: - pll_out = 24576000; - mclk_div = WM8510_MCLKDIV_2; + pll_out = 12288000; + mclk_div = WM8510_MCLKDIV_1; bclk = WM8510_BCLKDIV_8; break; case 44100: - pll_out = 22579200; - mclk_div = WM8510_MCLKDIV_2; + pll_out = 11289600; + mclk_div = WM8510_MCLKDIV_1; bclk = WM8510_BCLKDIV_8; break; case 22050: - pll_out = 22579200; - mclk_div = WM8510_MCLKDIV_4; + pll_out = 11289600; + mclk_div = WM8510_MCLKDIV_2; bclk = WM8510_BCLKDIV_8; break; case 16000: - pll_out = 24576000; - mclk_div = WM8510_MCLKDIV_6; + pll_out = 12288000; + mclk_div = WM8510_MCLKDIV_3; bclk = WM8510_BCLKDIV_8; break; case 11025: - pll_out = 22579200; - mclk_div = WM8510_MCLKDIV_8; + pll_out = 11289600; + mclk_div = WM8510_MCLKDIV_4; bclk = WM8510_BCLKDIV_8; break; case 8000: - pll_out = 24576000; - mclk_div = WM8510_MCLKDIV_12; + pll_out = 12288000; + mclk_div = WM8510_MCLKDIV_6; bclk = WM8510_BCLKDIV_8; break; diff --git a/trunk/sound/soc/atmel/sam9g20_wm8731.c b/trunk/sound/soc/atmel/sam9g20_wm8731.c index 173a239a541c..6ea04be911d0 100644 --- a/trunk/sound/soc/atmel/sam9g20_wm8731.c +++ b/trunk/sound/soc/atmel/sam9g20_wm8731.c @@ -36,7 +36,6 @@ #include #include #include -#include #include @@ -46,7 +45,6 @@ #include #include -#include #include #include @@ -54,9 +52,6 @@ #include "atmel-pcm.h" #include "atmel_ssc_dai.h" -#define MCLK_RATE 12000000 - -static struct clk *mclk; static int at91sam9g20ek_startup(struct snd_pcm_substream *substream) { @@ -64,12 +59,11 @@ static int at91sam9g20ek_startup(struct snd_pcm_substream *substream) struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; int ret; + /* codec system clock is supplied by PCK0, set to 12MHz */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, - MCLK_RATE, SND_SOC_CLOCK_IN); - if (ret < 0) { - clk_disable(mclk); + 12000000, SND_SOC_CLOCK_IN); + if (ret < 0) return ret; - } return 0; } @@ -195,31 +189,6 @@ static struct snd_soc_ops at91sam9g20ek_ops = { .shutdown = at91sam9g20ek_shutdown, }; -static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card, - enum snd_soc_bias_level level) -{ - static int mclk_on; - int ret = 0; - - switch (level) { - case SND_SOC_BIAS_ON: - case SND_SOC_BIAS_PREPARE: - if (!mclk_on) - ret = clk_enable(mclk); - if (ret == 0) - mclk_on = 1; - break; - - case SND_SOC_BIAS_OFF: - case SND_SOC_BIAS_STANDBY: - if (mclk_on) - clk_disable(mclk); - mclk_on = 0; - break; - } - - return ret; -} static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = { SND_SOC_DAPM_MIC("Int Mic", NULL), @@ -274,48 +243,21 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = { }; static struct snd_soc_card snd_soc_at91sam9g20ek = { - .name = "AT91SAMG20-EK", + .name = "WM8731", .platform = &atmel_soc_platform, .dai_link = &at91sam9g20ek_dai, .num_links = 1, - .set_bias_level = at91sam9g20ek_set_bias_level, }; -/* - * FIXME: This is a temporary bodge to avoid cross-tree merge issues. - * New drivers should register the wm8731 I2C device in the machine - * setup code (under arch/arm for ARM systems). - */ -static int wm8731_i2c_register(void) -{ - struct i2c_board_info info; - struct i2c_adapter *adapter; - struct i2c_client *client; - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = 0x1b; - strlcpy(info.type, "wm8731", I2C_NAME_SIZE); - - adapter = i2c_get_adapter(0); - if (!adapter) { - printk(KERN_ERR "can't get i2c adapter 0\n"); - return -ENODEV; - } - - client = i2c_new_device(adapter, &info); - i2c_put_adapter(adapter); - if (!client) { - printk(KERN_ERR "can't add i2c device at 0x%x\n", - (unsigned int)info.addr); - return -ENODEV; - } - - return 0; -} +static struct wm8731_setup_data at91sam9g20ek_wm8731_setup = { + .i2c_bus = 0, + .i2c_address = 0x1b, +}; static struct snd_soc_device at91sam9g20ek_snd_devdata = { .card = &snd_soc_at91sam9g20ek, .codec_dev = &soc_codec_dev_wm8731, + .codec_data = &at91sam9g20ek_wm8731_setup, }; static struct platform_device *at91sam9g20ek_snd_device; @@ -324,56 +266,23 @@ static int __init at91sam9g20ek_init(void) { struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data; struct ssc_device *ssc = NULL; - struct clk *pllb; int ret; - if (!machine_is_at91sam9g20ek()) - return -ENODEV; - - /* - * Codec MCLK is supplied by PCK0 - set it up. - */ - mclk = clk_get(NULL, "pck0"); - if (IS_ERR(mclk)) { - printk(KERN_ERR "ASoC: Failed to get MCLK\n"); - ret = PTR_ERR(mclk); - goto err; - } - - pllb = clk_get(NULL, "pllb"); - if (IS_ERR(mclk)) { - printk(KERN_ERR "ASoC: Failed to get PLLB\n"); - ret = PTR_ERR(mclk); - goto err_mclk; - } - ret = clk_set_parent(mclk, pllb); - clk_put(pllb); - if (ret != 0) { - printk(KERN_ERR "ASoC: Failed to set MCLK parent\n"); - goto err_mclk; - } - - clk_set_rate(mclk, MCLK_RATE); - /* * Request SSC device */ ssc = ssc_request(0); if (IS_ERR(ssc)) { - printk(KERN_ERR "ASoC: Failed to request SSC 0\n"); ret = PTR_ERR(ssc); ssc = NULL; goto err_ssc; } ssc_p->ssc = ssc; - ret = wm8731_i2c_register(); - if (ret != 0) - goto err_ssc; - at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); if (!at91sam9g20ek_snd_device) { - printk(KERN_ERR "ASoC: Platform device allocation failed\n"); + printk(KERN_DEBUG + "platform device allocation failed\n"); ret = -ENOMEM; } @@ -383,19 +292,14 @@ static int __init at91sam9g20ek_init(void) ret = platform_device_add(at91sam9g20ek_snd_device); if (ret) { - printk(KERN_ERR "ASoC: Platform device allocation failed\n"); + printk(KERN_DEBUG + "platform device allocation failed\n"); platform_device_put(at91sam9g20ek_snd_device); } return ret; err_ssc: - ssc_free(ssc); - ssc_p->ssc = NULL; -err_mclk: - clk_put(mclk); - mclk = NULL; -err: return ret; } @@ -413,8 +317,6 @@ static void __exit at91sam9g20ek_exit(void) platform_device_unregister(at91sam9g20ek_snd_device); at91sam9g20ek_snd_device = NULL; - clk_put(mclk); - mclk = NULL; } module_init(at91sam9g20ek_init); diff --git a/trunk/sound/soc/au1x/dbdma2.c b/trunk/sound/soc/au1x/dbdma2.c index 30490a259148..bc8d654576c0 100644 --- a/trunk/sound/soc/au1x/dbdma2.c +++ b/trunk/sound/soc/au1x/dbdma2.c @@ -305,7 +305,7 @@ static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops au1xpsc_pcm_ops = { +struct snd_pcm_ops au1xpsc_pcm_ops = { .open = au1xpsc_pcm_open, .close = au1xpsc_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/trunk/sound/soc/au1x/psc-ac97.c b/trunk/sound/soc/au1x/psc-ac97.c index 479d7bdf1865..f0e30aec7f23 100644 --- a/trunk/sound/soc/au1x/psc-ac97.c +++ b/trunk/sound/soc/au1x/psc-ac97.c @@ -342,11 +342,6 @@ static int au1xpsc_ac97_resume(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { - .trigger = au1xpsc_ac97_trigger, - .hw_params = au1xpsc_ac97_hw_params, -}; - struct snd_soc_dai au1xpsc_ac97_dai = { .name = "au1xpsc_ac97", .ac97_control = 1, @@ -366,7 +361,10 @@ struct snd_soc_dai au1xpsc_ac97_dai = { .channels_min = 2, .channels_max = 2, }, - .ops = &au1xpsc_ac97_dai_ops, + .ops = { + .trigger = au1xpsc_ac97_trigger, + .hw_params = au1xpsc_ac97_hw_params, + }, }; EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai); diff --git a/trunk/sound/soc/au1x/psc-i2s.c b/trunk/sound/soc/au1x/psc-i2s.c index bb589327ee32..f916de4400ed 100644 --- a/trunk/sound/soc/au1x/psc-i2s.c +++ b/trunk/sound/soc/au1x/psc-i2s.c @@ -367,12 +367,6 @@ static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai) return 0; } -static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { - .trigger = au1xpsc_i2s_trigger, - .hw_params = au1xpsc_i2s_hw_params, - .set_fmt = au1xpsc_i2s_set_fmt, -}; - struct snd_soc_dai au1xpsc_i2s_dai = { .name = "au1xpsc_i2s", .probe = au1xpsc_i2s_probe, @@ -391,7 +385,11 @@ struct snd_soc_dai au1xpsc_i2s_dai = { .channels_min = 2, .channels_max = 8, /* 2 without external help */ }, - .ops = &au1xpsc_i2s_dai_ops, + .ops = { + .trigger = au1xpsc_i2s_trigger, + .hw_params = au1xpsc_i2s_hw_params, + .set_fmt = au1xpsc_i2s_set_fmt, + }, }; EXPORT_SYMBOL(au1xpsc_i2s_dai); diff --git a/trunk/sound/soc/blackfin/bf5xx-ac97-pcm.c b/trunk/sound/soc/blackfin/bf5xx-ac97-pcm.c index 8cfed1a5dcbe..8067cfafa3a7 100644 --- a/trunk/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/trunk/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -297,7 +297,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, } #endif -static struct snd_pcm_ops bf5xx_pcm_ac97_ops = { +struct snd_pcm_ops bf5xx_pcm_ac97_ops = { .open = bf5xx_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = bf5xx_pcm_hw_params, diff --git a/trunk/sound/soc/blackfin/bf5xx-ac97.c b/trunk/sound/soc/blackfin/bf5xx-ac97.c index 8a935f2d1767..3be2be60576d 100644 --- a/trunk/sound/soc/blackfin/bf5xx-ac97.c +++ b/trunk/sound/soc/blackfin/bf5xx-ac97.c @@ -31,46 +31,72 @@ #include "bf5xx-sport.h" #include "bf5xx-ac97.h" +#if defined(CONFIG_BF54x) +#define PIN_REQ_SPORT_0 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, \ + P_SPORT0_RFS, P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0} + +#define PIN_REQ_SPORT_1 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, \ + P_SPORT1_RFS, P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0} + +#define PIN_REQ_SPORT_2 {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, \ + P_SPORT2_RFS, P_SPORT2_DRPRI, P_SPORT2_RSCLK, 0} + +#define PIN_REQ_SPORT_3 {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, \ + P_SPORT3_RFS, P_SPORT3_DRPRI, P_SPORT3_RSCLK, 0} +#else +#define PIN_REQ_SPORT_0 {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \ + P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0} + +#define PIN_REQ_SPORT_1 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \ + P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0} +#endif + static int *cmd_count; static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; -#define SPORT_REQ(x) \ - [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \ - P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0} static u16 sport_req[][7] = { -#ifdef SPORT0_TCR1 - SPORT_REQ(0), -#endif -#ifdef SPORT1_TCR1 - SPORT_REQ(1), + PIN_REQ_SPORT_0, +#ifdef PIN_REQ_SPORT_1 + PIN_REQ_SPORT_1, #endif -#ifdef SPORT2_TCR1 - SPORT_REQ(2), +#ifdef PIN_REQ_SPORT_2 + PIN_REQ_SPORT_2, #endif -#ifdef SPORT3_TCR1 - SPORT_REQ(3), +#ifdef PIN_REQ_SPORT_3 + PIN_REQ_SPORT_3, #endif -}; + }; -#define SPORT_PARAMS(x) \ - [x] = { \ - .dma_rx_chan = CH_SPORT##x##_RX, \ - .dma_tx_chan = CH_SPORT##x##_TX, \ - .err_irq = IRQ_SPORT##x##_ERROR, \ - .regs = (struct sport_register *)SPORT##x##_TCR1, \ - } static struct sport_param sport_params[4] = { -#ifdef SPORT0_TCR1 - SPORT_PARAMS(0), + { + .dma_rx_chan = CH_SPORT0_RX, + .dma_tx_chan = CH_SPORT0_TX, + .err_irq = IRQ_SPORT0_ERROR, + .regs = (struct sport_register *)SPORT0_TCR1, + }, +#ifdef PIN_REQ_SPORT_1 + { + .dma_rx_chan = CH_SPORT1_RX, + .dma_tx_chan = CH_SPORT1_TX, + .err_irq = IRQ_SPORT1_ERROR, + .regs = (struct sport_register *)SPORT1_TCR1, + }, #endif -#ifdef SPORT1_TCR1 - SPORT_PARAMS(1), +#ifdef PIN_REQ_SPORT_2 + { + .dma_rx_chan = CH_SPORT2_RX, + .dma_tx_chan = CH_SPORT2_TX, + .err_irq = IRQ_SPORT2_ERROR, + .regs = (struct sport_register *)SPORT2_TCR1, + }, #endif -#ifdef SPORT2_TCR1 - SPORT_PARAMS(2), -#endif -#ifdef SPORT3_TCR1 - SPORT_PARAMS(3), +#ifdef PIN_REQ_SPORT_3 + { + .dma_rx_chan = CH_SPORT3_RX, + .dma_tx_chan = CH_SPORT3_TX, + .err_irq = IRQ_SPORT3_ERROR, + .regs = (struct sport_register *)SPORT3_TCR1, + } #endif }; @@ -306,11 +332,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev, if (cmd_count == NULL) return -ENOMEM; - if (peripheral_request_list(sport_req[sport_num], "soc-audio")) { + if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { pr_err("Requesting Peripherals failed\n"); ret = -EFAULT; goto peripheral_err; - } + } #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET /* Request PB3 as reset pin */ @@ -357,9 +383,9 @@ static int bf5xx_ac97_probe(struct platform_device *pdev, sport_err: #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); -gpio_err: #endif - peripheral_free_list(sport_req[sport_num]); +gpio_err: + peripheral_free_list(&sport_req[sport_num][0]); peripheral_err: free_page((unsigned long)cmd_count); cmd_count = NULL; @@ -372,7 +398,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev, { free_page((unsigned long)cmd_count); cmd_count = NULL; - peripheral_free_list(sport_req[sport_num]); + peripheral_free_list(&sport_req[sport_num][0]); #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); #endif diff --git a/trunk/sound/soc/blackfin/bf5xx-ad73311.c b/trunk/sound/soc/blackfin/bf5xx-ad73311.c index edfbdc024e66..7f2a5e199075 100644 --- a/trunk/sound/soc/blackfin/bf5xx-ad73311.c +++ b/trunk/sound/soc/blackfin/bf5xx-ad73311.c @@ -114,7 +114,7 @@ static int snd_ad73311_configure(void) SSYNC(); /* When TUVF is set, the data is already send out */ - while (!(status & TUVF) && ++count < 10000) { + while (!(status & TUVF) && count++ < 10000) { udelay(1); status = bfin_read_SPORT_STAT(); SSYNC(); @@ -123,7 +123,7 @@ static int snd_ad73311_configure(void) SSYNC(); local_irq_enable(); - if (count >= 10000) { + if (count == 10000) { printk(KERN_ERR "ad73311: failed to configure codec\n"); return -1; } diff --git a/trunk/sound/soc/blackfin/bf5xx-i2s-pcm.c b/trunk/sound/soc/blackfin/bf5xx-i2s-pcm.c index 1318c4f627b7..53d290b3ea47 100644 --- a/trunk/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/trunk/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -184,7 +184,7 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream, return 0 ; } -static struct snd_pcm_ops bf5xx_pcm_i2s_ops = { +struct snd_pcm_ops bf5xx_pcm_i2s_ops = { .open = bf5xx_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = bf5xx_pcm_hw_params, diff --git a/trunk/sound/soc/blackfin/bf5xx-i2s.c b/trunk/sound/soc/blackfin/bf5xx-i2s.c index 964824419678..d1d95d2393fe 100644 --- a/trunk/sound/soc/blackfin/bf5xx-i2s.c +++ b/trunk/sound/soc/blackfin/bf5xx-i2s.c @@ -287,13 +287,6 @@ static int bf5xx_i2s_resume(struct platform_device *pdev, #define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { - .startup = bf5xx_i2s_startup, - .shutdown = bf5xx_i2s_shutdown, - .hw_params = bf5xx_i2s_hw_params, - .set_fmt = bf5xx_i2s_set_dai_fmt, -}; - struct snd_soc_dai bf5xx_i2s_dai = { .name = "bf5xx-i2s", .id = 0, @@ -311,7 +304,12 @@ struct snd_soc_dai bf5xx_i2s_dai = { .channels_max = 2, .rates = BF5XX_I2S_RATES, .formats = BF5XX_I2S_FORMATS,}, - .ops = &bf5xx_i2s_dai_ops, + .ops = { + .startup = bf5xx_i2s_startup, + .shutdown = bf5xx_i2s_shutdown, + .hw_params = bf5xx_i2s_hw_params, + .set_fmt = bf5xx_i2s_set_dai_fmt, + }, }; EXPORT_SYMBOL_GPL(bf5xx_i2s_dai); diff --git a/trunk/sound/soc/blackfin/bf5xx-sport.c b/trunk/sound/soc/blackfin/bf5xx-sport.c index b7953c8cf838..3b99e484d555 100644 --- a/trunk/sound/soc/blackfin/bf5xx-sport.c +++ b/trunk/sound/soc/blackfin/bf5xx-sport.c @@ -133,7 +133,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount, int i; for (i = 0; i < fragcount; ++i) { - desc[i].next_desc_addr = &(desc[i + 1]); + desc[i].next_desc_addr = (unsigned long)&(desc[i + 1]); desc[i].start_addr = (unsigned long)buf + i*fragsize; desc[i].cfg = cfg; desc[i].x_count = x_count; @@ -143,12 +143,12 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount, } /* make circular */ - desc[fragcount-1].next_desc_addr = desc; + desc[fragcount-1].next_desc_addr = (unsigned long)desc; - pr_debug("setup desc: desc0=%p, next0=%p, desc1=%p," - "next1=%p\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n", - desc, desc[0].next_desc_addr, - desc+1, desc[1].next_desc_addr, + pr_debug("setup desc: desc0=%p, next0=%lx, desc1=%p," + "next1=%lx\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n", + &(desc[0]), desc[0].next_desc_addr, + &(desc[1]), desc[1].next_desc_addr, desc[0].x_count, desc[0].y_count, desc[0].start_addr, desc[0].cfg); } @@ -184,20 +184,22 @@ static inline int sport_hook_rx_dummy(struct sport_device *sport) BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc); /* Maybe the dummy buffer descriptor ring is damaged */ - sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc + 1; + sport->dummy_rx_desc->next_desc_addr = \ + (unsigned long)(sport->dummy_rx_desc+1); local_irq_save(flags); - desc = get_dma_next_desc_ptr(sport->dma_rx_chan); + desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_rx_chan); /* Copy the descriptor which will be damaged to backup */ temp_desc = *desc; desc->x_count = 0xa; desc->y_count = 0; - desc->next_desc_addr = sport->dummy_rx_desc; + desc->next_desc_addr = (unsigned long)(sport->dummy_rx_desc); local_irq_restore(flags); /* Waiting for dummy buffer descriptor is already hooked*/ while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - - sizeof(struct dmasg)) != sport->dummy_rx_desc) - continue; + sizeof(struct dmasg)) != + (unsigned long)sport->dummy_rx_desc) + ; sport->curr_rx_desc = sport->dummy_rx_desc; /* Restore the damaged descriptor */ *desc = temp_desc; @@ -208,12 +210,14 @@ static inline int sport_hook_rx_dummy(struct sport_device *sport) static inline int sport_rx_dma_start(struct sport_device *sport, int dummy) { if (dummy) { - sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc; + sport->dummy_rx_desc->next_desc_addr = \ + (unsigned long) sport->dummy_rx_desc; sport->curr_rx_desc = sport->dummy_rx_desc; } else sport->curr_rx_desc = sport->dma_rx_desc; - set_dma_next_desc_addr(sport->dma_rx_chan, sport->curr_rx_desc); + set_dma_next_desc_addr(sport->dma_rx_chan, \ + (unsigned long)(sport->curr_rx_desc)); set_dma_x_count(sport->dma_rx_chan, 0); set_dma_x_modify(sport->dma_rx_chan, 0); set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \ @@ -227,12 +231,14 @@ static inline int sport_rx_dma_start(struct sport_device *sport, int dummy) static inline int sport_tx_dma_start(struct sport_device *sport, int dummy) { if (dummy) { - sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc; + sport->dummy_tx_desc->next_desc_addr = \ + (unsigned long) sport->dummy_tx_desc; sport->curr_tx_desc = sport->dummy_tx_desc; } else sport->curr_tx_desc = sport->dma_tx_desc; - set_dma_next_desc_addr(sport->dma_tx_chan, sport->curr_tx_desc); + set_dma_next_desc_addr(sport->dma_tx_chan, \ + (unsigned long)(sport->curr_tx_desc)); set_dma_x_count(sport->dma_tx_chan, 0); set_dma_x_modify(sport->dma_tx_chan, 0); set_dma_config(sport->dma_tx_chan, @@ -255,9 +261,11 @@ int sport_rx_start(struct sport_device *sport) BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc); local_irq_save(flags); while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - - sizeof(struct dmasg)) != sport->dummy_rx_desc) - continue; - sport->dummy_rx_desc->next_desc_addr = sport->dma_rx_desc; + sizeof(struct dmasg)) != + (unsigned long)sport->dummy_rx_desc) + ; + sport->dummy_rx_desc->next_desc_addr = + (unsigned long)(sport->dma_rx_desc); local_irq_restore(flags); sport->curr_rx_desc = sport->dma_rx_desc; } else { @@ -302,21 +310,23 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport) BUG_ON(sport->dummy_tx_desc == NULL); BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc); - sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc + 1; + sport->dummy_tx_desc->next_desc_addr = \ + (unsigned long)(sport->dummy_tx_desc+1); /* Shorten the time on last normal descriptor */ local_irq_save(flags); - desc = get_dma_next_desc_ptr(sport->dma_tx_chan); + desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_tx_chan); /* Store the descriptor which will be damaged */ temp_desc = *desc; desc->x_count = 0xa; desc->y_count = 0; - desc->next_desc_addr = sport->dummy_tx_desc; + desc->next_desc_addr = (unsigned long)(sport->dummy_tx_desc); local_irq_restore(flags); /* Waiting for dummy buffer descriptor is already hooked*/ while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \ - sizeof(struct dmasg)) != sport->dummy_tx_desc) - continue; + sizeof(struct dmasg)) != \ + (unsigned long)sport->dummy_tx_desc) + ; sport->curr_tx_desc = sport->dummy_tx_desc; /* Restore the damaged descriptor */ *desc = temp_desc; @@ -337,9 +347,11 @@ int sport_tx_start(struct sport_device *sport) /* Hook the normal buffer descriptor */ local_irq_save(flags); while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - - sizeof(struct dmasg)) != sport->dummy_tx_desc) - continue; - sport->dummy_tx_desc->next_desc_addr = sport->dma_tx_desc; + sizeof(struct dmasg)) != + (unsigned long)sport->dummy_tx_desc) + ; + sport->dummy_tx_desc->next_desc_addr = + (unsigned long)(sport->dma_tx_desc); local_irq_restore(flags); sport->curr_tx_desc = sport->dma_tx_desc; } else { @@ -524,17 +536,19 @@ static int sport_config_rx_dummy(struct sport_device *sport) unsigned config; pr_debug("%s entered\n", __func__); - if (L1_DATA_A_LENGTH) - desc = l1_data_sram_zalloc(2 * sizeof(*desc)); - else { +#if L1_DATA_A_LENGTH != 0 + desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc)); +#else + { dma_addr_t addr; desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0); - memset(desc, 0, 2 * sizeof(*desc)); } +#endif if (desc == NULL) { pr_err("Failed to allocate memory for dummy rx desc\n"); return -ENOMEM; } + memset(desc, 0, 2 * sizeof(*desc)); sport->dummy_rx_desc = desc; desc->start_addr = (unsigned long)sport->dummy_buf; config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize) @@ -545,8 +559,8 @@ static int sport_config_rx_dummy(struct sport_device *sport) desc->y_count = 0; desc->y_modify = 0; memcpy(desc+1, desc, sizeof(*desc)); - desc->next_desc_addr = desc + 1; - desc[1].next_desc_addr = desc; + desc->next_desc_addr = (unsigned long)(desc+1); + desc[1].next_desc_addr = (unsigned long)desc; return 0; } @@ -557,17 +571,19 @@ static int sport_config_tx_dummy(struct sport_device *sport) pr_debug("%s entered\n", __func__); - if (L1_DATA_A_LENGTH) - desc = l1_data_sram_zalloc(2 * sizeof(*desc)); - else { +#if L1_DATA_A_LENGTH != 0 + desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc)); +#else + { dma_addr_t addr; desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0); - memset(desc, 0, 2 * sizeof(*desc)); } +#endif if (!desc) { pr_err("Failed to allocate memory for dummy tx desc\n"); return -ENOMEM; } + memset(desc, 0, 2 * sizeof(*desc)); sport->dummy_tx_desc = desc; desc->start_addr = (unsigned long)sport->dummy_buf + \ sport->dummy_count; @@ -579,8 +595,8 @@ static int sport_config_tx_dummy(struct sport_device *sport) desc->y_count = 0; desc->y_modify = 0; memcpy(desc+1, desc, sizeof(*desc)); - desc->next_desc_addr = desc + 1; - desc[1].next_desc_addr = desc; + desc->next_desc_addr = (unsigned long)(desc+1); + desc[1].next_desc_addr = (unsigned long)desc; return 0; } @@ -856,15 +872,17 @@ struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, sport->wdsize = wdsize; sport->dummy_count = dummy_count; - if (L1_DATA_A_LENGTH) - sport->dummy_buf = l1_data_sram_zalloc(dummy_count * 2); - else - sport->dummy_buf = kzalloc(dummy_count * 2, GFP_KERNEL); +#if L1_DATA_A_LENGTH != 0 + sport->dummy_buf = l1_data_sram_alloc(dummy_count * 2); +#else + sport->dummy_buf = kmalloc(dummy_count * 2, GFP_KERNEL); +#endif if (sport->dummy_buf == NULL) { pr_err("Failed to allocate dummy buffer\n"); goto __error; } + memset(sport->dummy_buf, 0, dummy_count * 2); ret = sport_config_rx_dummy(sport); if (ret) { pr_err("Failed to config rx dummy ring\n"); @@ -921,7 +939,6 @@ void sport_done(struct sport_device *sport) sport = NULL; } EXPORT_SYMBOL(sport_done); - /* * It is only used to send several bytes when dma is not enabled * sport controller is configured but not enabled. @@ -1012,3 +1029,4 @@ EXPORT_SYMBOL(sport_send_and_recv); MODULE_AUTHOR("Roy Huang"); MODULE_DESCRIPTION("SPORT driver for ADI Blackfin"); MODULE_LICENSE("GPL"); + diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index b6c7f7a01cb0..d0e0d691ae51 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -10,11 +10,9 @@ config SND_SOC_I2C_AND_SPI config SND_SOC_ALL_CODECS tristate "Build all ASoC CODEC drivers" - select SND_SOC_L3 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS select SND_SOC_AD1980 if SND_SOC_AC97_BUS select SND_SOC_AD73311 if I2C - select SND_SOC_AK4104 if SPI_MASTER select SND_SOC_AK4535 if I2C select SND_SOC_CS4270 if I2C select SND_SOC_PCM3008 @@ -26,7 +24,6 @@ config SND_SOC_ALL_CODECS select SND_SOC_UDA134X select SND_SOC_UDA1380 if I2C select SND_SOC_WM8350 if MFD_WM8350 - select SND_SOC_WM8400 if MFD_WM8400 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8580 if I2C select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI @@ -37,7 +34,6 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8903 if I2C select SND_SOC_WM8971 if I2C select SND_SOC_WM8990 if I2C - select SND_SOC_WM9705 if SND_SOC_AC97_BUS select SND_SOC_WM9712 if SND_SOC_AC97_BUS select SND_SOC_WM9713 if SND_SOC_AC97_BUS help @@ -62,9 +58,6 @@ config SND_SOC_AD1980 config SND_SOC_AD73311 tristate -config SND_SOC_AK4104 - tristate - config SND_SOC_AK4535 tristate @@ -72,6 +65,12 @@ config SND_SOC_AK4535 config SND_SOC_CS4270 tristate +# Cirrus Logic CS4270 Codec Hardware Mute Support +# Select if you have external muting circuitry attached to your CS4270. +config SND_SOC_CS4270_HWMUTE + bool + depends on SND_SOC_CS4270 + # Cirrus Logic CS4270 Codec VD = 3.3V Errata # Select if you are affected by the errata where the part will not function # if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will @@ -91,6 +90,7 @@ config SND_SOC_SSM2602 config SND_SOC_TLV320AIC23 tristate + depends on I2C config SND_SOC_TLV320AIC26 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE @@ -98,12 +98,15 @@ config SND_SOC_TLV320AIC26 config SND_SOC_TLV320AIC3X tristate + depends on I2C config SND_SOC_TWL4030 tristate + depends on TWL4030_CORE config SND_SOC_UDA134X tristate + select SND_SOC_L3 config SND_SOC_UDA1380 tristate @@ -111,9 +114,6 @@ config SND_SOC_UDA1380 config SND_SOC_WM8350 tristate -config SND_SOC_WM8400 - tristate - config SND_SOC_WM8510 tristate @@ -144,9 +144,6 @@ config SND_SOC_WM8971 config SND_SOC_WM8990 tristate -config SND_SOC_WM9705 - tristate - config SND_SOC_WM9712 tristate diff --git a/trunk/sound/soc/codecs/Makefile b/trunk/sound/soc/codecs/Makefile index 030d2454725f..c4ddc9aa2bbd 100644 --- a/trunk/sound/soc/codecs/Makefile +++ b/trunk/sound/soc/codecs/Makefile @@ -1,7 +1,6 @@ snd-soc-ac97-objs := ac97.o snd-soc-ad1980-objs := ad1980.o snd-soc-ad73311-objs := ad73311.o -snd-soc-ak4104-objs := ak4104.o snd-soc-ak4535-objs := ak4535.o snd-soc-cs4270-objs := cs4270.o snd-soc-l3-objs := l3.o @@ -14,7 +13,6 @@ snd-soc-twl4030-objs := twl4030.o snd-soc-uda134x-objs := uda134x.o snd-soc-uda1380-objs := uda1380.o snd-soc-wm8350-objs := wm8350.o -snd-soc-wm8400-objs := wm8400.o snd-soc-wm8510-objs := wm8510.o snd-soc-wm8580-objs := wm8580.o snd-soc-wm8728-objs := wm8728.o @@ -25,14 +23,12 @@ snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o snd-soc-wm8971-objs := wm8971.o snd-soc-wm8990-objs := wm8990.o -snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o snd-soc-wm9713-objs := wm9713.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o -obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o @@ -45,7 +41,6 @@ obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o -obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o @@ -56,7 +51,5 @@ obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o -obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o -obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o diff --git a/trunk/sound/soc/codecs/ac97.c b/trunk/sound/soc/codecs/ac97.c index b0d4af145b87..fb53e6511af2 100644 --- a/trunk/sound/soc/codecs/ac97.c +++ b/trunk/sound/soc/codecs/ac97.c @@ -30,7 +30,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; @@ -41,10 +41,6 @@ static int ac97_prepare(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops ac97_dai_ops = { - .prepare = ac97_prepare, -}; - struct snd_soc_dai ac97_dai = { .name = "AC97 HiFi", .ac97_control = 1, @@ -60,7 +56,8 @@ struct snd_soc_dai ac97_dai = { .channels_max = 2, .rates = STD_AC97_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &ac97_dai_ops, + .ops = { + .prepare = ac97_prepare,}, }; EXPORT_SYMBOL_GPL(ac97_dai); @@ -87,10 +84,10 @@ static int ac97_soc_probe(struct platform_device *pdev) printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); - socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (!socdev->card->codec) + socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (!socdev->codec) return -ENOMEM; - codec = socdev->card->codec; + codec = socdev->codec; mutex_init(&codec->mutex); codec->name = "AC97"; @@ -126,21 +123,23 @@ static int ac97_soc_probe(struct platform_device *pdev) snd_soc_free_pcms(socdev); err: - kfree(socdev->card->codec); - socdev->card->codec = NULL; + kfree(socdev->codec->reg_cache); + kfree(socdev->codec); + socdev->codec = NULL; return ret; } static int ac97_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (!codec) return 0; snd_soc_free_pcms(socdev); - kfree(socdev->card->codec); + kfree(socdev->codec->reg_cache); + kfree(socdev->codec); return 0; } @@ -150,7 +149,7 @@ static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - snd_ac97_suspend(socdev->card->codec->ac97); + snd_ac97_suspend(socdev->codec->ac97); return 0; } @@ -159,7 +158,7 @@ static int ac97_soc_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - snd_ac97_resume(socdev->card->codec->ac97); + snd_ac97_resume(socdev->codec->ac97); return 0; } diff --git a/trunk/sound/soc/codecs/ad1980.c b/trunk/sound/soc/codecs/ad1980.c index ddb3b08ac23c..73fdbb4d4a3d 100644 --- a/trunk/sound/soc/codecs/ad1980.c +++ b/trunk/sound/soc/codecs/ad1980.c @@ -93,6 +93,20 @@ SOC_ENUM("Capture Source", ad1980_cap_src), SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0), }; +/* add non dapm controls */ +static int ad1980_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(ad1980_snd_ac97_controls); i++) { + err = snd_ctl_add(codec->card, snd_soc_cnew( + &ad1980_snd_ac97_controls[i], codec, NULL)); + if (err < 0) + return err; + } + return 0; +} + static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { @@ -109,7 +123,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, default: reg = reg >> 1; - if (reg >= ARRAY_SIZE(ad1980_reg)) + if (reg >= (ARRAY_SIZE(ad1980_reg))) return -EINVAL; return cache[reg]; @@ -123,7 +137,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, soc_ac97_ops.write(codec->ac97, reg, val); reg = reg >> 1; - if (reg < ARRAY_SIZE(ad1980_reg)) + if (reg < (ARRAY_SIZE(ad1980_reg))) cache[reg] = val; return 0; @@ -186,10 +200,10 @@ static int ad1980_soc_probe(struct platform_device *pdev) printk(KERN_INFO "AD1980 SoC Audio Codec\n"); - socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (socdev->card->codec == NULL) + socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (socdev->codec == NULL) return -ENOMEM; - codec = socdev->card->codec; + codec = socdev->codec; mutex_init(&codec->mutex); codec->reg_cache = @@ -255,8 +269,7 @@ static int ad1980_soc_probe(struct platform_device *pdev) ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); - snd_soc_add_controls(codec, ad1980_snd_ac97_controls, - ARRAY_SIZE(ad1980_snd_ac97_controls)); + ad1980_add_controls(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { printk(KERN_ERR "ad1980: failed to register card\n"); @@ -275,15 +288,15 @@ static int ad1980_soc_probe(struct platform_device *pdev) kfree(codec->reg_cache); cache_err: - kfree(socdev->card->codec); - socdev->card->codec = NULL; + kfree(socdev->codec); + socdev->codec = NULL; return ret; } static int ad1980_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec == NULL) return 0; diff --git a/trunk/sound/soc/codecs/ad73311.c b/trunk/sound/soc/codecs/ad73311.c index e61dac5e7b8f..b09289a1e55a 100644 --- a/trunk/sound/soc/codecs/ad73311.c +++ b/trunk/sound/soc/codecs/ad73311.c @@ -53,7 +53,7 @@ static int ad73311_soc_probe(struct platform_device *pdev) codec->owner = THIS_MODULE; codec->dai = &ad73311_dai; codec->num_dai = 1; - socdev->card->codec = codec; + socdev->codec = codec; INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -75,15 +75,15 @@ static int ad73311_soc_probe(struct platform_device *pdev) register_err: snd_soc_free_pcms(socdev); pcm_err: - kfree(socdev->card->codec); - socdev->card->codec = NULL; + kfree(socdev->codec); + socdev->codec = NULL; return ret; } static int ad73311_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec == NULL) return 0; diff --git a/trunk/sound/soc/codecs/ad73311.h b/trunk/sound/soc/codecs/ad73311.h index 569573d2d4d7..507ce0c30edf 100644 --- a/trunk/sound/soc/codecs/ad73311.h +++ b/trunk/sound/soc/codecs/ad73311.h @@ -70,7 +70,7 @@ #define REGD_IGS(x) (x & 0x7) #define REGD_RMOD (1 << 3) #define REGD_OGS(x) ((x & 0x7) << 4) -#define REGD_MUTE (1 << 7) +#define REGD_MUTE (x << 7) /* Control register E */ #define CTRL_REG_E (4 << 8) diff --git a/trunk/sound/soc/codecs/ak4104.c b/trunk/sound/soc/codecs/ak4104.c deleted file mode 100644 index 4d47bc4f7428..000000000000 --- a/trunk/sound/soc/codecs/ak4104.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * AK4104 ALSA SoC (ASoC) driver - * - * Copyright (c) 2009 Daniel Mack - * - * 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 "ak4104.h" - -/* AK4104 registers addresses */ -#define AK4104_REG_CONTROL1 0x00 -#define AK4104_REG_RESERVED 0x01 -#define AK4104_REG_CONTROL2 0x02 -#define AK4104_REG_TX 0x03 -#define AK4104_REG_CHN_STATUS(x) ((x) + 0x04) -#define AK4104_NUM_REGS 10 - -#define AK4104_REG_MASK 0x1f -#define AK4104_READ 0xc0 -#define AK4104_WRITE 0xe0 -#define AK4104_RESERVED_VAL 0x5b - -/* Bit masks for AK4104 registers */ -#define AK4104_CONTROL1_RSTN (1 << 0) -#define AK4104_CONTROL1_PW (1 << 1) -#define AK4104_CONTROL1_DIF0 (1 << 2) -#define AK4104_CONTROL1_DIF1 (1 << 3) - -#define AK4104_CONTROL2_SEL0 (1 << 0) -#define AK4104_CONTROL2_SEL1 (1 << 1) -#define AK4104_CONTROL2_MODE (1 << 2) - -#define AK4104_TX_TXE (1 << 0) -#define AK4104_TX_V (1 << 1) - -#define DRV_NAME "ak4104" - -struct ak4104_private { - struct snd_soc_codec codec; - u8 reg_cache[AK4104_NUM_REGS]; -}; - -static int ak4104_fill_cache(struct snd_soc_codec *codec) -{ - int i; - u8 *reg_cache = codec->reg_cache; - struct spi_device *spi = codec->control_data; - - for (i = 0; i < codec->reg_cache_size; i++) { - int ret = spi_w8r8(spi, i | AK4104_READ); - if (ret < 0) { - dev_err(&spi->dev, "SPI write failure\n"); - return ret; - } - - reg_cache[i] = ret; - } - - return 0; -} - -static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u8 *reg_cache = codec->reg_cache; - - if (reg >= codec->reg_cache_size) - return -EINVAL; - - return reg_cache[reg]; -} - -static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 *cache = codec->reg_cache; - struct spi_device *spi = codec->control_data; - - if (reg >= codec->reg_cache_size) - return -EINVAL; - - reg &= AK4104_REG_MASK; - reg |= AK4104_WRITE; - - /* only write to the hardware if value has changed */ - if (cache[reg] != value) { - u8 tmp[2] = { reg, value }; - if (spi_write(spi, tmp, sizeof(tmp))) { - dev_err(&spi->dev, "SPI write failed\n"); - return -EIO; - } - - cache[reg] = value; - } - - return 0; -} - -static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int format) -{ - struct snd_soc_codec *codec = codec_dai->codec; - int val = 0; - - val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); - if (val < 0) - return val; - - val &= ~(AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1); - - /* set DAI format */ - switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_LEFT_J: - val |= AK4104_CONTROL1_DIF0; - break; - case SND_SOC_DAIFMT_I2S: - val |= AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1; - break; - default: - dev_err(codec->dev, "invalid dai format\n"); - return -EINVAL; - } - - /* This device can only be slave */ - if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) - return -EINVAL; - - return ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); -} - -static int ak4104_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; - int val = 0; - - /* set the IEC958 bits: consumer mode, no copyright bit */ - val |= IEC958_AES0_CON_NOT_COPYRIGHT; - ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(0), val); - - val = 0; - - switch (params_rate(params)) { - case 44100: - val |= IEC958_AES3_CON_FS_44100; - break; - case 48000: - val |= IEC958_AES3_CON_FS_48000; - break; - case 32000: - val |= IEC958_AES3_CON_FS_32000; - break; - default: - dev_err(codec->dev, "unsupported sampling rate\n"); - return -EINVAL; - } - - return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val); -} - -static struct snd_soc_dai_ops ak4101_dai_ops = { - .hw_params = ak4104_hw_params, - .set_fmt = ak4104_set_dai_fmt, -}; - -struct snd_soc_dai ak4104_dai = { - .name = DRV_NAME, - .playback = { - .stream_name = "Playback", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_32000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S24_LE - }, - .ops = &ak4101_dai_ops, -}; - -static struct snd_soc_codec *ak4104_codec; - -static int ak4104_spi_probe(struct spi_device *spi) -{ - struct snd_soc_codec *codec; - struct ak4104_private *ak4104; - int ret, val; - - spi->bits_per_word = 8; - spi->mode = SPI_MODE_0; - ret = spi_setup(spi); - if (ret < 0) - return ret; - - ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL); - if (!ak4104) { - dev_err(&spi->dev, "could not allocate codec\n"); - return -ENOMEM; - } - - codec = &ak4104->codec; - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - codec->dev = &spi->dev; - codec->name = DRV_NAME; - codec->owner = THIS_MODULE; - codec->dai = &ak4104_dai; - codec->num_dai = 1; - codec->private_data = ak4104; - codec->control_data = spi; - codec->reg_cache = ak4104->reg_cache; - codec->reg_cache_size = AK4104_NUM_REGS; - - /* read all regs and fill the cache */ - ret = ak4104_fill_cache(codec); - if (ret < 0) { - dev_err(&spi->dev, "failed to fill register cache\n"); - return ret; - } - - /* read the 'reserved' register - according to the datasheet, it - * should contain 0x5b. Not a good way to verify the presence of - * the device, but there is no hardware ID register. */ - if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) != - AK4104_RESERVED_VAL) { - ret = -ENODEV; - goto error_free_codec; - } - - /* set power-up and non-reset bits */ - val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); - val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN; - ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); - if (ret < 0) - goto error_free_codec; - - /* enable transmitter */ - val = ak4104_read_reg_cache(codec, AK4104_REG_TX); - val |= AK4104_TX_TXE; - ret = ak4104_spi_write(codec, AK4104_REG_TX, val); - if (ret < 0) - goto error_free_codec; - - ak4104_codec = codec; - ret = snd_soc_register_dai(&ak4104_dai); - if (ret < 0) { - dev_err(&spi->dev, "failed to register DAI\n"); - goto error_free_codec; - } - - spi_set_drvdata(spi, ak4104); - dev_info(&spi->dev, "SPI device initialized\n"); - return 0; - -error_free_codec: - kfree(ak4104); - ak4104_dai.dev = NULL; - return ret; -} - -static int __devexit ak4104_spi_remove(struct spi_device *spi) -{ - int ret, val; - struct ak4104_private *ak4104 = spi_get_drvdata(spi); - - val = ak4104_read_reg_cache(&ak4104->codec, AK4104_REG_CONTROL1); - if (val < 0) - return val; - - /* clear power-up and non-reset bits */ - val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); - ret = ak4104_spi_write(&ak4104->codec, AK4104_REG_CONTROL1, val); - if (ret < 0) - return ret; - - ak4104_codec = NULL; - kfree(ak4104); - return 0; -} - -static int ak4104_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = ak4104_codec; - int ret; - - /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ - socdev->card->codec = codec; - - /* Register PCMs */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - dev_err(codec->dev, "failed to create pcms\n"); - return ret; - } - - /* Register the socdev */ - ret = snd_soc_init_card(socdev); - if (ret < 0) { - dev_err(codec->dev, "failed to register card\n"); - snd_soc_free_pcms(socdev); - return ret; - } - - return 0; -} - -static int ak4104_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - snd_soc_free_pcms(socdev); - return 0; -}; - -struct snd_soc_codec_device soc_codec_device_ak4104 = { - .probe = ak4104_probe, - .remove = ak4104_remove -}; -EXPORT_SYMBOL_GPL(soc_codec_device_ak4104); - -static struct spi_driver ak4104_spi_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ak4104_spi_probe, - .remove = __devexit_p(ak4104_spi_remove), -}; - -static int __init ak4104_init(void) -{ - pr_info("Asahi Kasei AK4104 ALSA SoC Codec Driver\n"); - return spi_register_driver(&ak4104_spi_driver); -} -module_init(ak4104_init); - -static void __exit ak4104_exit(void) -{ - spi_unregister_driver(&ak4104_spi_driver); -} -module_exit(ak4104_exit); - -MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/sound/soc/codecs/ak4104.h b/trunk/sound/soc/codecs/ak4104.h deleted file mode 100644 index eb88fe7e4def..000000000000 --- a/trunk/sound/soc/codecs/ak4104.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _AK4104_H -#define _AK4104_H - -extern struct snd_soc_dai ak4104_dai; -extern struct snd_soc_codec_device soc_codec_device_ak4104; - -#endif diff --git a/trunk/sound/soc/codecs/ak4535.c b/trunk/sound/soc/codecs/ak4535.c index 1f63d387a2f4..81300d8d42ca 100644 --- a/trunk/sound/soc/codecs/ak4535.c +++ b/trunk/sound/soc/codecs/ak4535.c @@ -155,6 +155,21 @@ static const struct snd_kcontrol_new ak4535_snd_controls[] = { SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL, 4, 7, 0), }; +/* add non dapm controls */ +static int ak4535_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(ak4535_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&ak4535_snd_controls[i], codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + /* Mono 1 Mixer */ static const struct snd_kcontrol_new ak4535_mono1_mixer_controls[] = { SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1, 4, 1, 0), @@ -329,7 +344,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct ak4535_priv *ak4535 = codec->private_data; u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); int rate = params_rate(params), fs = 256; @@ -421,13 +436,6 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops ak4535_dai_ops = { - .hw_params = ak4535_hw_params, - .set_fmt = ak4535_set_dai_fmt, - .digital_mute = ak4535_mute, - .set_sysclk = ak4535_set_dai_sysclk, -}; - struct snd_soc_dai ak4535_dai = { .name = "AK4535", .playback = { @@ -442,14 +450,19 @@ struct snd_soc_dai ak4535_dai = { .channels_max = 2, .rates = AK4535_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &ak4535_dai_ops, + .ops = { + .hw_params = ak4535_hw_params, + .set_fmt = ak4535_set_dai_fmt, + .digital_mute = ak4535_mute, + .set_sysclk = ak4535_set_dai_sysclk, + }, }; EXPORT_SYMBOL_GPL(ak4535_dai); static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -458,7 +471,7 @@ static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) static int ak4535_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; ak4535_sync(codec); ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); ak4535_set_bias_level(codec, codec->suspend_bias_level); @@ -471,7 +484,7 @@ static int ak4535_resume(struct platform_device *pdev) */ static int ak4535_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret = 0; codec->name = "AK4535"; @@ -497,8 +510,7 @@ static int ak4535_init(struct snd_soc_device *socdev) /* power on device */ ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, ak4535_snd_controls, - ARRAY_SIZE(ak4535_snd_controls)); + ak4535_add_controls(codec); ak4535_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -525,7 +537,7 @@ static int ak4535_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct snd_soc_device *socdev = ak4535_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -624,7 +636,7 @@ static int ak4535_probe(struct platform_device *pdev) } codec->private_data = ak4535; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -651,7 +663,7 @@ static int ak4535_probe(struct platform_device *pdev) static int ak4535_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/cs4270.c b/trunk/sound/soc/codecs/cs4270.c index 7fa09a387622..f1aa0c34421c 100644 --- a/trunk/sound/soc/codecs/cs4270.c +++ b/trunk/sound/soc/codecs/cs4270.c @@ -3,22 +3,27 @@ * * Author: Timur Tabi * - * Copyright 2007-2009 Freescale Semiconductor, Inc. This file is licensed - * under the terms of the GNU General Public License version 2. This - * program is licensed "as is" without any warranty of any kind, whether - * express or implied. + * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. * * This is an ASoC device driver for the Cirrus Logic CS4270 codec. * * Current features/limitations: * - * - Software mode is supported. Stand-alone mode is not supported. - * - Only I2C is supported, not SPI - * - Support for master and slave mode - * - The machine driver's 'startup' function must call - * cs4270_set_dai_sysclk() with the value of MCLK. - * - Only I2S and left-justified modes are supported - * - Power management is not supported + * 1) Software mode is supported. Stand-alone mode is automatically + * selected if I2C is disabled or if a CS4270 is not found on the I2C + * bus. However, stand-alone mode is only partially implemented because + * there is no mechanism yet for this driver and the machine driver to + * communicate the values of the M0, M1, MCLK1, and MCLK2 pins. + * 2) Only I2C is supported, not SPI + * 3) Only Master mode is supported, not Slave. + * 4) The machine driver's 'startup' function must call + * cs4270_set_dai_sysclk() with the value of MCLK. + * 5) Only I2S and left-justified modes are supported + * 6) Power management is not supported + * 7) The only supported control is volume and hardware mute (if enabled) */ #include @@ -30,6 +35,18 @@ #include "cs4270.h" +/* If I2C is defined, then we support software mode. However, if we're + not compiled as module but I2C is, then we can't use I2C calls. */ +#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) +#define USE_I2C +#endif + +/* Private data for the CS4270 */ +struct cs4270_private { + unsigned int mclk; /* Input frequency of the MCLK pin */ + unsigned int mode; /* The mode (I2S or left-justified) */ +}; + /* * The codec isn't really big-endian or little-endian, since the I2S * interface requires data to be sent serially with the MSbit first. @@ -43,6 +60,8 @@ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) +#ifdef USE_I2C + /* CS4270 registers addresses */ #define CS4270_CHIPID 0x01 /* Chip ID */ #define CS4270_PWRCTL 0x02 /* Power Control */ @@ -102,22 +121,8 @@ #define CS4270_MUTE_DAC_A 0x01 #define CS4270_MUTE_DAC_B 0x02 -/* Private data for the CS4270 */ -struct cs4270_private { - struct snd_soc_codec codec; - u8 reg_cache[CS4270_NUMREGS]; - unsigned int mclk; /* Input frequency of the MCLK pin */ - unsigned int mode; /* The mode (I2S or left-justified) */ - unsigned int slave_mode; -}; - -/** - * struct cs4270_mode_ratios - clock ratio tables - * @ratio: the ratio of MCLK to the sample rate - * @speed_mode: the Speed Mode bits to set in the Mode Control register for - * this ratio - * @mclk: the Ratio Select bits to set in the Mode Control register for this - * ratio +/* + * Clock Ratio Selection for Master Mode with I2C enabled * * The data for this chart is taken from Table 5 of the CS4270 reference * manual. @@ -126,30 +131,31 @@ struct cs4270_private { * It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling * rates the CS4270 currently supports. * - * @speed_mode is the corresponding bit pattern to be written to the + * Each element in this array corresponds to the ratios in mclk_ratios[]. + * These two arrays need to be in sync. + * + * 'speed_mode' is the corresponding bit pattern to be written to the * MODE bits of the Mode Control Register * - * @mclk is the corresponding bit pattern to be wirten to the MCLK bits of + * 'mclk' is the corresponding bit pattern to be wirten to the MCLK bits of * the Mode Control Register. * * In situations where a single ratio is represented by multiple speed * modes, we favor the slowest speed. E.g, for a ratio of 128, we pick * double-speed instead of quad-speed. However, the CS4270 errata states - * that divide-By-1.5 can cause failures, so we avoid that mode where + * that Divide-By-1.5 can cause failures, so we avoid that mode where * possible. * - * Errata: There is an errata for the CS4270 where divide-by-1.5 does not - * work if Vd is 3.3V. If this effects you, select the + * ERRATA: There is an errata for the CS4270 where divide-by-1.5 does not + * work if VD = 3.3V. If this effects you, select the * CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will * never select any sample rates that require divide-by-1.5. */ -struct cs4270_mode_ratios { +static struct { unsigned int ratio; u8 speed_mode; u8 mclk; -}; - -static struct cs4270_mode_ratios cs4270_mode_ratios[] = { +} cs4270_mode_ratios[] = { {64, CS4270_MODE_4X, CS4270_MODE_DIV1}, #ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA {96, CS4270_MODE_4X, CS4270_MODE_DIV15}, @@ -166,27 +172,34 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = { /* The number of MCLK/LRCK ratios supported by the CS4270 */ #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) -/** - * cs4270_set_dai_sysclk - determine the CS4270 samples rates. - * @codec_dai: the codec DAI - * @clk_id: the clock ID (ignored) - * @freq: the MCLK input frequency - * @dir: the clock direction (ignored) +/* + * Determine the CS4270 samples rates. * - * This function is used to tell the codec driver what the input MCLK - * frequency is. + * 'freq' is the input frequency to MCLK. The other parameters are ignored. * * The value of MCLK is used to determine which sample rates are supported * by the CS4270. The ratio of MCLK / Fs must be equal to one of nine - * supported values - 64, 96, 128, 192, 256, 384, 512, 768, and 1024. + * support values: 64, 96, 128, 192, 256, 384, 512, 768, and 1024. * * This function calculates the nine ratios and determines which ones match * a standard sample rate. If there's a match, then it is added to the list - * of supported sample rates. + * of support sample rates. * * This function must be called by the machine driver's 'startup' function, * otherwise the list of supported sample rates will not be available in * time for ALSA. + * + * Note that in stand-alone mode, the sample rate is determined by input + * pins M0, M1, MDIV1, and MDIV2. Also in stand-alone mode, divide-by-3 + * is not a programmable option. However, divide-by-3 is not an available + * option in stand-alone mode. This cases two problems: a ratio of 768 is + * not available (it requires divide-by-3) and B) ratios 192 and 384 can + * only be selected with divide-by-1.5, but there is an errate that make + * this selection difficult. + * + * In addition, there is no mechanism for communicating with the machine + * driver what the input settings can be. This would need to be implemented + * for stand-alone mode to work. */ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) @@ -212,7 +225,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, rates &= ~SNDRV_PCM_RATE_KNOT; if (!rates) { - dev_err(codec->dev, "could not find a valid sample rate\n"); + printk(KERN_ERR "cs4270: could not find a valid sample rate\n"); return -EINVAL; } @@ -227,10 +240,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, return 0; } -/** - * cs4270_set_dai_fmt - configure the codec for the selected audio format - * @codec_dai: the codec DAI - * @format: a SND_SOC_DAIFMT_x value indicating the data format +/* + * Configure the codec for the selected audio format * * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the * codec accordingly. @@ -247,43 +258,32 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, struct cs4270_private *cs4270 = codec->private_data; int ret = 0; - /* set DAI format */ switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_LEFT_J: cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK; break; default: - dev_err(codec->dev, "invalid dai format\n"); - ret = -EINVAL; - } - - /* set master/slave audio interface */ - switch (format & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - cs4270->slave_mode = 1; - break; - case SND_SOC_DAIFMT_CBM_CFM: - cs4270->slave_mode = 0; - break; - default: - /* all other modes are unsupported by the hardware */ + printk(KERN_ERR "cs4270: invalid DAI format\n"); ret = -EINVAL; } return ret; } -/** - * cs4270_fill_cache - pre-fill the CS4270 register cache. - * @codec: the codec for this CS4270 - * - * This function fills in the CS4270 register cache by reading the register - * values from the hardware. - * - * This CS4270 registers are cached to avoid excessive I2C I/O operations. - * After the initial read to pre-fill the cache, the CS4270 never updates - * the register values, so we won't have a cache coherency problem. +/* + * A list of addresses on which this CS4270 could use. I2C addresses are + * 7 bits. For the CS4270, the upper four bits are always 1001, and the + * lower three bits are determined via the AD2, AD1, and AD0 pins + * (respectively). + */ +static const unsigned short normal_i2c[] = { + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, I2C_CLIENT_END +}; +I2C_CLIENT_INSMOD; + +/* + * Pre-fill the CS4270 register cache. * * We use the auto-increment feature of the CS4270 to read all registers in * one shot. @@ -298,7 +298,7 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec) CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache); if (length != CS4270_NUMREGS) { - dev_err(codec->dev, "i2c read failure, addr=0x%x\n", + printk(KERN_ERR "cs4270: I2C read failure, addr=0x%x\n", i2c_client->addr); return -EIO; } @@ -306,17 +306,12 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec) return 0; } -/** - * cs4270_read_reg_cache - read from the CS4270 register cache. - * @codec: the codec for this CS4270 - * @reg: the register to read - * - * This function returns the value for a given register. It reads only from - * the register cache, not the hardware itself. +/* + * Read from the CS4270 register cache. * * This CS4270 registers are cached to avoid excessive I2C I/O operations. * After the initial read to pre-fill the cache, the CS4270 never updates - * the register values, so we won't have a cache coherency problem. + * the register values, so we won't have a cache coherncy problem. */ static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) @@ -329,11 +324,8 @@ static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, return cache[reg - CS4270_FIRSTREG]; } -/** - * cs4270_i2c_write - write to a CS4270 register via the I2C bus. - * @codec: the codec for this CS4270 - * @reg: the register to write - * @value: the value to write to the register +/* + * Write to a CS4270 register via the I2C bus. * * This function writes the given value to the given CS4270 register, and * also updates the register cache. @@ -354,7 +346,7 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg, if (cache[reg - CS4270_FIRSTREG] != value) { struct i2c_client *client = codec->control_data; if (i2c_smbus_write_byte_data(client, reg, value)) { - dev_err(codec->dev, "i2c write failed\n"); + printk(KERN_ERR "cs4270: I2C write failed\n"); return -EIO; } @@ -365,17 +357,11 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg, return 0; } -/** - * cs4270_hw_params - program the CS4270 with the given hardware parameters. - * @substream: the audio stream - * @params: the hardware parameters to set - * @dai: the SOC DAI (ignored) - * - * This function programs the hardware with the values provided. - * Specifically, the sample rate and the data format. +/* + * Program the CS4270 with the given hardware parameters. * - * The .ops functions are used to provide board-specific data, like input - * frequencies, to this driver. This function takes that information, + * The .ops functions are used to provide board-specific data, like + * input frequencies, to this driver. This function takes that information, * combines it with the hardware parameters provided, and programs the * hardware accordingly. */ @@ -385,7 +371,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct cs4270_private *cs4270 = codec->private_data; int ret; unsigned int i; @@ -405,28 +391,33 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, if (i == NUM_MCLK_RATIOS) { /* We did not find a matching ratio */ - dev_err(codec->dev, "could not find matching ratio\n"); + printk(KERN_ERR "cs4270: could not find matching ratio\n"); return -EINVAL; } - /* Set the sample rate */ + /* Freeze and power-down the codec */ + + ret = snd_soc_write(codec, CS4270_PWRCTL, CS4270_PWRCTL_FREEZE | + CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | + CS4270_PWRCTL_PDN); + if (ret < 0) { + printk(KERN_ERR "cs4270: I2C write failed\n"); + return ret; + } + + /* Program the mode control register */ reg = snd_soc_read(codec, CS4270_MODE); reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK); - reg |= cs4270_mode_ratios[i].mclk; - - if (cs4270->slave_mode) - reg |= CS4270_MODE_SLAVE; - else - reg |= cs4270_mode_ratios[i].speed_mode; + reg |= cs4270_mode_ratios[i].speed_mode | cs4270_mode_ratios[i].mclk; ret = snd_soc_write(codec, CS4270_MODE, reg); if (ret < 0) { - dev_err(codec->dev, "i2c write failed\n"); + printk(KERN_ERR "cs4270: I2C write failed\n"); return ret; } - /* Set the DAI format */ + /* Program the format register */ reg = snd_soc_read(codec, CS4270_FORMAT); reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK); @@ -439,23 +430,55 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ; break; default: - dev_err(codec->dev, "unknown dai format\n"); + printk(KERN_ERR "cs4270: unknown format\n"); return -EINVAL; } ret = snd_soc_write(codec, CS4270_FORMAT, reg); if (ret < 0) { - dev_err(codec->dev, "i2c write failed\n"); + printk(KERN_ERR "cs4270: I2C write failed\n"); + return ret; + } + + /* Disable auto-mute. This feature appears to be buggy, because in + some situations, auto-mute will not deactivate when it should. */ + + reg = snd_soc_read(codec, CS4270_MUTE); + reg &= ~CS4270_MUTE_AUTO; + ret = snd_soc_write(codec, CS4270_MUTE, reg); + if (ret < 0) { + printk(KERN_ERR "cs4270: I2C write failed\n"); + return ret; + } + + /* Disable automatic volume control. It's enabled by default, and + * it causes volume change commands to be delayed, sometimes until + * after playback has started. + */ + + reg = cs4270_read_reg_cache(codec, CS4270_TRANS); + reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); + ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); + if (ret < 0) { + printk(KERN_ERR "I2C write failed\n"); + return ret; + } + + /* Thaw and power-up the codec */ + + ret = snd_soc_write(codec, CS4270_PWRCTL, 0); + if (ret < 0) { + printk(KERN_ERR "cs4270: I2C write failed\n"); return ret; } return ret; } -/** - * cs4270_mute - enable/disable the CS4270 external mute - * @dai: the SOC DAI - * @mute: 0 = disable mute, 1 = enable mute +#ifdef CONFIG_SND_SOC_CS4270_HWMUTE + +/* + * Set the CS4270 external mute * * This function toggles the mute bits in the MUTE register. The CS4270's * mute capability is intended for external muting circuitry, so if the @@ -470,304 +493,274 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute) reg6 = snd_soc_read(codec, CS4270_MUTE); if (mute) - reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B; + reg6 |= CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | + CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B; else - reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B); + reg6 &= ~(CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | + CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B); return snd_soc_write(codec, CS4270_MUTE, reg6); } +#endif + +static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *); + /* A list of non-DAPM controls that the CS4270 supports */ static const struct snd_kcontrol_new cs4270_snd_controls[] = { SOC_DOUBLE_R("Master Playback Volume", - CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1), - SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0), - SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0), - SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), - SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), - SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), - SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0) + CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) }; -/* - * cs4270_codec - global variable to store codec for the ASoC probe function - * - * If struct i2c_driver had a private_data field, we wouldn't need to use - * cs4270_codec. This is the only way to pass the codec structure from - * cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good - * way to synchronize these two functions. cs4270_i2c_probe() can be called - * multiple times before cs4270_probe() is called even once. So for now, we - * also only allow cs4270_i2c_probe() to be run once. That means that we do - * not support more than one cs4270 device in the system, at least for now. - */ -static struct snd_soc_codec *cs4270_codec; - -static struct snd_soc_dai_ops cs4270_dai_ops = { - .hw_params = cs4270_hw_params, - .set_sysclk = cs4270_set_dai_sysclk, - .set_fmt = cs4270_set_dai_fmt, - .digital_mute = cs4270_mute, +static const struct i2c_device_id cs4270_id[] = { + {"cs4270", 0}, + {} }; +MODULE_DEVICE_TABLE(i2c, cs4270_id); -struct snd_soc_dai cs4270_dai = { - .name = "cs4270", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = 0, - .formats = CS4270_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = 0, - .formats = CS4270_FORMATS, +static struct i2c_driver cs4270_i2c_driver = { + .driver = { + .name = "CS4270 I2C", + .owner = THIS_MODULE, }, - .ops = &cs4270_dai_ops, + .id_table = cs4270_id, + .probe = cs4270_i2c_probe, }; -EXPORT_SYMBOL_GPL(cs4270_dai); -/** - * cs4270_probe - ASoC probe function - * @pdev: platform device +/* + * Global variable to store socdev for i2c probe function. * - * This function is called when ASoC has all the pieces it needs to - * instantiate a sound driver. + * If struct i2c_driver had a private_data field, we wouldn't need to use + * cs4270_socdec. This is the only way to pass the socdev structure to + * cs4270_i2c_probe(). + * + * The real solution to cs4270_socdev is to create a mechanism + * that maps I2C addresses to snd_soc_device structures. Perhaps the + * creation of the snd_soc_device object should be moved out of + * cs4270_probe() and into cs4270_i2c_probe(), but that would make this + * driver dependent on I2C. The CS4270 supports "stand-alone" mode, whereby + * the chip is *not* connected to the I2C bus, but is instead configured via + * input pins. */ -static int cs4270_probe(struct platform_device *pdev) +static struct snd_soc_device *cs4270_socdev; + +/* + * Initialize the I2C interface of the CS4270 + * + * This function is called for whenever the I2C subsystem finds a device + * at a particular address. + * + * Note: snd_soc_new_pcms() must be called before this function can be called, + * because of snd_ctl_add(). + */ +static int cs4270_i2c_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = cs4270_codec; - int ret; + struct snd_soc_device *socdev = cs4270_socdev; + struct snd_soc_codec *codec = socdev->codec; + int i; + int ret = 0; - /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ - socdev->card->codec = codec; + /* Probing all possible addresses has one drawback: if there are + multiple CS4270s on the bus, then you cannot specify which + socdev is matched with which CS4270. For now, we just reject + this I2C device if the socdev already has one attached. */ + if (codec->control_data) + return -ENODEV; - /* Register PCMs */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - dev_err(codec->dev, "failed to create pcms\n"); - return ret; + /* Note: codec_dai->codec is NULL here */ + + codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL); + if (!codec->reg_cache) { + printk(KERN_ERR "cs4270: could not allocate register cache\n"); + ret = -ENOMEM; + goto error; } - /* Add the non-DAPM controls */ - ret = snd_soc_add_controls(codec, cs4270_snd_controls, - ARRAY_SIZE(cs4270_snd_controls)); + /* Verify that we have a CS4270 */ + + ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); if (ret < 0) { - dev_err(codec->dev, "failed to add controls\n"); - goto error_free_pcms; + printk(KERN_ERR "cs4270: failed to read I2C\n"); + goto error; + } + /* The top four bits of the chip ID should be 1100. */ + if ((ret & 0xF0) != 0xC0) { + /* The device at this address is not a CS4270 codec */ + ret = -ENODEV; + goto error; } - /* And finally, register the socdev */ - ret = snd_soc_init_card(socdev); + printk(KERN_INFO "cs4270: found device at I2C address %X\n", + i2c_client->addr); + printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF); + + codec->control_data = i2c_client; + codec->read = cs4270_read_reg_cache; + codec->write = cs4270_i2c_write; + codec->reg_cache_size = CS4270_NUMREGS; + + /* The I2C interface is set up, so pre-fill our register cache */ + + ret = cs4270_fill_cache(codec); if (ret < 0) { - dev_err(codec->dev, "failed to register card\n"); - goto error_free_pcms; + printk(KERN_ERR "cs4270: failed to fill register cache\n"); + goto error; } + /* Add the non-DAPM controls */ + + for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) { + struct snd_kcontrol *kctrl = + snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL); + + ret = snd_ctl_add(codec->card, kctrl); + if (ret < 0) + goto error; + } + + i2c_set_clientdata(i2c_client, codec); + return 0; -error_free_pcms: - snd_soc_free_pcms(socdev); +error: + codec->control_data = NULL; + + kfree(codec->reg_cache); + codec->reg_cache = NULL; + codec->reg_cache_size = 0; return ret; } -/** - * cs4270_remove - ASoC remove function - * @pdev: platform device - * - * This function is the counterpart to cs4270_probe(). - */ -static int cs4270_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - - snd_soc_free_pcms(socdev); +#endif /* USE_I2C*/ - return 0; +struct snd_soc_dai cs4270_dai = { + .name = "CS4270", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = 0, + .formats = CS4270_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = 0, + .formats = CS4270_FORMATS, + }, }; +EXPORT_SYMBOL_GPL(cs4270_dai); -/** - * cs4270_i2c_probe - initialize the I2C interface of the CS4270 - * @i2c_client: the I2C client object - * @id: the I2C device ID (ignored) +/* + * ASoC probe function * - * This function is called whenever the I2C subsystem finds a device that - * matches the device ID given via a prior call to i2c_add_driver(). + * This function is called when the machine driver calls + * platform_device_add(). */ -static int cs4270_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs4270_probe(struct platform_device *pdev) { + struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec; - struct cs4270_private *cs4270; - unsigned int reg; - int ret; - - /* For now, we only support one cs4270 device in the system. See the - * comment for cs4270_codec. - */ - if (cs4270_codec) { - dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n", - i2c_client->addr); - dev_err(&i2c_client->dev, "only one per board allowed\n"); - /* Should we return something other than ENODEV here? */ - return -ENODEV; - } - - /* Verify that we have a CS4270 */ - - ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); - if (ret < 0) { - dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n", - i2c_client->addr); - return ret; - } - /* The top four bits of the chip ID should be 1100. */ - if ((ret & 0xF0) != 0xC0) { - dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n", - i2c_client->addr); - return -ENODEV; - } + int ret = 0; - dev_info(&i2c_client->dev, "found device at i2c address %X\n", - i2c_client->addr); - dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF); + printk(KERN_INFO "CS4270 ALSA SoC Codec\n"); /* Allocate enough space for the snd_soc_codec structure and our private data together. */ - cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL); - if (!cs4270) { - dev_err(&i2c_client->dev, "could not allocate codec\n"); + codec = kzalloc(ALIGN(sizeof(struct snd_soc_codec), 4) + + sizeof(struct cs4270_private), GFP_KERNEL); + if (!codec) { + printk(KERN_ERR "cs4270: Could not allocate codec structure\n"); return -ENOMEM; } - codec = &cs4270->codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); - codec->dev = &i2c_client->dev; codec->name = "CS4270"; codec->owner = THIS_MODULE; codec->dai = &cs4270_dai; codec->num_dai = 1; - codec->private_data = cs4270; - codec->control_data = i2c_client; - codec->read = cs4270_read_reg_cache; - codec->write = cs4270_i2c_write; - codec->reg_cache = cs4270->reg_cache; - codec->reg_cache_size = CS4270_NUMREGS; + codec->private_data = (void *) codec + + ALIGN(sizeof(struct snd_soc_codec), 4); - /* The I2C interface is set up, so pre-fill our register cache */ + socdev->codec = codec; - ret = cs4270_fill_cache(codec); + /* Register PCMs */ + + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { - dev_err(&i2c_client->dev, "failed to fill register cache\n"); + printk(KERN_ERR "cs4270: failed to create PCMs\n"); goto error_free_codec; } - /* Disable auto-mute. This feature appears to be buggy. In some - * situations, auto-mute will not deactivate when it should, so we want - * this feature disabled by default. An application (e.g. alsactl) can - * re-enabled it by using the controls. - */ +#ifdef USE_I2C + cs4270_socdev = socdev; - reg = cs4270_read_reg_cache(codec, CS4270_MUTE); - reg &= ~CS4270_MUTE_AUTO; - ret = cs4270_i2c_write(codec, CS4270_MUTE, reg); - if (ret < 0) { - dev_err(&i2c_client->dev, "i2c write failed\n"); - return ret; + ret = i2c_add_driver(&cs4270_i2c_driver); + if (ret) { + printk(KERN_ERR "cs4270: failed to attach driver"); + goto error_free_pcms; } - /* Disable automatic volume control. The hardware enables, and it - * causes volume change commands to be delayed, sometimes until after - * playback has started. An application (e.g. alsactl) can - * re-enabled it by using the controls. - */ + /* Did we find a CS4270 on the I2C bus? */ + if (codec->control_data) { + /* Initialize codec ops */ + cs4270_dai.ops.hw_params = cs4270_hw_params; + cs4270_dai.ops.set_sysclk = cs4270_set_dai_sysclk; + cs4270_dai.ops.set_fmt = cs4270_set_dai_fmt; +#ifdef CONFIG_SND_SOC_CS4270_HWMUTE + cs4270_dai.ops.digital_mute = cs4270_mute; +#endif + } else + printk(KERN_INFO "cs4270: no I2C device found, " + "using stand-alone mode\n"); +#else + printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n"); +#endif - reg = cs4270_read_reg_cache(codec, CS4270_TRANS); - reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); - ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); + ret = snd_soc_init_card(socdev); if (ret < 0) { - dev_err(&i2c_client->dev, "i2c write failed\n"); - return ret; + printk(KERN_ERR "cs4270: failed to register card\n"); + goto error_del_driver; } - /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI - * structure for each CS4270 device, but the machine driver needs to - * have a pointer to the DAI structure, so for now it must be a global - * variable. - */ - cs4270_dai.dev = &i2c_client->dev; - - /* Register the DAI. If all the other ASoC driver have already - * registered, then this will call our probe function, so - * cs4270_codec needs to be ready. - */ - cs4270_codec = codec; - ret = snd_soc_register_dai(&cs4270_dai); - if (ret < 0) { - dev_err(&i2c_client->dev, "failed to register DAIe\n"); - goto error_free_codec; - } + return 0; - i2c_set_clientdata(i2c_client, cs4270); +error_del_driver: +#ifdef USE_I2C + i2c_del_driver(&cs4270_i2c_driver); - return 0; +error_free_pcms: +#endif + snd_soc_free_pcms(socdev); error_free_codec: - kfree(cs4270); - cs4270_codec = NULL; - cs4270_dai.dev = NULL; + kfree(socdev->codec); + socdev->codec = NULL; return ret; } -/** - * cs4270_i2c_remove - remove an I2C device - * @i2c_client: the I2C client object - * - * This function is the counterpart to cs4270_i2c_probe(). - */ -static int cs4270_i2c_remove(struct i2c_client *i2c_client) +static int cs4270_remove(struct platform_device *pdev) { - struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client); + struct snd_soc_device *socdev = platform_get_drvdata(pdev); - kfree(cs4270); - cs4270_codec = NULL; - cs4270_dai.dev = NULL; + snd_soc_free_pcms(socdev); - return 0; -} +#ifdef USE_I2C + i2c_del_driver(&cs4270_i2c_driver); +#endif -/* - * cs4270_id - I2C device IDs supported by this driver - */ -static struct i2c_device_id cs4270_id[] = { - {"cs4270", 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, cs4270_id); + kfree(socdev->codec); + socdev->codec = NULL; -/* - * cs4270_i2c_driver - I2C device identification - * - * This structure tells the I2C subsystem how to identify and support a - * given I2C device type. - */ -static struct i2c_driver cs4270_i2c_driver = { - .driver = { - .name = "cs4270", - .owner = THIS_MODULE, - }, - .id_table = cs4270_id, - .probe = cs4270_i2c_probe, - .remove = cs4270_i2c_remove, -}; + return 0; +} /* * ASoC codec device structure @@ -783,15 +776,13 @@ EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); static int __init cs4270_init(void) { - pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n"); - - return i2c_add_driver(&cs4270_i2c_driver); + return snd_soc_register_dai(&cs4270_dai); } module_init(cs4270_init); static void __exit cs4270_exit(void) { - i2c_del_driver(&cs4270_i2c_driver); + snd_soc_unregister_dai(&cs4270_dai); } module_exit(cs4270_exit); diff --git a/trunk/sound/soc/codecs/pcm3008.c b/trunk/sound/soc/codecs/pcm3008.c index 5cda9e6b5a74..9a3e67e5319c 100644 --- a/trunk/sound/soc/codecs/pcm3008.c +++ b/trunk/sound/soc/codecs/pcm3008.c @@ -67,11 +67,11 @@ static int pcm3008_soc_probe(struct platform_device *pdev) printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION); - socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (!socdev->card->codec) + socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (!socdev->codec) return -ENOMEM; - codec = socdev->card->codec; + codec = socdev->codec; mutex_init(&codec->mutex); codec->name = "PCM3008"; @@ -139,7 +139,7 @@ static int pcm3008_soc_probe(struct platform_device *pdev) card_err: snd_soc_free_pcms(socdev); pcm_err: - kfree(socdev->card->codec); + kfree(socdev->codec); return ret; } @@ -147,7 +147,7 @@ static int pcm3008_soc_probe(struct platform_device *pdev) static int pcm3008_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct pcm3008_setup_data *setup = socdev->codec_data; if (!codec) @@ -155,7 +155,7 @@ static int pcm3008_soc_remove(struct platform_device *pdev) pcm3008_gpio_free(setup); snd_soc_free_pcms(socdev); - kfree(socdev->card->codec); + kfree(socdev->codec); return 0; } diff --git a/trunk/sound/soc/codecs/ssm2602.c b/trunk/sound/soc/codecs/ssm2602.c index 87f606c76822..cac373616768 100644 --- a/trunk/sound/soc/codecs/ssm2602.c +++ b/trunk/sound/soc/codecs/ssm2602.c @@ -151,6 +151,21 @@ SOC_ENUM("Capture Source", ssm2602_enum[0]), SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]), }; +/* add non dapm controls */ +static int ssm2602_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(ssm2602_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&ssm2602_snd_controls[i], codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + /* Output Mixer */ static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = { SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0), @@ -276,7 +291,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream, u16 srate; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct ssm2602_priv *ssm2602 = codec->private_data; struct i2c_client *i2c = codec->control_data; u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; @@ -321,7 +336,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct ssm2602_priv *ssm2602 = codec->private_data; struct i2c_client *i2c = codec->control_data; struct snd_pcm_runtime *master_runtime; @@ -358,7 +373,7 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; /* set active */ ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); @@ -370,7 +385,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct ssm2602_priv *ssm2602 = codec->private_data; /* deactivate */ if (!codec->active) @@ -506,16 +521,6 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, #define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops ssm2602_dai_ops = { - .startup = ssm2602_startup, - .prepare = ssm2602_pcm_prepare, - .hw_params = ssm2602_hw_params, - .shutdown = ssm2602_shutdown, - .digital_mute = ssm2602_mute, - .set_sysclk = ssm2602_set_dai_sysclk, - .set_fmt = ssm2602_set_dai_fmt, -}; - struct snd_soc_dai ssm2602_dai = { .name = "SSM2602", .playback = { @@ -530,14 +535,22 @@ struct snd_soc_dai ssm2602_dai = { .channels_max = 2, .rates = SSM2602_RATES, .formats = SSM2602_FORMATS,}, - .ops = &ssm2602_dai_ops, + .ops = { + .startup = ssm2602_startup, + .prepare = ssm2602_pcm_prepare, + .hw_params = ssm2602_hw_params, + .shutdown = ssm2602_shutdown, + .digital_mute = ssm2602_mute, + .set_sysclk = ssm2602_set_dai_sysclk, + .set_fmt = ssm2602_set_dai_fmt, + } }; EXPORT_SYMBOL_GPL(ssm2602_dai); static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -546,7 +559,7 @@ static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state) static int ssm2602_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u16 *cache = codec->reg_cache; @@ -568,7 +581,7 @@ static int ssm2602_resume(struct platform_device *pdev) */ static int ssm2602_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int reg, ret = 0; codec->name = "SSM2602"; @@ -609,8 +622,7 @@ static int ssm2602_init(struct snd_soc_device *socdev) APANA_ENABLE_MIC_BOOST); ssm2602_write(codec, SSM2602_PWR, 0); - snd_soc_add_controls(codec, ssm2602_snd_controls, - ARRAY_SIZE(ssm2602_snd_controls)); + ssm2602_add_controls(codec); ssm2602_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -641,7 +653,7 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct snd_soc_device *socdev = ssm2602_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -735,7 +747,7 @@ static int ssm2602_probe(struct platform_device *pdev) } codec->private_data = ssm2602; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -756,7 +768,7 @@ static int ssm2602_probe(struct platform_device *pdev) static int ssm2602_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/tlv320aic23.c b/trunk/sound/soc/codecs/tlv320aic23.c index c3f4afb5d017..cfdea007c4cb 100644 --- a/trunk/sound/soc/codecs/tlv320aic23.c +++ b/trunk/sound/soc/codecs/tlv320aic23.c @@ -183,6 +183,24 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), }; +/* add non dapm controls */ +static int tlv320aic23_add_controls(struct snd_soc_codec *codec) +{ + + int err, i; + + for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&tlv320aic23_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; + +} + /* PGA Mixer controls for Line and Mic switch */ static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = { SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0), @@ -405,7 +423,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 iface_reg; int ret; struct aic23 *aic23 = container_of(codec, struct aic23, codec); @@ -453,7 +471,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; /* set active */ tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); @@ -466,7 +484,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct aic23 *aic23 = container_of(codec, struct aic23, codec); /* deactivate */ @@ -580,15 +598,6 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, #define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops tlv320aic23_dai_ops = { - .prepare = tlv320aic23_pcm_prepare, - .hw_params = tlv320aic23_hw_params, - .shutdown = tlv320aic23_shutdown, - .digital_mute = tlv320aic23_mute, - .set_fmt = tlv320aic23_set_dai_fmt, - .set_sysclk = tlv320aic23_set_dai_sysclk, -}; - struct snd_soc_dai tlv320aic23_dai = { .name = "tlv320aic23", .playback = { @@ -603,7 +612,14 @@ struct snd_soc_dai tlv320aic23_dai = { .channels_max = 2, .rates = AIC23_RATES, .formats = AIC23_FORMATS,}, - .ops = &tlv320aic23_dai_ops, + .ops = { + .prepare = tlv320aic23_pcm_prepare, + .hw_params = tlv320aic23_hw_params, + .shutdown = tlv320aic23_shutdown, + .digital_mute = tlv320aic23_mute, + .set_fmt = tlv320aic23_set_dai_fmt, + .set_sysclk = tlv320aic23_set_dai_sysclk, + } }; EXPORT_SYMBOL_GPL(tlv320aic23_dai); @@ -611,7 +627,7 @@ static int tlv320aic23_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -622,7 +638,7 @@ static int tlv320aic23_suspend(struct platform_device *pdev, static int tlv320aic23_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u16 reg; @@ -644,7 +660,7 @@ static int tlv320aic23_resume(struct platform_device *pdev) */ static int tlv320aic23_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret = 0; u16 reg; @@ -702,8 +718,7 @@ static int tlv320aic23_init(struct snd_soc_device *socdev) tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); - snd_soc_add_controls(codec, tlv320aic23_snd_controls, - ARRAY_SIZE(tlv320aic23_snd_controls)); + tlv320aic23_add_controls(codec); tlv320aic23_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -731,7 +746,7 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c, const struct i2c_device_id *i2c_id) { struct snd_soc_device *socdev = tlv320aic23_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -789,7 +804,7 @@ static int tlv320aic23_probe(struct platform_device *pdev) if (aic23 == NULL) return -ENOMEM; codec = &aic23->codec; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -808,7 +823,7 @@ static int tlv320aic23_probe(struct platform_device *pdev) static int tlv320aic23_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct aic23 *aic23 = container_of(codec, struct aic23, codec); if (codec->control_data) diff --git a/trunk/sound/soc/codecs/tlv320aic26.c b/trunk/sound/soc/codecs/tlv320aic26.c index 3387d9e736ea..29f2f1a017fd 100644 --- a/trunk/sound/soc/codecs/tlv320aic26.c +++ b/trunk/sound/soc/codecs/tlv320aic26.c @@ -130,7 +130,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct aic26 *aic26 = codec->private_data; int fsref, divisor, wlen, pval, jval, dval, qval; u16 reg; @@ -270,13 +270,6 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) #define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\ SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE) -static struct snd_soc_dai_ops aic26_dai_ops = { - .hw_params = aic26_hw_params, - .digital_mute = aic26_mute, - .set_sysclk = aic26_set_sysclk, - .set_fmt = aic26_set_fmt, -}; - struct snd_soc_dai aic26_dai = { .name = "tlv320aic26", .playback = { @@ -293,7 +286,12 @@ struct snd_soc_dai aic26_dai = { .rates = AIC26_RATES, .formats = AIC26_FORMATS, }, - .ops = &aic26_dai_ops, + .ops = { + .hw_params = aic26_hw_params, + .digital_mute = aic26_mute, + .set_sysclk = aic26_set_sysclk, + .set_fmt = aic26_set_fmt, + }, }; EXPORT_SYMBOL_GPL(aic26_dai); @@ -324,8 +322,9 @@ static int aic26_probe(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec; + struct snd_kcontrol *kcontrol; struct aic26 *aic26; - int ret, err; + int i, ret, err; dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n"); dev_dbg(&pdev->dev, "socdev=%p\n", socdev); @@ -339,7 +338,7 @@ static int aic26_probe(struct platform_device *pdev) return -ENODEV; } codec = &aic26->codec; - socdev->card->codec = codec; + socdev->codec = codec; dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n", &pdev->dev, socdev->dev); @@ -352,9 +351,11 @@ static int aic26_probe(struct platform_device *pdev) /* register controls */ dev_dbg(&pdev->dev, "Registering controls\n"); - err = snd_soc_add_controls(codec, aic26_snd_controls, - ARRAY_SIZE(aic26_snd_controls)); - WARN_ON(err < 0); + for (i = 0; i < ARRAY_SIZE(aic26_snd_controls); i++) { + kcontrol = snd_soc_cnew(&aic26_snd_controls[i], codec, NULL); + err = snd_ctl_add(codec->card, kcontrol); + WARN_ON(err < 0); + } /* CODEC is setup, we can register the card now */ dev_dbg(&pdev->dev, "Registering card\n"); diff --git a/trunk/sound/soc/codecs/tlv320aic3x.c b/trunk/sound/soc/codecs/tlv320aic3x.c index ab099f482487..aea0cb72d80a 100644 --- a/trunk/sound/soc/codecs/tlv320aic3x.c +++ b/trunk/sound/soc/codecs/tlv320aic3x.c @@ -45,7 +45,6 @@ #include #include #include -#include #include "tlv320aic3x.h" @@ -251,86 +250,56 @@ static const struct soc_enum aic3x_enum[] = { SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf), }; -/* - * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps - */ -static DECLARE_TLV_DB_SCALE(dac_tlv, -6350, 50, 0); -/* ADC PGA gain volumes. From 0 to 59.5 dB in 0.5 dB steps */ -static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0); -/* - * Output stage volumes. From -78.3 to 0 dB. Muted below -78.3 dB. - * Step size is approximately 0.5 dB over most of the scale but increasing - * near the very low levels. - * Define dB scale so that it is mostly correct for range about -55 to 0 dB - * but having increasing dB difference below that (and where it doesn't count - * so much). This setting shows -50 dB (actual is -50.3 dB) for register - * value 100 and -58.5 dB (actual is -78.3 dB) for register value 117. - */ -static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1); - static const struct snd_kcontrol_new aic3x_snd_controls[] = { /* Output */ - SOC_DOUBLE_R_TLV("PCM Playback Volume", - LDAC_VOL, RDAC_VOL, 0, 0x7f, 1, dac_tlv), + SOC_DOUBLE_R("PCM Playback Volume", LDAC_VOL, RDAC_VOL, 0, 0x7f, 1), - SOC_DOUBLE_R_TLV("Line DAC Playback Volume", - DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL, - 0, 118, 1, output_stage_tlv), + SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL, + DACR1_2_RLOPM_VOL, 0, 0x7f, 1), SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0), SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0), - SOC_DOUBLE_R_TLV("LineL DAC Playback Volume", - DACL1_2_LLOPM_VOL, DACR1_2_LLOPM_VOL, - 0, 118, 1, output_stage_tlv), - SOC_SINGLE_TLV("LineL Left PGA Bypass Playback Volume", - PGAL_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv), - SOC_SINGLE_TLV("LineR Right PGA Bypass Playback Volume", - PGAR_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("LineL Line2 Bypass Playback Volume", - LINE2L_2_LLOPM_VOL, LINE2R_2_LLOPM_VOL, - 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("LineR Line2 Bypass Playback Volume", - LINE2L_2_RLOPM_VOL, LINE2R_2_RLOPM_VOL, - 0, 118, 1, output_stage_tlv), - - SOC_DOUBLE_R_TLV("Mono DAC Playback Volume", - DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL, - 0, 118, 1, output_stage_tlv), + SOC_DOUBLE_R("LineL DAC Playback Volume", DACL1_2_LLOPM_VOL, + DACR1_2_LLOPM_VOL, 0, 0x7f, 1), + SOC_SINGLE("LineL Left PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL, + 0, 0x7f, 1), + SOC_SINGLE("LineR Right PGA Bypass Playback Volume", PGAR_2_RLOPM_VOL, + 0, 0x7f, 1), + SOC_DOUBLE_R("LineL Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL, + LINE2R_2_LLOPM_VOL, 0, 0x7f, 1), + SOC_DOUBLE_R("LineR Line2 Bypass Playback Volume", LINE2L_2_RLOPM_VOL, + LINE2R_2_RLOPM_VOL, 0, 0x7f, 1), + + SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL, + DACR1_2_MONOLOPM_VOL, 0, 0x7f, 1), SOC_SINGLE("Mono DAC Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0), - SOC_DOUBLE_R_TLV("Mono PGA Bypass Playback Volume", - PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL, - 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("Mono Line2 Bypass Playback Volume", - LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL, - 0, 118, 1, output_stage_tlv), - - SOC_DOUBLE_R_TLV("HP DAC Playback Volume", - DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL, - 0, 118, 1, output_stage_tlv), + SOC_DOUBLE_R("Mono PGA Bypass Playback Volume", PGAL_2_MONOLOPM_VOL, + PGAR_2_MONOLOPM_VOL, 0, 0x7f, 1), + SOC_DOUBLE_R("Mono Line2 Bypass Playback Volume", LINE2L_2_MONOLOPM_VOL, + LINE2R_2_MONOLOPM_VOL, 0, 0x7f, 1), + + SOC_DOUBLE_R("HP DAC Playback Volume", DACL1_2_HPLOUT_VOL, + DACR1_2_HPROUT_VOL, 0, 0x7f, 1), SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, 0x01, 0), - SOC_DOUBLE_R_TLV("HP Right PGA Bypass Playback Volume", - PGAR_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL, - 0, 118, 1, output_stage_tlv), - SOC_SINGLE_TLV("HPL PGA Bypass Playback Volume", - PGAL_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), - SOC_SINGLE_TLV("HPR PGA Bypass Playback Volume", - PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("HP Line2 Bypass Playback Volume", - LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL, - 0, 118, 1, output_stage_tlv), - - SOC_DOUBLE_R_TLV("HPCOM DAC Playback Volume", - DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL, - 0, 118, 1, output_stage_tlv), + SOC_DOUBLE_R("HP Right PGA Bypass Playback Volume", PGAR_2_HPLOUT_VOL, + PGAR_2_HPROUT_VOL, 0, 0x7f, 1), + SOC_SINGLE("HPL PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL, + 0, 0x7f, 1), + SOC_SINGLE("HPR PGA Bypass Playback Volume", PGAL_2_HPROUT_VOL, + 0, 0x7f, 1), + SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL, + LINE2R_2_HPROUT_VOL, 0, 0x7f, 1), + + SOC_DOUBLE_R("HPCOM DAC Playback Volume", DACL1_2_HPLCOM_VOL, + DACR1_2_HPRCOM_VOL, 0, 0x7f, 1), SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, 0x01, 0), - SOC_SINGLE_TLV("HPLCOM PGA Bypass Playback Volume", - PGAL_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv), - SOC_SINGLE_TLV("HPRCOM PGA Bypass Playback Volume", - PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Playback Volume", - LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL, - 0, 118, 1, output_stage_tlv), + SOC_SINGLE("HPLCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL, + 0, 0x7f, 1), + SOC_SINGLE("HPRCOM PGA Bypass Playback Volume", PGAL_2_HPRCOM_VOL, + 0, 0x7f, 1), + SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL, + LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1), /* * Note: enable Automatic input Gain Controller with care. It can @@ -339,13 +308,28 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0), /* Input */ - SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL, - 0, 119, 0, adc_tlv), + SOC_DOUBLE_R("PGA Capture Volume", LADC_VOL, RADC_VOL, 0, 0x7f, 0), SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), }; +/* add non dapm controls */ +static int aic3x_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(aic3x_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&aic3x_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + /* Left DAC Mux */ static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]); @@ -762,7 +746,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct aic3x_priv *aic3x = codec->private_data; int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; @@ -1088,13 +1072,6 @@ EXPORT_SYMBOL_GPL(aic3x_button_pressed); #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops aic3x_dai_ops = { - .hw_params = aic3x_hw_params, - .digital_mute = aic3x_mute, - .set_sysclk = aic3x_set_dai_sysclk, - .set_fmt = aic3x_set_dai_fmt, -}; - struct snd_soc_dai aic3x_dai = { .name = "tlv320aic3x", .playback = { @@ -1109,14 +1086,19 @@ struct snd_soc_dai aic3x_dai = { .channels_max = 2, .rates = AIC3X_RATES, .formats = AIC3X_FORMATS,}, - .ops = &aic3x_dai_ops, + .ops = { + .hw_params = aic3x_hw_params, + .digital_mute = aic3x_mute, + .set_sysclk = aic3x_set_dai_sysclk, + .set_fmt = aic3x_set_dai_fmt, + } }; EXPORT_SYMBOL_GPL(aic3x_dai); static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1126,7 +1108,7 @@ static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) static int aic3x_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u8 *cache = codec->reg_cache; @@ -1149,7 +1131,7 @@ static int aic3x_resume(struct platform_device *pdev) */ static int aic3x_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct aic3x_setup_data *setup = socdev->codec_data; int reg, ret = 0; @@ -1245,8 +1227,7 @@ static int aic3x_init(struct snd_soc_device *socdev) aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); - snd_soc_add_controls(codec, aic3x_snd_controls, - ARRAY_SIZE(aic3x_snd_controls)); + aic3x_add_controls(codec); aic3x_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -1280,7 +1261,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct snd_soc_device *socdev = aic3x_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -1385,7 +1366,7 @@ static int aic3x_probe(struct platform_device *pdev) } codec->private_data = aic3x; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -1411,7 +1392,7 @@ static int aic3x_probe(struct platform_device *pdev) static int aic3x_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; /* power down chip */ if (codec->control_data) diff --git a/trunk/sound/soc/codecs/twl4030.c b/trunk/sound/soc/codecs/twl4030.c index 97738e2ece04..ea370a4f86d5 100644 --- a/trunk/sound/soc/codecs/twl4030.c +++ b/trunk/sound/soc/codecs/twl4030.c @@ -42,7 +42,7 @@ */ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { 0x00, /* this register not used */ - 0x91, /* REG_CODEC_MODE (0x1) */ + 0x93, /* REG_CODEC_MODE (0x1) */ 0xc3, /* REG_OPTION (0x2) */ 0x00, /* REG_UNKNOWN (0x3) */ 0x00, /* REG_MICBIAS_CTL (0x4) */ @@ -117,13 +117,6 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { 0x00, /* REG_MISC_SET_2 (0x49) */ }; -/* codec private data */ -struct twl4030_priv { - unsigned int bypass_state; - unsigned int codec_powered; - unsigned int codec_muted; -}; - /* * read twl4030 register cache */ @@ -132,9 +125,6 @@ static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec, { u8 *cache = codec->reg_cache; - if (reg >= TWL4030_CACHEREGNUM) - return -EIO; - return cache[reg]; } @@ -161,22 +151,26 @@ static int twl4030_write(struct snd_soc_codec *codec, return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); } -static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) +static void twl4030_clear_codecpdz(struct snd_soc_codec *codec) { - struct twl4030_priv *twl4030 = codec->private_data; u8 mode; - if (enable == twl4030->codec_powered) - return; - mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); - if (enable) - mode |= TWL4030_CODECPDZ; - else - mode &= ~TWL4030_CODECPDZ; + twl4030_write(codec, TWL4030_REG_CODEC_MODE, + mode & ~TWL4030_CODECPDZ); - twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); - twl4030->codec_powered = enable; + /* REVISIT: this delay is present in TI sample drivers */ + /* but there seems to be no TRM requirement for it */ + udelay(10); +} + +static void twl4030_set_codecpdz(struct snd_soc_codec *codec) +{ + u8 mode; + + mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); + twl4030_write(codec, TWL4030_REG_CODEC_MODE, + mode | TWL4030_CODECPDZ); /* REVISIT: this delay is present in TI sample drivers */ /* but there seems to be no TRM requirement for it */ @@ -188,7 +182,7 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) int i; /* clear CODECPDZ prior to setting register defaults */ - twl4030_codec_enable(codec, 0); + twl4030_clear_codecpdz(codec); /* set all audio section registers to reasonable defaults */ for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) @@ -196,122 +190,6 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) } -static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) -{ - struct twl4030_priv *twl4030 = codec->private_data; - u8 reg_val; - - if (mute == twl4030->codec_muted) - return; - - if (mute) { - /* Bypass the reg_cache and mute the volumes - * Headset mute is done in it's own event handler - * Things to mute: Earpiece, PreDrivL/R, CarkitL/R - */ - reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - reg_val & (~TWL4030_EAR_GAIN), - TWL4030_REG_EAR_CTL); - - reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - reg_val & (~TWL4030_PREDL_GAIN), - TWL4030_REG_PREDL_CTL); - reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - reg_val & (~TWL4030_PREDR_GAIN), - TWL4030_REG_PREDL_CTL); - - reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - reg_val & (~TWL4030_PRECKL_GAIN), - TWL4030_REG_PRECKL_CTL); - reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - reg_val & (~TWL4030_PRECKL_GAIN), - TWL4030_REG_PRECKR_CTL); - - /* Disable PLL */ - reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); - reg_val &= ~TWL4030_APLL_EN; - twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); - } else { - /* Restore the volumes - * Headset mute is done in it's own event handler - * Things to restore: Earpiece, PreDrivL/R, CarkitL/R - */ - twl4030_write(codec, TWL4030_REG_EAR_CTL, - twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL)); - - twl4030_write(codec, TWL4030_REG_PREDL_CTL, - twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL)); - twl4030_write(codec, TWL4030_REG_PREDR_CTL, - twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL)); - - twl4030_write(codec, TWL4030_REG_PRECKL_CTL, - twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL)); - twl4030_write(codec, TWL4030_REG_PRECKR_CTL, - twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL)); - - /* Enable PLL */ - reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); - reg_val |= TWL4030_APLL_EN; - twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); - } - - twl4030->codec_muted = mute; -} - -static void twl4030_power_up(struct snd_soc_codec *codec) -{ - struct twl4030_priv *twl4030 = codec->private_data; - u8 anamicl, regmisc1, byte; - int i = 0; - - if (twl4030->codec_powered) - return; - - /* set CODECPDZ to turn on codec */ - twl4030_codec_enable(codec, 1); - - /* initiate offset cancellation */ - anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); - twl4030_write(codec, TWL4030_REG_ANAMICL, - anamicl | TWL4030_CNCL_OFFSET_START); - - /* wait for offset cancellation to complete */ - do { - /* this takes a little while, so don't slam i2c */ - udelay(2000); - twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, - TWL4030_REG_ANAMICL); - } while ((i++ < 100) && - ((byte & TWL4030_CNCL_OFFSET_START) == - TWL4030_CNCL_OFFSET_START)); - - /* Make sure that the reg_cache has the same value as the HW */ - twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte); - - /* anti-pop when changing analog gain */ - regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1); - twl4030_write(codec, TWL4030_REG_MISC_SET_1, - regmisc1 | TWL4030_SMOOTH_ANAVOL_EN); - - /* toggle CODECPDZ as per TRM */ - twl4030_codec_enable(codec, 0); - twl4030_codec_enable(codec, 1); -} - -/* - * Unconditional power down - */ -static void twl4030_power_down(struct snd_soc_codec *codec) -{ - /* power down */ - twl4030_codec_enable(codec, 0); -} - /* Earpiece */ static const char *twl4030_earpiece_texts[] = {"Off", "DACL1", "DACL2", "DACR1"}; @@ -488,41 +366,6 @@ static const struct soc_enum twl4030_micpathtx2_enum = static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control = SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum); -/* Analog bypass for AudioR1 */ -static const struct snd_kcontrol_new twl4030_dapm_abypassr1_control = - SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR1_APGA_CTL, 2, 1, 0); - -/* Analog bypass for AudioL1 */ -static const struct snd_kcontrol_new twl4030_dapm_abypassl1_control = - SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL1_APGA_CTL, 2, 1, 0); - -/* Analog bypass for AudioR2 */ -static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control = - SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR2_APGA_CTL, 2, 1, 0); - -/* Analog bypass for AudioL2 */ -static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control = - SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0); - -/* Digital bypass gain, 0 mutes the bypass */ -static const unsigned int twl4030_dapm_dbypass_tlv[] = { - TLV_DB_RANGE_HEAD(2), - 0, 3, TLV_DB_SCALE_ITEM(-2400, 0, 1), - 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0), -}; - -/* Digital bypass left (TX1L -> RX2L) */ -static const struct snd_kcontrol_new twl4030_dapm_dbypassl_control = - SOC_DAPM_SINGLE_TLV("Volume", - TWL4030_REG_ATX2ARXPGA, 3, 7, 0, - twl4030_dapm_dbypass_tlv); - -/* Digital bypass right (TX1R -> RX2R) */ -static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control = - SOC_DAPM_SINGLE_TLV("Volume", - TWL4030_REG_ATX2ARXPGA, 0, 7, 0, - twl4030_dapm_dbypass_tlv); - static int micpath_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -577,79 +420,6 @@ static int handsfree_event(struct snd_soc_dapm_widget *w, return 0; } -static int headsetl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - unsigned char hs_gain, hs_pop; - - /* Save the current volume */ - hs_gain = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_GAIN_SET); - hs_pop = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_POPN_SET); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - /* Do the anti-pop/bias ramp enable according to the TRM */ - hs_pop |= TWL4030_VMID_EN; - twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); - /* Is this needed? Can we just use whatever gain here? */ - twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET, - (hs_gain & (~0x0f)) | 0x0a); - hs_pop |= TWL4030_RAMP_EN; - twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); - - /* Restore the original volume */ - twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET, hs_gain); - break; - case SND_SOC_DAPM_POST_PMD: - /* Do the anti-pop/bias ramp disable according to the TRM */ - hs_pop &= ~TWL4030_RAMP_EN; - twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); - /* Bypass the reg_cache to mute the headset */ - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - hs_gain & (~0x0f), - TWL4030_REG_HS_GAIN_SET); - hs_pop &= ~TWL4030_VMID_EN; - twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); - break; - } - return 0; -} - -static int bypass_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct soc_mixer_control *m = - (struct soc_mixer_control *)w->kcontrols->private_value; - struct twl4030_priv *twl4030 = w->codec->private_data; - unsigned char reg; - - reg = twl4030_read_reg_cache(w->codec, m->reg); - - if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) { - /* Analog bypass */ - if (reg & (1 << m->shift)) - twl4030->bypass_state |= - (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); - else - twl4030->bypass_state &= - ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); - } else { - /* Digital bypass */ - if (reg & (0x7 << m->shift)) - twl4030->bypass_state |= (1 << (m->shift ? 5 : 4)); - else - twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4)); - } - - if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) { - if (twl4030->bypass_state) - twl4030_codec_mute(w->codec, 0); - else - twl4030_codec_mute(w->codec, 1); - } - return 0; -} - /* * Some of the gain controls in TWL (mostly those which are associated with * the outputs) are implemented in an interesting way: @@ -844,17 +614,6 @@ static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0); */ static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0); -static const char *twl4030_rampdelay_texts[] = { - "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms", - "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms", - "3495/2581/1748 ms" -}; - -static const struct soc_enum twl4030_rampdelay_enum = - SOC_ENUM_SINGLE(TWL4030_REG_HS_POPN_SET, 2, - ARRAY_SIZE(twl4030_rampdelay_texts), - twl4030_rampdelay_texts); - static const struct snd_kcontrol_new twl4030_snd_controls[] = { /* Common playback gain controls */ SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume", @@ -909,10 +668,24 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN, 0, 3, 5, 0, input_gain_tlv), - - SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum), }; +/* add non dapm controls */ +static int twl4030_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&twl4030_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { /* Left channel inputs */ SND_SOC_DAPM_INPUT("MAINMIC"), @@ -941,13 +714,13 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { /* DACs */ SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", - SND_SOC_NOPM, 0, 0), + TWL4030_REG_AVDAC_CTL, 0, 0), SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback", - SND_SOC_NOPM, 0, 0), + TWL4030_REG_AVDAC_CTL, 1, 0), SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback", - SND_SOC_NOPM, 0, 0), + TWL4030_REG_AVDAC_CTL, 2, 0), SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", - SND_SOC_NOPM, 0, 0), + TWL4030_REG_AVDAC_CTL, 3, 0), /* Analog PGAs */ SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, @@ -959,37 +732,6 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL, 0, 0, NULL, 0), - /* Analog bypasses */ - SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_abypassr1_control, bypass_event, - SND_SOC_DAPM_POST_REG), - SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_abypassl1_control, - bypass_event, SND_SOC_DAPM_POST_REG), - SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_abypassr2_control, - bypass_event, SND_SOC_DAPM_POST_REG), - SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_abypassl2_control, - bypass_event, SND_SOC_DAPM_POST_REG), - - /* Digital bypasses */ - SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_dbypassl_control, bypass_event, - SND_SOC_DAPM_POST_REG), - SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_dbypassr_control, bypass_event, - SND_SOC_DAPM_POST_REG), - - SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL, - 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer", TWL4030_REG_AVDAC_CTL, - 1, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer", TWL4030_REG_AVDAC_CTL, - 2, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, - 3, 0, NULL, 0), - /* Output MUX controls */ /* Earpiece */ SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0, @@ -1000,9 +742,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0, &twl4030_dapm_predriver_control), /* HeadsetL/R */ - SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_hsol_control, headsetl_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsol_control), SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, &twl4030_dapm_hsor_control), /* CarkitL/R */ @@ -1041,16 +782,16 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD| SND_SOC_DAPM_POST_REG), - /* Analog input muxes with switch for the capture amplifiers */ + /* Analog input muxes with power switch for the physical ADCL/R */ SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route", - TWL4030_REG_ANAMICL, 4, 0, &twl4030_dapm_analoglmic_control), + TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control), SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route", - TWL4030_REG_ANAMICR, 4, 0, &twl4030_dapm_analogrmic_control), + TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control), - SND_SOC_DAPM_PGA("ADC Physical Left", - TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0), - SND_SOC_DAPM_PGA("ADC Physical Right", - TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA("Analog Left Amplifier", + TWL4030_REG_ANAMICL, 4, 0, NULL, 0), + SND_SOC_DAPM_PGA("Analog Right Amplifier", + TWL4030_REG_ANAMICR, 4, 0, NULL, 0), SND_SOC_DAPM_PGA("Digimic0 Enable", TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0), @@ -1060,19 +801,13 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0), - }; static const struct snd_soc_dapm_route intercon[] = { - {"Analog L1 Playback Mixer", NULL, "DAC Left1"}, - {"Analog R1 Playback Mixer", NULL, "DAC Right1"}, - {"Analog L2 Playback Mixer", NULL, "DAC Left2"}, - {"Analog R2 Playback Mixer", NULL, "DAC Right2"}, - - {"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"}, - {"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"}, - {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"}, - {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"}, + {"ARXL1_APGA", NULL, "DAC Left1"}, + {"ARXR1_APGA", NULL, "DAC Right1"}, + {"ARXL2_APGA", NULL, "DAC Left2"}, + {"ARXR2_APGA", NULL, "DAC Right2"}, /* Internal playback routings */ /* Earpiece */ @@ -1130,23 +865,23 @@ static const struct snd_soc_dapm_route intercon[] = { {"Analog Right Capture Route", "Sub mic", "SUBMIC"}, {"Analog Right Capture Route", "AUXR", "AUXR"}, - {"ADC Physical Left", NULL, "Analog Left Capture Route"}, - {"ADC Physical Right", NULL, "Analog Right Capture Route"}, + {"Analog Left Amplifier", NULL, "Analog Left Capture Route"}, + {"Analog Right Amplifier", NULL, "Analog Right Capture Route"}, {"Digimic0 Enable", NULL, "DIGIMIC0"}, {"Digimic1 Enable", NULL, "DIGIMIC1"}, /* TX1 Left capture path */ - {"TX1 Capture Route", "Analog", "ADC Physical Left"}, + {"TX1 Capture Route", "Analog", "Analog Left Amplifier"}, {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, /* TX1 Right capture path */ - {"TX1 Capture Route", "Analog", "ADC Physical Right"}, + {"TX1 Capture Route", "Analog", "Analog Right Amplifier"}, {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, /* TX2 Left capture path */ - {"TX2 Capture Route", "Analog", "ADC Physical Left"}, + {"TX2 Capture Route", "Analog", "Analog Left Amplifier"}, {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"}, /* TX2 Right capture path */ - {"TX2 Capture Route", "Analog", "ADC Physical Right"}, + {"TX2 Capture Route", "Analog", "Analog Right Amplifier"}, {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"}, {"ADC Virtual Left1", NULL, "TX1 Capture Route"}, @@ -1154,24 +889,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, - /* Analog bypass routes */ - {"Right1 Analog Loopback", "Switch", "Analog Right Capture Route"}, - {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, - {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, - {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, - - {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, - {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, - {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, - {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"}, - - /* Digital bypass routes */ - {"Right Digital Loopback", "Volume", "TX1 Capture Route"}, - {"Left Digital Loopback", "Volume", "TX1 Capture Route"}, - - {"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"}, - {"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"}, - }; static int twl4030_add_widgets(struct snd_soc_codec *codec) @@ -1185,28 +902,82 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec) return 0; } +static void twl4030_power_up(struct snd_soc_codec *codec) +{ + u8 anamicl, regmisc1, byte, popn; + int i = 0; + + /* set CODECPDZ to turn on codec */ + twl4030_set_codecpdz(codec); + + /* initiate offset cancellation */ + anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); + twl4030_write(codec, TWL4030_REG_ANAMICL, + anamicl | TWL4030_CNCL_OFFSET_START); + + + /* wait for offset cancellation to complete */ + do { + /* this takes a little while, so don't slam i2c */ + udelay(2000); + twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, + TWL4030_REG_ANAMICL); + } while ((i++ < 100) && + ((byte & TWL4030_CNCL_OFFSET_START) == + TWL4030_CNCL_OFFSET_START)); + + /* anti-pop when changing analog gain */ + regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1); + twl4030_write(codec, TWL4030_REG_MISC_SET_1, + regmisc1 | TWL4030_SMOOTH_ANAVOL_EN); + + /* toggle CODECPDZ as per TRM */ + twl4030_clear_codecpdz(codec); + twl4030_set_codecpdz(codec); + + /* program anti-pop with bias ramp delay */ + popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); + popn &= TWL4030_RAMP_DELAY; + popn |= TWL4030_RAMP_DELAY_645MS; + twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); + popn |= TWL4030_VMID_EN; + twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); + + /* enable anti-pop ramp */ + popn |= TWL4030_RAMP_EN; + twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); +} + +static void twl4030_power_down(struct snd_soc_codec *codec) +{ + u8 popn; + + /* disable anti-pop ramp */ + popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); + popn &= ~TWL4030_RAMP_EN; + twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); + + /* disable bias out */ + popn &= ~TWL4030_VMID_EN; + twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); + + /* power down */ + twl4030_clear_codecpdz(codec); +} + static int twl4030_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct twl4030_priv *twl4030 = codec->private_data; - switch (level) { case SND_SOC_BIAS_ON: - twl4030_codec_mute(codec, 0); + twl4030_power_up(codec); break; case SND_SOC_BIAS_PREPARE: - twl4030_power_up(codec); - if (twl4030->bypass_state) - twl4030_codec_mute(codec, 0); - else - twl4030_codec_mute(codec, 1); + /* TODO: develop a twl4030_prepare function */ break; case SND_SOC_BIAS_STANDBY: - twl4030_power_up(codec); - if (twl4030->bypass_state) - twl4030_codec_mute(codec, 0); - else - twl4030_codec_mute(codec, 1); + /* TODO: develop a twl4030_standby function */ + twl4030_power_down(codec); break; case SND_SOC_BIAS_OFF: twl4030_power_down(codec); @@ -1223,9 +994,10 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u8 mode, old_mode, format, old_format; + /* bit rate */ old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; @@ -1267,9 +1039,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, if (mode != old_mode) { /* change rate and set CODECPDZ */ - twl4030_codec_enable(codec, 0); twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); - twl4030_codec_enable(codec, 1); + twl4030_set_codecpdz(codec); } /* sample size */ @@ -1292,13 +1063,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, if (format != old_format) { /* clear CODECPDZ before changing format (codec requirement) */ - twl4030_codec_enable(codec, 0); + twl4030_clear_codecpdz(codec); /* change format */ twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); /* set CODECPDZ afterwards */ - twl4030_codec_enable(codec, 1); + twl4030_set_codecpdz(codec); } return 0; } @@ -1368,13 +1139,13 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, if (format != old_format) { /* clear CODECPDZ before changing format (codec requirement) */ - twl4030_codec_enable(codec, 0); + twl4030_clear_codecpdz(codec); /* change format */ twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); /* set CODECPDZ afterwards */ - twl4030_codec_enable(codec, 1); + twl4030_set_codecpdz(codec); } return 0; @@ -1383,12 +1154,6 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, #define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) #define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) -static struct snd_soc_dai_ops twl4030_dai_ops = { - .hw_params = twl4030_hw_params, - .set_sysclk = twl4030_set_dai_sysclk, - .set_fmt = twl4030_set_dai_fmt, -}; - struct snd_soc_dai twl4030_dai = { .name = "twl4030", .playback = { @@ -1403,14 +1168,18 @@ struct snd_soc_dai twl4030_dai = { .channels_max = 2, .rates = TWL4030_RATES, .formats = TWL4030_FORMATS,}, - .ops = &twl4030_dai_ops, + .ops = { + .hw_params = twl4030_hw_params, + .set_sysclk = twl4030_set_dai_sysclk, + .set_fmt = twl4030_set_dai_fmt, + } }; EXPORT_SYMBOL_GPL(twl4030_dai); static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1420,7 +1189,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) static int twl4030_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); twl4030_set_bias_level(codec, codec->suspend_bias_level); @@ -1434,7 +1203,7 @@ static int twl4030_resume(struct platform_device *pdev) static int twl4030_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret = 0; printk(KERN_INFO "TWL4030 Audio Codec init \n"); @@ -1464,8 +1233,7 @@ static int twl4030_init(struct snd_soc_device *socdev) /* power on device */ twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, twl4030_snd_controls, - ARRAY_SIZE(twl4030_snd_controls)); + twl4030_add_controls(codec); twl4030_add_widgets(codec); ret = snd_soc_init_card(socdev); @@ -1490,20 +1258,12 @@ static int twl4030_probe(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec; - struct twl4030_priv *twl4030; codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); if (codec == NULL) return -ENOMEM; - twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); - if (twl4030 == NULL) { - kfree(codec); - return -ENOMEM; - } - - codec->private_data = twl4030; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -1517,13 +1277,11 @@ static int twl4030_probe(struct platform_device *pdev) static int twl4030_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; printk(KERN_INFO "TWL4030 Audio Codec remove\n"); - twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_free_pcms(socdev); snd_soc_dapm_free(socdev); - kfree(codec->private_data); kfree(codec); return 0; diff --git a/trunk/sound/soc/codecs/twl4030.h b/trunk/sound/soc/codecs/twl4030.h index 33dbb144dad1..442e5a828617 100644 --- a/trunk/sound/soc/codecs/twl4030.h +++ b/trunk/sound/soc/codecs/twl4030.h @@ -170,9 +170,6 @@ #define TWL4030_CLK256FS_EN 0x02 #define TWL4030_AIF_EN 0x01 -/* EAR_CTL (0x21) */ -#define TWL4030_EAR_GAIN 0x30 - /* HS_GAIN_SET (0x23) Fields */ #define TWL4030_HSR_GAIN 0x0C @@ -201,18 +198,6 @@ #define TWL4030_RAMP_DELAY_2581MS 0x1C #define TWL4030_RAMP_EN 0x02 -/* PREDL_CTL (0x25) */ -#define TWL4030_PREDL_GAIN 0x30 - -/* PREDR_CTL (0x26) */ -#define TWL4030_PREDR_GAIN 0x30 - -/* PRECKL_CTL (0x27) */ -#define TWL4030_PRECKL_GAIN 0x30 - -/* PRECKR_CTL (0x28) */ -#define TWL4030_PRECKR_GAIN 0x30 - /* HFL_CTL (0x29, 0x2A) Fields */ #define TWL4030_HF_CTL_HB_EN 0x04 #define TWL4030_HF_CTL_LOOP_EN 0x08 diff --git a/trunk/sound/soc/codecs/uda134x.c b/trunk/sound/soc/codecs/uda134x.c index ddefb8f80145..a2c5064a774b 100644 --- a/trunk/sound/soc/codecs/uda134x.c +++ b/trunk/sound/soc/codecs/uda134x.c @@ -173,7 +173,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct uda134x_priv *uda134x = codec->private_data; struct snd_pcm_runtime *master_runtime; @@ -206,7 +206,7 @@ static void uda134x_shutdown(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct uda134x_priv *uda134x = codec->private_data; if (uda134x->master_substream == substream) @@ -221,7 +221,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct uda134x_priv *uda134x = codec->private_data; u8 hw_params; @@ -431,14 +431,38 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]), SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), }; -static struct snd_soc_dai_ops uda134x_dai_ops = { - .startup = uda134x_startup, - .shutdown = uda134x_shutdown, - .hw_params = uda134x_hw_params, - .digital_mute = uda134x_mute, - .set_sysclk = uda134x_set_dai_sysclk, - .set_fmt = uda134x_set_dai_fmt, -}; +static int uda134x_add_controls(struct snd_soc_codec *codec) +{ + int err, i, n; + const struct snd_kcontrol_new *ctrls; + struct uda134x_platform_data *pd = codec->control_data; + + switch (pd->model) { + case UDA134X_UDA1340: + case UDA134X_UDA1344: + n = ARRAY_SIZE(uda1340_snd_controls); + ctrls = uda1340_snd_controls; + break; + case UDA134X_UDA1341: + n = ARRAY_SIZE(uda1341_snd_controls); + ctrls = uda1341_snd_controls; + break; + default: + printk(KERN_ERR "%s unkown codec type: %d", + __func__, pd->model); + return -EINVAL; + } + + for (i = 0; i < n; i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&ctrls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} struct snd_soc_dai uda134x_dai = { .name = "UDA134X", @@ -459,7 +483,14 @@ struct snd_soc_dai uda134x_dai = { .formats = UDA134X_FORMATS, }, /* pcm operations */ - .ops = &uda134x_dai_ops, + .ops = { + .startup = uda134x_startup, + .shutdown = uda134x_shutdown, + .hw_params = uda134x_hw_params, + .digital_mute = uda134x_mute, + .set_sysclk = uda134x_set_dai_sysclk, + .set_fmt = uda134x_set_dai_fmt, + } }; EXPORT_SYMBOL(uda134x_dai); @@ -494,11 +525,11 @@ static int uda134x_soc_probe(struct platform_device *pdev) return -EINVAL; } - socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (socdev->card->codec == NULL) + socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (socdev->codec == NULL) return ret; - codec = socdev->card->codec; + codec = socdev->codec; uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); if (uda134x == NULL) @@ -541,22 +572,7 @@ static int uda134x_soc_probe(struct platform_device *pdev) goto pcm_err; } - switch (pd->model) { - case UDA134X_UDA1340: - case UDA134X_UDA1344: - ret = snd_soc_add_controls(codec, uda1340_snd_controls, - ARRAY_SIZE(uda1340_snd_controls)); - break; - case UDA134X_UDA1341: - ret = snd_soc_add_controls(codec, uda1341_snd_controls, - ARRAY_SIZE(uda1341_snd_controls)); - break; - default: - printk(KERN_ERR "%s unkown codec type: %d", - __func__, pd->model); - return -EINVAL; - } - + ret = uda134x_add_controls(codec); if (ret < 0) { printk(KERN_ERR "UDA134X: failed to register controls\n"); goto pcm_err; @@ -586,7 +602,7 @@ static int uda134x_soc_probe(struct platform_device *pdev) static int uda134x_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -606,7 +622,7 @@ static int uda134x_soc_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -616,7 +632,7 @@ static int uda134x_soc_suspend(struct platform_device *pdev, static int uda134x_soc_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); diff --git a/trunk/sound/soc/codecs/uda1380.c b/trunk/sound/soc/codecs/uda1380.c index 5b21594e0e58..e6bf0844fbf3 100644 --- a/trunk/sound/soc/codecs/uda1380.c +++ b/trunk/sound/soc/codecs/uda1380.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -36,8 +35,7 @@ #include "uda1380.h" -static struct work_struct uda1380_work; -static struct snd_soc_codec *uda1380_codec; +#define UDA1380_VERSION "0.6" /* * uda1380 register cache @@ -54,8 +52,6 @@ static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = { 0x0000, 0x8000, 0x0002, 0x0000, }; -static unsigned long uda1380_cache_dirty; - /* * read uda1380 register cache */ @@ -77,11 +73,8 @@ static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, u16 reg, unsigned int value) { u16 *cache = codec->reg_cache; - if (reg >= UDA1380_CACHEREGNUM) return; - if ((reg >= 0x10) && (cache[reg] != value)) - set_bit(reg - 0x10, &uda1380_cache_dirty); cache[reg] = value; } @@ -120,8 +113,6 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, (data[0]<<8) | data[1]); return -EIO; } - if (reg >= 0x10) - clear_bit(reg - 0x10, &uda1380_cache_dirty); return 0; } else return -EIO; @@ -129,20 +120,6 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, #define uda1380_reset(c) uda1380_write(c, UDA1380_RESET, 0) -static void uda1380_flush_work(struct work_struct *work) -{ - int bit, reg; - - for_each_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { - reg = 0x10 + bit; - pr_debug("uda1380: flush reg %x val %x:\n", reg, - uda1380_read_reg_cache(uda1380_codec, reg)); - uda1380_write(uda1380_codec, reg, - uda1380_read_reg_cache(uda1380_codec, reg)); - clear_bit(bit, &uda1380_cache_dirty); - } -} - /* declarations of ALSA reg_elem_REAL controls */ static const char *uda1380_deemp[] = { "None", @@ -277,6 +254,7 @@ static const struct snd_kcontrol_new uda1380_snd_controls[] = { SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0), /* DA_POL_INV */ SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum), /* SEL_NS */ SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum), /* MIX_POS, MIX */ + SOC_SINGLE("Silence Switch", UDA1380_MIXER, 7, 1, 0), /* SILENCE, force DAC output to silence */ SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0), /* SDET_ON */ SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum), /* SD_VALUE */ SOC_ENUM("Oversampling Input", uda1380_os_enum), /* OS */ @@ -293,6 +271,21 @@ static const struct snd_kcontrol_new uda1380_snd_controls[] = { SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0), }; +/* add non dapm controls */ +static int uda1380_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(uda1380_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&uda1380_snd_controls[i], codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + /* Input mux */ static const struct snd_kcontrol_new uda1380_input_mux_control = SOC_DAPM_ENUM("Route", uda1380_input_sel_enum); @@ -378,7 +371,7 @@ static int uda1380_add_widgets(struct snd_soc_codec *codec) return 0; } -static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai, +static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -388,107 +381,61 @@ static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai, iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK); + /* FIXME: how to select I2S for DATAO and MSB for DATAI correctly? */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: iface |= R01_SFORI_I2S | R01_SFORO_I2S; break; case SND_SOC_DAIFMT_LSB: - iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16; + iface |= R01_SFORI_LSB16 | R01_SFORO_I2S; break; case SND_SOC_DAIFMT_MSB: - iface |= R01_SFORI_MSB | R01_SFORO_MSB; + iface |= R01_SFORI_MSB | R01_SFORO_I2S; } - /* DATAI is slave only, so in single-link mode, this has to be slave */ - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) - return -EINVAL; + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) + iface |= R01_SIM; uda1380_write(codec, UDA1380_IFACE, iface); return 0; } -static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai, - unsigned int fmt) +/* + * Flush reg cache + * We can only write the interpolator and decimator registers + * when the DAI is being clocked by the CPU DAI. It's up to the + * machine and cpu DAI driver to do this before we are called. + */ +static int uda1380_pcm_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) { - struct snd_soc_codec *codec = codec_dai->codec; - int iface; - - /* set up DAI based upon fmt */ - iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); - iface &= ~R01_SFORI_MASK; - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface |= R01_SFORI_I2S; - break; - case SND_SOC_DAIFMT_LSB: - iface |= R01_SFORI_LSB16; - break; - case SND_SOC_DAIFMT_MSB: - iface |= R01_SFORI_MSB; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->codec; + int reg, reg_start, reg_end, clk; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + reg_start = UDA1380_MVOL; + reg_end = UDA1380_MIXER; + } else { + reg_start = UDA1380_DEC; + reg_end = UDA1380_AGC; } - /* DATAI is slave only, so this has to be slave */ - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) - return -EINVAL; - - uda1380_write(codec, UDA1380_IFACE, iface); - - return 0; -} - -static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - int iface; - - /* set up DAI based upon fmt */ - iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); - iface &= ~(R01_SIM | R01_SFORO_MASK); + /* FIXME disable DAC_CLK */ + clk = uda1380_read_reg_cache(codec, UDA1380_CLK); + uda1380_write(codec, UDA1380_CLK, clk & ~R00_DAC_CLK); - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface |= R01_SFORO_I2S; - break; - case SND_SOC_DAIFMT_LSB: - iface |= R01_SFORO_LSB16; - break; - case SND_SOC_DAIFMT_MSB: - iface |= R01_SFORO_MSB; + for (reg = reg_start; reg <= reg_end; reg++) { + pr_debug("uda1380: flush reg %x val %x:", reg, + uda1380_read_reg_cache(codec, reg)); + uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg)); } - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) - iface |= R01_SIM; + /* FIXME enable DAC_CLK */ + uda1380_write(codec, UDA1380_CLK, clk | R00_DAC_CLK); - uda1380_write(codec, UDA1380_IFACE, iface); - - return 0; -} - -static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; - int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - uda1380_write_reg_cache(codec, UDA1380_MIXER, - mixer & ~R14_SILENCE); - schedule_work(&uda1380_work); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - uda1380_write_reg_cache(codec, UDA1380_MIXER, - mixer | R14_SILENCE); - schedule_work(&uda1380_work); - break; - } return 0; } @@ -498,7 +445,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); /* set WSPLL power and divider if running from this clock */ @@ -537,7 +484,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); /* shut down WSPLL power if running from this clock */ @@ -554,6 +501,24 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, uda1380_write(codec, UDA1380_CLK, clk); } +static int uda1380_mute(struct snd_soc_dai *codec_dai, int mute) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 mute_reg = uda1380_read_reg_cache(codec, UDA1380_DEEMP) & ~R13_MTM; + + /* FIXME: mute(codec,0) is called when the magician clock is already + * set to WSPLL, but for some unknown reason writing to interpolator + * registers works only when clocked by SYSCLK */ + u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); + uda1380_write(codec, UDA1380_CLK, ~R00_DAC_CLK & clk); + if (mute) + uda1380_write(codec, UDA1380_DEEMP, mute_reg | R13_MTM); + else + uda1380_write(codec, UDA1380_DEEMP, mute_reg); + uda1380_write(codec, UDA1380_CLK, clk); + return 0; +} + static int uda1380_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -579,27 +544,6 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops uda1380_dai_ops = { - .hw_params = uda1380_pcm_hw_params, - .shutdown = uda1380_pcm_shutdown, - .trigger = uda1380_trigger, - .set_fmt = uda1380_set_dai_fmt_both, -}; - -static struct snd_soc_dai_ops uda1380_dai_ops_playback = { - .hw_params = uda1380_pcm_hw_params, - .shutdown = uda1380_pcm_shutdown, - .trigger = uda1380_trigger, - .set_fmt = uda1380_set_dai_fmt_playback, -}; - -static struct snd_soc_dai_ops uda1380_dai_ops_capture = { - .hw_params = uda1380_pcm_hw_params, - .shutdown = uda1380_pcm_shutdown, - .trigger = uda1380_trigger, - .set_fmt = uda1380_set_dai_fmt_capture, -}; - struct snd_soc_dai uda1380_dai[] = { { .name = "UDA1380", @@ -615,7 +559,13 @@ struct snd_soc_dai uda1380_dai[] = { .channels_max = 2, .rates = UDA1380_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &uda1380_dai_ops, + .ops = { + .hw_params = uda1380_pcm_hw_params, + .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, + .digital_mute = uda1380_mute, + .set_fmt = uda1380_set_dai_fmt, + }, }, { /* playback only - dual interface */ .name = "UDA1380", @@ -626,7 +576,13 @@ struct snd_soc_dai uda1380_dai[] = { .rates = UDA1380_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &uda1380_dai_ops_playback, + .ops = { + .hw_params = uda1380_pcm_hw_params, + .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, + .digital_mute = uda1380_mute, + .set_fmt = uda1380_set_dai_fmt, + }, }, { /* capture only - dual interface*/ .name = "UDA1380", @@ -637,7 +593,12 @@ struct snd_soc_dai uda1380_dai[] = { .rates = UDA1380_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &uda1380_dai_ops_capture, + .ops = { + .hw_params = uda1380_pcm_hw_params, + .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, + .set_fmt = uda1380_set_dai_fmt, + }, }, }; EXPORT_SYMBOL_GPL(uda1380_dai); @@ -645,7 +606,7 @@ EXPORT_SYMBOL_GPL(uda1380_dai); static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -654,7 +615,7 @@ static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) static int uda1380_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u16 *cache = codec->reg_cache; @@ -676,7 +637,7 @@ static int uda1380_resume(struct platform_device *pdev) */ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret = 0; codec->name = "UDA1380"; @@ -694,9 +655,6 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) codec->reg_cache_step = 1; uda1380_reset(codec); - uda1380_codec = codec; - INIT_WORK(&uda1380_work, uda1380_flush_work); - /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { @@ -717,8 +675,7 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) } /* uda1380 init */ - snd_soc_add_controls(codec, uda1380_snd_controls, - ARRAY_SIZE(uda1380_snd_controls)); + uda1380_add_controls(codec); uda1380_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -745,7 +702,7 @@ static int uda1380_i2c_probe(struct i2c_client *i2c, { struct snd_soc_device *socdev = uda1380_socdev; struct uda1380_setup_data *setup = socdev->codec_data; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -829,12 +786,14 @@ static int uda1380_probe(struct platform_device *pdev) struct snd_soc_codec *codec; int ret; + pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION); + setup = socdev->codec_data; codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); if (codec == NULL) return -ENOMEM; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -858,7 +817,7 @@ static int uda1380_probe(struct platform_device *pdev) static int uda1380_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/wm8350.c b/trunk/sound/soc/codecs/wm8350.c index 3b1d0993bed9..35d99750c383 100644 --- a/trunk/sound/soc/codecs/wm8350.c +++ b/trunk/sound/soc/codecs/wm8350.c @@ -51,17 +51,10 @@ struct wm8350_output { u16 mute; }; -struct wm8350_jack_data { - struct snd_soc_jack *jack; - int report; -}; - struct wm8350_data { struct snd_soc_codec codec; struct wm8350_output out1; struct wm8350_output out2; - struct wm8350_jack_data hpl; - struct wm8350_jack_data hpr; struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; }; @@ -782,6 +775,21 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Beep", NULL, "IN3R PGA"}, }; +static int wm8350_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8350_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8350_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + static int wm8350_add_widgets(struct snd_soc_codec *codec) { int ret; @@ -1301,7 +1309,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1310,7 +1318,7 @@ static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) static int wm8350_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1320,95 +1328,6 @@ static int wm8350_resume(struct platform_device *pdev) return 0; } -static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data) -{ - struct wm8350_data *priv = data; - u16 reg; - int report; - int mask; - struct wm8350_jack_data *jack = NULL; - - switch (irq) { - case WM8350_IRQ_CODEC_JCK_DET_L: - jack = &priv->hpl; - mask = WM8350_JACK_L_LVL; - break; - - case WM8350_IRQ_CODEC_JCK_DET_R: - jack = &priv->hpr; - mask = WM8350_JACK_R_LVL; - break; - - default: - BUG(); - } - - if (!jack->jack) { - dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); - return; - } - - /* Debounce */ - msleep(200); - - reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); - if (reg & mask) - report = jack->report; - else - report = 0; - - snd_soc_jack_report(jack->jack, report, jack->report); -} - -/** - * wm8350_hp_jack_detect - Enable headphone jack detection. - * - * @codec: WM8350 codec - * @which: left or right jack detect signal - * @jack: jack to report detection events on - * @report: value to report - * - * Enables the headphone jack detection of the WM8350. - */ -int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, - struct snd_soc_jack *jack, int report) -{ - struct wm8350_data *priv = codec->private_data; - struct wm8350 *wm8350 = codec->control_data; - int irq; - int ena; - - switch (which) { - case WM8350_JDL: - priv->hpl.jack = jack; - priv->hpl.report = report; - irq = WM8350_IRQ_CODEC_JCK_DET_L; - ena = WM8350_JDL_ENA; - break; - - case WM8350_JDR: - priv->hpr.jack = jack; - priv->hpr.report = report; - irq = WM8350_IRQ_CODEC_JCK_DET_R; - ena = WM8350_JDR_ENA; - break; - - default: - return -EINVAL; - } - - wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); - wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); - - /* Sync status */ - wm8350_hp_jack_handler(wm8350, irq, priv); - - wm8350_unmask_irq(wm8350, irq); - - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); - static struct snd_soc_codec *wm8350_codec; static int wm8350_probe(struct platform_device *pdev) @@ -1423,8 +1342,8 @@ static int wm8350_probe(struct platform_device *pdev) BUG_ON(!wm8350_codec); - socdev->card->codec = wm8350_codec; - codec = socdev->card->codec; + socdev->codec = wm8350_codec; + codec = socdev->codec; wm8350 = codec->control_data; priv = codec->private_data; @@ -1462,21 +1381,13 @@ static int wm8350_probe(struct platform_device *pdev) wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, WM8350_OUT2_VU | WM8350_OUT2R_MUTE); - wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); - wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); - wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, - wm8350_hp_jack_handler, priv); - wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, - wm8350_hp_jack_handler, priv); - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { dev_err(&pdev->dev, "failed to create pcms\n"); return ret; } - snd_soc_add_controls(codec, wm8350_snd_controls, - ARRAY_SIZE(wm8350_snd_controls)); + wm8350_add_controls(codec); wm8350_add_widgets(codec); wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1498,23 +1409,10 @@ static int wm8350_probe(struct platform_device *pdev) static int wm8350_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8350 *wm8350 = codec->control_data; - struct wm8350_data *priv = codec->private_data; int ret; - wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, - WM8350_JDL_ENA | WM8350_JDR_ENA); - wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); - - wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); - wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); - wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); - wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); - - priv->hpl.jack = NULL; - priv->hpr.jack = NULL; - /* cancel any work waiting to be queued. */ ret = cancel_delayed_work(&codec->delayed_work); @@ -1538,16 +1436,6 @@ static int wm8350_remove(struct platform_device *pdev) SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8350_dai_ops = { - .hw_params = wm8350_pcm_hw_params, - .digital_mute = wm8350_mute, - .trigger = wm8350_pcm_trigger, - .set_fmt = wm8350_set_dai_fmt, - .set_sysclk = wm8350_set_dai_sysclk, - .set_pll = wm8350_set_fll, - .set_clkdiv = wm8350_set_clkdiv, -}; - struct snd_soc_dai wm8350_dai = { .name = "WM8350", .playback = { @@ -1564,7 +1452,15 @@ struct snd_soc_dai wm8350_dai = { .rates = WM8350_RATES, .formats = WM8350_FORMATS, }, - .ops = &wm8350_dai_ops, + .ops = { + .hw_params = wm8350_pcm_hw_params, + .digital_mute = wm8350_mute, + .trigger = wm8350_pcm_trigger, + .set_fmt = wm8350_set_dai_fmt, + .set_sysclk = wm8350_set_dai_sysclk, + .set_pll = wm8350_set_fll, + .set_clkdiv = wm8350_set_clkdiv, + }, }; EXPORT_SYMBOL_GPL(wm8350_dai); @@ -1576,7 +1472,7 @@ struct snd_soc_codec_device soc_codec_dev_wm8350 = { }; EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350); -static __devinit int wm8350_codec_probe(struct platform_device *pdev) +static int wm8350_codec_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = platform_get_drvdata(pdev); struct wm8350_data *priv; diff --git a/trunk/sound/soc/codecs/wm8350.h b/trunk/sound/soc/codecs/wm8350.h index d11bd9288cf9..cc2887aa6c38 100644 --- a/trunk/sound/soc/codecs/wm8350.h +++ b/trunk/sound/soc/codecs/wm8350.h @@ -17,12 +17,4 @@ extern struct snd_soc_dai wm8350_dai; extern struct snd_soc_codec_device soc_codec_dev_wm8350; -enum wm8350_jack { - WM8350_JDL = 1, - WM8350_JDR = 2, -}; - -int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, - struct snd_soc_jack *jack, int report); - #endif diff --git a/trunk/sound/soc/codecs/wm8400.c b/trunk/sound/soc/codecs/wm8400.c deleted file mode 100644 index 510efa604008..000000000000 --- a/trunk/sound/soc/codecs/wm8400.c +++ /dev/null @@ -1,1582 +0,0 @@ -/* - * wm8400.c -- WM8400 ALSA Soc Audio driver - * - * Copyright 2008, 2009 Wolfson Microelectronics PLC. - * Author: Mark Brown - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wm8400.h" - -/* Fake register for internal state */ -#define WM8400_INTDRIVBITS (WM8400_REGISTER_COUNT + 1) -#define WM8400_INMIXL_PWR 0 -#define WM8400_AINLMUX_PWR 1 -#define WM8400_INMIXR_PWR 2 -#define WM8400_AINRMUX_PWR 3 - -static struct regulator_bulk_data power[] = { - { - .supply = "I2S1VDD", - }, - { - .supply = "I2S2VDD", - }, - { - .supply = "DCVDD", - }, - { - .supply = "AVDD", - }, - { - .supply = "FLLVDD", - }, - { - .supply = "HPVDD", - }, - { - .supply = "SPKVDD", - }, -}; - -/* codec private data */ -struct wm8400_priv { - struct snd_soc_codec codec; - struct wm8400 *wm8400; - u16 fake_register; - unsigned int sysclk; - unsigned int pcmclk; - struct work_struct work; - int fll_in, fll_out; -}; - -static inline unsigned int wm8400_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - struct wm8400_priv *wm8400 = codec->private_data; - - if (reg == WM8400_INTDRIVBITS) - return wm8400->fake_register; - else - return wm8400_reg_read(wm8400->wm8400, reg); -} - -/* - * write to the wm8400 register space - */ -static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - struct wm8400_priv *wm8400 = codec->private_data; - - if (reg == WM8400_INTDRIVBITS) { - wm8400->fake_register = value; - return 0; - } else - return wm8400_set_bits(wm8400->wm8400, reg, 0xffff, value); -} - -static void wm8400_codec_reset(struct snd_soc_codec *codec) -{ - struct wm8400_priv *wm8400 = codec->private_data; - - wm8400_reset_codec_reg_cache(wm8400->wm8400); -} - -static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); - -static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000); - -static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, -2100, 0); - -static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600); - -static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0); - -static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0); - -static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763); - -static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0); - -static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int reg = mc->reg; - int ret; - u16 val; - - ret = snd_soc_put_volsw(kcontrol, ucontrol); - if (ret < 0) - return ret; - - /* now hit the volume update bits (always bit 8) */ - val = wm8400_read(codec, reg); - return wm8400_write(codec, reg, val | 0x0100); -} - -#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ - SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_get_volsw, .put = wm8400_outpga_put_volsw_vu, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } - - -static const char *wm8400_digital_sidetone[] = - {"None", "Left ADC", "Right ADC", "Reserved"}; - -static const struct soc_enum wm8400_left_digital_sidetone_enum = -SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, - WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone); - -static const struct soc_enum wm8400_right_digital_sidetone_enum = -SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, - WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone); - -static const char *wm8400_adcmode[] = - {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; - -static const struct soc_enum wm8400_right_adcmode_enum = -SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode); - -static const struct snd_kcontrol_new wm8400_snd_controls[] = { -/* INMIXL */ -SOC_SINGLE("LIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L12MNBST_SHIFT, - 1, 0), -SOC_SINGLE("LIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L34MNBST_SHIFT, - 1, 0), -/* INMIXR */ -SOC_SINGLE("RIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R12MNBST_SHIFT, - 1, 0), -SOC_SINGLE("RIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R34MNBST_SHIFT, - 1, 0), - -/* LOMIX */ -SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER3, - WM8400_LLI3LOVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3, - WM8400_LR12LOVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3, - WM8400_LL12LOVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER5, - WM8400_LRI3LOVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER5, - WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER5, - WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv), - -/* ROMIX */ -SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER4, - WM8400_RRI3ROVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4, - WM8400_RL12ROVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4, - WM8400_RR12ROVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER6, - WM8400_RLI3ROVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER6, - WM8400_RLBROVOL_SHIFT, 7, 0, out_mix_tlv), -SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER6, - WM8400_RRBROVOL_SHIFT, 7, 0, out_mix_tlv), - -/* LOUT */ -WM8400_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8400_LEFT_OUTPUT_VOLUME, - WM8400_LOUTVOL_SHIFT, WM8400_LOUTVOL_MASK, 0, out_pga_tlv), -SOC_SINGLE("LOUT ZC", WM8400_LEFT_OUTPUT_VOLUME, WM8400_LOZC_SHIFT, 1, 0), - -/* ROUT */ -WM8400_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8400_RIGHT_OUTPUT_VOLUME, - WM8400_ROUTVOL_SHIFT, WM8400_ROUTVOL_MASK, 0, out_pga_tlv), -SOC_SINGLE("ROUT ZC", WM8400_RIGHT_OUTPUT_VOLUME, WM8400_ROZC_SHIFT, 1, 0), - -/* LOPGA */ -WM8400_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8400_LEFT_OPGA_VOLUME, - WM8400_LOPGAVOL_SHIFT, WM8400_LOPGAVOL_MASK, 0, out_pga_tlv), -SOC_SINGLE("LOPGA ZC Switch", WM8400_LEFT_OPGA_VOLUME, - WM8400_LOPGAZC_SHIFT, 1, 0), - -/* ROPGA */ -WM8400_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8400_RIGHT_OPGA_VOLUME, - WM8400_ROPGAVOL_SHIFT, WM8400_ROPGAVOL_MASK, 0, out_pga_tlv), -SOC_SINGLE("ROPGA ZC Switch", WM8400_RIGHT_OPGA_VOLUME, - WM8400_ROPGAZC_SHIFT, 1, 0), - -SOC_SINGLE("LON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME, - WM8400_LONMUTE_SHIFT, 1, 0), -SOC_SINGLE("LOP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME, - WM8400_LOPMUTE_SHIFT, 1, 0), -SOC_SINGLE("LOP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME, - WM8400_LOATTN_SHIFT, 1, 0), -SOC_SINGLE("RON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME, - WM8400_RONMUTE_SHIFT, 1, 0), -SOC_SINGLE("ROP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME, - WM8400_ROPMUTE_SHIFT, 1, 0), -SOC_SINGLE("ROP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME, - WM8400_ROATTN_SHIFT, 1, 0), - -SOC_SINGLE("OUT3 Mute Switch", WM8400_OUT3_4_VOLUME, - WM8400_OUT3MUTE_SHIFT, 1, 0), -SOC_SINGLE("OUT3 Attenuation Switch", WM8400_OUT3_4_VOLUME, - WM8400_OUT3ATTN_SHIFT, 1, 0), - -SOC_SINGLE("OUT4 Mute Switch", WM8400_OUT3_4_VOLUME, - WM8400_OUT4MUTE_SHIFT, 1, 0), -SOC_SINGLE("OUT4 Attenuation Switch", WM8400_OUT3_4_VOLUME, - WM8400_OUT4ATTN_SHIFT, 1, 0), - -SOC_SINGLE("Speaker Mode Switch", WM8400_CLASSD1, - WM8400_CDMODE_SHIFT, 1, 0), - -SOC_SINGLE("Speaker Output Attenuation Volume", WM8400_SPEAKER_VOLUME, - WM8400_SPKATTN_SHIFT, WM8400_SPKATTN_MASK, 0), -SOC_SINGLE("Speaker DC Boost Volume", WM8400_CLASSD3, - WM8400_DCGAIN_SHIFT, 6, 0), -SOC_SINGLE("Speaker AC Boost Volume", WM8400_CLASSD3, - WM8400_ACGAIN_SHIFT, 6, 0), - -WM8400_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume", - WM8400_LEFT_DAC_DIGITAL_VOLUME, WM8400_DACL_VOL_SHIFT, - 127, 0, out_dac_tlv), - -WM8400_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume", - WM8400_RIGHT_DAC_DIGITAL_VOLUME, WM8400_DACR_VOL_SHIFT, - 127, 0, out_dac_tlv), - -SOC_ENUM("Left Digital Sidetone", wm8400_left_digital_sidetone_enum), -SOC_ENUM("Right Digital Sidetone", wm8400_right_digital_sidetone_enum), - -SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE, - WM8400_ADCL_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv), -SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE, - WM8400_ADCR_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv), - -SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8400_ADC_CTRL, - WM8400_ADC_HPF_ENA_SHIFT, 1, 0), - -SOC_ENUM("ADC HPF Mode", wm8400_right_adcmode_enum), - -WM8400_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume", - WM8400_LEFT_ADC_DIGITAL_VOLUME, - WM8400_ADCL_VOL_SHIFT, - WM8400_ADCL_VOL_MASK, - 0, - in_adc_tlv), - -WM8400_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume", - WM8400_RIGHT_ADC_DIGITAL_VOLUME, - WM8400_ADCR_VOL_SHIFT, - WM8400_ADCR_VOL_MASK, - 0, - in_adc_tlv), - -WM8400_OUTPGA_SINGLE_R_TLV("LIN12 Volume", - WM8400_LEFT_LINE_INPUT_1_2_VOLUME, - WM8400_LIN12VOL_SHIFT, - WM8400_LIN12VOL_MASK, - 0, - in_pga_tlv), - -SOC_SINGLE("LIN12 ZC Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME, - WM8400_LI12ZC_SHIFT, 1, 0), - -SOC_SINGLE("LIN12 Mute Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME, - WM8400_LI12MUTE_SHIFT, 1, 0), - -WM8400_OUTPGA_SINGLE_R_TLV("LIN34 Volume", - WM8400_LEFT_LINE_INPUT_3_4_VOLUME, - WM8400_LIN34VOL_SHIFT, - WM8400_LIN34VOL_MASK, - 0, - in_pga_tlv), - -SOC_SINGLE("LIN34 ZC Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME, - WM8400_LI34ZC_SHIFT, 1, 0), - -SOC_SINGLE("LIN34 Mute Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME, - WM8400_LI34MUTE_SHIFT, 1, 0), - -WM8400_OUTPGA_SINGLE_R_TLV("RIN12 Volume", - WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, - WM8400_RIN12VOL_SHIFT, - WM8400_RIN12VOL_MASK, - 0, - in_pga_tlv), - -SOC_SINGLE("RIN12 ZC Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, - WM8400_RI12ZC_SHIFT, 1, 0), - -SOC_SINGLE("RIN12 Mute Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, - WM8400_RI12MUTE_SHIFT, 1, 0), - -WM8400_OUTPGA_SINGLE_R_TLV("RIN34 Volume", - WM8400_RIGHT_LINE_INPUT_3_4_VOLUME, - WM8400_RIN34VOL_SHIFT, - WM8400_RIN34VOL_MASK, - 0, - in_pga_tlv), - -SOC_SINGLE("RIN34 ZC Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME, - WM8400_RI34ZC_SHIFT, 1, 0), - -SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME, - WM8400_RI34MUTE_SHIFT, 1, 0), - -}; - -/* add non dapm controls */ -static int wm8400_add_controls(struct snd_soc_codec *codec) -{ - return snd_soc_add_controls(codec, wm8400_snd_controls, - ARRAY_SIZE(wm8400_snd_controls)); -} - -/* - * _DAPM_ Controls - */ - -static int inmixer_event (struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - u16 reg, fakepower; - - reg = wm8400_read(w->codec, WM8400_POWER_MANAGEMENT_2); - fakepower = wm8400_read(w->codec, WM8400_INTDRIVBITS); - - if (fakepower & ((1 << WM8400_INMIXL_PWR) | - (1 << WM8400_AINLMUX_PWR))) { - reg |= WM8400_AINL_ENA; - } else { - reg &= ~WM8400_AINL_ENA; - } - - if (fakepower & ((1 << WM8400_INMIXR_PWR) | - (1 << WM8400_AINRMUX_PWR))) { - reg |= WM8400_AINR_ENA; - } else { - reg &= ~WM8400_AINL_ENA; - } - wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg); - - return 0; -} - -static int outmixer_event (struct snd_soc_dapm_widget *w, - struct snd_kcontrol * kcontrol, int event) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - u32 reg_shift = mc->shift; - int ret = 0; - u16 reg; - - switch (reg_shift) { - case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) : - reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER1); - if (reg & WM8400_LDLO) { - printk(KERN_WARNING - "Cannot set as Output Mixer 1 LDLO Set\n"); - ret = -1; - } - break; - case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8): - reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER2); - if (reg & WM8400_RDRO) { - printk(KERN_WARNING - "Cannot set as Output Mixer 2 RDRO Set\n"); - ret = -1; - } - break; - case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8): - reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER); - if (reg & WM8400_LDSPK) { - printk(KERN_WARNING - "Cannot set as Speaker Mixer LDSPK Set\n"); - ret = -1; - } - break; - case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8): - reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER); - if (reg & WM8400_RDSPK) { - printk(KERN_WARNING - "Cannot set as Speaker Mixer RDSPK Set\n"); - ret = -1; - } - break; - } - - return ret; -} - -/* INMIX dB values */ -static const unsigned int in_mix_tlv[] = { - TLV_DB_RANGE_HEAD(1), - 0,7, TLV_DB_LINEAR_ITEM(-1200, 600), -}; - -/* Left In PGA Connections */ -static const struct snd_kcontrol_new wm8400_dapm_lin12_pga_controls[] = { -SOC_DAPM_SINGLE("LIN1 Switch", WM8400_INPUT_MIXER2, WM8400_LMN1_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LIN2 Switch", WM8400_INPUT_MIXER2, WM8400_LMP2_SHIFT, 1, 0), -}; - -static const struct snd_kcontrol_new wm8400_dapm_lin34_pga_controls[] = { -SOC_DAPM_SINGLE("LIN3 Switch", WM8400_INPUT_MIXER2, WM8400_LMN3_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LIN4 Switch", WM8400_INPUT_MIXER2, WM8400_LMP4_SHIFT, 1, 0), -}; - -/* Right In PGA Connections */ -static const struct snd_kcontrol_new wm8400_dapm_rin12_pga_controls[] = { -SOC_DAPM_SINGLE("RIN1 Switch", WM8400_INPUT_MIXER2, WM8400_RMN1_SHIFT, 1, 0), -SOC_DAPM_SINGLE("RIN2 Switch", WM8400_INPUT_MIXER2, WM8400_RMP2_SHIFT, 1, 0), -}; - -static const struct snd_kcontrol_new wm8400_dapm_rin34_pga_controls[] = { -SOC_DAPM_SINGLE("RIN3 Switch", WM8400_INPUT_MIXER2, WM8400_RMN3_SHIFT, 1, 0), -SOC_DAPM_SINGLE("RIN4 Switch", WM8400_INPUT_MIXER2, WM8400_RMP4_SHIFT, 1, 0), -}; - -/* INMIXL */ -static const struct snd_kcontrol_new wm8400_dapm_inmixl_controls[] = { -SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8400_INPUT_MIXER3, - WM8400_LDBVOL_SHIFT, WM8400_LDBVOL_MASK, 0, in_mix_tlv), -SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8400_INPUT_MIXER5, WM8400_LI2BVOL_SHIFT, - 7, 0, in_mix_tlv), -SOC_DAPM_SINGLE("LINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT, - 1, 0), -SOC_DAPM_SINGLE("LINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT, - 1, 0), -}; - -/* INMIXR */ -static const struct snd_kcontrol_new wm8400_dapm_inmixr_controls[] = { -SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8400_INPUT_MIXER4, - WM8400_RDBVOL_SHIFT, WM8400_RDBVOL_MASK, 0, in_mix_tlv), -SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8400_INPUT_MIXER6, WM8400_RI2BVOL_SHIFT, - 7, 0, in_mix_tlv), -SOC_DAPM_SINGLE("RINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT, - 1, 0), -SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT, - 1, 0), -}; - -/* AINLMUX */ -static const char *wm8400_ainlmux[] = - {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; - -static const struct soc_enum wm8400_ainlmux_enum = -SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT, - ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux); - -static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = -SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); - -/* DIFFINL */ - -/* AINRMUX */ -static const char *wm8400_ainrmux[] = - {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; - -static const struct soc_enum wm8400_ainrmux_enum = -SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT, - ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux); - -static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = -SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); - -/* RXVOICE */ -static const struct snd_kcontrol_new wm8400_dapm_rxvoice_controls[] = { -SOC_DAPM_SINGLE_TLV("LIN4/RXN", WM8400_INPUT_MIXER5, WM8400_LR4BVOL_SHIFT, - WM8400_LR4BVOL_MASK, 0, in_mix_tlv), -SOC_DAPM_SINGLE_TLV("RIN4/RXP", WM8400_INPUT_MIXER6, WM8400_RL4BVOL_SHIFT, - WM8400_RL4BVOL_MASK, 0, in_mix_tlv), -}; - -/* LOMIX */ -static const struct snd_kcontrol_new wm8400_dapm_lomix_controls[] = { -SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER1, - WM8400_LRBLO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER1, - WM8400_LLBLO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER1, - WM8400_LRI3LO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER1, - WM8400_LLI3LO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1, - WM8400_LR12LO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1, - WM8400_LL12LO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8400_OUTPUT_MIXER1, - WM8400_LDLO_SHIFT, 1, 0), -}; - -/* ROMIX */ -static const struct snd_kcontrol_new wm8400_dapm_romix_controls[] = { -SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER2, - WM8400_RLBRO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER2, - WM8400_RRBRO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER2, - WM8400_RLI3RO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER2, - WM8400_RRI3RO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2, - WM8400_RL12RO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2, - WM8400_RR12RO_SHIFT, 1, 0), -SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8400_OUTPUT_MIXER2, - WM8400_RDRO_SHIFT, 1, 0), -}; - -/* LONMIX */ -static const struct snd_kcontrol_new wm8400_dapm_lonmix_controls[] = { -SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1, - WM8400_LLOPGALON_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER1, - WM8400_LROPGALON_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8400_LINE_MIXER1, - WM8400_LOPLON_SHIFT, 1, 0), -}; - -/* LOPMIX */ -static const struct snd_kcontrol_new wm8400_dapm_lopmix_controls[] = { -SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER1, - WM8400_LR12LOP_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER1, - WM8400_LL12LOP_SHIFT, 1, 0), -SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1, - WM8400_LLOPGALOP_SHIFT, 1, 0), -}; - -/* RONMIX */ -static const struct snd_kcontrol_new wm8400_dapm_ronmix_controls[] = { -SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2, - WM8400_RROPGARON_SHIFT, 1, 0), -SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER2, - WM8400_RLOPGARON_SHIFT, 1, 0), -SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8400_LINE_MIXER2, - WM8400_ROPRON_SHIFT, 1, 0), -}; - -/* ROPMIX */ -static const struct snd_kcontrol_new wm8400_dapm_ropmix_controls[] = { -SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER2, - WM8400_RL12ROP_SHIFT, 1, 0), -SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER2, - WM8400_RR12ROP_SHIFT, 1, 0), -SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2, - WM8400_RROPGAROP_SHIFT, 1, 0), -}; - -/* OUT3MIX */ -static const struct snd_kcontrol_new wm8400_dapm_out3mix_controls[] = { -SOC_DAPM_SINGLE("OUT3MIX LIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER, - WM8400_LI4O3_SHIFT, 1, 0), -SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8400_OUT3_4_MIXER, - WM8400_LPGAO3_SHIFT, 1, 0), -}; - -/* OUT4MIX */ -static const struct snd_kcontrol_new wm8400_dapm_out4mix_controls[] = { -SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8400_OUT3_4_MIXER, - WM8400_RPGAO4_SHIFT, 1, 0), -SOC_DAPM_SINGLE("OUT4MIX RIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER, - WM8400_RI4O4_SHIFT, 1, 0), -}; - -/* SPKMIX */ -static const struct snd_kcontrol_new wm8400_dapm_spkmix_controls[] = { -SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8400_SPEAKER_MIXER, - WM8400_LI2SPK_SHIFT, 1, 0), -SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8400_SPEAKER_MIXER, - WM8400_LB2SPK_SHIFT, 1, 0), -SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8400_SPEAKER_MIXER, - WM8400_LOPGASPK_SHIFT, 1, 0), -SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8400_SPEAKER_MIXER, - WM8400_LDSPK_SHIFT, 1, 0), -SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8400_SPEAKER_MIXER, - WM8400_RDSPK_SHIFT, 1, 0), -SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8400_SPEAKER_MIXER, - WM8400_ROPGASPK_SHIFT, 1, 0), -SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8400_SPEAKER_MIXER, - WM8400_RL12ROP_SHIFT, 1, 0), -SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8400_SPEAKER_MIXER, - WM8400_RI2SPK_SHIFT, 1, 0), -}; - -static const struct snd_soc_dapm_widget wm8400_dapm_widgets[] = { -/* Input Side */ -/* Input Lines */ -SND_SOC_DAPM_INPUT("LIN1"), -SND_SOC_DAPM_INPUT("LIN2"), -SND_SOC_DAPM_INPUT("LIN3"), -SND_SOC_DAPM_INPUT("LIN4/RXN"), -SND_SOC_DAPM_INPUT("RIN3"), -SND_SOC_DAPM_INPUT("RIN4/RXP"), -SND_SOC_DAPM_INPUT("RIN1"), -SND_SOC_DAPM_INPUT("RIN2"), -SND_SOC_DAPM_INPUT("Internal ADC Source"), - -/* DACs */ -SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8400_POWER_MANAGEMENT_2, - WM8400_ADCL_ENA_SHIFT, 0), -SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8400_POWER_MANAGEMENT_2, - WM8400_ADCR_ENA_SHIFT, 0), - -/* Input PGAs */ -SND_SOC_DAPM_MIXER("LIN12 PGA", WM8400_POWER_MANAGEMENT_2, - WM8400_LIN12_ENA_SHIFT, - 0, &wm8400_dapm_lin12_pga_controls[0], - ARRAY_SIZE(wm8400_dapm_lin12_pga_controls)), -SND_SOC_DAPM_MIXER("LIN34 PGA", WM8400_POWER_MANAGEMENT_2, - WM8400_LIN34_ENA_SHIFT, - 0, &wm8400_dapm_lin34_pga_controls[0], - ARRAY_SIZE(wm8400_dapm_lin34_pga_controls)), -SND_SOC_DAPM_MIXER("RIN12 PGA", WM8400_POWER_MANAGEMENT_2, - WM8400_RIN12_ENA_SHIFT, - 0, &wm8400_dapm_rin12_pga_controls[0], - ARRAY_SIZE(wm8400_dapm_rin12_pga_controls)), -SND_SOC_DAPM_MIXER("RIN34 PGA", WM8400_POWER_MANAGEMENT_2, - WM8400_RIN34_ENA_SHIFT, - 0, &wm8400_dapm_rin34_pga_controls[0], - ARRAY_SIZE(wm8400_dapm_rin34_pga_controls)), - -/* INMIXL */ -SND_SOC_DAPM_MIXER_E("INMIXL", WM8400_INTDRIVBITS, WM8400_INMIXL_PWR, 0, - &wm8400_dapm_inmixl_controls[0], - ARRAY_SIZE(wm8400_dapm_inmixl_controls), - inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - -/* AINLMUX */ -SND_SOC_DAPM_MUX_E("AILNMUX", WM8400_INTDRIVBITS, WM8400_AINLMUX_PWR, 0, - &wm8400_dapm_ainlmux_controls, inmixer_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - -/* INMIXR */ -SND_SOC_DAPM_MIXER_E("INMIXR", WM8400_INTDRIVBITS, WM8400_INMIXR_PWR, 0, - &wm8400_dapm_inmixr_controls[0], - ARRAY_SIZE(wm8400_dapm_inmixr_controls), - inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - -/* AINRMUX */ -SND_SOC_DAPM_MUX_E("AIRNMUX", WM8400_INTDRIVBITS, WM8400_AINRMUX_PWR, 0, - &wm8400_dapm_ainrmux_controls, inmixer_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - -/* Output Side */ -/* DACs */ -SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8400_POWER_MANAGEMENT_3, - WM8400_DACL_ENA_SHIFT, 0), -SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8400_POWER_MANAGEMENT_3, - WM8400_DACR_ENA_SHIFT, 0), - -/* LOMIX */ -SND_SOC_DAPM_MIXER_E("LOMIX", WM8400_POWER_MANAGEMENT_3, - WM8400_LOMIX_ENA_SHIFT, - 0, &wm8400_dapm_lomix_controls[0], - ARRAY_SIZE(wm8400_dapm_lomix_controls), - outmixer_event, SND_SOC_DAPM_PRE_REG), - -/* LONMIX */ -SND_SOC_DAPM_MIXER("LONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LON_ENA_SHIFT, - 0, &wm8400_dapm_lonmix_controls[0], - ARRAY_SIZE(wm8400_dapm_lonmix_controls)), - -/* LOPMIX */ -SND_SOC_DAPM_MIXER("LOPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LOP_ENA_SHIFT, - 0, &wm8400_dapm_lopmix_controls[0], - ARRAY_SIZE(wm8400_dapm_lopmix_controls)), - -/* OUT3MIX */ -SND_SOC_DAPM_MIXER("OUT3MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT3_ENA_SHIFT, - 0, &wm8400_dapm_out3mix_controls[0], - ARRAY_SIZE(wm8400_dapm_out3mix_controls)), - -/* SPKMIX */ -SND_SOC_DAPM_MIXER_E("SPKMIX", WM8400_POWER_MANAGEMENT_1, WM8400_SPK_ENA_SHIFT, - 0, &wm8400_dapm_spkmix_controls[0], - ARRAY_SIZE(wm8400_dapm_spkmix_controls), outmixer_event, - SND_SOC_DAPM_PRE_REG), - -/* OUT4MIX */ -SND_SOC_DAPM_MIXER("OUT4MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT4_ENA_SHIFT, - 0, &wm8400_dapm_out4mix_controls[0], - ARRAY_SIZE(wm8400_dapm_out4mix_controls)), - -/* ROPMIX */ -SND_SOC_DAPM_MIXER("ROPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_ROP_ENA_SHIFT, - 0, &wm8400_dapm_ropmix_controls[0], - ARRAY_SIZE(wm8400_dapm_ropmix_controls)), - -/* RONMIX */ -SND_SOC_DAPM_MIXER("RONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_RON_ENA_SHIFT, - 0, &wm8400_dapm_ronmix_controls[0], - ARRAY_SIZE(wm8400_dapm_ronmix_controls)), - -/* ROMIX */ -SND_SOC_DAPM_MIXER_E("ROMIX", WM8400_POWER_MANAGEMENT_3, - WM8400_ROMIX_ENA_SHIFT, - 0, &wm8400_dapm_romix_controls[0], - ARRAY_SIZE(wm8400_dapm_romix_controls), - outmixer_event, SND_SOC_DAPM_PRE_REG), - -/* LOUT PGA */ -SND_SOC_DAPM_PGA("LOUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_LOUT_ENA_SHIFT, - 0, NULL, 0), - -/* ROUT PGA */ -SND_SOC_DAPM_PGA("ROUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_ROUT_ENA_SHIFT, - 0, NULL, 0), - -/* LOPGA */ -SND_SOC_DAPM_PGA("LOPGA", WM8400_POWER_MANAGEMENT_3, WM8400_LOPGA_ENA_SHIFT, 0, - NULL, 0), - -/* ROPGA */ -SND_SOC_DAPM_PGA("ROPGA", WM8400_POWER_MANAGEMENT_3, WM8400_ROPGA_ENA_SHIFT, 0, - NULL, 0), - -/* MICBIAS */ -SND_SOC_DAPM_MICBIAS("MICBIAS", WM8400_POWER_MANAGEMENT_1, - WM8400_MIC1BIAS_ENA_SHIFT, 0), - -SND_SOC_DAPM_OUTPUT("LON"), -SND_SOC_DAPM_OUTPUT("LOP"), -SND_SOC_DAPM_OUTPUT("OUT3"), -SND_SOC_DAPM_OUTPUT("LOUT"), -SND_SOC_DAPM_OUTPUT("SPKN"), -SND_SOC_DAPM_OUTPUT("SPKP"), -SND_SOC_DAPM_OUTPUT("ROUT"), -SND_SOC_DAPM_OUTPUT("OUT4"), -SND_SOC_DAPM_OUTPUT("ROP"), -SND_SOC_DAPM_OUTPUT("RON"), - -SND_SOC_DAPM_OUTPUT("Internal DAC Sink"), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* Make DACs turn on when playing even if not mixed into any outputs */ - {"Internal DAC Sink", NULL, "Left DAC"}, - {"Internal DAC Sink", NULL, "Right DAC"}, - - /* Make ADCs turn on when recording - * even if not mixed from any inputs */ - {"Left ADC", NULL, "Internal ADC Source"}, - {"Right ADC", NULL, "Internal ADC Source"}, - - /* Input Side */ - /* LIN12 PGA */ - {"LIN12 PGA", "LIN1 Switch", "LIN1"}, - {"LIN12 PGA", "LIN2 Switch", "LIN2"}, - /* LIN34 PGA */ - {"LIN34 PGA", "LIN3 Switch", "LIN3"}, - {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"}, - /* INMIXL */ - {"INMIXL", "Record Left Volume", "LOMIX"}, - {"INMIXL", "LIN2 Volume", "LIN2"}, - {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"}, - {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"}, - /* AILNMUX */ - {"AILNMUX", "INMIXL Mix", "INMIXL"}, - {"AILNMUX", "DIFFINL Mix", "LIN12 PGA"}, - {"AILNMUX", "DIFFINL Mix", "LIN34 PGA"}, - {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"}, - {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"}, - /* ADC */ - {"Left ADC", NULL, "AILNMUX"}, - - /* RIN12 PGA */ - {"RIN12 PGA", "RIN1 Switch", "RIN1"}, - {"RIN12 PGA", "RIN2 Switch", "RIN2"}, - /* RIN34 PGA */ - {"RIN34 PGA", "RIN3 Switch", "RIN3"}, - {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"}, - /* INMIXL */ - {"INMIXR", "Record Right Volume", "ROMIX"}, - {"INMIXR", "RIN2 Volume", "RIN2"}, - {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"}, - {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"}, - /* AIRNMUX */ - {"AIRNMUX", "INMIXR Mix", "INMIXR"}, - {"AIRNMUX", "DIFFINR Mix", "RIN12 PGA"}, - {"AIRNMUX", "DIFFINR Mix", "RIN34 PGA"}, - {"AIRNMUX", "RXVOICE Mix", "LIN4/RXN"}, - {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"}, - /* ADC */ - {"Right ADC", NULL, "AIRNMUX"}, - - /* LOMIX */ - {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"}, - {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"}, - {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"}, - {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"}, - {"LOMIX", "LOMIX Right ADC Bypass Switch", "AIRNMUX"}, - {"LOMIX", "LOMIX Left ADC Bypass Switch", "AILNMUX"}, - {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"}, - - /* ROMIX */ - {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"}, - {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"}, - {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"}, - {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"}, - {"ROMIX", "ROMIX Right ADC Bypass Switch", "AIRNMUX"}, - {"ROMIX", "ROMIX Left ADC Bypass Switch", "AILNMUX"}, - {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"}, - - /* SPKMIX */ - {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"}, - {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"}, - {"SPKMIX", "SPKMIX LADC Bypass Switch", "AILNMUX"}, - {"SPKMIX", "SPKMIX RADC Bypass Switch", "AIRNMUX"}, - {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"}, - {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"}, - {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"}, - {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"}, - - /* LONMIX */ - {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"}, - {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"}, - {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"}, - - /* LOPMIX */ - {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"}, - {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"}, - {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"}, - - /* OUT3MIX */ - {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"}, - {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"}, - - /* OUT4MIX */ - {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"}, - {"OUT4MIX", "OUT4MIX RIN4/RXP Bypass Switch", "RIN4/RXP"}, - - /* RONMIX */ - {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"}, - {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"}, - {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"}, - - /* ROPMIX */ - {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"}, - {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"}, - {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"}, - - /* Out Mixer PGAs */ - {"LOPGA", NULL, "LOMIX"}, - {"ROPGA", NULL, "ROMIX"}, - - {"LOUT PGA", NULL, "LOMIX"}, - {"ROUT PGA", NULL, "ROMIX"}, - - /* Output Pins */ - {"LON", NULL, "LONMIX"}, - {"LOP", NULL, "LOPMIX"}, - {"OUT3", NULL, "OUT3MIX"}, - {"LOUT", NULL, "LOUT PGA"}, - {"SPKN", NULL, "SPKMIX"}, - {"ROUT", NULL, "ROUT PGA"}, - {"OUT4", NULL, "OUT4MIX"}, - {"ROP", NULL, "ROPMIX"}, - {"RON", NULL, "RONMIX"}, -}; - -static int wm8400_add_widgets(struct snd_soc_codec *codec) -{ - snd_soc_dapm_new_controls(codec, wm8400_dapm_widgets, - ARRAY_SIZE(wm8400_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - - snd_soc_dapm_new_widgets(codec); - return 0; -} - -/* - * Clock after FLL and dividers - */ -static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct wm8400_priv *wm8400 = codec->private_data; - - wm8400->sysclk = freq; - return 0; -} - -struct fll_factors { - u16 n; - u16 k; - u16 outdiv; - u16 fratio; - u16 freq_ref; -}; - -#define FIXED_FLL_SIZE ((1 << 16) * 10) - -static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors, - unsigned int Fref, unsigned int Fout) -{ - u64 Kpart; - unsigned int K, Nmod, target; - - factors->outdiv = 2; - while (Fout * factors->outdiv < 90000000 || - Fout * factors->outdiv > 100000000) { - factors->outdiv *= 2; - if (factors->outdiv > 32) { - dev_err(wm8400->wm8400->dev, - "Unsupported FLL output frequency %dHz\n", - Fout); - return -EINVAL; - } - } - target = Fout * factors->outdiv; - factors->outdiv = factors->outdiv >> 2; - - if (Fref < 48000) - factors->freq_ref = 1; - else - factors->freq_ref = 0; - - if (Fref < 1000000) - factors->fratio = 9; - else - factors->fratio = 0; - - /* Ensure we have a fractional part */ - do { - if (Fref < 1000000) - factors->fratio--; - else - factors->fratio++; - - if (factors->fratio < 1 || factors->fratio > 8) { - dev_err(wm8400->wm8400->dev, - "Unable to calculate FRATIO\n"); - return -EINVAL; - } - - factors->n = target / (Fref * factors->fratio); - Nmod = target % (Fref * factors->fratio); - } while (Nmod == 0); - - /* Calculate fractional part - scale up so we can round. */ - Kpart = FIXED_FLL_SIZE * (long long)Nmod; - - do_div(Kpart, (Fref * factors->fratio)); - - K = Kpart & 0xFFFFFFFF; - - if ((K % 10) >= 5) - K += 5; - - /* Move down to proper range now rounding is done */ - factors->k = K / 10; - - dev_dbg(wm8400->wm8400->dev, - "FLL: Fref=%d Fout=%d N=%x K=%x, FRATIO=%x OUTDIV=%x\n", - Fref, Fout, - factors->n, factors->k, factors->fratio, factors->outdiv); - - return 0; -} - -static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, - unsigned int freq_in, unsigned int freq_out) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct wm8400_priv *wm8400 = codec->private_data; - struct fll_factors factors; - int ret; - u16 reg; - - if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out) - return 0; - - if (freq_out != 0) { - ret = fll_factors(wm8400, &factors, freq_in, freq_out); - if (ret != 0) - return ret; - } - - wm8400->fll_out = freq_out; - wm8400->fll_in = freq_in; - - /* We *must* disable the FLL before any changes */ - reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_2); - reg &= ~WM8400_FLL_ENA; - wm8400_write(codec, WM8400_POWER_MANAGEMENT_2, reg); - - reg = wm8400_read(codec, WM8400_FLL_CONTROL_1); - reg &= ~WM8400_FLL_OSC_ENA; - wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); - - if (freq_out == 0) - return 0; - - reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK); - reg |= WM8400_FLL_FRAC | factors.fratio; - reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT; - wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); - - wm8400_write(codec, WM8400_FLL_CONTROL_2, factors.k); - wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n); - - reg = wm8400_read(codec, WM8400_FLL_CONTROL_4); - reg &= WM8400_FLL_OUTDIV_MASK; - reg |= factors.outdiv; - wm8400_write(codec, WM8400_FLL_CONTROL_4, reg); - - return 0; -} - -/* - * Sets ADC and Voice DAC format. - */ -static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 audio1, audio3; - - audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1); - audio3 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_3); - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - audio3 &= ~WM8400_AIF_MSTR1; - break; - case SND_SOC_DAIFMT_CBM_CFM: - audio3 |= WM8400_AIF_MSTR1; - break; - default: - return -EINVAL; - } - - audio1 &= ~WM8400_AIF_FMT_MASK; - - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - audio1 |= WM8400_AIF_FMT_I2S; - audio1 &= ~WM8400_AIF_LRCLK_INV; - break; - case SND_SOC_DAIFMT_RIGHT_J: - audio1 |= WM8400_AIF_FMT_RIGHTJ; - audio1 &= ~WM8400_AIF_LRCLK_INV; - break; - case SND_SOC_DAIFMT_LEFT_J: - audio1 |= WM8400_AIF_FMT_LEFTJ; - audio1 &= ~WM8400_AIF_LRCLK_INV; - break; - case SND_SOC_DAIFMT_DSP_A: - audio1 |= WM8400_AIF_FMT_DSP; - audio1 &= ~WM8400_AIF_LRCLK_INV; - break; - case SND_SOC_DAIFMT_DSP_B: - audio1 |= WM8400_AIF_FMT_DSP | WM8400_AIF_LRCLK_INV; - break; - default: - return -EINVAL; - } - - wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1); - wm8400_write(codec, WM8400_AUDIO_INTERFACE_3, audio3); - return 0; -} - -static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai, - int div_id, int div) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 reg; - - switch (div_id) { - case WM8400_MCLK_DIV: - reg = wm8400_read(codec, WM8400_CLOCKING_2) & - ~WM8400_MCLK_DIV_MASK; - wm8400_write(codec, WM8400_CLOCKING_2, reg | div); - break; - case WM8400_DACCLK_DIV: - reg = wm8400_read(codec, WM8400_CLOCKING_2) & - ~WM8400_DAC_CLKDIV_MASK; - wm8400_write(codec, WM8400_CLOCKING_2, reg | div); - break; - case WM8400_ADCCLK_DIV: - reg = wm8400_read(codec, WM8400_CLOCKING_2) & - ~WM8400_ADC_CLKDIV_MASK; - wm8400_write(codec, WM8400_CLOCKING_2, reg | div); - break; - case WM8400_BCLK_DIV: - reg = wm8400_read(codec, WM8400_CLOCKING_1) & - ~WM8400_BCLK_DIV_MASK; - wm8400_write(codec, WM8400_CLOCKING_1, reg | div); - break; - default: - return -EINVAL; - } - - return 0; -} - -/* - * Set PCM DAI bit size and sample rate. - */ -static int wm8400_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; - u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1); - - audio1 &= ~WM8400_AIF_WL_MASK; - /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - audio1 |= WM8400_AIF_WL_20BITS; - break; - case SNDRV_PCM_FORMAT_S24_LE: - audio1 |= WM8400_AIF_WL_24BITS; - break; - case SNDRV_PCM_FORMAT_S32_LE: - audio1 |= WM8400_AIF_WL_32BITS; - break; - } - - wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1); - return 0; -} - -static int wm8400_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - u16 val = wm8400_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE; - - if (mute) - wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); - else - wm8400_write(codec, WM8400_DAC_CTRL, val); - - return 0; -} - -/* TODO: set bias for best performance at standby */ -static int wm8400_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - struct wm8400_priv *wm8400 = codec->private_data; - u16 val; - int ret; - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - /* VMID=2*50k */ - val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) & - ~WM8400_VMID_MODE_MASK; - wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2); - break; - - case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { - ret = regulator_bulk_enable(ARRAY_SIZE(power), - &power[0]); - if (ret != 0) { - dev_err(wm8400->wm8400->dev, - "Failed to enable regulators: %d\n", - ret); - return ret; - } - - wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, - WM8400_CODEC_ENA | WM8400_SYSCLK_ENA); - - /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */ - wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | - WM8400_BUFDCOPEN | WM8400_POBCTRL); - - msleep(50); - - /* Enable VREF & VMID at 2x50k */ - val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); - val |= 0x2 | WM8400_VREF_ENA; - wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); - - /* Enable BUFIOEN */ - wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | - WM8400_BUFDCOPEN | WM8400_POBCTRL | - WM8400_BUFIOEN); - - /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ - wm8400_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN); - } - - /* VMID=2*300k */ - val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) & - ~WM8400_VMID_MODE_MASK; - wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4); - break; - - case SND_SOC_BIAS_OFF: - /* Enable POBCTRL and SOFT_ST */ - wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | - WM8400_POBCTRL | WM8400_BUFIOEN); - - /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */ - wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | - WM8400_BUFDCOPEN | WM8400_POBCTRL | - WM8400_BUFIOEN); - - /* mute DAC */ - val = wm8400_read(codec, WM8400_DAC_CTRL); - wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); - - /* Enable any disabled outputs */ - val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); - val |= WM8400_SPK_ENA | WM8400_OUT3_ENA | - WM8400_OUT4_ENA | WM8400_LOUT_ENA | - WM8400_ROUT_ENA; - wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); - - /* Disable VMID */ - val &= ~WM8400_VMID_MODE_MASK; - wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); - - msleep(300); - - /* Enable all output discharge bits */ - wm8400_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE | - WM8400_DIS_RLINE | WM8400_DIS_OUT3 | - WM8400_DIS_OUT4 | WM8400_DIS_LOUT | - WM8400_DIS_ROUT); - - /* Disable VREF */ - val &= ~WM8400_VREF_ENA; - wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); - - /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ - wm8400_write(codec, WM8400_ANTIPOP2, 0x0); - - ret = regulator_bulk_disable(ARRAY_SIZE(power), - &power[0]); - if (ret != 0) - return ret; - - break; - } - - codec->bias_level = level; - return 0; -} - -#define WM8400_RATES SNDRV_PCM_RATE_8000_96000 - -#define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -static struct snd_soc_dai_ops wm8400_dai_ops = { - .hw_params = wm8400_hw_params, - .digital_mute = wm8400_mute, - .set_fmt = wm8400_set_dai_fmt, - .set_clkdiv = wm8400_set_dai_clkdiv, - .set_sysclk = wm8400_set_dai_sysclk, - .set_pll = wm8400_set_dai_pll, -}; - -/* - * The WM8400 supports 2 different and mutually exclusive DAI - * configurations. - * - * 1. ADC/DAC on Primary Interface - * 2. ADC on Primary Interface/DAC on secondary - */ -struct snd_soc_dai wm8400_dai = { -/* ADC/DAC on primary */ - .name = "WM8400 ADC/DAC Primary", - .id = 1, - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8400_RATES, - .formats = WM8400_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8400_RATES, - .formats = WM8400_FORMATS, - }, - .ops = &wm8400_dai_ops, -}; -EXPORT_SYMBOL_GPL(wm8400_dai); - -static int wm8400_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm8400_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static struct snd_soc_codec *wm8400_codec; - -static int wm8400_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret; - - if (!wm8400_codec) { - dev_err(&pdev->dev, "wm8400 not yet discovered\n"); - return -ENODEV; - } - codec = wm8400_codec; - - socdev->card->codec = codec; - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - dev_err(&pdev->dev, "failed to create pcms\n"); - goto pcm_err; - } - - wm8400_add_controls(codec); - wm8400_add_widgets(codec); - - ret = snd_soc_init_card(socdev); - if (ret < 0) { - dev_err(&pdev->dev, "failed to register card\n"); - goto card_err; - } - - return ret; - -card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - return ret; -} - -/* power down chip */ -static int wm8400_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm8400 = { - .probe = wm8400_probe, - .remove = wm8400_remove, - .suspend = wm8400_suspend, - .resume = wm8400_resume, -}; - -static void wm8400_probe_deferred(struct work_struct *work) -{ - struct wm8400_priv *priv = container_of(work, struct wm8400_priv, - work); - struct snd_soc_codec *codec = &priv->codec; - int ret; - - /* charge output caps */ - wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - /* We're done, tell the subsystem. */ - ret = snd_soc_register_codec(codec); - if (ret != 0) { - dev_err(priv->wm8400->dev, - "Failed to register codec: %d\n", ret); - goto err; - } - - ret = snd_soc_register_dai(&wm8400_dai); - if (ret != 0) { - dev_err(priv->wm8400->dev, - "Failed to register DAI: %d\n", ret); - goto err_codec; - } - - return; - -err_codec: - snd_soc_unregister_codec(codec); -err: - wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF); -} - -static int wm8400_codec_probe(struct platform_device *dev) -{ - struct wm8400_priv *priv; - int ret; - u16 reg; - struct snd_soc_codec *codec; - - priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - - codec = &priv->codec; - codec->private_data = priv; - codec->control_data = dev->dev.driver_data; - priv->wm8400 = dev->dev.driver_data; - - ret = regulator_bulk_get(priv->wm8400->dev, - ARRAY_SIZE(power), &power[0]); - if (ret != 0) { - dev_err(&dev->dev, "Failed to get regulators: %d\n", ret); - goto err; - } - - codec->dev = &dev->dev; - wm8400_dai.dev = &dev->dev; - - codec->name = "WM8400"; - codec->owner = THIS_MODULE; - codec->read = wm8400_read; - codec->write = wm8400_write; - codec->bias_level = SND_SOC_BIAS_OFF; - codec->set_bias_level = wm8400_set_bias_level; - codec->dai = &wm8400_dai; - codec->num_dai = 1; - codec->reg_cache_size = WM8400_REGISTER_COUNT; - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - INIT_WORK(&priv->work, wm8400_probe_deferred); - - wm8400_codec_reset(codec); - - reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); - wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA); - - /* Latch volume update bits */ - reg = wm8400_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME); - wm8400_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME, - reg & WM8400_IPVU); - reg = wm8400_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME); - wm8400_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, - reg & WM8400_IPVU); - - wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); - wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); - - wm8400_codec = codec; - - if (!schedule_work(&priv->work)) { - ret = -EINVAL; - goto err_regulator; - } - - return 0; - -err_regulator: - wm8400_codec = NULL; - regulator_bulk_free(ARRAY_SIZE(power), power); -err: - kfree(priv); - return ret; -} - -static int __exit wm8400_codec_remove(struct platform_device *dev) -{ - struct wm8400_priv *priv = wm8400_codec->private_data; - u16 reg; - - snd_soc_unregister_dai(&wm8400_dai); - snd_soc_unregister_codec(wm8400_codec); - - reg = wm8400_read(wm8400_codec, WM8400_POWER_MANAGEMENT_1); - wm8400_write(wm8400_codec, WM8400_POWER_MANAGEMENT_1, - reg & (~WM8400_CODEC_ENA)); - - regulator_bulk_free(ARRAY_SIZE(power), power); - kfree(priv); - - wm8400_codec = NULL; - - return 0; -} - -static struct platform_driver wm8400_codec_driver = { - .driver = { - .name = "wm8400-codec", - .owner = THIS_MODULE, - }, - .probe = wm8400_codec_probe, - .remove = __exit_p(wm8400_codec_remove), -}; - -static int __init wm8400_codec_init(void) -{ - return platform_driver_register(&wm8400_codec_driver); -} -module_init(wm8400_codec_init); - -static void __exit wm8400_codec_exit(void) -{ - platform_driver_unregister(&wm8400_codec_driver); -} -module_exit(wm8400_codec_exit); - -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8400); - -MODULE_DESCRIPTION("ASoC WM8400 driver"); -MODULE_AUTHOR("Mark Brown"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:wm8400-codec"); diff --git a/trunk/sound/soc/codecs/wm8400.h b/trunk/sound/soc/codecs/wm8400.h deleted file mode 100644 index 79c5934d4776..000000000000 --- a/trunk/sound/soc/codecs/wm8400.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * wm8400.h -- audio driver for WM8400 - * - * Copyright 2008 Wolfson Microelectronics PLC. - * Author: Mark Brown - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#ifndef _WM8400_CODEC_H -#define _WM8400_CODEC_H - -#define WM8400_MCLK_DIV 0 -#define WM8400_DACCLK_DIV 1 -#define WM8400_ADCCLK_DIV 2 -#define WM8400_BCLK_DIV 3 - -#define WM8400_MCLK_DIV_1 0x400 -#define WM8400_MCLK_DIV_2 0x800 - -#define WM8400_DAC_CLKDIV_1 0x00 -#define WM8400_DAC_CLKDIV_1_5 0x04 -#define WM8400_DAC_CLKDIV_2 0x08 -#define WM8400_DAC_CLKDIV_3 0x0c -#define WM8400_DAC_CLKDIV_4 0x10 -#define WM8400_DAC_CLKDIV_5_5 0x14 -#define WM8400_DAC_CLKDIV_6 0x18 - -#define WM8400_ADC_CLKDIV_1 0x00 -#define WM8400_ADC_CLKDIV_1_5 0x20 -#define WM8400_ADC_CLKDIV_2 0x40 -#define WM8400_ADC_CLKDIV_3 0x60 -#define WM8400_ADC_CLKDIV_4 0x80 -#define WM8400_ADC_CLKDIV_5_5 0xa0 -#define WM8400_ADC_CLKDIV_6 0xc0 - - -#define WM8400_BCLK_DIV_1 (0x0 << 1) -#define WM8400_BCLK_DIV_1_5 (0x1 << 1) -#define WM8400_BCLK_DIV_2 (0x2 << 1) -#define WM8400_BCLK_DIV_3 (0x3 << 1) -#define WM8400_BCLK_DIV_4 (0x4 << 1) -#define WM8400_BCLK_DIV_5_5 (0x5 << 1) -#define WM8400_BCLK_DIV_6 (0x6 << 1) -#define WM8400_BCLK_DIV_8 (0x7 << 1) -#define WM8400_BCLK_DIV_11 (0x8 << 1) -#define WM8400_BCLK_DIV_12 (0x9 << 1) -#define WM8400_BCLK_DIV_16 (0xA << 1) -#define WM8400_BCLK_DIV_22 (0xB << 1) -#define WM8400_BCLK_DIV_24 (0xC << 1) -#define WM8400_BCLK_DIV_32 (0xD << 1) -#define WM8400_BCLK_DIV_44 (0xE << 1) -#define WM8400_BCLK_DIV_48 (0xF << 1) - -extern struct snd_soc_dai wm8400_dai; -extern struct snd_soc_codec_device soc_codec_dev_wm8400; - -#endif diff --git a/trunk/sound/soc/codecs/wm8510.c b/trunk/sound/soc/codecs/wm8510.c index 6a4cea09c45d..40f8238df717 100644 --- a/trunk/sound/soc/codecs/wm8510.c +++ b/trunk/sound/soc/codecs/wm8510.c @@ -171,6 +171,22 @@ SOC_SINGLE("Capture Boost(+20dB)", WM8510_ADCBOOST, 8, 1, 0), SOC_SINGLE("Mono Playback Switch", WM8510_MONOMIX, 6, 1, 1), }; +/* add non dapm controls */ +static int wm8510_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8510_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8510_snd_controls[i], codec, + NULL)); + if (err < 0) + return err; + } + + return 0; +} + /* Speaker Output Mixer */ static const struct snd_kcontrol_new wm8510_speaker_mixer_controls[] = { SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_SPKMIX, 1, 1, 0), @@ -336,7 +352,7 @@ static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, return 0; } - pll_factors(freq_out*4, freq_in); + pll_factors(freq_out*8, freq_in); wm8510_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n); wm8510_write(codec, WM8510_PLLK1, pll_div.k >> 18); @@ -367,7 +383,7 @@ static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai, wm8510_write(codec, WM8510_GPIO, reg | div); break; case WM8510_MCLKDIV: - reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x11f; + reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1f; wm8510_write(codec, WM8510_CLOCK, reg | div); break; case WM8510_ADCCLK: @@ -452,7 +468,7 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f; u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1; @@ -554,14 +570,6 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, #define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8510_dai_ops = { - .hw_params = wm8510_pcm_hw_params, - .digital_mute = wm8510_mute, - .set_fmt = wm8510_set_dai_fmt, - .set_clkdiv = wm8510_set_dai_clkdiv, - .set_pll = wm8510_set_dai_pll, -}; - struct snd_soc_dai wm8510_dai = { .name = "WM8510 HiFi", .playback = { @@ -576,14 +584,20 @@ struct snd_soc_dai wm8510_dai = { .channels_max = 2, .rates = WM8510_RATES, .formats = WM8510_FORMATS,}, - .ops = &wm8510_dai_ops, + .ops = { + .hw_params = wm8510_pcm_hw_params, + .digital_mute = wm8510_mute, + .set_fmt = wm8510_set_dai_fmt, + .set_clkdiv = wm8510_set_dai_clkdiv, + .set_pll = wm8510_set_dai_pll, + }, }; EXPORT_SYMBOL_GPL(wm8510_dai); static int wm8510_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -592,7 +606,7 @@ static int wm8510_suspend(struct platform_device *pdev, pm_message_t state) static int wm8510_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u16 *cache = codec->reg_cache; @@ -614,7 +628,7 @@ static int wm8510_resume(struct platform_device *pdev) */ static int wm8510_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret = 0; codec->name = "WM8510"; @@ -642,8 +656,7 @@ static int wm8510_init(struct snd_soc_device *socdev) /* power on device */ codec->bias_level = SND_SOC_BIAS_OFF; wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8510_snd_controls, - ARRAY_SIZE(wm8510_snd_controls)); + wm8510_add_controls(codec); wm8510_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -672,7 +685,7 @@ static int wm8510_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct snd_soc_device *socdev = wm8510_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -753,7 +766,7 @@ static int wm8510_add_i2c_device(struct platform_device *pdev, static int __devinit wm8510_spi_probe(struct spi_device *spi) { struct snd_soc_device *socdev = wm8510_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; codec->control_data = spi; @@ -819,7 +832,7 @@ static int wm8510_probe(struct platform_device *pdev) if (codec == NULL) return -ENOMEM; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -849,7 +862,7 @@ static int wm8510_probe(struct platform_device *pdev) static int wm8510_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/wm8580.c b/trunk/sound/soc/codecs/wm8580.c index 442ea6f160fc..d004e5845298 100644 --- a/trunk/sound/soc/codecs/wm8580.c +++ b/trunk/sound/soc/codecs/wm8580.c @@ -1,7 +1,7 @@ /* * wm8580.c -- WM8580 ALSA Soc Audio driver * - * Copyright 2008, 2009 Wolfson Microelectronics PLC. + * Copyright 2008 Wolfson Microelectronics PLC. * * 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 @@ -35,6 +35,19 @@ #include "wm8580.h" +#define WM8580_VERSION "0.1" + +struct pll_state { + unsigned int in; + unsigned int out; +}; + +/* codec private data */ +struct wm8580_priv { + struct pll_state a; + struct pll_state b; +}; + /* WM8580 register space */ #define WM8580_PLLA1 0x00 #define WM8580_PLLA2 0x01 @@ -89,8 +102,6 @@ #define WM8580_READBACK 0x34 #define WM8580_RESET 0x35 -#define WM8580_MAX_REGISTER 0x35 - /* PLLB4 (register 7h) */ #define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60 #define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20 @@ -182,20 +193,6 @@ static const u16 wm8580_reg[] = { 0x0000, 0x0000 /*R53*/ }; -struct pll_state { - unsigned int in; - unsigned int out; -}; - -/* codec private data */ -struct wm8580_priv { - struct snd_soc_codec codec; - u16 reg_cache[WM8580_MAX_REGISTER + 1]; - struct pll_state a; - struct pll_state b; -}; - - /* * read wm8580 register cache */ @@ -203,7 +200,7 @@ static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { u16 *cache = codec->reg_cache; - BUG_ON(reg >= ARRAY_SIZE(wm8580_reg)); + BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); return cache[reg]; } @@ -226,7 +223,7 @@ static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg, { u8 data[2]; - BUG_ON(reg >= ARRAY_SIZE(wm8580_reg)); + BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); /* Registers are 9 bits wide */ value &= 0x1ff; @@ -333,6 +330,20 @@ SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0), SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), }; +/* Add non-DAPM controls */ +static int wm8580_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8580_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8580_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + return 0; +} static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1), SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1), @@ -542,7 +553,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id); paifb &= ~WM8580_AIF_LENGTH_MASK; @@ -760,22 +771,8 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, switch (level) { case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: - break; - case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { - /* Power up and get individual control of the DACs */ - reg = wm8580_read(codec, WM8580_PWRDN1); - reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); - wm8580_write(codec, WM8580_PWRDN1, reg); - - /* Make VMID high impedence */ - reg = wm8580_read(codec, WM8580_ADC_CONTROL1); - reg &= ~0x100; - wm8580_write(codec, WM8580_ADC_CONTROL1, reg); - } break; - case SND_SOC_BIAS_OFF: reg = wm8580_read(codec, WM8580_PWRDN1); wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); @@ -788,21 +785,6 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, #define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8580_dai_ops_playback = { - .hw_params = wm8580_paif_hw_params, - .set_fmt = wm8580_set_paif_dai_fmt, - .set_clkdiv = wm8580_set_dai_clkdiv, - .set_pll = wm8580_set_dai_pll, - .digital_mute = wm8580_digital_mute, -}; - -static struct snd_soc_dai_ops wm8580_dai_ops_capture = { - .hw_params = wm8580_paif_hw_params, - .set_fmt = wm8580_set_paif_dai_fmt, - .set_clkdiv = wm8580_set_dai_clkdiv, - .set_pll = wm8580_set_dai_pll, -}; - struct snd_soc_dai wm8580_dai[] = { { .name = "WM8580 PAIFRX", @@ -814,7 +796,13 @@ struct snd_soc_dai wm8580_dai[] = { .rates = SNDRV_PCM_RATE_8000_192000, .formats = WM8580_FORMATS, }, - .ops = &wm8580_dai_ops_playback, + .ops = { + .hw_params = wm8580_paif_hw_params, + .set_fmt = wm8580_set_paif_dai_fmt, + .set_clkdiv = wm8580_set_dai_clkdiv, + .set_pll = wm8580_set_dai_pll, + .digital_mute = wm8580_digital_mute, + }, }, { .name = "WM8580 PAIFTX", @@ -826,168 +814,109 @@ struct snd_soc_dai wm8580_dai[] = { .rates = SNDRV_PCM_RATE_8000_192000, .formats = WM8580_FORMATS, }, - .ops = &wm8580_dai_ops_capture, + .ops = { + .hw_params = wm8580_paif_hw_params, + .set_fmt = wm8580_set_paif_dai_fmt, + .set_clkdiv = wm8580_set_dai_clkdiv, + .set_pll = wm8580_set_dai_pll, + }, }, }; EXPORT_SYMBOL_GPL(wm8580_dai); -static struct snd_soc_codec *wm8580_codec; - -static int wm8580_probe(struct platform_device *pdev) +/* + * initialise the WM8580 driver + * register the mixer and dsp interfaces with the kernel + */ +static int wm8580_init(struct snd_soc_device *socdev) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; + struct snd_soc_codec *codec = socdev->codec; int ret = 0; - if (wm8580_codec == NULL) { - dev_err(&pdev->dev, "Codec device not registered\n"); - return -ENODEV; - } + codec->name = "WM8580"; + codec->owner = THIS_MODULE; + codec->read = wm8580_read_reg_cache; + codec->write = wm8580_write; + codec->set_bias_level = wm8580_set_bias_level; + codec->dai = wm8580_dai; + codec->num_dai = ARRAY_SIZE(wm8580_dai); + codec->reg_cache_size = ARRAY_SIZE(wm8580_reg); + codec->reg_cache = kmemdup(wm8580_reg, sizeof(wm8580_reg), + GFP_KERNEL); + + if (codec->reg_cache == NULL) + return -ENOMEM; - socdev->card->codec = wm8580_codec; - codec = wm8580_codec; + /* Get the codec into a known state */ + wm8580_write(codec, WM8580_RESET, 0); + + /* Power up and get individual control of the DACs */ + wm8580_write(codec, WM8580_PWRDN1, wm8580_read(codec, WM8580_PWRDN1) & + ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD)); + + /* Make VMID high impedence */ + wm8580_write(codec, WM8580_ADC_CONTROL1, + wm8580_read(codec, WM8580_ADC_CONTROL1) & ~0x100); /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, + SNDRV_DEFAULT_STR1); if (ret < 0) { - dev_err(codec->dev, "failed to create pcms: %d\n", ret); + printk(KERN_ERR "wm8580: failed to create pcms\n"); goto pcm_err; } - snd_soc_add_controls(codec, wm8580_snd_controls, - ARRAY_SIZE(wm8580_snd_controls)); + wm8580_add_controls(codec); wm8580_add_widgets(codec); + ret = snd_soc_init_card(socdev); if (ret < 0) { - dev_err(codec->dev, "failed to register card: %d\n", ret); + printk(KERN_ERR "wm8580: failed to register card\n"); goto card_err; } - return ret; card_err: snd_soc_free_pcms(socdev); snd_soc_dapm_free(socdev); pcm_err: + kfree(codec->reg_cache); return ret; } -/* power down chip */ -static int wm8580_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm8580 = { - .probe = wm8580_probe, - .remove = wm8580_remove, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); - -static int wm8580_register(struct wm8580_priv *wm8580) -{ - int ret, i; - struct snd_soc_codec *codec = &wm8580->codec; - - if (wm8580_codec) { - dev_err(codec->dev, "Another WM8580 is registered\n"); - ret = -EINVAL; - goto err; - } - - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - codec->private_data = wm8580; - codec->name = "WM8580"; - codec->owner = THIS_MODULE; - codec->read = wm8580_read_reg_cache; - codec->write = wm8580_write; - codec->bias_level = SND_SOC_BIAS_OFF; - codec->set_bias_level = wm8580_set_bias_level; - codec->dai = wm8580_dai; - codec->num_dai = ARRAY_SIZE(wm8580_dai); - codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache); - codec->reg_cache = &wm8580->reg_cache; - - memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg)); +/* If the i2c layer weren't so broken, we could pass this kind of data + around */ +static struct snd_soc_device *wm8580_socdev; - /* Get the codec into a known state */ - ret = wm8580_write(codec, WM8580_RESET, 0); - if (ret != 0) { - dev_err(codec->dev, "Failed to reset codec: %d\n", ret); - goto err; - } - - for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++) - wm8580_dai[i].dev = codec->dev; - - wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - wm8580_codec = codec; - - ret = snd_soc_register_codec(codec); - if (ret != 0) { - dev_err(codec->dev, "Failed to register codec: %d\n", ret); - goto err; - } - - ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); - if (ret != 0) { - dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - goto err_codec; - } - - return 0; - -err_codec: - snd_soc_unregister_codec(codec); -err: - kfree(wm8580); - return ret; -} +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static void wm8580_unregister(struct wm8580_priv *wm8580) -{ - wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); - snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); - snd_soc_unregister_codec(&wm8580->codec); - kfree(wm8580); - wm8580_codec = NULL; -} +/* + * WM8580 2 wire address is determined by GPIO5 + * state during powerup. + * low = 0x1a + * high = 0x1b + */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static int wm8580_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct wm8580_priv *wm8580; - struct snd_soc_codec *codec; - - wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL); - if (wm8580 == NULL) - return -ENOMEM; - - codec = &wm8580->codec; - codec->hw_write = (hw_write_t)i2c_master_send; + struct snd_soc_device *socdev = wm8580_socdev; + struct snd_soc_codec *codec = socdev->codec; + int ret; - i2c_set_clientdata(i2c, wm8580); + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; - codec->dev = &i2c->dev; - - return wm8580_register(wm8580); + ret = wm8580_init(socdev); + if (ret < 0) + dev_err(&i2c->dev, "failed to initialise WM8580\n"); + return ret; } static int wm8580_i2c_remove(struct i2c_client *client) { - struct wm8580_priv *wm8580 = i2c_get_clientdata(client); - wm8580_unregister(wm8580); + struct snd_soc_codec *codec = i2c_get_clientdata(client); + kfree(codec->reg_cache); return 0; } @@ -999,35 +928,129 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id); static struct i2c_driver wm8580_i2c_driver = { .driver = { - .name = "wm8580", + .name = "WM8580 I2C Codec", .owner = THIS_MODULE, }, .probe = wm8580_i2c_probe, .remove = wm8580_i2c_remove, .id_table = wm8580_i2c_id, }; -#endif -static int __init wm8580_modinit(void) +static int wm8580_add_i2c_device(struct platform_device *pdev, + const struct wm8580_setup_data *setup) { + struct i2c_board_info info; + struct i2c_adapter *adapter; + struct i2c_client *client; int ret; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8580_i2c_driver); if (ret != 0) { - pr_err("Failed to register WM8580 I2C driver: %d\n", ret); + dev_err(&pdev->dev, "can't add i2c driver\n"); + return ret; + } + + memset(&info, 0, sizeof(struct i2c_board_info)); + info.addr = setup->i2c_address; + strlcpy(info.type, "wm8580", I2C_NAME_SIZE); + + adapter = i2c_get_adapter(setup->i2c_bus); + if (!adapter) { + dev_err(&pdev->dev, "can't get i2c adapter %d\n", + setup->i2c_bus); + goto err_driver; + } + + client = i2c_new_device(adapter, &info); + i2c_put_adapter(adapter); + if (!client) { + dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", + (unsigned int)info.addr); + goto err_driver; } -#endif return 0; + +err_driver: + i2c_del_driver(&wm8580_i2c_driver); + return -ENODEV; } -module_init(wm8580_modinit); +#endif -static void __exit wm8580_exit(void) +static int wm8580_probe(struct platform_device *pdev) { + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct wm8580_setup_data *setup; + struct snd_soc_codec *codec; + struct wm8580_priv *wm8580; + int ret = 0; + + pr_info("WM8580 Audio Codec %s\n", WM8580_VERSION); + + setup = socdev->codec_data; + codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (codec == NULL) + return -ENOMEM; + + wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL); + if (wm8580 == NULL) { + kfree(codec); + return -ENOMEM; + } + + codec->private_data = wm8580; + socdev->codec = codec; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + wm8580_socdev = socdev; + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + if (setup->i2c_address) { + codec->hw_write = (hw_write_t)i2c_master_send; + ret = wm8580_add_i2c_device(pdev, setup); + } +#else + /* Add other interfaces here */ +#endif + return ret; +} + +/* power down chip */ +static int wm8580_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + if (codec->control_data) + wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF); + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_unregister_device(codec->control_data); i2c_del_driver(&wm8580_i2c_driver); #endif + kfree(codec->private_data); + kfree(codec); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_wm8580 = { + .probe = wm8580_probe, + .remove = wm8580_remove, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); + +static int __init wm8580_modinit(void) +{ + return snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); +} +module_init(wm8580_modinit); + +static void __exit wm8580_exit(void) +{ + snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); } module_exit(wm8580_exit); diff --git a/trunk/sound/soc/codecs/wm8580.h b/trunk/sound/soc/codecs/wm8580.h index 0dfb5ddde6a2..09e4422f6f2f 100644 --- a/trunk/sound/soc/codecs/wm8580.h +++ b/trunk/sound/soc/codecs/wm8580.h @@ -28,6 +28,11 @@ #define WM8580_CLKSRC_OSC 4 #define WM8580_CLKSRC_NONE 5 +struct wm8580_setup_data { + int i2c_bus; + unsigned short i2c_address; +}; + #define WM8580_DAI_PAIFRX 0 #define WM8580_DAI_PAIFTX 1 diff --git a/trunk/sound/soc/codecs/wm8728.c b/trunk/sound/soc/codecs/wm8728.c index e7ff2121ede9..80b11983e137 100644 --- a/trunk/sound/soc/codecs/wm8728.c +++ b/trunk/sound/soc/codecs/wm8728.c @@ -47,7 +47,7 @@ static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { u16 *cache = codec->reg_cache; - BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults)); + BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults)); return cache[reg]; } @@ -55,7 +55,7 @@ static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec, u16 reg, unsigned int value) { u16 *cache = codec->reg_cache; - BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults)); + BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults)); cache[reg] = value; } @@ -92,6 +92,21 @@ SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8728_DACLVOL, WM8728_DACRVOL, SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0), }; +static int wm8728_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8728_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8728_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + /* * DAPM controls. */ @@ -137,7 +152,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL); dac &= ~0x18; @@ -244,12 +259,6 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec, #define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8728_dai_ops = { - .hw_params = wm8728_hw_params, - .digital_mute = wm8728_mute, - .set_fmt = wm8728_set_dai_fmt, -}; - struct snd_soc_dai wm8728_dai = { .name = "WM8728", .playback = { @@ -259,14 +268,18 @@ struct snd_soc_dai wm8728_dai = { .rates = WM8728_RATES, .formats = WM8728_FORMATS, }, - .ops = &wm8728_dai_ops, + .ops = { + .hw_params = wm8728_hw_params, + .digital_mute = wm8728_mute, + .set_fmt = wm8728_set_dai_fmt, + } }; EXPORT_SYMBOL_GPL(wm8728_dai); static int wm8728_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -276,7 +289,7 @@ static int wm8728_suspend(struct platform_device *pdev, pm_message_t state) static int wm8728_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8728_set_bias_level(codec, codec->suspend_bias_level); @@ -289,7 +302,7 @@ static int wm8728_resume(struct platform_device *pdev) */ static int wm8728_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret = 0; codec->name = "WM8728"; @@ -317,8 +330,7 @@ static int wm8728_init(struct snd_soc_device *socdev) /* power on device */ wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8728_snd_controls, - ARRAY_SIZE(wm8728_snd_controls)); + wm8728_add_controls(codec); wm8728_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -351,7 +363,7 @@ static int wm8728_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct snd_soc_device *socdev = wm8728_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -432,7 +444,7 @@ static int wm8728_add_i2c_device(struct platform_device *pdev, static int __devinit wm8728_spi_probe(struct spi_device *spi) { struct snd_soc_device *socdev = wm8728_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; codec->control_data = spi; @@ -496,7 +508,7 @@ static int wm8728_probe(struct platform_device *pdev) if (codec == NULL) return -ENOMEM; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -529,7 +541,7 @@ static int wm8728_probe(struct platform_device *pdev) static int wm8728_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/wm8731.c b/trunk/sound/soc/codecs/wm8731.c index e043e3f60008..c444b9f2701e 100644 --- a/trunk/sound/soc/codecs/wm8731.c +++ b/trunk/sound/soc/codecs/wm8731.c @@ -29,20 +29,15 @@ #include "wm8731.h" -static struct snd_soc_codec *wm8731_codec; +#define WM8731_VERSION "0.13" + struct snd_soc_codec_device soc_codec_dev_wm8731; /* codec private data */ struct wm8731_priv { - struct snd_soc_codec codec; - u16 reg_cache[WM8731_CACHEREGNUM]; unsigned int sysclk; }; -#ifdef CONFIG_SPI_MASTER -static int wm8731_spi_write(struct spi_device *spi, const char *data, int len); -#endif - /* * wm8731 register cache * We can't read the WM8731 register space when we are @@ -134,6 +129,22 @@ SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), }; +/* add non dapm controls */ +static int wm8731_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8731_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8731_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + /* Output Mixer */ static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), @@ -258,7 +269,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8731_priv *wm8731 = codec->private_data; u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3; int i = get_coeff(wm8731->sysclk, params_rate(params)); @@ -288,7 +299,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; /* set active */ wm8731_write(codec, WM8731_ACTIVE, 0x0001); @@ -301,7 +312,7 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; /* deactivate */ if (!codec->active) { @@ -403,19 +414,21 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, static int wm8731_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg; + u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; switch (level) { case SND_SOC_BIAS_ON: + /* vref/mid, osc on, dac unmute */ + wm8731_write(codec, WM8731_PWR, reg); break; case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - /* Clear PWROFF, gate CLKOUT, everything else as-is */ - reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; + /* everything off except vref/vmid, */ wm8731_write(codec, WM8731_PWR, reg | 0x0040); break; case SND_SOC_BIAS_OFF: + /* everything off, dac mute, inactive */ wm8731_write(codec, WM8731_ACTIVE, 0x0); wm8731_write(codec, WM8731_PWR, 0xffff); break; @@ -433,15 +446,6 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8731_dai_ops = { - .prepare = wm8731_pcm_prepare, - .hw_params = wm8731_hw_params, - .shutdown = wm8731_shutdown, - .digital_mute = wm8731_mute, - .set_sysclk = wm8731_set_dai_sysclk, - .set_fmt = wm8731_set_dai_fmt, -}; - struct snd_soc_dai wm8731_dai = { .name = "WM8731", .playback = { @@ -456,14 +460,21 @@ struct snd_soc_dai wm8731_dai = { .channels_max = 2, .rates = WM8731_RATES, .formats = WM8731_FORMATS,}, - .ops = &wm8731_dai_ops, + .ops = { + .prepare = wm8731_pcm_prepare, + .hw_params = wm8731_hw_params, + .shutdown = wm8731_shutdown, + .digital_mute = wm8731_mute, + .set_sysclk = wm8731_set_dai_sysclk, + .set_fmt = wm8731_set_dai_fmt, + } }; EXPORT_SYMBOL_GPL(wm8731_dai); static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8731_write(codec, WM8731_ACTIVE, 0x0); wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -473,7 +484,7 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) static int wm8731_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u16 *cache = codec->reg_cache; @@ -489,33 +500,54 @@ static int wm8731_resume(struct platform_device *pdev) return 0; } -static int wm8731_probe(struct platform_device *pdev) +/* + * initialise the WM8731 driver + * register the mixer and dsp interfaces with the kernel + */ +static int wm8731_init(struct snd_soc_device *socdev) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret = 0; + struct snd_soc_codec *codec = socdev->codec; + int reg, ret = 0; - if (wm8731_codec == NULL) { - dev_err(&pdev->dev, "Codec device not registered\n"); - return -ENODEV; - } + codec->name = "WM8731"; + codec->owner = THIS_MODULE; + codec->read = wm8731_read_reg_cache; + codec->write = wm8731_write; + codec->set_bias_level = wm8731_set_bias_level; + codec->dai = &wm8731_dai; + codec->num_dai = 1; + codec->reg_cache_size = ARRAY_SIZE(wm8731_reg); + codec->reg_cache = kmemdup(wm8731_reg, sizeof(wm8731_reg), GFP_KERNEL); + if (codec->reg_cache == NULL) + return -ENOMEM; - socdev->card->codec = wm8731_codec; - codec = wm8731_codec; + wm8731_reset(codec); /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { - dev_err(codec->dev, "failed to create pcms: %d\n", ret); + printk(KERN_ERR "wm8731: failed to create pcms\n"); goto pcm_err; } - snd_soc_add_controls(codec, wm8731_snd_controls, - ARRAY_SIZE(wm8731_snd_controls)); + /* power on device */ + wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* set the update bits */ + reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); + wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100); + reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); + wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100); + reg = wm8731_read_reg_cache(codec, WM8731_LINVOL); + wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100); + reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); + wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100); + + wm8731_add_controls(codec); wm8731_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { - dev_err(codec->dev, "failed to register card: %d\n", ret); + printk(KERN_ERR "wm8731: failed to register card\n"); goto card_err; } @@ -525,109 +557,133 @@ static int wm8731_probe(struct platform_device *pdev) snd_soc_free_pcms(socdev); snd_soc_dapm_free(socdev); pcm_err: + kfree(codec->reg_cache); return ret; } -/* power down chip */ -static int wm8731_remove(struct platform_device *pdev) +static struct snd_soc_device *wm8731_socdev; + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + +/* + * WM8731 2 wire address is determined by GPIO5 + * state during powerup. + * low = 0x1a + * high = 0x1b + */ + +static int wm8731_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_device *socdev = wm8731_socdev; + struct snd_soc_codec *codec = socdev->codec; + int ret; - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); + i2c_set_clientdata(i2c, codec); + codec->control_data = i2c; + + ret = wm8731_init(socdev); + if (ret < 0) + pr_err("failed to initialise WM8731\n"); + return ret; +} + +static int wm8731_i2c_remove(struct i2c_client *client) +{ + struct snd_soc_codec *codec = i2c_get_clientdata(client); + kfree(codec->reg_cache); return 0; } -struct snd_soc_codec_device soc_codec_dev_wm8731 = { - .probe = wm8731_probe, - .remove = wm8731_remove, - .suspend = wm8731_suspend, - .resume = wm8731_resume, +static const struct i2c_device_id wm8731_i2c_id[] = { + { "wm8731", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); + +static struct i2c_driver wm8731_i2c_driver = { + .driver = { + .name = "WM8731 I2C Codec", + .owner = THIS_MODULE, + }, + .probe = wm8731_i2c_probe, + .remove = wm8731_i2c_remove, + .id_table = wm8731_i2c_id, }; -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); -static int wm8731_register(struct wm8731_priv *wm8731) +static int wm8731_add_i2c_device(struct platform_device *pdev, + const struct wm8731_setup_data *setup) { + struct i2c_board_info info; + struct i2c_adapter *adapter; + struct i2c_client *client; int ret; - struct snd_soc_codec *codec = &wm8731->codec; - u16 reg; - if (wm8731_codec) { - dev_err(codec->dev, "Another WM8731 is registered\n"); - return -EINVAL; + ret = i2c_add_driver(&wm8731_i2c_driver); + if (ret != 0) { + dev_err(&pdev->dev, "can't add i2c driver\n"); + return ret; } - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); + memset(&info, 0, sizeof(struct i2c_board_info)); + info.addr = setup->i2c_address; + strlcpy(info.type, "wm8731", I2C_NAME_SIZE); - codec->private_data = wm8731; - codec->name = "WM8731"; - codec->owner = THIS_MODULE; - codec->read = wm8731_read_reg_cache; - codec->write = wm8731_write; - codec->bias_level = SND_SOC_BIAS_OFF; - codec->set_bias_level = wm8731_set_bias_level; - codec->dai = &wm8731_dai; - codec->num_dai = 1; - codec->reg_cache_size = WM8731_CACHEREGNUM; - codec->reg_cache = &wm8731->reg_cache; - - memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); - - ret = wm8731_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - return ret; + adapter = i2c_get_adapter(setup->i2c_bus); + if (!adapter) { + dev_err(&pdev->dev, "can't get i2c adapter %d\n", + setup->i2c_bus); + goto err_driver; } - wm8731_dai.dev = codec->dev; - - wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + client = i2c_new_device(adapter, &info); + i2c_put_adapter(adapter); + if (!client) { + dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", + (unsigned int)info.addr); + goto err_driver; + } - /* Latch the update bits */ - reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); - wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100); - reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); - wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100); - reg = wm8731_read_reg_cache(codec, WM8731_LINVOL); - wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100); - reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); - wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100); + return 0; - /* Disable bypass path by default */ - reg = wm8731_read_reg_cache(codec, WM8731_APANA); - wm8731_write(codec, WM8731_APANA, reg & ~0x4); +err_driver: + i2c_del_driver(&wm8731_i2c_driver); + return -ENODEV; +} +#endif - wm8731_codec = codec; +#if defined(CONFIG_SPI_MASTER) +static int __devinit wm8731_spi_probe(struct spi_device *spi) +{ + struct snd_soc_device *socdev = wm8731_socdev; + struct snd_soc_codec *codec = socdev->codec; + int ret; - ret = snd_soc_register_codec(codec); - if (ret != 0) { - dev_err(codec->dev, "Failed to register codec: %d\n", ret); - return ret; - } + codec->control_data = spi; - ret = snd_soc_register_dai(&wm8731_dai); - if (ret != 0) { - dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); - return ret; - } + ret = wm8731_init(socdev); + if (ret < 0) + dev_err(&spi->dev, "failed to initialise WM8731\n"); - return 0; + return ret; } -static void wm8731_unregister(struct wm8731_priv *wm8731) +static int __devexit wm8731_spi_remove(struct spi_device *spi) { - wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); - snd_soc_unregister_dai(&wm8731_dai); - snd_soc_unregister_codec(&wm8731->codec); - kfree(wm8731); - wm8731_codec = NULL; + return 0; } -#if defined(CONFIG_SPI_MASTER) +static struct spi_driver wm8731_spi_driver = { + .driver = { + .name = "wm8731", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = wm8731_spi_probe, + .remove = __devexit_p(wm8731_spi_remove), +}; + static int wm8731_spi_write(struct spi_device *spi, const char *data, int len) { struct spi_transfer t; @@ -651,121 +707,101 @@ static int wm8731_spi_write(struct spi_device *spi, const char *data, int len) return len; } +#endif /* CONFIG_SPI_MASTER */ -static int __devinit wm8731_spi_probe(struct spi_device *spi) +static int wm8731_probe(struct platform_device *pdev) { + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct wm8731_setup_data *setup; struct snd_soc_codec *codec; struct wm8731_priv *wm8731; + int ret = 0; - wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); - if (wm8731 == NULL) - return -ENOMEM; + pr_info("WM8731 Audio Codec %s", WM8731_VERSION); - codec = &wm8731->codec; - codec->control_data = spi; - codec->hw_write = (hw_write_t)wm8731_spi_write; - codec->dev = &spi->dev; + setup = socdev->codec_data; + codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (codec == NULL) + return -ENOMEM; - spi->dev.driver_data = wm8731; + wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); + if (wm8731 == NULL) { + kfree(codec); + return -ENOMEM; + } - return wm8731_register(wm8731); -} + codec->private_data = wm8731; + socdev->codec = codec; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); -static int __devexit wm8731_spi_remove(struct spi_device *spi) -{ - struct wm8731_priv *wm8731 = spi->dev.driver_data; + wm8731_socdev = socdev; + ret = -ENODEV; - wm8731_unregister(wm8731); +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + if (setup->i2c_address) { + codec->hw_write = (hw_write_t)i2c_master_send; + ret = wm8731_add_i2c_device(pdev, setup); + } +#endif +#if defined(CONFIG_SPI_MASTER) + if (setup->spi) { + codec->hw_write = (hw_write_t)wm8731_spi_write; + ret = spi_register_driver(&wm8731_spi_driver); + if (ret != 0) + printk(KERN_ERR "can't add spi driver"); + } +#endif - return 0; + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } + return ret; } -static struct spi_driver wm8731_spi_driver = { - .driver = { - .name = "wm8731", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm8731_spi_probe, - .remove = __devexit_p(wm8731_spi_remove), -}; -#endif /* CONFIG_SPI_MASTER */ - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static __devinit int wm8731_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +/* power down chip */ +static int wm8731_remove(struct platform_device *pdev) { - struct wm8731_priv *wm8731; - struct snd_soc_codec *codec; - - wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); - if (wm8731 == NULL) - return -ENOMEM; - - codec = &wm8731->codec; - codec->hw_write = (hw_write_t)i2c_master_send; - - i2c_set_clientdata(i2c, wm8731); - codec->control_data = i2c; + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; - codec->dev = &i2c->dev; + if (codec->control_data) + wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); - return wm8731_register(wm8731); -} + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_unregister_device(codec->control_data); + i2c_del_driver(&wm8731_i2c_driver); +#endif +#if defined(CONFIG_SPI_MASTER) + spi_unregister_driver(&wm8731_spi_driver); +#endif + kfree(codec->private_data); + kfree(codec); -static __devexit int wm8731_i2c_remove(struct i2c_client *client) -{ - struct wm8731_priv *wm8731 = i2c_get_clientdata(client); - wm8731_unregister(wm8731); return 0; } -static const struct i2c_device_id wm8731_i2c_id[] = { - { "wm8731", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); - -static struct i2c_driver wm8731_i2c_driver = { - .driver = { - .name = "WM8731 I2C Codec", - .owner = THIS_MODULE, - }, - .probe = wm8731_i2c_probe, - .remove = __devexit_p(wm8731_i2c_remove), - .id_table = wm8731_i2c_id, +struct snd_soc_codec_device soc_codec_dev_wm8731 = { + .probe = wm8731_probe, + .remove = wm8731_remove, + .suspend = wm8731_suspend, + .resume = wm8731_resume, }; -#endif +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); static int __init wm8731_modinit(void) { - int ret; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm8731_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n", - ret); - } -#endif -#if defined(CONFIG_SPI_MASTER) - ret = spi_register_driver(&wm8731_spi_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n", - ret); - } -#endif - return 0; + return snd_soc_register_dai(&wm8731_dai); } module_init(wm8731_modinit); static void __exit wm8731_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&wm8731_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - spi_unregister_driver(&wm8731_spi_driver); -#endif + snd_soc_unregister_dai(&wm8731_dai); } module_exit(wm8731_exit); diff --git a/trunk/sound/soc/codecs/wm8731.h b/trunk/sound/soc/codecs/wm8731.h index cd7b806e8ad0..95190e9c0c14 100644 --- a/trunk/sound/soc/codecs/wm8731.h +++ b/trunk/sound/soc/codecs/wm8731.h @@ -34,6 +34,12 @@ #define WM8731_SYSCLK 0 #define WM8731_DAI 0 +struct wm8731_setup_data { + int spi; + int i2c_bus; + unsigned short i2c_address; +}; + extern struct snd_soc_dai wm8731_dai; extern struct snd_soc_codec_device soc_codec_dev_wm8731; diff --git a/trunk/sound/soc/codecs/wm8750.c b/trunk/sound/soc/codecs/wm8750.c index b64509b01a49..5997fa68e0d5 100644 --- a/trunk/sound/soc/codecs/wm8750.c +++ b/trunk/sound/soc/codecs/wm8750.c @@ -231,6 +231,21 @@ SOC_SINGLE("Mono Playback Volume", WM8750_MOUTV, 0, 127, 0), }; +/* add non dapm controls */ +static int wm8750_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8750_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8750_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + return 0; +} + /* * DAPM Controls */ @@ -604,7 +619,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8750_priv *wm8750 = codec->private_data; u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; @@ -679,13 +694,6 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec, #define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8750_dai_ops = { - .hw_params = wm8750_pcm_hw_params, - .digital_mute = wm8750_mute, - .set_fmt = wm8750_set_dai_fmt, - .set_sysclk = wm8750_set_dai_sysclk, -}; - struct snd_soc_dai wm8750_dai = { .name = "WM8750", .playback = { @@ -700,7 +708,12 @@ struct snd_soc_dai wm8750_dai = { .channels_max = 2, .rates = WM8750_RATES, .formats = WM8750_FORMATS,}, - .ops = &wm8750_dai_ops, + .ops = { + .hw_params = wm8750_pcm_hw_params, + .digital_mute = wm8750_mute, + .set_fmt = wm8750_set_dai_fmt, + .set_sysclk = wm8750_set_dai_sysclk, + }, }; EXPORT_SYMBOL_GPL(wm8750_dai); @@ -714,7 +727,7 @@ static void wm8750_work(struct work_struct *work) static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -723,7 +736,7 @@ static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) static int wm8750_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u16 *cache = codec->reg_cache; @@ -756,7 +769,7 @@ static int wm8750_resume(struct platform_device *pdev) */ static int wm8750_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int reg, ret = 0; codec->name = "WM8750"; @@ -803,8 +816,7 @@ static int wm8750_init(struct snd_soc_device *socdev) reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); - snd_soc_add_controls(codec, wm8750_snd_controls, - ARRAY_SIZE(wm8750_snd_controls)); + wm8750_add_controls(codec); wm8750_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -838,7 +850,7 @@ static int wm8750_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct snd_soc_device *socdev = wm8750_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -919,7 +931,7 @@ static int wm8750_add_i2c_device(struct platform_device *pdev, static int __devinit wm8750_spi_probe(struct spi_device *spi) { struct snd_soc_device *socdev = wm8750_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; codec->control_data = spi; @@ -991,7 +1003,7 @@ static int wm8750_probe(struct platform_device *pdev) } codec->private_data = wm8750; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -1045,7 +1057,7 @@ static int run_delayed_work(struct delayed_work *dwork) static int wm8750_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/wm8753.c b/trunk/sound/soc/codecs/wm8753.c index a6e8f3f7f052..77620ab98756 100644 --- a/trunk/sound/soc/codecs/wm8753.c +++ b/trunk/sound/soc/codecs/wm8753.c @@ -51,6 +51,8 @@ #include "wm8753.h" +#define WM8753_VERSION "0.16" + static int caps_charge = 2000; module_param(caps_charge, int, 0); MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); @@ -58,6 +60,12 @@ MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode); +/* codec private data */ +struct wm8753_priv { + unsigned int sysclk; + unsigned int pcmclk; +}; + /* * wm8753 register cache * We can't read the WM8753 register space when we @@ -82,14 +90,6 @@ static const u16 wm8753_reg[] = { 0x0000, 0x0000 }; -/* codec private data */ -struct wm8753_priv { - unsigned int sysclk; - unsigned int pcmclk; - struct snd_soc_codec codec; - u16 reg_cache[ARRAY_SIZE(wm8753_reg)]; -}; - /* * read wm8753 register cache */ @@ -97,7 +97,7 @@ static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { u16 *cache = codec->reg_cache; - if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1)) + if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1)) return -1; return cache[reg - 1]; } @@ -109,7 +109,7 @@ static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u16 *cache = codec->reg_cache; - if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1)) + if (reg < 1 || reg > 0x3f) return; cache[reg - 1] = value; } @@ -339,6 +339,21 @@ SOC_ENUM("ADC Data Select", wm8753_enum[27]), SOC_ENUM("ROUT2 Phase", wm8753_enum[28]), }; +/* add non dapm controls */ +static int wm8753_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8753_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8753_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + return 0; +} + /* * _DAPM_ Controls */ @@ -912,7 +927,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8753_priv *wm8753 = codec->private_data; u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; @@ -1146,7 +1161,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8753_priv *wm8753 = codec->private_data; u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; @@ -1301,51 +1316,6 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec, * 3. Voice disabled - HIFI over HIFI * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture */ -static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = { - .hw_params = wm8753_i2s_hw_params, - .digital_mute = wm8753_mute, - .set_fmt = wm8753_mode1h_set_dai_fmt, - .set_clkdiv = wm8753_set_dai_clkdiv, - .set_pll = wm8753_set_dai_pll, - .set_sysclk = wm8753_set_dai_sysclk, -}; - -static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = { - .hw_params = wm8753_pcm_hw_params, - .digital_mute = wm8753_mute, - .set_fmt = wm8753_mode1v_set_dai_fmt, - .set_clkdiv = wm8753_set_dai_clkdiv, - .set_pll = wm8753_set_dai_pll, - .set_sysclk = wm8753_set_dai_sysclk, -}; - -static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = { - .hw_params = wm8753_pcm_hw_params, - .digital_mute = wm8753_mute, - .set_fmt = wm8753_mode2_set_dai_fmt, - .set_clkdiv = wm8753_set_dai_clkdiv, - .set_pll = wm8753_set_dai_pll, - .set_sysclk = wm8753_set_dai_sysclk, -}; - -static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = { - .hw_params = wm8753_i2s_hw_params, - .digital_mute = wm8753_mute, - .set_fmt = wm8753_mode3_4_set_dai_fmt, - .set_clkdiv = wm8753_set_dai_clkdiv, - .set_pll = wm8753_set_dai_pll, - .set_sysclk = wm8753_set_dai_sysclk, -}; - -static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = { - .hw_params = wm8753_i2s_hw_params, - .digital_mute = wm8753_mute, - .set_fmt = wm8753_mode3_4_set_dai_fmt, - .set_clkdiv = wm8753_set_dai_clkdiv, - .set_pll = wm8753_set_dai_pll, - .set_sysclk = wm8753_set_dai_sysclk, -}; - static const struct snd_soc_dai wm8753_all_dai[] = { /* DAI HiFi mode 1 */ { .name = "WM8753 HiFi", @@ -1362,7 +1332,14 @@ static const struct snd_soc_dai wm8753_all_dai[] = { .channels_max = 2, .rates = WM8753_RATES, .formats = WM8753_FORMATS}, - .ops = &wm8753_dai_ops_hifi_mode1, + .ops = { + .hw_params = wm8753_i2s_hw_params, + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode1h_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, }, /* DAI Voice mode 1 */ { .name = "WM8753 Voice", @@ -1379,7 +1356,14 @@ static const struct snd_soc_dai wm8753_all_dai[] = { .channels_max = 2, .rates = WM8753_RATES, .formats = WM8753_FORMATS,}, - .ops = &wm8753_dai_ops_voice_mode1, + .ops = { + .hw_params = wm8753_pcm_hw_params, + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode1v_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, }, /* DAI HiFi mode 2 - dummy */ { .name = "WM8753 HiFi", @@ -1400,7 +1384,14 @@ static const struct snd_soc_dai wm8753_all_dai[] = { .channels_max = 2, .rates = WM8753_RATES, .formats = WM8753_FORMATS,}, - .ops = &wm8753_dai_ops_voice_mode2, + .ops = { + .hw_params = wm8753_pcm_hw_params, + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode2_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, }, /* DAI HiFi mode 3 */ { .name = "WM8753 HiFi", @@ -1417,7 +1408,14 @@ static const struct snd_soc_dai wm8753_all_dai[] = { .channels_max = 2, .rates = WM8753_RATES, .formats = WM8753_FORMATS,}, - .ops = &wm8753_dai_ops_hifi_mode3, + .ops = { + .hw_params = wm8753_i2s_hw_params, + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode3_4_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, }, /* DAI Voice mode 3 - dummy */ { .name = "WM8753 Voice", @@ -1438,7 +1436,14 @@ static const struct snd_soc_dai wm8753_all_dai[] = { .channels_max = 2, .rates = WM8753_RATES, .formats = WM8753_FORMATS,}, - .ops = &wm8753_dai_ops_hifi_mode4, + .ops = { + .hw_params = wm8753_i2s_hw_params, + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode3_4_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, }, /* DAI Voice mode 4 - dummy */ { .name = "WM8753 Voice", @@ -1461,35 +1466,30 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) if (mode < 4) { int playback_active, capture_active, codec_active, pop_wait; void *private_data; - struct list_head list; playback_active = wm8753_dai[0].playback.active; capture_active = wm8753_dai[0].capture.active; codec_active = wm8753_dai[0].active; private_data = wm8753_dai[0].private_data; pop_wait = wm8753_dai[0].pop_wait; - list = wm8753_dai[0].list; wm8753_dai[0] = wm8753_all_dai[mode << 1]; wm8753_dai[0].playback.active = playback_active; wm8753_dai[0].capture.active = capture_active; wm8753_dai[0].active = codec_active; wm8753_dai[0].private_data = private_data; wm8753_dai[0].pop_wait = pop_wait; - wm8753_dai[0].list = list; playback_active = wm8753_dai[1].playback.active; capture_active = wm8753_dai[1].capture.active; codec_active = wm8753_dai[1].active; private_data = wm8753_dai[1].private_data; pop_wait = wm8753_dai[1].pop_wait; - list = wm8753_dai[1].list; wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1]; wm8753_dai[1].playback.active = playback_active; wm8753_dai[1].capture.active = capture_active; wm8753_dai[1].active = codec_active; wm8753_dai[1].private_data = private_data; wm8753_dai[1].pop_wait = pop_wait; - wm8753_dai[1].list = list; } wm8753_dai[0].codec = codec; wm8753_dai[1].codec = codec; @@ -1505,7 +1505,7 @@ static void wm8753_work(struct work_struct *work) static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; /* we only need to suspend if we are a valid card */ if (!codec->card) @@ -1518,7 +1518,7 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) static int wm8753_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u16 *cache = codec->reg_cache; @@ -1531,11 +1531,6 @@ static int wm8753_resume(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { if (i + 1 == WM8753_RESET) continue; - - /* No point in writing hardware default values back */ - if (cache[i] == wm8753_reg[i]) - continue; - data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); data[1] = cache[i] & 0x00ff; codec->hw_write(codec->control_data, data, 2); @@ -1554,129 +1549,44 @@ static int wm8753_resume(struct platform_device *pdev) return 0; } -static struct snd_soc_codec *wm8753_codec; - -static int wm8753_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret = 0; - - if (!wm8753_codec) { - dev_err(&pdev->dev, "WM8753 codec not yet registered\n"); - return -EINVAL; - } - - socdev->card->codec = wm8753_codec; - codec = wm8753_codec; - - wm8753_set_dai_mode(codec, 0); - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - printk(KERN_ERR "wm8753: failed to create pcms\n"); - goto pcm_err; - } - - snd_soc_add_controls(codec, wm8753_snd_controls, - ARRAY_SIZE(wm8753_snd_controls)); - wm8753_add_widgets(codec); - ret = snd_soc_init_card(socdev); - if (ret < 0) { - printk(KERN_ERR "wm8753: failed to register card\n"); - goto card_err; - } - - return 0; - -card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - -pcm_err: - return ret; -} - /* - * This function forces any delayed work to be queued and run. + * initialise the WM8753 driver + * register the mixer and dsp interfaces with the kernel */ -static int run_delayed_work(struct delayed_work *dwork) -{ - int ret; - - /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(dwork); - - /* if there was any work waiting then we run it now and - * wait for it's completion */ - if (ret) { - schedule_delayed_work(dwork, 0); - flush_scheduled_work(); - } - return ret; -} - -/* power down chip */ -static int wm8753_remove(struct platform_device *pdev) +static int wm8753_init(struct snd_soc_device *socdev) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm8753 = { - .probe = wm8753_probe, - .remove = wm8753_remove, - .suspend = wm8753_suspend, - .resume = wm8753_resume, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); - -static int wm8753_register(struct wm8753_priv *wm8753) -{ - int ret, i; - struct snd_soc_codec *codec = &wm8753->codec; - u16 reg; - - if (wm8753_codec) { - dev_err(codec->dev, "Multiple WM8753 devices not supported\n"); - ret = -EINVAL; - goto err; - } - - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); + struct snd_soc_codec *codec = socdev->codec; + int reg, ret = 0; codec->name = "WM8753"; codec->owner = THIS_MODULE; codec->read = wm8753_read_reg_cache; codec->write = wm8753_write; - codec->bias_level = SND_SOC_BIAS_STANDBY; codec->set_bias_level = wm8753_set_bias_level; codec->dai = wm8753_dai; codec->num_dai = 2; - codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache); - codec->reg_cache = &wm8753->reg_cache; - codec->private_data = wm8753; + codec->reg_cache_size = ARRAY_SIZE(wm8753_reg); + codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL); - memcpy(codec->reg_cache, wm8753_reg, sizeof(codec->reg_cache)); - INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); + if (codec->reg_cache == NULL) + return -ENOMEM; + + wm8753_set_dai_mode(codec, 0); - ret = wm8753_reset(codec); + wm8753_reset(codec); + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - goto err; + printk(KERN_ERR "wm8753: failed to create pcms\n"); + goto pcm_err; } /* charge output caps */ wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); + codec->bias_level = SND_SOC_BIAS_STANDBY; schedule_delayed_work(&codec->delayed_work, - msecs_to_jiffies(caps_charge)); + msecs_to_jiffies(caps_charge)); /* set the update bits */ reg = wm8753_read_reg_cache(codec, WM8753_LDAC); @@ -1700,70 +1610,59 @@ static int wm8753_register(struct wm8753_priv *wm8753) reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); - wm8753_codec = codec; - - for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++) - wm8753_dai[i].dev = codec->dev; - - ret = snd_soc_register_codec(codec); - if (ret != 0) { - dev_err(codec->dev, "Failed to register codec: %d\n", ret); - goto err; - } - - ret = snd_soc_register_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); - if (ret != 0) { - dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); - goto err_codec; + wm8753_add_controls(codec); + wm8753_add_widgets(codec); + ret = snd_soc_init_card(socdev); + if (ret < 0) { + printk(KERN_ERR "wm8753: failed to register card\n"); + goto card_err; } - return 0; + return ret; -err_codec: - run_delayed_work(&codec->delayed_work); - snd_soc_unregister_codec(codec); -err: - kfree(wm8753); +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + kfree(codec->reg_cache); return ret; } -static void wm8753_unregister(struct wm8753_priv *wm8753) -{ - wm8753_set_bias_level(&wm8753->codec, SND_SOC_BIAS_OFF); - run_delayed_work(&wm8753->codec.delayed_work); - snd_soc_unregister_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); - snd_soc_unregister_codec(&wm8753->codec); - kfree(wm8753); - wm8753_codec = NULL; -} +/* If the i2c layer weren't so broken, we could pass this kind of data + around */ +static struct snd_soc_device *wm8753_socdev; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +/* + * WM8753 2 wire address is determined by GPIO5 + * state during powerup. + * low = 0x1a + * high = 0x1b + */ + static int wm8753_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct snd_soc_codec *codec; - struct wm8753_priv *wm8753; - - wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); - if (wm8753 == NULL) - return -ENOMEM; + struct snd_soc_device *socdev = wm8753_socdev; + struct snd_soc_codec *codec = socdev->codec; + int ret; - codec = &wm8753->codec; - codec->hw_write = (hw_write_t)i2c_master_send; - codec->control_data = i2c; - i2c_set_clientdata(i2c, wm8753); + i2c_set_clientdata(i2c, codec); + codec->control_data = i2c; - codec->dev = &i2c->dev; + ret = wm8753_init(socdev); + if (ret < 0) + pr_err("failed to initialise WM8753\n"); - return wm8753_register(wm8753); + return ret; } static int wm8753_i2c_remove(struct i2c_client *client) { - struct wm8753_priv *wm8753 = i2c_get_clientdata(client); - wm8753_unregister(wm8753); - return 0; + struct snd_soc_codec *codec = i2c_get_clientdata(client); + kfree(codec->reg_cache); + return 0; } static const struct i2c_device_id wm8753_i2c_id[] = { @@ -1774,16 +1673,86 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id); static struct i2c_driver wm8753_i2c_driver = { .driver = { - .name = "wm8753", + .name = "WM8753 I2C Codec", .owner = THIS_MODULE, }, .probe = wm8753_i2c_probe, .remove = wm8753_i2c_remove, .id_table = wm8753_i2c_id, }; + +static int wm8753_add_i2c_device(struct platform_device *pdev, + const struct wm8753_setup_data *setup) +{ + struct i2c_board_info info; + struct i2c_adapter *adapter; + struct i2c_client *client; + int ret; + + ret = i2c_add_driver(&wm8753_i2c_driver); + if (ret != 0) { + dev_err(&pdev->dev, "can't add i2c driver\n"); + return ret; + } + + memset(&info, 0, sizeof(struct i2c_board_info)); + info.addr = setup->i2c_address; + strlcpy(info.type, "wm8753", I2C_NAME_SIZE); + + adapter = i2c_get_adapter(setup->i2c_bus); + if (!adapter) { + dev_err(&pdev->dev, "can't get i2c adapter %d\n", + setup->i2c_bus); + goto err_driver; + } + + client = i2c_new_device(adapter, &info); + i2c_put_adapter(adapter); + if (!client) { + dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", + (unsigned int)info.addr); + goto err_driver; + } + + return 0; + +err_driver: + i2c_del_driver(&wm8753_i2c_driver); + return -ENODEV; +} #endif #if defined(CONFIG_SPI_MASTER) +static int __devinit wm8753_spi_probe(struct spi_device *spi) +{ + struct snd_soc_device *socdev = wm8753_socdev; + struct snd_soc_codec *codec = socdev->codec; + int ret; + + codec->control_data = spi; + + ret = wm8753_init(socdev); + if (ret < 0) + dev_err(&spi->dev, "failed to initialise WM8753\n"); + + return ret; +} + +static int __devexit wm8753_spi_remove(struct spi_device *spi) +{ + return 0; +} + +static struct spi_driver wm8753_spi_driver = { + .driver = { + .name = "wm8753", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = wm8753_spi_probe, + .remove = __devexit_p(wm8753_spi_remove), +}; + static int wm8753_spi_write(struct spi_device *spi, const char *data, int len) { struct spi_transfer t; @@ -1807,69 +1776,120 @@ static int wm8753_spi_write(struct spi_device *spi, const char *data, int len) return len; } +#endif -static int __devinit wm8753_spi_probe(struct spi_device *spi) + +static int wm8753_probe(struct platform_device *pdev) { + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct wm8753_setup_data *setup; struct snd_soc_codec *codec; struct wm8753_priv *wm8753; + int ret = 0; + + pr_info("WM8753 Audio Codec %s", WM8753_VERSION); + + setup = socdev->codec_data; + codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (codec == NULL) + return -ENOMEM; wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); - if (wm8753 == NULL) + if (wm8753 == NULL) { + kfree(codec); return -ENOMEM; + } - codec = &wm8753->codec; - codec->control_data = spi; - codec->hw_write = (hw_write_t)wm8753_spi_write; - codec->dev = &spi->dev; + codec->private_data = wm8753; + socdev->codec = codec; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + wm8753_socdev = socdev; + INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); - spi->dev.driver_data = wm8753; +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + if (setup->i2c_address) { + codec->hw_write = (hw_write_t)i2c_master_send; + ret = wm8753_add_i2c_device(pdev, setup); + } +#endif +#if defined(CONFIG_SPI_MASTER) + if (setup->spi) { + codec->hw_write = (hw_write_t)wm8753_spi_write; + ret = spi_register_driver(&wm8753_spi_driver); + if (ret != 0) + printk(KERN_ERR "can't add spi driver"); + } +#endif - return wm8753_register(wm8753); + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } + return ret; } -static int __devexit wm8753_spi_remove(struct spi_device *spi) +/* + * This function forces any delayed work to be queued and run. + */ +static int run_delayed_work(struct delayed_work *dwork) { - struct wm8753_priv *wm8753 = spi->dev.driver_data; - wm8753_unregister(wm8753); - return 0; -} + int ret; -static struct spi_driver wm8753_spi_driver = { - .driver = { - .name = "wm8753", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm8753_spi_probe, - .remove = __devexit_p(wm8753_spi_remove), -}; -#endif + /* cancel any work waiting to be queued. */ + ret = cancel_delayed_work(dwork); -static int __init wm8753_modinit(void) + /* if there was any work waiting then we run it now and + * wait for it's completion */ + if (ret) { + schedule_delayed_work(dwork, 0); + flush_scheduled_work(); + } + return ret; +} + +/* power down chip */ +static int wm8753_remove(struct platform_device *pdev) { - int ret; + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + if (codec->control_data) + wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); + run_delayed_work(&codec->delayed_work); + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm8753_i2c_driver); - if (ret != 0) - pr_err("Failed to register WM8753 I2C driver: %d\n", ret); + i2c_unregister_device(codec->control_data); + i2c_del_driver(&wm8753_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) - ret = spi_register_driver(&wm8753_spi_driver); - if (ret != 0) - pr_err("Failed to register WM8753 SPI driver: %d\n", ret); + spi_unregister_driver(&wm8753_spi_driver); #endif + kfree(codec->private_data); + kfree(codec); + return 0; } + +struct snd_soc_codec_device soc_codec_dev_wm8753 = { + .probe = wm8753_probe, + .remove = wm8753_remove, + .suspend = wm8753_suspend, + .resume = wm8753_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); + +static int __init wm8753_modinit(void) +{ + return snd_soc_register_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai)); +} module_init(wm8753_modinit); static void __exit wm8753_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&wm8753_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - spi_unregister_driver(&wm8753_spi_driver); -#endif + snd_soc_unregister_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai)); } module_exit(wm8753_exit); diff --git a/trunk/sound/soc/codecs/wm8753.h b/trunk/sound/soc/codecs/wm8753.h index 57b2ba244040..f55704ce931b 100644 --- a/trunk/sound/soc/codecs/wm8753.h +++ b/trunk/sound/soc/codecs/wm8753.h @@ -77,6 +77,12 @@ #define WM8753_BIASCTL 0x3d #define WM8753_ADCTL2 0x3f +struct wm8753_setup_data { + int spi; + int i2c_bus; + unsigned short i2c_address; +}; + #define WM8753_PLL1 0 #define WM8753_PLL2 1 diff --git a/trunk/sound/soc/codecs/wm8900.c b/trunk/sound/soc/codecs/wm8900.c index 46c5ea1ff921..6767de10ded0 100644 --- a/trunk/sound/soc/codecs/wm8900.c +++ b/trunk/sound/soc/codecs/wm8900.c @@ -517,6 +517,22 @@ SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1, }; +/* add non dapm controls */ +static int wm8900_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8900_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8900_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + static const struct snd_kcontrol_new wm8900_dapm_loutput2_control = SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0); @@ -720,7 +736,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 reg; reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60; @@ -1088,14 +1104,6 @@ static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute) (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ SNDRV_PCM_FORMAT_S24_LE) -static struct snd_soc_dai_ops wm8900_dai_ops = { - .hw_params = wm8900_hw_params, - .set_clkdiv = wm8900_set_dai_clkdiv, - .set_pll = wm8900_set_dai_pll, - .set_fmt = wm8900_set_dai_fmt, - .digital_mute = wm8900_digital_mute, -}; - struct snd_soc_dai wm8900_dai = { .name = "WM8900 HiFi", .playback = { @@ -1112,7 +1120,13 @@ struct snd_soc_dai wm8900_dai = { .rates = WM8900_RATES, .formats = WM8900_PCM_FORMATS, }, - .ops = &wm8900_dai_ops, + .ops = { + .hw_params = wm8900_hw_params, + .set_clkdiv = wm8900_set_dai_clkdiv, + .set_pll = wm8900_set_dai_pll, + .set_fmt = wm8900_set_dai_fmt, + .digital_mute = wm8900_digital_mute, + }, }; EXPORT_SYMBOL_GPL(wm8900_dai); @@ -1212,7 +1226,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8900_priv *wm8900 = codec->private_data; int fll_out = wm8900->fll_out; int fll_in = wm8900->fll_in; @@ -1236,7 +1250,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) static int wm8900_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8900_priv *wm8900 = codec->private_data; u16 *cache; int i, ret; @@ -1274,8 +1288,8 @@ static int wm8900_resume(struct platform_device *pdev) static struct snd_soc_codec *wm8900_codec; -static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8900_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8900_priv *wm8900; struct snd_soc_codec *codec; @@ -1374,7 +1388,7 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8900_i2c_remove(struct i2c_client *client) +static int wm8900_i2c_remove(struct i2c_client *client) { snd_soc_unregister_dai(&wm8900_dai); snd_soc_unregister_codec(wm8900_codec); @@ -1400,7 +1414,7 @@ static struct i2c_driver wm8900_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8900_i2c_probe, - .remove = __devexit_p(wm8900_i2c_remove), + .remove = wm8900_i2c_remove, .id_table = wm8900_i2c_id, }; @@ -1416,7 +1430,7 @@ static int wm8900_probe(struct platform_device *pdev) } codec = wm8900_codec; - socdev->card->codec = codec; + socdev->codec = codec; /* Register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); @@ -1425,8 +1439,7 @@ static int wm8900_probe(struct platform_device *pdev) goto pcm_err; } - snd_soc_add_controls(codec, wm8900_snd_controls, - ARRAY_SIZE(wm8900_snd_controls)); + wm8900_add_controls(codec); wm8900_add_widgets(codec); ret = snd_soc_init_card(socdev); diff --git a/trunk/sound/soc/codecs/wm8903.c b/trunk/sound/soc/codecs/wm8903.c index 8cf571f1a803..bde74546db4a 100644 --- a/trunk/sound/soc/codecs/wm8903.c +++ b/trunk/sound/soc/codecs/wm8903.c @@ -744,6 +744,21 @@ SOC_DOUBLE_R_TLV("Speaker Volume", 0, 63, 0, out_tlv), }; +static int wm8903_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8903_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8903_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + static const struct snd_kcontrol_new linput_mode_mux = SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum); @@ -1261,7 +1276,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8903_priv *wm8903 = codec->private_data; struct i2c_client *i2c = codec->control_data; struct snd_pcm_runtime *master_runtime; @@ -1303,7 +1318,7 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8903_priv *wm8903 = codec->private_data; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -1323,7 +1338,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8903_priv *wm8903 = codec->private_data; struct i2c_client *i2c = codec->control_data; int fs = params_rate(params); @@ -1497,15 +1512,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8903_dai_ops = { - .startup = wm8903_startup, - .shutdown = wm8903_shutdown, - .hw_params = wm8903_hw_params, - .digital_mute = wm8903_digital_mute, - .set_fmt = wm8903_set_dai_fmt, - .set_sysclk = wm8903_set_dai_sysclk, -}; - struct snd_soc_dai wm8903_dai = { .name = "WM8903", .playback = { @@ -1522,14 +1528,21 @@ struct snd_soc_dai wm8903_dai = { .rates = WM8903_CAPTURE_RATES, .formats = WM8903_FORMATS, }, - .ops = &wm8903_dai_ops, + .ops = { + .startup = wm8903_startup, + .shutdown = wm8903_shutdown, + .hw_params = wm8903_hw_params, + .digital_mute = wm8903_digital_mute, + .set_fmt = wm8903_set_dai_fmt, + .set_sysclk = wm8903_set_dai_sysclk + } }; EXPORT_SYMBOL_GPL(wm8903_dai); static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1539,7 +1552,7 @@ static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) static int wm8903_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct i2c_client *i2c = codec->control_data; int i; u16 *reg_cache = codec->reg_cache; @@ -1564,8 +1577,8 @@ static int wm8903_resume(struct platform_device *pdev) static struct snd_soc_codec *wm8903_codec; -static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8903_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) { struct wm8903_priv *wm8903; struct snd_soc_codec *codec; @@ -1671,7 +1684,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, return ret; } -static __devexit int wm8903_i2c_remove(struct i2c_client *client) +static int wm8903_i2c_remove(struct i2c_client *client) { struct snd_soc_codec *codec = i2c_get_clientdata(client); @@ -1701,7 +1714,7 @@ static struct i2c_driver wm8903_i2c_driver = { .owner = THIS_MODULE, }, .probe = wm8903_i2c_probe, - .remove = __devexit_p(wm8903_i2c_remove), + .remove = wm8903_i2c_remove, .id_table = wm8903_i2c_id, }; @@ -1715,7 +1728,7 @@ static int wm8903_probe(struct platform_device *pdev) goto err; } - socdev->card->codec = wm8903_codec; + socdev->codec = wm8903_codec; /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); @@ -1724,9 +1737,8 @@ static int wm8903_probe(struct platform_device *pdev) goto err; } - snd_soc_add_controls(socdev->card->codec, wm8903_snd_controls, - ARRAY_SIZE(wm8903_snd_controls)); - wm8903_add_widgets(socdev->card->codec); + wm8903_add_controls(socdev->codec); + wm8903_add_widgets(socdev->codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -1747,7 +1759,7 @@ static int wm8903_probe(struct platform_device *pdev) static int wm8903_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/wm8971.c b/trunk/sound/soc/codecs/wm8971.c index 032dca22dbd3..88ead7f8dd98 100644 --- a/trunk/sound/soc/codecs/wm8971.c +++ b/trunk/sound/soc/codecs/wm8971.c @@ -195,6 +195,21 @@ static const struct snd_kcontrol_new wm8971_snd_controls[] = { SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0), }; +/* add non-DAPM controls */ +static int wm8971_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8971_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8971_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + return 0; +} + /* * DAPM Controls */ @@ -531,7 +546,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm8971_priv *wm8971 = codec->private_data; u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3; u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0; @@ -604,13 +619,6 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec, #define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8971_dai_ops = { - .hw_params = wm8971_pcm_hw_params, - .digital_mute = wm8971_mute, - .set_fmt = wm8971_set_dai_fmt, - .set_sysclk = wm8971_set_dai_sysclk, -}; - struct snd_soc_dai wm8971_dai = { .name = "WM8971", .playback = { @@ -625,7 +633,12 @@ struct snd_soc_dai wm8971_dai = { .channels_max = 2, .rates = WM8971_RATES, .formats = WM8971_FORMATS,}, - .ops = &wm8971_dai_ops, + .ops = { + .hw_params = wm8971_pcm_hw_params, + .digital_mute = wm8971_mute, + .set_fmt = wm8971_set_dai_fmt, + .set_sysclk = wm8971_set_dai_sysclk, + }, }; EXPORT_SYMBOL_GPL(wm8971_dai); @@ -639,7 +652,7 @@ static void wm8971_work(struct work_struct *work) static int wm8971_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -648,7 +661,7 @@ static int wm8971_suspend(struct platform_device *pdev, pm_message_t state) static int wm8971_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u16 *cache = codec->reg_cache; @@ -679,7 +692,7 @@ static int wm8971_resume(struct platform_device *pdev) static int wm8971_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int reg, ret = 0; codec->name = "WM8971"; @@ -732,8 +745,7 @@ static int wm8971_init(struct snd_soc_device *socdev) reg = wm8971_read_reg_cache(codec, WM8971_RINVOL); wm8971_write(codec, WM8971_RINVOL, reg | 0x0100); - snd_soc_add_controls(codec, wm8971_snd_controls, - ARRAY_SIZE(wm8971_snd_controls)); + wm8971_add_controls(codec); wm8971_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -760,7 +772,7 @@ static int wm8971_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct snd_soc_device *socdev = wm8971_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -861,7 +873,7 @@ static int wm8971_probe(struct platform_device *pdev) } codec->private_data = wm8971; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -896,7 +908,7 @@ static int wm8971_probe(struct platform_device *pdev) static int wm8971_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/wm8990.c b/trunk/sound/soc/codecs/wm8990.c index c518c3e5aa3f..a5731faa150c 100644 --- a/trunk/sound/soc/codecs/wm8990.c +++ b/trunk/sound/soc/codecs/wm8990.c @@ -115,7 +115,7 @@ static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { u16 *cache = codec->reg_cache; - BUG_ON(reg >= ARRAY_SIZE(wm8990_reg)); + BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1); return cache[reg]; } @@ -128,7 +128,7 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec, u16 *cache = codec->reg_cache; /* Reset register and reserved registers are uncached */ - if (reg == 0 || reg >= ARRAY_SIZE(wm8990_reg)) + if (reg == 0 || reg > ARRAY_SIZE(wm8990_reg) - 1) return; cache[reg] = value; @@ -418,6 +418,21 @@ SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME, }; +/* add non dapm controls */ +static int wm8990_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8990_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8990_snd_controls[i], codec, + NULL)); + if (err < 0) + return err; + } + return 0; +} + /* * _DAPM_ Controls */ @@ -1163,7 +1178,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1); audio1 &= ~WM8990_AIF_WL_MASK; @@ -1332,15 +1347,6 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, * 1. ADC/DAC on Primary Interface * 2. ADC on Primary Interface/DAC on secondary */ -static struct snd_soc_dai_ops wm8990_dai_ops = { - .hw_params = wm8990_hw_params, - .digital_mute = wm8990_mute, - .set_fmt = wm8990_set_dai_fmt, - .set_clkdiv = wm8990_set_dai_clkdiv, - .set_pll = wm8990_set_dai_pll, - .set_sysclk = wm8990_set_dai_sysclk, -}; - struct snd_soc_dai wm8990_dai = { /* ADC/DAC on primary */ .name = "WM8990 ADC/DAC Primary", @@ -1357,14 +1363,21 @@ struct snd_soc_dai wm8990_dai = { .channels_max = 2, .rates = WM8990_RATES, .formats = WM8990_FORMATS,}, - .ops = &wm8990_dai_ops, + .ops = { + .hw_params = wm8990_hw_params, + .digital_mute = wm8990_mute, + .set_fmt = wm8990_set_dai_fmt, + .set_clkdiv = wm8990_set_dai_clkdiv, + .set_pll = wm8990_set_dai_pll, + .set_sysclk = wm8990_set_dai_sysclk, + }, }; EXPORT_SYMBOL_GPL(wm8990_dai); static int wm8990_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; /* we only need to suspend if we are a valid card */ if (!codec->card) @@ -1377,7 +1390,7 @@ static int wm8990_suspend(struct platform_device *pdev, pm_message_t state) static int wm8990_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; u8 data[2]; u16 *cache = codec->reg_cache; @@ -1405,7 +1418,7 @@ static int wm8990_resume(struct platform_device *pdev) */ static int wm8990_init(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 reg; int ret = 0; @@ -1448,8 +1461,7 @@ static int wm8990_init(struct snd_soc_device *socdev) wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); - snd_soc_add_controls(codec, wm8990_snd_controls, - ARRAY_SIZE(wm8990_snd_controls)); + wm8990_add_controls(codec); wm8990_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -1483,7 +1495,7 @@ static int wm8990_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct snd_soc_device *socdev = wm8990_socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret; i2c_set_clientdata(i2c, codec); @@ -1582,7 +1594,7 @@ static int wm8990_probe(struct platform_device *pdev) } codec->private_data = wm8990; - socdev->card->codec = codec; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -1608,7 +1620,7 @@ static int wm8990_probe(struct platform_device *pdev) static int wm8990_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/trunk/sound/soc/codecs/wm9705.c b/trunk/sound/soc/codecs/wm9705.c deleted file mode 100644 index 3265817c5c26..000000000000 --- a/trunk/sound/soc/codecs/wm9705.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * wm9705.c -- ALSA Soc WM9705 codec support - * - * Copyright 2008 Ian Molton - * - * 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; Version 2 of the License only. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wm9705.h" - -/* - * WM9705 register cache - */ -static const u16 wm9705_reg[] = { - 0x6150, 0x8000, 0x8000, 0x8000, /* 0x0 */ - 0x0000, 0x8000, 0x8008, 0x8008, /* 0x8 */ - 0x8808, 0x8808, 0x8808, 0x8808, /* 0x10 */ - 0x8808, 0x0000, 0x8000, 0x0000, /* 0x18 */ - 0x0000, 0x0000, 0x0000, 0x000f, /* 0x20 */ - 0x0605, 0x0000, 0xbb80, 0x0000, /* 0x28 */ - 0x0000, 0xbb80, 0x0000, 0x0000, /* 0x30 */ - 0x0000, 0x2000, 0x0000, 0x0000, /* 0x38 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x40 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x48 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x50 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x58 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x60 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x68 */ - 0x0000, 0x0808, 0x0000, 0x0006, /* 0x70 */ - 0x0000, 0x0000, 0x574d, 0x4c05, /* 0x78 */ -}; - -static const struct snd_kcontrol_new wm9705_snd_ac97_controls[] = { - SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), - SOC_SINGLE("Master Playback Switch", AC97_MASTER, 15, 1, 1), - SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), - SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1), - SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1), - SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1), - SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1), - SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1), - SOC_SINGLE("PCBeep Playback Volume", AC97_PC_BEEP, 1, 15, 1), - SOC_SINGLE("Phone Playback Volume", AC97_PHONE, 0, 31, 1), - SOC_DOUBLE("Line Playback Volume", AC97_LINE, 8, 0, 31, 1), - SOC_DOUBLE("CD Playback Volume", AC97_CD, 8, 0, 31, 1), - SOC_SINGLE("Mic Playback Volume", AC97_MIC, 0, 31, 1), - SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 6, 1, 0), - SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0), - SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1), -}; - -static const char *wm9705_mic[] = {"Mic 1", "Mic 2"}; -static const char *wm9705_rec_sel[] = {"Mic", "CD", "NC", "NC", - "Line", "Stereo Mix", "Mono Mix", "Phone"}; - -static const struct soc_enum wm9705_enum_mic = - SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, wm9705_mic); -static const struct soc_enum wm9705_enum_rec_l = - SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9705_rec_sel); -static const struct soc_enum wm9705_enum_rec_r = - SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9705_rec_sel); - -/* Headphone Mixer */ -static const struct snd_kcontrol_new wm9705_hp_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Playback Switch", AC97_PC_BEEP, 15, 1, 1), - SOC_DAPM_SINGLE("CD Playback Switch", AC97_CD, 15, 1, 1), - SOC_DAPM_SINGLE("Mic Playback Switch", AC97_MIC, 15, 1, 1), - SOC_DAPM_SINGLE("Phone Playback Switch", AC97_PHONE, 15, 1, 1), - SOC_DAPM_SINGLE("Line Playback Switch", AC97_LINE, 15, 1, 1), -}; - -/* Mic source */ -static const struct snd_kcontrol_new wm9705_mic_src_controls = - SOC_DAPM_ENUM("Route", wm9705_enum_mic); - -/* Capture source */ -static const struct snd_kcontrol_new wm9705_capture_selectl_controls = - SOC_DAPM_ENUM("Route", wm9705_enum_rec_l); -static const struct snd_kcontrol_new wm9705_capture_selectr_controls = - SOC_DAPM_ENUM("Route", wm9705_enum_rec_r); - -/* DAPM widgets */ -static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = { - SND_SOC_DAPM_MUX("Mic Source", SND_SOC_NOPM, 0, 0, - &wm9705_mic_src_controls), - SND_SOC_DAPM_MUX("Left Capture Source", SND_SOC_NOPM, 0, 0, - &wm9705_capture_selectl_controls), - SND_SOC_DAPM_MUX("Right Capture Source", SND_SOC_NOPM, 0, 0, - &wm9705_capture_selectr_controls), - SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_MIXER_NAMED_CTL("HP Mixer", SND_SOC_NOPM, 0, 0, - &wm9705_hp_mixer_controls[0], - ARRAY_SIZE(wm9705_hp_mixer_controls)), - SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_PGA("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("Speaker PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("Line PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("Line out PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mono PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("Phone PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mic PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("PCBEEP PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("CD PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("ADC PGA", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_OUTPUT("HPOUTL"), - SND_SOC_DAPM_OUTPUT("HPOUTR"), - SND_SOC_DAPM_OUTPUT("LOUT"), - SND_SOC_DAPM_OUTPUT("ROUT"), - SND_SOC_DAPM_OUTPUT("MONOOUT"), - SND_SOC_DAPM_INPUT("PHONE"), - SND_SOC_DAPM_INPUT("LINEINL"), - SND_SOC_DAPM_INPUT("LINEINR"), - SND_SOC_DAPM_INPUT("CDINL"), - SND_SOC_DAPM_INPUT("CDINR"), - SND_SOC_DAPM_INPUT("PCBEEP"), - SND_SOC_DAPM_INPUT("MIC1"), - SND_SOC_DAPM_INPUT("MIC2"), -}; - -/* Audio map - * WM9705 has no switches to disable the route from the inputs to the HP mixer - * so in order to prevent active inputs from forcing the audio outputs to be - * constantly enabled, we use the mutes on those inputs to simulate such - * controls. - */ -static const struct snd_soc_dapm_route audio_map[] = { - /* HP mixer */ - {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"}, - {"HP Mixer", "CD Playback Switch", "CD PGA"}, - {"HP Mixer", "Mic Playback Switch", "Mic PGA"}, - {"HP Mixer", "Phone Playback Switch", "Phone PGA"}, - {"HP Mixer", "Line Playback Switch", "Line PGA"}, - {"HP Mixer", NULL, "Left DAC"}, - {"HP Mixer", NULL, "Right DAC"}, - - /* mono mixer */ - {"Mono Mixer", NULL, "HP Mixer"}, - - /* outputs */ - {"Headphone PGA", NULL, "HP Mixer"}, - {"HPOUTL", NULL, "Headphone PGA"}, - {"HPOUTR", NULL, "Headphone PGA"}, - {"Line out PGA", NULL, "HP Mixer"}, - {"LOUT", NULL, "Line out PGA"}, - {"ROUT", NULL, "Line out PGA"}, - {"Mono PGA", NULL, "Mono Mixer"}, - {"MONOOUT", NULL, "Mono PGA"}, - - /* inputs */ - {"CD PGA", NULL, "CDINL"}, - {"CD PGA", NULL, "CDINR"}, - {"Line PGA", NULL, "LINEINL"}, - {"Line PGA", NULL, "LINEINR"}, - {"Phone PGA", NULL, "PHONE"}, - {"Mic Source", "Mic 1", "MIC1"}, - {"Mic Source", "Mic 2", "MIC2"}, - {"Mic PGA", NULL, "Mic Source"}, - {"PCBEEP PGA", NULL, "PCBEEP"}, - - /* Left capture selector */ - {"Left Capture Source", "Mic", "Mic Source"}, - {"Left Capture Source", "CD", "CDINL"}, - {"Left Capture Source", "Line", "LINEINL"}, - {"Left Capture Source", "Stereo Mix", "HP Mixer"}, - {"Left Capture Source", "Mono Mix", "HP Mixer"}, - {"Left Capture Source", "Phone", "PHONE"}, - - /* Right capture source */ - {"Right Capture Source", "Mic", "Mic Source"}, - {"Right Capture Source", "CD", "CDINR"}, - {"Right Capture Source", "Line", "LINEINR"}, - {"Right Capture Source", "Stereo Mix", "HP Mixer"}, - {"Right Capture Source", "Mono Mix", "HP Mixer"}, - {"Right Capture Source", "Phone", "PHONE"}, - - {"ADC PGA", NULL, "Left Capture Source"}, - {"ADC PGA", NULL, "Right Capture Source"}, - - /* ADC's */ - {"Left ADC", NULL, "ADC PGA"}, - {"Right ADC", NULL, "ADC PGA"}, -}; - -static int wm9705_add_widgets(struct snd_soc_codec *codec) -{ - snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, - ARRAY_SIZE(wm9705_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_new_widgets(codec); - - return 0; -} - -/* We use a register cache to enhance read performance. */ -static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) -{ - u16 *cache = codec->reg_cache; - - switch (reg) { - case AC97_RESET: - case AC97_VENDOR_ID1: - case AC97_VENDOR_ID2: - return soc_ac97_ops.read(codec->ac97, reg); - default: - reg = reg >> 1; - - if (reg >= (ARRAY_SIZE(wm9705_reg))) - return -EIO; - - return cache[reg]; - } -} - -static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - u16 *cache = codec->reg_cache; - - soc_ac97_ops.write(codec->ac97, reg, val); - reg = reg >> 1; - if (reg < (ARRAY_SIZE(wm9705_reg))) - cache[reg] = val; - - return 0; -} - -static int ac97_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; - int reg; - u16 vra; - - vra = ac97_read(codec, AC97_EXTENDED_STATUS); - ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - reg = AC97_PCM_FRONT_DAC_RATE; - else - reg = AC97_PCM_LR_ADC_RATE; - - return ac97_write(codec, reg, runtime->rate); -} - -#define WM9705_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \ - SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000) - -static struct snd_soc_dai_ops wm9705_dai_ops = { - .prepare = ac97_prepare, -}; - -struct snd_soc_dai wm9705_dai[] = { - { - .name = "AC97 HiFi", - .ac97_control = 1, - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM9705_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM9705_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &wm9705_dai_ops, - }, - { - .name = "AC97 Aux", - .playback = { - .stream_name = "Aux Playback", - .channels_min = 1, - .channels_max = 1, - .rates = WM9705_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - } -}; -EXPORT_SYMBOL_GPL(wm9705_dai); - -static int wm9705_reset(struct snd_soc_codec *codec) -{ - if (soc_ac97_ops.reset) { - soc_ac97_ops.reset(codec->ac97); - if (ac97_read(codec, 0) == wm9705_reg[0]) - return 0; /* Success */ - } - - return -EIO; -} - -static int wm9705_soc_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret = 0; - - printk(KERN_INFO "WM9705 SoC Audio Codec\n"); - - socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), - GFP_KERNEL); - if (socdev->card->codec == NULL) - return -ENOMEM; - codec = socdev->card->codec; - mutex_init(&codec->mutex); - - codec->reg_cache = kmemdup(wm9705_reg, sizeof(wm9705_reg), GFP_KERNEL); - if (codec->reg_cache == NULL) { - ret = -ENOMEM; - goto cache_err; - } - codec->reg_cache_size = sizeof(wm9705_reg); - codec->reg_cache_step = 2; - - codec->name = "WM9705"; - codec->owner = THIS_MODULE; - codec->dai = wm9705_dai; - codec->num_dai = ARRAY_SIZE(wm9705_dai); - codec->write = ac97_write; - codec->read = ac97_read; - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); - if (ret < 0) { - printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); - goto codec_err; - } - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) - goto pcm_err; - - ret = wm9705_reset(codec); - if (ret) - goto reset_err; - - snd_soc_add_controls(codec, wm9705_snd_ac97_controls, - ARRAY_SIZE(wm9705_snd_ac97_controls)); - wm9705_add_widgets(codec); - - ret = snd_soc_init_card(socdev); - if (ret < 0) { - printk(KERN_ERR "wm9705: failed to register card\n"); - goto pcm_err; - } - - return 0; - -reset_err: - snd_soc_free_pcms(socdev); -pcm_err: - snd_soc_free_ac97_codec(codec); -codec_err: - kfree(codec->reg_cache); -cache_err: - kfree(socdev->card->codec); - socdev->card->codec = NULL; - return ret; -} - -static int wm9705_soc_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - if (codec == NULL) - return 0; - - snd_soc_dapm_free(socdev); - snd_soc_free_pcms(socdev); - snd_soc_free_ac97_codec(codec); - kfree(codec->reg_cache); - kfree(codec); - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm9705 = { - .probe = wm9705_soc_probe, - .remove = wm9705_soc_remove, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705); - -MODULE_DESCRIPTION("ASoC WM9705 driver"); -MODULE_AUTHOR("Ian Molton"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/sound/soc/codecs/wm9705.h b/trunk/sound/soc/codecs/wm9705.h deleted file mode 100644 index d380f110f9e2..000000000000 --- a/trunk/sound/soc/codecs/wm9705.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * wm9705.h -- WM9705 Soc Audio driver - */ - -#ifndef _WM9705_H -#define _WM9705_H - -#define WM9705_DAI_AC97_HIFI 0 -#define WM9705_DAI_AC97_AUX 1 - -extern struct snd_soc_dai wm9705_dai[2]; -extern struct snd_soc_codec_device soc_codec_dev_wm9705; - -#endif diff --git a/trunk/sound/soc/codecs/wm9712.c b/trunk/sound/soc/codecs/wm9712.c index 765cf1e7369e..af83d629078a 100644 --- a/trunk/sound/soc/codecs/wm9712.c +++ b/trunk/sound/soc/codecs/wm9712.c @@ -154,6 +154,21 @@ SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), }; +/* add non dapm controls */ +static int wm9712_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm9712_snd_ac97_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm9712_snd_ac97_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + return 0; +} + /* We have to create a fake left and right HP mixers because * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path. @@ -452,7 +467,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, else { reg = reg >> 1; - if (reg >= (ARRAY_SIZE(wm9712_reg))) + if (reg > (ARRAY_SIZE(wm9712_reg))) return -EIO; return cache[reg]; @@ -466,7 +481,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, soc_ac97_ops.write(codec->ac97, reg, val); reg = reg >> 1; - if (reg < (ARRAY_SIZE(wm9712_reg))) + if (reg <= (ARRAY_SIZE(wm9712_reg))) cache[reg] = val; return 0; @@ -478,7 +493,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int reg; u16 vra; @@ -499,7 +514,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 vra, xsle; vra = ac97_read(codec, AC97_EXTENDED_STATUS); @@ -517,14 +532,6 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops wm9712_dai_ops_hifi = { - .prepare = ac97_prepare, -}; - -static struct snd_soc_dai_ops wm9712_dai_ops_aux = { - .prepare = ac97_aux_prepare, -}; - struct snd_soc_dai wm9712_dai[] = { { .name = "AC97 HiFi", @@ -541,7 +548,8 @@ struct snd_soc_dai wm9712_dai[] = { .channels_max = 2, .rates = WM9712_AC97_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &wm9712_dai_ops_hifi, + .ops = { + .prepare = ac97_prepare,}, }, { .name = "AC97 Aux", @@ -551,7 +559,8 @@ struct snd_soc_dai wm9712_dai[] = { .channels_max = 1, .rates = WM9712_AC97_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &wm9712_dai_ops_aux, + .ops = { + .prepare = ac97_aux_prepare,}, } }; EXPORT_SYMBOL_GPL(wm9712_dai); @@ -598,7 +607,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -607,7 +616,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev, static int wm9712_soc_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; int i, ret; u16 *cache = codec->reg_cache; @@ -643,11 +652,10 @@ static int wm9712_soc_probe(struct platform_device *pdev) printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); - socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), - GFP_KERNEL); - if (socdev->card->codec == NULL) + socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (socdev->codec == NULL) return -ENOMEM; - codec = socdev->card->codec; + codec = socdev->codec; mutex_init(&codec->mutex); codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); @@ -690,8 +698,7 @@ static int wm9712_soc_probe(struct platform_device *pdev) ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm9712_snd_ac97_controls, - ARRAY_SIZE(wm9712_snd_ac97_controls)); + wm9712_add_controls(codec); wm9712_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) { @@ -711,15 +718,15 @@ static int wm9712_soc_probe(struct platform_device *pdev) kfree(codec->reg_cache); cache_err: - kfree(socdev->card->codec); - socdev->card->codec = NULL; + kfree(socdev->codec); + socdev->codec = NULL; return ret; } static int wm9712_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec == NULL) return 0; diff --git a/trunk/sound/soc/codecs/wm9713.c b/trunk/sound/soc/codecs/wm9713.c index 523bad077fa0..f3ca8aaf0139 100644 --- a/trunk/sound/soc/codecs/wm9713.c +++ b/trunk/sound/soc/codecs/wm9713.c @@ -32,6 +32,7 @@ struct wm9713_priv { u32 pll_in; /* PLL input frequency */ + u32 pll_out; /* PLL output frequency */ }; static unsigned int ac97_read(struct snd_soc_codec *codec, @@ -189,6 +190,21 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), }; +/* add non dapm controls */ +static int wm9713_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm9713_snd_ac97_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm9713_snd_ac97_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + return 0; +} + /* We have to create a fake left and right HP mixers because * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path using the current @@ -620,7 +636,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, else { reg = reg >> 1; - if (reg >= (ARRAY_SIZE(wm9713_reg))) + if (reg > (ARRAY_SIZE(wm9713_reg))) return -EIO; return cache[reg]; @@ -634,7 +650,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, if (reg < 0x7c) soc_ac97_ops.write(codec->ac97, reg, val); reg = reg >> 1; - if (reg < (ARRAY_SIZE(wm9713_reg))) + if (reg <= (ARRAY_SIZE(wm9713_reg))) cache[reg] = val; return 0; @@ -722,13 +738,13 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, struct _pll_div pll_div; /* turn PLL off ? */ - if (freq_in == 0) { + if (freq_in == 0 || freq_out == 0) { /* disable PLL power and select ext source */ reg = ac97_read(codec, AC97_HANDSET_RATE); ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080); reg = ac97_read(codec, AC97_EXTENDED_MID); ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200); - wm9713->pll_in = 0; + wm9713->pll_out = 0; return 0; } @@ -772,6 +788,7 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff); reg = ac97_read(codec, AC97_HANDSET_RATE); ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f); + wm9713->pll_out = freq_out; wm9713->pll_in = freq_in; /* wait 10ms AC97 link frames for the link to stabilise */ @@ -940,14 +957,13 @@ static void wm9713_voiceshutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; - u16 status, rate; + u16 status; /* Gracefully shut down the voice interface. */ status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000; - rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF; - ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200); + ac97_write(codec, AC97_HANDSET_RATE, 0x0280); schedule_timeout_interruptible(msecs_to_jiffies(1)); - ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); + ac97_write(codec, AC97_HANDSET_RATE, 0x0F80); ac97_write(codec, AC97_EXTENDED_MID, status); } @@ -1005,27 +1021,6 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream, (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ SNDRV_PCM_FORMAT_S24_LE) -static struct snd_soc_dai_ops wm9713_dai_ops_hifi = { - .prepare = ac97_hifi_prepare, - .set_clkdiv = wm9713_set_dai_clkdiv, - .set_pll = wm9713_set_dai_pll, -}; - -static struct snd_soc_dai_ops wm9713_dai_ops_aux = { - .prepare = ac97_aux_prepare, - .set_clkdiv = wm9713_set_dai_clkdiv, - .set_pll = wm9713_set_dai_pll, -}; - -static struct snd_soc_dai_ops wm9713_dai_ops_voice = { - .hw_params = wm9713_pcm_hw_params, - .shutdown = wm9713_voiceshutdown, - .set_clkdiv = wm9713_set_dai_clkdiv, - .set_pll = wm9713_set_dai_pll, - .set_fmt = wm9713_set_dai_fmt, - .set_tristate = wm9713_set_dai_tristate, -}; - struct snd_soc_dai wm9713_dai[] = { { .name = "AC97 HiFi", @@ -1042,7 +1037,10 @@ struct snd_soc_dai wm9713_dai[] = { .channels_max = 2, .rates = WM9713_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &wm9713_dai_ops_hifi, + .ops = { + .prepare = ac97_hifi_prepare, + .set_clkdiv = wm9713_set_dai_clkdiv, + .set_pll = wm9713_set_dai_pll,}, }, { .name = "AC97 Aux", @@ -1052,7 +1050,10 @@ struct snd_soc_dai wm9713_dai[] = { .channels_max = 1, .rates = WM9713_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &wm9713_dai_ops_aux, + .ops = { + .prepare = ac97_aux_prepare, + .set_clkdiv = wm9713_set_dai_clkdiv, + .set_pll = wm9713_set_dai_pll,}, }, { .name = "WM9713 Voice", @@ -1068,7 +1069,14 @@ struct snd_soc_dai wm9713_dai[] = { .channels_max = 2, .rates = WM9713_PCM_RATES, .formats = WM9713_PCM_FORMATS,}, - .ops = &wm9713_dai_ops_voice, + .ops = { + .hw_params = wm9713_pcm_hw_params, + .shutdown = wm9713_voiceshutdown, + .set_clkdiv = wm9713_set_dai_clkdiv, + .set_pll = wm9713_set_dai_pll, + .set_fmt = wm9713_set_dai_fmt, + .set_tristate = wm9713_set_dai_tristate, + }, }, }; EXPORT_SYMBOL_GPL(wm9713_dai); @@ -1124,7 +1132,7 @@ static int wm9713_soc_suspend(struct platform_device *pdev, pm_message_t state) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; u16 reg; /* Disable everything except touchpanel - that will be handled @@ -1142,7 +1150,7 @@ static int wm9713_soc_suspend(struct platform_device *pdev, static int wm9713_soc_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; struct wm9713_priv *wm9713 = codec->private_data; int i, ret; u16 *cache = codec->reg_cache; @@ -1156,8 +1164,8 @@ static int wm9713_soc_resume(struct platform_device *pdev) wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* do we need to re-start the PLL ? */ - if (wm9713->pll_in) - wm9713_set_pll(codec, 0, wm9713->pll_in, 0); + if (wm9713->pll_out) + wm9713_set_pll(codec, 0, wm9713->pll_in, wm9713->pll_out); /* only synchronise the codec if warm reset failed */ if (ret == 0) { @@ -1183,11 +1191,10 @@ static int wm9713_soc_probe(struct platform_device *pdev) printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION); - socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), - GFP_KERNEL); - if (socdev->card->codec == NULL) + socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (socdev->codec == NULL) return -ENOMEM; - codec = socdev->card->codec; + codec = socdev->codec; mutex_init(&codec->mutex); codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL); @@ -1238,8 +1245,7 @@ static int wm9713_soc_probe(struct platform_device *pdev) reg = ac97_read(codec, AC97_CD) & 0x7fff; ac97_write(codec, AC97_CD, reg); - snd_soc_add_controls(codec, wm9713_snd_ac97_controls, - ARRAY_SIZE(wm9713_snd_ac97_controls)); + wm9713_add_controls(codec); wm9713_add_widgets(codec); ret = snd_soc_init_card(socdev); if (ret < 0) @@ -1259,15 +1265,15 @@ static int wm9713_soc_probe(struct platform_device *pdev) kfree(codec->reg_cache); cache_err: - kfree(socdev->card->codec); - socdev->card->codec = NULL; + kfree(socdev->codec); + socdev->codec = NULL; return ret; } static int wm9713_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; if (codec == NULL) return 0; diff --git a/trunk/sound/soc/davinci/Kconfig b/trunk/sound/soc/davinci/Kconfig index bd7392c9657e..b502741692d6 100644 --- a/trunk/sound/soc/davinci/Kconfig +++ b/trunk/sound/soc/davinci/Kconfig @@ -20,7 +20,7 @@ config SND_DAVINCI_SOC_EVM config SND_DAVINCI_SOC_SFFSDR tristate "SoC Audio support for SFFSDR" - depends on SND_DAVINCI_SOC && MACH_SFFSDR + depends on SND_DAVINCI_SOC && MACH_DAVINCI_SFFSDR select SND_DAVINCI_SOC_I2S select SND_SOC_PCM3008 select SFFSDR_FPGA diff --git a/trunk/sound/soc/davinci/davinci-evm.c b/trunk/sound/soc/davinci/davinci-evm.c index 9b90b347007c..54851f318568 100644 --- a/trunk/sound/soc/davinci/davinci-evm.c +++ b/trunk/sound/soc/davinci/davinci-evm.c @@ -186,8 +186,7 @@ static int __init evm_init(void) platform_set_drvdata(evm_snd_device, &evm_snd_devdata); evm_snd_devdata.dev = &evm_snd_device->dev; - platform_device_add_data(evm_snd_device, &evm_snd_data, - sizeof(evm_snd_data)); + evm_snd_device->dev.platform_data = &evm_snd_data; ret = platform_device_add_resources(evm_snd_device, evm_snd_resources, ARRAY_SIZE(evm_snd_resources)); diff --git a/trunk/sound/soc/davinci/davinci-i2s.c b/trunk/sound/soc/davinci/davinci-i2s.c index ffdb9439d3d8..0fee779e3c76 100644 --- a/trunk/sound/soc/davinci/davinci-i2s.c +++ b/trunk/sound/soc/davinci/davinci-i2s.c @@ -499,13 +499,6 @@ static void davinci_i2s_remove(struct platform_device *pdev, #define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 -static struct snd_soc_dai_ops davinci_i2s_dai_ops = { - .startup = davinci_i2s_startup, - .trigger = davinci_i2s_trigger, - .hw_params = davinci_i2s_hw_params, - .set_fmt = davinci_i2s_set_dai_fmt, -}; - struct snd_soc_dai davinci_i2s_dai = { .name = "davinci-i2s", .id = 0, @@ -521,7 +514,12 @@ struct snd_soc_dai davinci_i2s_dai = { .channels_max = 2, .rates = DAVINCI_I2S_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &davinci_i2s_dai_ops, + .ops = { + .startup = davinci_i2s_startup, + .trigger = davinci_i2s_trigger, + .hw_params = davinci_i2s_hw_params, + .set_fmt = davinci_i2s_set_dai_fmt, + }, }; EXPORT_SYMBOL_GPL(davinci_i2s_dai); diff --git a/trunk/sound/soc/davinci/davinci-pcm.c b/trunk/sound/soc/davinci/davinci-pcm.c index 7af3b5b3a53d..366049d8578c 100644 --- a/trunk/sound/soc/davinci/davinci-pcm.c +++ b/trunk/sound/soc/davinci/davinci-pcm.c @@ -286,7 +286,7 @@ static int davinci_pcm_mmap(struct snd_pcm_substream *substream, runtime->dma_bytes); } -static struct snd_pcm_ops davinci_pcm_ops = { +struct snd_pcm_ops davinci_pcm_ops = { .open = davinci_pcm_open, .close = davinci_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/trunk/sound/soc/davinci/davinci-sffsdr.c b/trunk/sound/soc/davinci/davinci-sffsdr.c index 40eccfe9e358..4935d1bcbd8d 100644 --- a/trunk/sound/soc/davinci/davinci-sffsdr.c +++ b/trunk/sound/soc/davinci/davinci-sffsdr.c @@ -25,9 +25,7 @@ #include #include -#ifdef CONFIG_SFFSDR_FPGA #include -#endif #include #include @@ -36,45 +34,31 @@ #include "davinci-pcm.h" #include "davinci-i2s.h" -/* - * CLKX and CLKR are the inputs for the Sample Rate Generator. - * FSX and FSR are outputs, driven by the sample Rate Generator. - */ -#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ - SND_SOC_DAIFMT_CBM_CFS | \ - SND_SOC_DAIFMT_IB_NF) - static int sffsdr_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; int fs; int ret = 0; - /* Fsref can be 32000, 44100 or 48000. */ - fs = params_rate(params); - -#ifndef CONFIG_SFFSDR_FPGA - /* Without the FPGA module, the Fs is fixed at 44100 Hz */ - if (fs != 44100) { - pr_debug("warning: only 44.1 kHz is supported without SFFSDR FPGA module\n"); - return -EINVAL; - } -#endif - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT); + /* Set cpu DAI configuration: + * CLKX and CLKR are the inputs for the Sample Rate Generator. + * FSX and FSR are outputs, driven by the sample Rate Generator. */ + ret = snd_soc_dai_set_fmt(cpu_dai, + SND_SOC_DAIFMT_RIGHT_J | + SND_SOC_DAIFMT_CBM_CFS | + SND_SOC_DAIFMT_IB_NF); if (ret < 0) return ret; + /* Fsref can be 32000, 44100 or 48000. */ + fs = params_rate(params); + pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs); -#ifndef CONFIG_SFFSDR_FPGA - return 0; -#else return sffsdr_fpga_set_codec_fs(fs); -#endif } static struct snd_soc_ops sffsdr_ops = { @@ -143,8 +127,7 @@ static int __init sffsdr_init(void) platform_set_drvdata(sffsdr_snd_device, &sffsdr_snd_devdata); sffsdr_snd_devdata.dev = &sffsdr_snd_device->dev; - platform_device_add_data(sffsdr_snd_device, &sffsdr_snd_data, - sizeof(sffsdr_snd_data)); + sffsdr_snd_device->dev.platform_data = &sffsdr_snd_data; ret = platform_device_add_resources(sffsdr_snd_device, sffsdr_snd_resources, diff --git a/trunk/sound/soc/fsl/Kconfig b/trunk/sound/soc/fsl/Kconfig index 9fc908283371..95c12b26fe37 100644 --- a/trunk/sound/soc/fsl/Kconfig +++ b/trunk/sound/soc/fsl/Kconfig @@ -1,18 +1,17 @@ config SND_SOC_OF_SIMPLE tristate -# ASoC platform support for the Freescale MPC8610 SOC. This compiles drivers -# for the SSI and the Elo DMA controller. You will still need to select -# a platform driver and a codec driver. config SND_SOC_MPC8610 - tristate - depends on MPC8610 + bool "ALSA SoC support for the MPC8610 SOC" + depends on MPC8610_HPCD + default y if MPC8610 + help + Say Y if you want to add support for codecs attached to the SSI + device on an MPC8610. config SND_SOC_MPC8610_HPCD - tristate "ALSA SoC support for the Freescale MPC8610 HPCD board" - # I2C is necessary for the CS4270 driver - depends on MPC8610_HPCD && I2C - select SND_SOC_MPC8610 + bool "ALSA SoC support for the Freescale MPC8610 HPCD board" + depends on SND_SOC_MPC8610 select SND_SOC_CS4270 select SND_SOC_CS4270_VD33_ERRATA default y if MPC8610_HPCD diff --git a/trunk/sound/soc/fsl/Makefile b/trunk/sound/soc/fsl/Makefile index f85134c86387..035da4afec34 100644 --- a/trunk/sound/soc/fsl/Makefile +++ b/trunk/sound/soc/fsl/Makefile @@ -2,13 +2,10 @@ obj-$(CONFIG_SND_SOC_OF_SIMPLE) += soc-of-simple.o # MPC8610 HPCD Machine Support -snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o -obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o +obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += mpc8610_hpcd.o # MPC8610 Platform Support -snd-soc-fsl-ssi-objs := fsl_ssi.o -snd-soc-fsl-dma-objs := fsl_dma.o -obj-$(CONFIG_SND_SOC_MPC8610) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o +obj-$(CONFIG_SND_SOC_MPC8610) += fsl_ssi.o fsl_dma.o obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o diff --git a/trunk/sound/soc/fsl/fsl_dma.c b/trunk/sound/soc/fsl/fsl_dma.c index b3eb8570cd7b..64993eda5679 100644 --- a/trunk/sound/soc/fsl/fsl_dma.c +++ b/trunk/sound/soc/fsl/fsl_dma.c @@ -142,8 +142,7 @@ static const struct snd_pcm_hardware fsl_dma_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_JOINT_DUPLEX | - SNDRV_PCM_INFO_PAUSE, + SNDRV_PCM_INFO_JOINT_DUPLEX, .formats = FSLDMA_PCM_FORMATS, .rates = FSLDMA_PCM_RATES, .rate_min = 5512, @@ -465,7 +464,11 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) sizeof(struct fsl_dma_link_descriptor); for (i = 0; i < NUM_DMA_LINKS; i++) { - dma_private->link[i].next = cpu_to_be64(temp_link); + struct fsl_dma_link_descriptor *link = &dma_private->link[i]; + + link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); + link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); + link->next = cpu_to_be64(temp_link); temp_link += sizeof(struct fsl_dma_link_descriptor); } @@ -522,9 +525,79 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) * This function obtains hardware parameters about the opened stream and * programs the DMA controller accordingly. * - * One drawback of big-endian is that when copying integers of different - * sizes to a fixed-sized register, the address to which the integer must be - * copied is dependent on the size of the integer. + * Note that due to a quirk of the SSI's STX register, the target address + * for the DMA operations depends on the sample size. So we don't program + * the dest_addr (for playback -- source_addr for capture) fields in the + * link descriptors here. We do that in fsl_dma_prepare() + */ +static int fsl_dma_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct fsl_dma_private *dma_private = runtime->private_data; + + dma_addr_t temp_addr; /* Pointer to next period */ + + unsigned int i; + + /* Get all the parameters we need */ + size_t buffer_size = params_buffer_bytes(hw_params); + size_t period_size = params_period_bytes(hw_params); + + /* Initialize our DMA tracking variables */ + dma_private->period_size = period_size; + dma_private->num_periods = params_periods(hw_params); + dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size; + dma_private->dma_buf_next = dma_private->dma_buf_phys + + (NUM_DMA_LINKS * period_size); + if (dma_private->dma_buf_next >= dma_private->dma_buf_end) + dma_private->dma_buf_next = dma_private->dma_buf_phys; + + /* + * The actual address in STX0 (destination for playback, source for + * capture) is based on the sample size, but we don't know the sample + * size in this function, so we'll have to adjust that later. See + * comments in fsl_dma_prepare(). + * + * The DMA controller does not have a cache, so the CPU does not + * need to tell it to flush its cache. However, the DMA + * controller does need to tell the CPU to flush its cache. + * That's what the SNOOP bit does. + * + * Also, even though the DMA controller supports 36-bit addressing, for + * simplicity we currently support only 32-bit addresses for the audio + * buffer itself. + */ + temp_addr = substream->dma_buffer.addr; + + for (i = 0; i < NUM_DMA_LINKS; i++) { + struct fsl_dma_link_descriptor *link = &dma_private->link[i]; + + link->count = cpu_to_be32(period_size); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + link->source_addr = cpu_to_be32(temp_addr); + else + link->dest_addr = cpu_to_be32(temp_addr); + + temp_addr += period_size; + } + + return 0; +} + +/** + * fsl_dma_prepare - prepare the DMA registers for playback. + * + * This function is called after the specifics of the audio data are known, + * i.e. snd_pcm_runtime is initialized. + * + * In this function, we finish programming the registers of the DMA + * controller that are dependent on the sample size. + * + * One of the drawbacks with big-endian is that when copying integers of + * different sizes to a fixed-sized register, the address to which the + * integer must be copied is dependent on the size of the integer. * * For example, if P is the address of a 32-bit register, and X is a 32-bit * integer, then X should be copied to address P. However, if X is a 16-bit @@ -540,58 +613,22 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) * and 8 bytes at a time). So we do not support packed 24-bit samples. * 24-bit data must be padded to 32 bits. */ -static int fsl_dma_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) +static int fsl_dma_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_dma_private *dma_private = runtime->private_data; - - /* Number of bits per sample */ - unsigned int sample_size = - snd_pcm_format_physical_width(params_format(hw_params)); - - /* Number of bytes per frame */ - unsigned int frame_size = 2 * (sample_size / 8); - - /* Bus address of SSI STX register */ - dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys; - - /* Size of the DMA buffer, in bytes */ - size_t buffer_size = params_buffer_bytes(hw_params); - - /* Number of bytes per period */ - size_t period_size = params_period_bytes(hw_params); - - /* Pointer to next period */ - dma_addr_t temp_addr = substream->dma_buffer.addr; - - /* Pointer to DMA controller */ struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; - - u32 mr; /* DMA Mode Register */ - + u32 mr; unsigned int i; + dma_addr_t ssi_sxx_phys; /* Bus address of SSI STX register */ + unsigned int frame_size; /* Number of bytes per frame */ - /* Initialize our DMA tracking variables */ - dma_private->period_size = period_size; - dma_private->num_periods = params_periods(hw_params); - dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size; - dma_private->dma_buf_next = dma_private->dma_buf_phys + - (NUM_DMA_LINKS * period_size); - - if (dma_private->dma_buf_next >= dma_private->dma_buf_end) - /* This happens if the number of periods == NUM_DMA_LINKS */ - dma_private->dma_buf_next = dma_private->dma_buf_phys; + ssi_sxx_phys = dma_private->ssi_sxx_phys; mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK | CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK); - /* Due to a quirk of the SSI's STX register, the target address - * for the DMA operations depends on the sample size. So we calculate - * that offset here. While we're at it, also tell the DMA controller - * how much data to transfer per sample. - */ - switch (sample_size) { + switch (runtime->sample_bits) { case 8: mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1; ssi_sxx_phys += 3; @@ -604,12 +641,12 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4; break; default: - /* We should never get here */ dev_err(substream->pcm->card->dev, - "unsupported sample size %u\n", sample_size); + "unsupported sample size %u\n", runtime->sample_bits); return -EINVAL; } + frame_size = runtime->frame_bits / 8; /* * BWC should always be a multiple of the frame size. BWC determines * how many bytes are sent/received before the DMA controller checks the @@ -618,6 +655,7 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, * capture, the receive FIFO is triggered when it contains one frame, so * we want to receive one frame at a time. */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) mr |= CCSR_DMA_MR_BWC(2 * frame_size); else @@ -625,48 +663,16 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, out_be32(&dma_channel->mr, mr); + /* + * Program the address of the DMA transfer to/from the SSI. + */ for (i = 0; i < NUM_DMA_LINKS; i++) { struct fsl_dma_link_descriptor *link = &dma_private->link[i]; - link->count = cpu_to_be32(period_size); - - /* Even though the DMA controller supports 36-bit addressing, - * for simplicity we allow only 32-bit addresses for the audio - * buffer itself. This was enforced in fsl_dma_new() with the - * DMA mask. - * - * The snoop bit tells the DMA controller whether it should tell - * the ECM to snoop during a read or write to an address. For - * audio, we use DMA to transfer data between memory and an I/O - * device (the SSI's STX0 or SRX0 register). Snooping is only - * needed if there is a cache, so we need to snoop memory - * addresses only. For playback, that means we snoop the source - * but not the destination. For capture, we snoop the - * destination but not the source. - * - * Note that failing to snoop properly is unlikely to cause - * cache incoherency if the period size is larger than the - * size of L1 cache. This is because filling in one period will - * flush out the data for the previous period. So if you - * increased period_bytes_min to a large enough size, you might - * get more performance by not snooping, and you'll still be - * okay. - */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - link->source_addr = cpu_to_be32(temp_addr); - link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); - + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) link->dest_addr = cpu_to_be32(ssi_sxx_phys); - link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP); - } else { + else link->source_addr = cpu_to_be32(ssi_sxx_phys); - link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP); - - link->dest_addr = cpu_to_be32(temp_addr); - link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); - } - - temp_addr += period_size; } return 0; @@ -802,6 +808,7 @@ static struct snd_pcm_ops fsl_dma_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = fsl_dma_hw_params, .hw_free = fsl_dma_hw_free, + .prepare = fsl_dma_prepare, .pointer = fsl_dma_pointer, }; diff --git a/trunk/sound/soc/fsl/fsl_ssi.c b/trunk/sound/soc/fsl/fsl_ssi.c index 169bca295b78..c6d6eb71dc1d 100644 --- a/trunk/sound/soc/fsl/fsl_ssi.c +++ b/trunk/sound/soc/fsl/fsl_ssi.c @@ -72,7 +72,6 @@ * @dev: struct device pointer * @playback: the number of playback streams opened * @capture: the number of capture streams opened - * @asynchronous: 0=synchronous mode, 1=asynchronous mode * @cpu_dai: the CPU DAI for this device * @dev_attr: the sysfs device attribute structure * @stats: SSI statistics @@ -87,7 +86,6 @@ struct fsl_ssi_private { struct device *dev; unsigned int playback; unsigned int capture; - int asynchronous; struct snd_soc_dai cpu_dai; struct device_attribute dev_attr; @@ -303,10 +301,9 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, * * FIXME: Little-endian samples require a different shift dir */ - clrsetbits_be32(&ssi->scr, - CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, - CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE - | (ssi_private->asynchronous ? 0 : CCSR_SSI_SCR_SYN)); + clrsetbits_be32(&ssi->scr, CCSR_SSI_SCR_I2S_MODE_MASK, + CCSR_SSI_SCR_TFR_CLK_DIS | + CCSR_SSI_SCR_I2S_MODE_SLAVE | CCSR_SSI_SCR_SYN); out_be32(&ssi->stcr, CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | @@ -385,15 +382,10 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, SNDRV_PCM_HW_PARAM_RATE, first_runtime->rate, first_runtime->rate); - /* If we're in synchronous mode, then we need to constrain - * the sample size as well. We don't support independent sample - * rates in asynchronous mode. - */ - if (!ssi_private->asynchronous) - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - first_runtime->sample_bits, - first_runtime->sample_bits); + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + first_runtime->sample_bits, + first_runtime->sample_bits); ssi_private->second_stream = substream; } @@ -408,7 +400,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, } /** - * fsl_ssi_hw_params - program the sample size + * fsl_ssi_prepare: prepare the SSI. * * Most of the SSI registers have been programmed in the startup function, * but the word length must be programmed here. Unfortunately, programming @@ -420,27 +412,23 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the * clock master. */ -static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) +static int fsl_ssi_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) { - struct fsl_ssi_private *ssi_private = cpu_dai->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; + + struct ccsr_ssi __iomem *ssi = ssi_private->ssi; if (substream == ssi_private->first_stream) { - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - unsigned int sample_size = - snd_pcm_format_width(params_format(hw_params)); - u32 wl = CCSR_SSI_SxCCR_WL(sample_size); + u32 wl; /* The SSI should always be disabled at this points (SSIEN=0) */ + wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); /* In synchronous mode, the SSI uses STCCR for capture */ - if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || - !ssi_private->asynchronous) - clrsetbits_be32(&ssi->stccr, - CCSR_SSI_SxCCR_WL_MASK, wl); - else - clrsetbits_be32(&ssi->srccr, - CCSR_SSI_SxCCR_WL_MASK, wl); + clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); } return 0; @@ -464,33 +452,28 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); setbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); } else { - long timeout = jiffies + 10; - + clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); setbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); - /* Wait until the SSI has filled its FIFO. Without this - * delay, ALSA complains about overruns. When the FIFO - * is full, the DMA controller initiates its first - * transfer. Until then, however, the DMA's DAR - * register is zero, which translates to an - * out-of-bounds pointer. This makes ALSA think an - * overrun has occurred. + /* + * I think we need this delay to allow time for the SSI + * to put data into its FIFO. Without it, ALSA starts + * to complain about overruns. */ - while (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0) && - (jiffies < timeout)); - if (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0)) - return -EIO; + mdelay(1); } break; case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) clrbits32(&ssi->scr, CCSR_SSI_SCR_TE); @@ -580,15 +563,6 @@ static int fsl_ssi_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format) /** * fsl_ssi_dai_template: template CPU DAI for the SSI */ -static struct snd_soc_dai_ops fsl_ssi_dai_ops = { - .startup = fsl_ssi_startup, - .hw_params = fsl_ssi_hw_params, - .shutdown = fsl_ssi_shutdown, - .trigger = fsl_ssi_trigger, - .set_sysclk = fsl_ssi_set_sysclk, - .set_fmt = fsl_ssi_set_fmt, -}; - static struct snd_soc_dai fsl_ssi_dai_template = { .playback = { /* The SSI does not support monaural audio. */ @@ -603,7 +577,14 @@ static struct snd_soc_dai fsl_ssi_dai_template = { .rates = FSLSSI_I2S_RATES, .formats = FSLSSI_I2S_FORMATS, }, - .ops = &fsl_ssi_dai_ops, + .ops = { + .startup = fsl_ssi_startup, + .prepare = fsl_ssi_prepare, + .shutdown = fsl_ssi_shutdown, + .trigger = fsl_ssi_trigger, + .set_sysclk = fsl_ssi_set_sysclk, + .set_fmt = fsl_ssi_set_fmt, + }, }; /** @@ -673,7 +654,6 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) ssi_private->ssi_phys = ssi_info->ssi_phys; ssi_private->irq = ssi_info->irq; ssi_private->dev = ssi_info->dev; - ssi_private->asynchronous = ssi_info->asynchronous; ssi_private->dev->driver_data = fsl_ssi_dai; @@ -724,14 +704,6 @@ void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai) } EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai); -static int __init fsl_ssi_init(void) -{ - printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n"); - - return 0; -} -module_init(fsl_ssi_init); - MODULE_AUTHOR("Timur Tabi "); MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/fsl/fsl_ssi.h b/trunk/sound/soc/fsl/fsl_ssi.h index eade01feaab6..83b44d700e33 100644 --- a/trunk/sound/soc/fsl/fsl_ssi.h +++ b/trunk/sound/soc/fsl/fsl_ssi.h @@ -208,7 +208,6 @@ struct ccsr_ssi { * ssi_phys: physical address of the SSI registers * irq: IRQ of this SSI * dev: struct device, used to create the sysfs statistics file - * asynchronous: 0=synchronous mode, 1=asynchronous mode */ struct fsl_ssi_info { unsigned int id; @@ -216,7 +215,6 @@ struct fsl_ssi_info { dma_addr_t ssi_phys; unsigned int irq; struct device *dev; - int asynchronous; }; struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info); diff --git a/trunk/sound/soc/fsl/mpc5200_psc_i2s.c b/trunk/sound/soc/fsl/mpc5200_psc_i2s.c index 3aa729df27b5..9eb1ce185bd0 100644 --- a/trunk/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/trunk/sound/soc/fsl/mpc5200_psc_i2s.c @@ -468,16 +468,6 @@ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format) /** * psc_i2s_dai_template: template CPU Digital Audio Interface */ -static struct snd_soc_dai_ops psc_i2s_dai_ops = { - .startup = psc_i2s_startup, - .hw_params = psc_i2s_hw_params, - .hw_free = psc_i2s_hw_free, - .shutdown = psc_i2s_shutdown, - .trigger = psc_i2s_trigger, - .set_sysclk = psc_i2s_set_sysclk, - .set_fmt = psc_i2s_set_fmt, -}; - static struct snd_soc_dai psc_i2s_dai_template = { .playback = { .channels_min = 2, @@ -491,7 +481,15 @@ static struct snd_soc_dai psc_i2s_dai_template = { .rates = PSC_I2S_RATES, .formats = PSC_I2S_FORMATS, }, - .ops = &psc_i2s_dai_ops, + .ops = { + .startup = psc_i2s_startup, + .hw_params = psc_i2s_hw_params, + .hw_free = psc_i2s_hw_free, + .shutdown = psc_i2s_shutdown, + .trigger = psc_i2s_trigger, + .set_sysclk = psc_i2s_set_sysclk, + .set_fmt = psc_i2s_set_fmt, + }, }; /* --------------------------------------------------------------------- diff --git a/trunk/sound/soc/fsl/mpc8610_hpcd.c b/trunk/sound/soc/fsl/mpc8610_hpcd.c index ef67d1cdffe7..acf39a646b2f 100644 --- a/trunk/sound/soc/fsl/mpc8610_hpcd.c +++ b/trunk/sound/soc/fsl/mpc8610_hpcd.c @@ -353,11 +353,6 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev, } ssi_info.irq = machine_data->ssi_irq; - /* Do we want to use asynchronous mode? */ - ssi_info.asynchronous = - of_find_property(np, "fsl,ssi-asynchronous", NULL) ? 1 : 0; - if (ssi_info.asynchronous) - dev_info(&ofdev->dev, "using asynchronous mode\n"); /* Map the global utilities registers. */ guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts"); diff --git a/trunk/sound/soc/omap/Kconfig b/trunk/sound/soc/omap/Kconfig index 675732e724d5..4f7f04014585 100644 --- a/trunk/sound/soc/omap/Kconfig +++ b/trunk/sound/soc/omap/Kconfig @@ -8,7 +8,7 @@ config SND_OMAP_SOC_MCBSP config SND_OMAP_SOC_N810 tristate "SoC Audio support for Nokia N810" - depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C + depends on SND_OMAP_SOC && MACH_NOKIA_N810 select SND_OMAP_SOC_MCBSP select OMAP_MUX select SND_SOC_TLV320AIC3X @@ -17,7 +17,7 @@ config SND_OMAP_SOC_N810 config SND_OMAP_SOC_OSK5912 tristate "SoC Audio support for omap osk5912" - depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C + depends on SND_OMAP_SOC && MACH_OMAP_OSK select SND_OMAP_SOC_MCBSP select SND_SOC_TLV320AIC23 help @@ -55,13 +55,3 @@ config SND_OMAP_SOC_OMAP3_PANDORA select SND_SOC_TWL4030 help Say Y if you want to add support for SoC audio on the OMAP3 Pandora. - -config SND_OMAP_SOC_OMAP3_BEAGLE - tristate "SoC Audio support for OMAP3 Beagle" - depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE - select SND_OMAP_SOC_MCBSP - select SND_SOC_TWL4030 - help - Say Y if you want to add support for SoC audio on the Beagleboard. - - diff --git a/trunk/sound/soc/omap/Makefile b/trunk/sound/soc/omap/Makefile index 0c9e4ac37660..76fedd96e365 100644 --- a/trunk/sound/soc/omap/Makefile +++ b/trunk/sound/soc/omap/Makefile @@ -12,7 +12,6 @@ snd-soc-overo-objs := overo.o snd-soc-omap2evm-objs := omap2evm.o snd-soc-sdp3430-objs := sdp3430.o snd-soc-omap3pandora-objs := omap3pandora.o -snd-soc-omap3beagle-objs := omap3beagle.o obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o @@ -20,4 +19,3 @@ obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o -obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o diff --git a/trunk/sound/soc/omap/n810.c b/trunk/sound/soc/omap/n810.c index a6d1178ce128..25593fee9121 100644 --- a/trunk/sound/soc/omap/n810.c +++ b/trunk/sound/soc/omap/n810.c @@ -40,13 +40,6 @@ #define N810_HEADSET_AMP_GPIO 10 #define N810_SPEAKER_AMP_GPIO 101 -enum { - N810_JACK_DISABLED, - N810_JACK_HP, - N810_JACK_HS, - N810_JACK_MIC, -}; - static struct clk *sys_clkout2; static struct clk *sys_clkout2_src; static struct clk *func96m_clk; @@ -57,32 +50,15 @@ static int n810_dmic_func; static void n810_ext_control(struct snd_soc_codec *codec) { - int hp = 0, line1l = 0; - - switch (n810_jack_func) { - case N810_JACK_HS: - line1l = 1; - case N810_JACK_HP: - hp = 1; - break; - case N810_JACK_MIC: - line1l = 1; - break; - } - if (n810_spk_func) snd_soc_dapm_enable_pin(codec, "Ext Spk"); else snd_soc_dapm_disable_pin(codec, "Ext Spk"); - if (hp) + if (n810_jack_func) snd_soc_dapm_enable_pin(codec, "Headphone Jack"); else snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - if (line1l) - snd_soc_dapm_enable_pin(codec, "LINE1L"); - else - snd_soc_dapm_disable_pin(codec, "LINE1L"); if (n810_dmic_func) snd_soc_dapm_enable_pin(codec, "DMic"); @@ -96,7 +72,7 @@ static int n810_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); @@ -253,7 +229,7 @@ static const struct snd_soc_dapm_route audio_map[] = { }; static const char *spk_function[] = {"Off", "On"}; -static const char *jack_function[] = {"Off", "Headphone", "Headset", "Mic"}; +static const char *jack_function[] = {"Off", "Headphone"}; static const char *input_function[] = {"ADC", "Digital Mic"}; static const struct soc_enum n810_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), @@ -272,23 +248,20 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = { static int n810_aic33_init(struct snd_soc_codec *codec) { - int err; + int i, err; /* Not connected */ snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); snd_soc_dapm_nc_pin(codec, "HPLCOM"); snd_soc_dapm_nc_pin(codec, "HPRCOM"); - snd_soc_dapm_nc_pin(codec, "MIC3L"); - snd_soc_dapm_nc_pin(codec, "MIC3R"); - snd_soc_dapm_nc_pin(codec, "LINE1R"); - snd_soc_dapm_nc_pin(codec, "LINE2L"); - snd_soc_dapm_nc_pin(codec, "LINE2R"); /* Add N810 specific controls */ - err = snd_soc_add_controls(codec, aic33_n810_controls, - ARRAY_SIZE(aic33_n810_controls)); - if (err < 0) - return err; + for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&aic33_n810_controls[i], codec, NULL)); + if (err < 0) + return err; + } /* Add N810 specific widgets */ snd_soc_dapm_new_controls(codec, aic33_dapm_widgets, diff --git a/trunk/sound/soc/omap/omap-mcbsp.c b/trunk/sound/soc/omap/omap-mcbsp.c index d6882be33452..05dd5abcddf4 100644 --- a/trunk/sound/soc/omap/omap-mcbsp.c +++ b/trunk/sound/soc/omap/omap-mcbsp.c @@ -461,16 +461,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, return err; } -static struct snd_soc_dai_ops omap_mcbsp_dai_ops = { - .startup = omap_mcbsp_dai_startup, - .shutdown = omap_mcbsp_dai_shutdown, - .trigger = omap_mcbsp_dai_trigger, - .hw_params = omap_mcbsp_dai_hw_params, - .set_fmt = omap_mcbsp_dai_set_dai_fmt, - .set_clkdiv = omap_mcbsp_dai_set_clkdiv, - .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, -}; - #define OMAP_MCBSP_DAI_BUILDER(link_id) \ { \ .name = "omap-mcbsp-dai-"#link_id, \ @@ -487,7 +477,15 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = { .rates = OMAP_MCBSP_RATES, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ - .ops = &omap_mcbsp_dai_ops, \ + .ops = { \ + .startup = omap_mcbsp_dai_startup, \ + .shutdown = omap_mcbsp_dai_shutdown, \ + .trigger = omap_mcbsp_dai_trigger, \ + .hw_params = omap_mcbsp_dai_hw_params, \ + .set_fmt = omap_mcbsp_dai_set_dai_fmt, \ + .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \ + .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \ + }, \ .private_data = &mcbsp_data[(link_id)].bus_id, \ } diff --git a/trunk/sound/soc/omap/omap-pcm.c b/trunk/sound/soc/omap/omap-pcm.c index 8e1431cb46bb..dd3bb2933762 100644 --- a/trunk/sound/soc/omap/omap-pcm.c +++ b/trunk/sound/soc/omap/omap-pcm.c @@ -265,7 +265,7 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream, runtime->dma_bytes); } -static struct snd_pcm_ops omap_pcm_ops = { +struct snd_pcm_ops omap_pcm_ops = { .open = omap_pcm_open, .close = omap_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/trunk/sound/soc/omap/omap3pandora.c b/trunk/sound/soc/omap/omap3pandora.c index fe282d4ef422..fcc2f5d9a878 100644 --- a/trunk/sound/soc/omap/omap3pandora.c +++ b/trunk/sound/soc/omap/omap3pandora.c @@ -143,7 +143,7 @@ static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { }; static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = { - SND_SOC_DAPM_MIC("Mic (internal)", NULL), + SND_SOC_DAPM_MIC("Mic (Internal)", NULL), SND_SOC_DAPM_MIC("Mic (external)", NULL), SND_SOC_DAPM_LINE("Line In", NULL), }; @@ -155,33 +155,16 @@ static const struct snd_soc_dapm_route omap3pandora_out_map[] = { }; static const struct snd_soc_dapm_route omap3pandora_in_map[] = { - {"AUXL", NULL, "Line In"}, - {"AUXR", NULL, "Line In"}, - - {"MAINMIC", NULL, "Mic Bias 1"}, - {"Mic Bias 1", NULL, "Mic (internal)"}, - - {"SUBMIC", NULL, "Mic Bias 2"}, - {"Mic Bias 2", NULL, "Mic (external)"}, + {"INL", NULL, "Line In"}, + {"INR", NULL, "Line In"}, + {"INL", NULL, "Mic (Internal)"}, + {"INR", NULL, "Mic (external)"}, }; static int omap3pandora_out_init(struct snd_soc_codec *codec) { int ret; - /* All TWL4030 output pins are floating */ - snd_soc_dapm_nc_pin(codec, "OUTL"); - snd_soc_dapm_nc_pin(codec, "OUTR"); - snd_soc_dapm_nc_pin(codec, "EARPIECE"); - snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); - snd_soc_dapm_nc_pin(codec, "PREDRIVER"); - snd_soc_dapm_nc_pin(codec, "HSOL"); - snd_soc_dapm_nc_pin(codec, "HSOR"); - snd_soc_dapm_nc_pin(codec, "CARKITL"); - snd_soc_dapm_nc_pin(codec, "CARKITR"); - snd_soc_dapm_nc_pin(codec, "HFL"); - snd_soc_dapm_nc_pin(codec, "HFR"); - ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, ARRAY_SIZE(omap3pandora_out_dapm_widgets)); if (ret < 0) @@ -197,11 +180,18 @@ static int omap3pandora_in_init(struct snd_soc_codec *codec) { int ret; - /* Not comnnected */ - snd_soc_dapm_nc_pin(codec, "HSMIC"); - snd_soc_dapm_nc_pin(codec, "CARKITMIC"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); + /* All TWL4030 output pins are floating */ + snd_soc_dapm_nc_pin(codec, "OUTL"), + snd_soc_dapm_nc_pin(codec, "OUTR"), + snd_soc_dapm_nc_pin(codec, "EARPIECE"), + snd_soc_dapm_nc_pin(codec, "PREDRIVEL"), + snd_soc_dapm_nc_pin(codec, "PREDRIVER"), + snd_soc_dapm_nc_pin(codec, "HSOL"), + snd_soc_dapm_nc_pin(codec, "HSOR"), + snd_soc_dapm_nc_pin(codec, "CARKITL"), + snd_soc_dapm_nc_pin(codec, "CARKITR"), + snd_soc_dapm_nc_pin(codec, "HFL"), + snd_soc_dapm_nc_pin(codec, "HFR"), ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets, ARRAY_SIZE(omap3pandora_in_dapm_widgets)); @@ -261,9 +251,10 @@ static int __init omap3pandora_soc_init(void) { int ret; - if (!machine_is_omap3_pandora()) + if (!machine_is_omap3_pandora()) { + pr_debug(PREFIX "Not OMAP3 Pandora\n"); return -ENODEV; - + } pr_info("OMAP3 Pandora SoC init\n"); ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power"); diff --git a/trunk/sound/soc/omap/osk5912.c b/trunk/sound/soc/omap/osk5912.c index a952a4eb3361..cd41a948df7b 100644 --- a/trunk/sound/soc/omap/osk5912.c +++ b/trunk/sound/soc/omap/osk5912.c @@ -186,6 +186,13 @@ static int __init osk_soc_init(void) return -ENODEV; } + if (clk_get_usecount(tlv320aic23_mclk) > 0) { + /* MCLK is already in use */ + printk(KERN_WARNING + "MCLK in use at %d Hz. We change it to %d Hz\n", + (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK); + } + /* * Configure 12 MHz output on MCLK. */ @@ -198,8 +205,9 @@ static int __init osk_soc_init(void) } } - printk(KERN_INFO "MCLK = %d [%d]\n", - (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK); + printk(KERN_INFO "MCLK = %d [%d], usecount = %d\n", + (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK, + clk_get_usecount(tlv320aic23_mclk)); return 0; err1: diff --git a/trunk/sound/soc/omap/sdp3430.c b/trunk/sound/soc/omap/sdp3430.c index 10f1c867f11d..e226fa75669c 100644 --- a/trunk/sound/soc/omap/sdp3430.c +++ b/trunk/sound/soc/omap/sdp3430.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -39,8 +38,6 @@ #include "omap-pcm.h" #include "../codecs/twl4030.h" -static struct snd_soc_card snd_soc_sdp3430; - static int sdp3430_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -84,121 +81,12 @@ static struct snd_soc_ops sdp3430_ops = { .hw_params = sdp3430_hw_params, }; -/* Headset jack */ -static struct snd_soc_jack hs_jack; - -/* Headset jack detection DAPM pins */ -static struct snd_soc_jack_pin hs_jack_pins[] = { - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, - { - .pin = "Headset Stereophone", - .mask = SND_JACK_HEADPHONE, - }, -}; - -/* Headset jack detection gpios */ -static struct snd_soc_jack_gpio hs_jack_gpios[] = { - { - .gpio = (OMAP_MAX_GPIO_LINES + 2), - .name = "hsdet-gpio", - .report = SND_JACK_HEADSET, - .debounce_time = 200, - }, -}; - -/* SDP3430 machine DAPM */ -static const struct snd_soc_dapm_widget sdp3430_twl4030_dapm_widgets[] = { - SND_SOC_DAPM_MIC("Ext Mic", NULL), - SND_SOC_DAPM_SPK("Ext Spk", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_HP("Headset Stereophone", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* External Mics: MAINMIC, SUBMIC with bias*/ - {"MAINMIC", NULL, "Mic Bias 1"}, - {"SUBMIC", NULL, "Mic Bias 2"}, - {"Mic Bias 1", NULL, "Ext Mic"}, - {"Mic Bias 2", NULL, "Ext Mic"}, - - /* External Speakers: HFL, HFR */ - {"Ext Spk", NULL, "HFL"}, - {"Ext Spk", NULL, "HFR"}, - - /* Headset Mic: HSMIC with bias */ - {"HSMIC", NULL, "Headset Mic Bias"}, - {"Headset Mic Bias", NULL, "Headset Mic"}, - - /* Headset Stereophone (Headphone): HSOL, HSOR */ - {"Headset Stereophone", NULL, "HSOL"}, - {"Headset Stereophone", NULL, "HSOR"}, -}; - -static int sdp3430_twl4030_init(struct snd_soc_codec *codec) -{ - int ret; - - /* Add SDP3430 specific widgets */ - ret = snd_soc_dapm_new_controls(codec, sdp3430_twl4030_dapm_widgets, - ARRAY_SIZE(sdp3430_twl4030_dapm_widgets)); - if (ret) - return ret; - - /* Set up SDP3430 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - - /* SDP3430 connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); - - /* TWL4030 not connected pins */ - snd_soc_dapm_nc_pin(codec, "AUXL"); - snd_soc_dapm_nc_pin(codec, "AUXR"); - snd_soc_dapm_nc_pin(codec, "CARKITMIC"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); - - snd_soc_dapm_nc_pin(codec, "OUTL"); - snd_soc_dapm_nc_pin(codec, "OUTR"); - snd_soc_dapm_nc_pin(codec, "EARPIECE"); - snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); - snd_soc_dapm_nc_pin(codec, "PREDRIVER"); - snd_soc_dapm_nc_pin(codec, "CARKITL"); - snd_soc_dapm_nc_pin(codec, "CARKITR"); - - ret = snd_soc_dapm_sync(codec); - if (ret) - return ret; - - /* Headset jack detection */ - ret = snd_soc_jack_new(&snd_soc_sdp3430, "Headset Jack", - SND_JACK_HEADSET, &hs_jack); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); - if (ret) - return ret; - - ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - - return ret; -} - /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link sdp3430_dai = { .name = "TWL4030", .stream_name = "TWL4030", .cpu_dai = &omap_mcbsp_dai[0], .codec_dai = &twl4030_dai, - .init = sdp3430_twl4030_init, .ops = &sdp3430_ops, }; @@ -254,9 +142,6 @@ module_init(sdp3430_soc_init); static void __exit sdp3430_soc_exit(void) { - snd_soc_jack_free_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - platform_device_unregister(sdp3430_snd_device); } module_exit(sdp3430_soc_exit); diff --git a/trunk/sound/soc/pxa/Kconfig b/trunk/sound/soc/pxa/Kconfig index 5998ab366e83..f82e10699471 100644 --- a/trunk/sound/soc/pxa/Kconfig +++ b/trunk/sound/soc/pxa/Kconfig @@ -61,24 +61,6 @@ config SND_PXA2XX_SOC_TOSA Say Y if you want to add support for SoC audio on Sharp Zaurus SL-C6000x models (Tosa). -config SND_PXA2XX_SOC_E740 - tristate "SoC AC97 Audio support for e740" - depends on SND_PXA2XX_SOC && MACH_E740 - select SND_SOC_WM9705 - select SND_PXA2XX_SOC_AC97 - help - Say Y if you want to add support for SoC audio on the - toshiba e740 PDA - -config SND_PXA2XX_SOC_E750 - tristate "SoC AC97 Audio support for e750" - depends on SND_PXA2XX_SOC && MACH_E750 - select SND_SOC_WM9705 - select SND_PXA2XX_SOC_AC97 - help - Say Y if you want to add support for SoC audio on the - toshiba e750 PDA - config SND_PXA2XX_SOC_E800 tristate "SoC AC97 Audio support for e800" depends on SND_PXA2XX_SOC && MACH_E800 @@ -115,12 +97,3 @@ config SND_SOC_ZYLONITE help Say Y if you want to add support for SoC audio on the Marvell Zylonite reference platform. - -config SND_PXA2XX_SOC_MIOA701 - tristate "SoC Audio support for MIO A701" - depends on SND_PXA2XX_SOC && MACH_MIOA701 - select SND_PXA2XX_SOC_AC97 - select SND_SOC_WM9713 - help - Say Y if you want to add support for SoC audio on the - MIO A701. diff --git a/trunk/sound/soc/pxa/Makefile b/trunk/sound/soc/pxa/Makefile index 8ed881c5e5cc..08a9f2797729 100644 --- a/trunk/sound/soc/pxa/Makefile +++ b/trunk/sound/soc/pxa/Makefile @@ -13,23 +13,17 @@ obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o snd-soc-corgi-objs := corgi.o snd-soc-poodle-objs := poodle.o snd-soc-tosa-objs := tosa.o -snd-soc-e740-objs := e740_wm9705.o -snd-soc-e750-objs := e750_wm9705.o snd-soc-e800-objs := e800_wm9712.o snd-soc-spitz-objs := spitz.o snd-soc-em-x270-objs := em-x270.o snd-soc-palm27x-objs := palm27x.o snd-soc-zylonite-objs := zylonite.o -snd-soc-mioa701-objs := mioa701_wm9713.o obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o -obj-$(CONFIG_SND_PXA2XX_SOC_E740) += snd-soc-e740.o -obj-$(CONFIG_SND_PXA2XX_SOC_E750) += snd-soc-e750.o obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o -obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o diff --git a/trunk/sound/soc/pxa/corgi.c b/trunk/sound/soc/pxa/corgi.c index 02263e5d8f03..1ba25a559524 100644 --- a/trunk/sound/soc/pxa/corgi.c +++ b/trunk/sound/soc/pxa/corgi.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -101,7 +100,7 @@ static void corgi_ext_control(struct snd_soc_codec *codec) static int corgi_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ corgi_ext_control(codec); @@ -276,16 +275,18 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = { */ static int corgi_wm8731_init(struct snd_soc_codec *codec) { - int err; + int i, err; snd_soc_dapm_nc_pin(codec, "LLINEIN"); snd_soc_dapm_nc_pin(codec, "RLINEIN"); /* Add corgi specific controls */ - err = snd_soc_add_controls(codec, wm8731_corgi_controls, - ARRAY_SIZE(wm8731_corgi_controls)); - if (err < 0) - return err; + for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8731_corgi_controls[i], codec, NULL)); + if (err < 0) + return err; + } /* Add corgi specific widgets */ snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, @@ -316,44 +317,19 @@ static struct snd_soc_card snd_soc_corgi = { .num_links = 1, }; +/* corgi audio private data */ +static struct wm8731_setup_data corgi_wm8731_setup = { + .i2c_bus = 0, + .i2c_address = 0x1b, +}; + /* corgi audio subsystem */ static struct snd_soc_device corgi_snd_devdata = { .card = &snd_soc_corgi, .codec_dev = &soc_codec_dev_wm8731, + .codec_data = &corgi_wm8731_setup, }; -/* - * FIXME: This is a temporary bodge to avoid cross-tree merge issues. - * New drivers should register the wm8731 I2C device in the machine - * setup code (under arch/arm for ARM systems). - */ -static int wm8731_i2c_register(void) -{ - struct i2c_board_info info; - struct i2c_adapter *adapter; - struct i2c_client *client; - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = 0x1b; - strlcpy(info.type, "wm8731", I2C_NAME_SIZE); - - adapter = i2c_get_adapter(0); - if (!adapter) { - printk(KERN_ERR "can't get i2c adapter 0\n"); - return -ENODEV; - } - - client = i2c_new_device(adapter, &info); - i2c_put_adapter(adapter); - if (!client) { - printk(KERN_ERR "can't add i2c device at 0x%x\n", - (unsigned int)info.addr); - return -ENODEV; - } - - return 0; -} - static struct platform_device *corgi_snd_device; static int __init corgi_init(void) @@ -364,10 +340,6 @@ static int __init corgi_init(void) machine_is_husky())) return -ENODEV; - ret = wm8731_i2c_register(); - if (ret != 0) - return ret; - corgi_snd_device = platform_device_alloc("soc-audio", -1); if (!corgi_snd_device) return -ENOMEM; diff --git a/trunk/sound/soc/pxa/e740_wm9705.c b/trunk/sound/soc/pxa/e740_wm9705.c deleted file mode 100644 index 7cd2f89d7b10..000000000000 --- a/trunk/sound/soc/pxa/e740_wm9705.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * e740-wm9705.c -- SoC audio for e740 - * - * Copyright 2007 (c) Ian Molton - * - * 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; version 2 ONLY. - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include "../codecs/wm9705.h" -#include "pxa2xx-pcm.h" -#include "pxa2xx-ac97.h" - - -#define E740_AUDIO_OUT 1 -#define E740_AUDIO_IN 2 - -static int e740_audio_power; - -static void e740_sync_audio_power(int status) -{ - gpio_set_value(GPIO_E740_WM9705_nAVDD2, !status); - gpio_set_value(GPIO_E740_AMP_ON, (status & E740_AUDIO_OUT) ? 1 : 0); - gpio_set_value(GPIO_E740_MIC_ON, (status & E740_AUDIO_IN) ? 1 : 0); -} - -static int e740_mic_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - e740_audio_power |= E740_AUDIO_IN; - else if (event & SND_SOC_DAPM_POST_PMD) - e740_audio_power &= ~E740_AUDIO_IN; - - e740_sync_audio_power(e740_audio_power); - - return 0; -} - -static int e740_output_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - e740_audio_power |= E740_AUDIO_OUT; - else if (event & SND_SOC_DAPM_POST_PMD) - e740_audio_power &= ~E740_AUDIO_OUT; - - e740_sync_audio_power(e740_audio_power); - - return 0; -} - -static const struct snd_soc_dapm_widget e740_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_MIC("Mic (Internal)", NULL), - SND_SOC_DAPM_PGA_E("Output Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e740_output_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("Mic Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e740_mic_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Output Amp", NULL, "LOUT"}, - {"Output Amp", NULL, "ROUT"}, - {"Output Amp", NULL, "MONOOUT"}, - - {"Speaker", NULL, "Output Amp"}, - {"Headphone Jack", NULL, "Output Amp"}, - - {"MIC1", NULL, "Mic Amp"}, - {"Mic Amp", NULL, "Mic (Internal)"}, -}; - -static int e740_ac97_init(struct snd_soc_codec *codec) -{ - snd_soc_dapm_nc_pin(codec, "HPOUTL"); - snd_soc_dapm_nc_pin(codec, "HPOUTR"); - snd_soc_dapm_nc_pin(codec, "PHONE"); - snd_soc_dapm_nc_pin(codec, "LINEINL"); - snd_soc_dapm_nc_pin(codec, "LINEINR"); - snd_soc_dapm_nc_pin(codec, "CDINL"); - snd_soc_dapm_nc_pin(codec, "CDINR"); - snd_soc_dapm_nc_pin(codec, "PCBEEP"); - snd_soc_dapm_nc_pin(codec, "MIC2"); - - snd_soc_dapm_new_controls(codec, e740_dapm_widgets, - ARRAY_SIZE(e740_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - - snd_soc_dapm_sync(codec); - - return 0; -} - -static struct snd_soc_dai_link e740_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], - .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI], - .init = e740_ac97_init, - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], - .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX], - }, -}; - -static struct snd_soc_card e740 = { - .name = "Toshiba e740", - .platform = &pxa2xx_soc_platform, - .dai_link = e740_dai, - .num_links = ARRAY_SIZE(e740_dai), -}; - -static struct snd_soc_device e740_snd_devdata = { - .card = &e740, - .codec_dev = &soc_codec_dev_wm9705, -}; - -static struct platform_device *e740_snd_device; - -static int __init e740_init(void) -{ - int ret; - - if (!machine_is_e740()) - return -ENODEV; - - ret = gpio_request(GPIO_E740_MIC_ON, "Mic amp"); - if (ret) - return ret; - - ret = gpio_request(GPIO_E740_AMP_ON, "Output amp"); - if (ret) - goto free_mic_amp_gpio; - - ret = gpio_request(GPIO_E740_WM9705_nAVDD2, "Audio power"); - if (ret) - goto free_op_amp_gpio; - - /* Disable audio */ - ret = gpio_direction_output(GPIO_E740_MIC_ON, 0); - if (ret) - goto free_apwr_gpio; - ret = gpio_direction_output(GPIO_E740_AMP_ON, 0); - if (ret) - goto free_apwr_gpio; - ret = gpio_direction_output(GPIO_E740_WM9705_nAVDD2, 1); - if (ret) - goto free_apwr_gpio; - - e740_snd_device = platform_device_alloc("soc-audio", -1); - if (!e740_snd_device) { - ret = -ENOMEM; - goto free_apwr_gpio; - } - - platform_set_drvdata(e740_snd_device, &e740_snd_devdata); - e740_snd_devdata.dev = &e740_snd_device->dev; - ret = platform_device_add(e740_snd_device); - - if (!ret) - return 0; - -/* Fail gracefully */ - platform_device_put(e740_snd_device); -free_apwr_gpio: - gpio_free(GPIO_E740_WM9705_nAVDD2); -free_op_amp_gpio: - gpio_free(GPIO_E740_AMP_ON); -free_mic_amp_gpio: - gpio_free(GPIO_E740_MIC_ON); - - return ret; -} - -static void __exit e740_exit(void) -{ - platform_device_unregister(e740_snd_device); -} - -module_init(e740_init); -module_exit(e740_exit); - -/* Module information */ -MODULE_AUTHOR("Ian Molton "); -MODULE_DESCRIPTION("ALSA SoC driver for e740"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/sound/soc/pxa/e750_wm9705.c b/trunk/sound/soc/pxa/e750_wm9705.c deleted file mode 100644 index 8dceccc5e059..000000000000 --- a/trunk/sound/soc/pxa/e750_wm9705.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * e750-wm9705.c -- SoC audio for e750 - * - * Copyright 2007 (c) Ian Molton - * - * 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; version 2 ONLY. - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include "../codecs/wm9705.h" -#include "pxa2xx-pcm.h" -#include "pxa2xx-ac97.h" - -static int e750_spk_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - gpio_set_value(GPIO_E750_SPK_AMP_OFF, 0); - else if (event & SND_SOC_DAPM_POST_PMD) - gpio_set_value(GPIO_E750_SPK_AMP_OFF, 1); - - return 0; -} - -static int e750_hp_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - gpio_set_value(GPIO_E750_HP_AMP_OFF, 0); - else if (event & SND_SOC_DAPM_POST_PMD) - gpio_set_value(GPIO_E750_HP_AMP_OFF, 1); - - return 0; -} - -static const struct snd_soc_dapm_widget e750_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_MIC("Mic (Internal)", NULL), - SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e750_hp_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e750_spk_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Headphone Amp", NULL, "HPOUTL"}, - {"Headphone Amp", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "Headphone Amp"}, - - {"Speaker Amp", NULL, "MONOOUT"}, - {"Speaker", NULL, "Speaker Amp"}, - - {"MIC1", NULL, "Mic (Internal)"}, -}; - -static int e750_ac97_init(struct snd_soc_codec *codec) -{ - snd_soc_dapm_nc_pin(codec, "LOUT"); - snd_soc_dapm_nc_pin(codec, "ROUT"); - snd_soc_dapm_nc_pin(codec, "PHONE"); - snd_soc_dapm_nc_pin(codec, "LINEINL"); - snd_soc_dapm_nc_pin(codec, "LINEINR"); - snd_soc_dapm_nc_pin(codec, "CDINL"); - snd_soc_dapm_nc_pin(codec, "CDINR"); - snd_soc_dapm_nc_pin(codec, "PCBEEP"); - snd_soc_dapm_nc_pin(codec, "MIC2"); - - snd_soc_dapm_new_controls(codec, e750_dapm_widgets, - ARRAY_SIZE(e750_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - - snd_soc_dapm_sync(codec); - - return 0; -} - -static struct snd_soc_dai_link e750_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], - .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI], - .init = e750_ac97_init, - /* use ops to check startup state */ - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], - .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX], - }, -}; - -static struct snd_soc_card e750 = { - .name = "Toshiba e750", - .platform = &pxa2xx_soc_platform, - .dai_link = e750_dai, - .num_links = ARRAY_SIZE(e750_dai), -}; - -static struct snd_soc_device e750_snd_devdata = { - .card = &e750, - .codec_dev = &soc_codec_dev_wm9705, -}; - -static struct platform_device *e750_snd_device; - -static int __init e750_init(void) -{ - int ret; - - if (!machine_is_e750()) - return -ENODEV; - - ret = gpio_request(GPIO_E750_HP_AMP_OFF, "Headphone amp"); - if (ret) - return ret; - - ret = gpio_request(GPIO_E750_SPK_AMP_OFF, "Speaker amp"); - if (ret) - goto free_hp_amp_gpio; - - ret = gpio_direction_output(GPIO_E750_HP_AMP_OFF, 1); - if (ret) - goto free_spk_amp_gpio; - - ret = gpio_direction_output(GPIO_E750_SPK_AMP_OFF, 1); - if (ret) - goto free_spk_amp_gpio; - - e750_snd_device = platform_device_alloc("soc-audio", -1); - if (!e750_snd_device) { - ret = -ENOMEM; - goto free_spk_amp_gpio; - } - - platform_set_drvdata(e750_snd_device, &e750_snd_devdata); - e750_snd_devdata.dev = &e750_snd_device->dev; - ret = platform_device_add(e750_snd_device); - - if (!ret) - return 0; - -/* Fail gracefully */ - platform_device_put(e750_snd_device); -free_spk_amp_gpio: - gpio_free(GPIO_E750_SPK_AMP_OFF); -free_hp_amp_gpio: - gpio_free(GPIO_E750_HP_AMP_OFF); - - return ret; -} - -static void __exit e750_exit(void) -{ - platform_device_unregister(e750_snd_device); - gpio_free(GPIO_E750_SPK_AMP_OFF); - gpio_free(GPIO_E750_HP_AMP_OFF); -} - -module_init(e750_init); -module_exit(e750_exit); - -/* Module information */ -MODULE_AUTHOR("Ian Molton "); -MODULE_DESCRIPTION("ALSA SoC driver for e750"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/sound/soc/pxa/e800_wm9712.c b/trunk/sound/soc/pxa/e800_wm9712.c index bc019cdce429..2e3386dfa0f0 100644 --- a/trunk/sound/soc/pxa/e800_wm9712.c +++ b/trunk/sound/soc/pxa/e800_wm9712.c @@ -1,6 +1,8 @@ /* * e800-wm9712.c -- SoC audio for e800 * + * Based on tosa.c + * * Copyright 2007 (c) Ian Molton * * This program is free software; you can redistribute it and/or modify it @@ -11,7 +13,7 @@ #include #include -#include +#include #include #include @@ -19,85 +21,23 @@ #include #include +#include +#include #include -#include #include "../codecs/wm9712.h" #include "pxa2xx-pcm.h" #include "pxa2xx-ac97.h" -static int e800_spk_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - gpio_set_value(GPIO_E800_SPK_AMP_ON, 1); - else if (event & SND_SOC_DAPM_POST_PMD) - gpio_set_value(GPIO_E800_SPK_AMP_ON, 0); - - return 0; -} - -static int e800_hp_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - gpio_set_value(GPIO_E800_HP_AMP_OFF, 0); - else if (event & SND_SOC_DAPM_POST_PMD) - gpio_set_value(GPIO_E800_HP_AMP_OFF, 1); - - return 0; -} - -static const struct snd_soc_dapm_widget e800_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Mic (Internal1)", NULL), - SND_SOC_DAPM_MIC("Mic (Internal2)", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e800_hp_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e800_spk_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Headphone Jack", NULL, "HPOUTL"}, - {"Headphone Jack", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "Headphone Amp"}, - - {"Speaker Amp", NULL, "MONOOUT"}, - {"Speaker", NULL, "Speaker Amp"}, - - {"MIC1", NULL, "Mic (Internal1)"}, - {"MIC2", NULL, "Mic (Internal2)"}, -}; - -static int e800_ac97_init(struct snd_soc_codec *codec) -{ - snd_soc_dapm_new_controls(codec, e800_dapm_widgets, - ARRAY_SIZE(e800_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); - - return 0; -} +static struct snd_soc_card e800; static struct snd_soc_dai_link e800_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], - .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], - .init = e800_ac97_init, - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], - .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], - }, +{ + .name = "AC97 Aux", + .stream_name = "AC97 Aux", + .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], + .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], +}, }; static struct snd_soc_card e800 = { @@ -121,22 +61,6 @@ static int __init e800_init(void) if (!machine_is_e800()) return -ENODEV; - ret = gpio_request(GPIO_E800_HP_AMP_OFF, "Headphone amp"); - if (ret) - return ret; - - ret = gpio_request(GPIO_E800_SPK_AMP_ON, "Speaker amp"); - if (ret) - goto free_hp_amp_gpio; - - ret = gpio_direction_output(GPIO_E800_HP_AMP_OFF, 1); - if (ret) - goto free_spk_amp_gpio; - - ret = gpio_direction_output(GPIO_E800_SPK_AMP_ON, 1); - if (ret) - goto free_spk_amp_gpio; - e800_snd_device = platform_device_alloc("soc-audio", -1); if (!e800_snd_device) return -ENOMEM; @@ -145,15 +69,8 @@ static int __init e800_init(void) e800_snd_devdata.dev = &e800_snd_device->dev; ret = platform_device_add(e800_snd_device); - if (!ret) - return 0; - -/* Fail gracefully */ - platform_device_put(e800_snd_device); -free_spk_amp_gpio: - gpio_free(GPIO_E800_SPK_AMP_ON); -free_hp_amp_gpio: - gpio_free(GPIO_E800_HP_AMP_OFF); + if (ret) + platform_device_put(e800_snd_device); return ret; } @@ -161,8 +78,6 @@ static int __init e800_init(void) static void __exit e800_exit(void) { platform_device_unregister(e800_snd_device); - gpio_free(GPIO_E800_SPK_AMP_ON); - gpio_free(GPIO_E800_HP_AMP_OFF); } module_init(e800_init); @@ -171,4 +86,4 @@ module_exit(e800_exit); /* Module information */ MODULE_AUTHOR("Ian Molton "); MODULE_DESCRIPTION("ALSA SoC driver for e800"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/mioa701_wm9713.c b/trunk/sound/soc/pxa/mioa701_wm9713.c deleted file mode 100644 index 19eda8bbfdaf..000000000000 --- a/trunk/sound/soc/pxa/mioa701_wm9713.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Handles the Mitac mioa701 SoC system - * - * Copyright (C) 2008 Robert Jarzmik - * - * 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 in version 2 of the License. - * - * 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 - * - * This is a little schema of the sound interconnections : - * - * Sagem X200 Wolfson WM9713 - * +--------+ +-------------------+ Rear Speaker - * | | | | /-+ - * | +--->----->---+MONOIN SPKL+--->----+-+ | - * | GSM | | | | | | - * | +--->----->---+PCBEEP SPKR+--->----+-+ | - * | CHIP | | | \-+ - * | +---<-----<---+MONO | - * | | | | Front Speaker - * +--------+ | | /-+ - * | HPL+--->----+-+ | - * | | | | | - * | OUT3+--->----+-+ | - * | | \-+ - * | | - * | | Front Micro - * | | + - * | MIC1+-----<--+o+ - * | | + - * +-------------------+ --- - */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "pxa2xx-pcm.h" -#include "pxa2xx-ac97.h" -#include "../codecs/wm9713.h" - -#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) - -#define AC97_GPIO_PULL 0x58 - -/* Use GPIO8 for rear speaker amplifier */ -static int rear_amp_power(struct snd_soc_codec *codec, int power) -{ - unsigned short reg; - - if (power) { - reg = snd_soc_read(codec, AC97_GPIO_CFG); - snd_soc_write(codec, AC97_GPIO_CFG, reg | 0x0100); - reg = snd_soc_read(codec, AC97_GPIO_PULL); - snd_soc_write(codec, AC97_GPIO_PULL, reg | (1<<15)); - } else { - reg = snd_soc_read(codec, AC97_GPIO_CFG); - snd_soc_write(codec, AC97_GPIO_CFG, reg & ~0x0100); - reg = snd_soc_read(codec, AC97_GPIO_PULL); - snd_soc_write(codec, AC97_GPIO_PULL, reg & ~(1<<15)); - } - - return 0; -} - -static int rear_amp_event(struct snd_soc_dapm_widget *widget, - struct snd_kcontrol *kctl, int event) -{ - struct snd_soc_codec *codec = widget->codec; - - return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event)); -} - -/* mioa701 machine dapm widgets */ -static const struct snd_soc_dapm_widget mioa701_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Front Speaker", NULL), - SND_SOC_DAPM_SPK("Rear Speaker", rear_amp_event), - SND_SOC_DAPM_MIC("Headset", NULL), - SND_SOC_DAPM_LINE("GSM Line Out", NULL), - SND_SOC_DAPM_LINE("GSM Line In", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Front Mic", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* Call Mic */ - {"Mic Bias", NULL, "Front Mic"}, - {"MIC1", NULL, "Mic Bias"}, - - /* Headset Mic */ - {"LINEL", NULL, "Headset Mic"}, - {"LINER", NULL, "Headset Mic"}, - - /* GSM Module */ - {"MONOIN", NULL, "GSM Line Out"}, - {"PCBEEP", NULL, "GSM Line Out"}, - {"GSM Line In", NULL, "MONO"}, - - /* headphone connected to HPL, HPR */ - {"Headset", NULL, "HPL"}, - {"Headset", NULL, "HPR"}, - - /* front speaker connected to HPL, OUT3 */ - {"Front Speaker", NULL, "HPL"}, - {"Front Speaker", NULL, "OUT3"}, - - /* rear speaker connected to SPKL, SPKR */ - {"Rear Speaker", NULL, "SPKL"}, - {"Rear Speaker", NULL, "SPKR"}, -}; - -static int mioa701_wm9713_init(struct snd_soc_codec *codec) -{ - unsigned short reg; - - /* Add mioa701 specific widgets */ - snd_soc_dapm_new_controls(codec, ARRAY_AND_SIZE(mioa701_dapm_widgets)); - - /* Set up mioa701 specific audio path audio_mapnects */ - snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map)); - - /* Prepare GPIO8 for rear speaker amplifier */ - reg = codec->read(codec, AC97_GPIO_CFG); - codec->write(codec, AC97_GPIO_CFG, reg | 0x0100); - - /* Prepare MIC input */ - reg = codec->read(codec, AC97_3D_CONTROL); - codec->write(codec, AC97_3D_CONTROL, reg | 0xc000); - - snd_soc_dapm_enable_pin(codec, "Front Speaker"); - snd_soc_dapm_enable_pin(codec, "Rear Speaker"); - snd_soc_dapm_enable_pin(codec, "Front Mic"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_sync(codec); - - return 0; -} - -static struct snd_soc_ops mioa701_ops; - -static struct snd_soc_dai_link mioa701_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], - .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI], - .init = mioa701_wm9713_init, - .ops = &mioa701_ops, - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], - .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX], - .ops = &mioa701_ops, - }, -}; - -static struct snd_soc_card mioa701 = { - .name = "MioA701", - .platform = &pxa2xx_soc_platform, - .dai_link = mioa701_dai, - .num_links = ARRAY_SIZE(mioa701_dai), -}; - -static struct snd_soc_device mioa701_snd_devdata = { - .card = &mioa701, - .codec_dev = &soc_codec_dev_wm9713, -}; - -static struct platform_device *mioa701_snd_device; - -static int mioa701_wm9713_probe(struct platform_device *pdev) -{ - int ret; - - if (!machine_is_mioa701()) - return -ENODEV; - - dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will" - "lead to overheating and possible destruction of your device." - "Do not use without a good knowledge of mio's board design!\n"); - - mioa701_snd_device = platform_device_alloc("soc-audio", -1); - if (!mioa701_snd_device) - return -ENOMEM; - - platform_set_drvdata(mioa701_snd_device, &mioa701_snd_devdata); - mioa701_snd_devdata.dev = &mioa701_snd_device->dev; - - ret = platform_device_add(mioa701_snd_device); - if (!ret) - return 0; - - platform_device_put(mioa701_snd_device); - return ret; -} - -static int __devexit mioa701_wm9713_remove(struct platform_device *pdev) -{ - platform_device_unregister(mioa701_snd_device); - return 0; -} - -static struct platform_driver mioa701_wm9713_driver = { - .probe = mioa701_wm9713_probe, - .remove = __devexit_p(mioa701_wm9713_remove), - .driver = { - .name = "mioa701-wm9713", - .owner = THIS_MODULE, - }, -}; - -static int __init mioa701_asoc_init(void) -{ - return platform_driver_register(&mioa701_wm9713_driver); -} - -static void __exit mioa701_asoc_exit(void) -{ - platform_driver_unregister(&mioa701_wm9713_driver); -} - -module_init(mioa701_asoc_init); -module_exit(mioa701_asoc_exit); - -/* Module information */ -MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)"); -MODULE_DESCRIPTION("ALSA SoC WM9713 MIO A701"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/palm27x.c b/trunk/sound/soc/pxa/palm27x.c index 48a73f64500b..4a9cf3083af0 100644 --- a/trunk/sound/soc/pxa/palm27x.c +++ b/trunk/sound/soc/pxa/palm27x.c @@ -55,7 +55,7 @@ static void palm27x_ext_control(struct snd_soc_codec *codec) static int palm27x_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ palm27x_ext_control(codec); @@ -146,16 +146,19 @@ static const struct snd_kcontrol_new palm27x_controls[] = { static int palm27x_ac97_init(struct snd_soc_codec *codec) { - int err; + int i, err; snd_soc_dapm_nc_pin(codec, "OUT3"); snd_soc_dapm_nc_pin(codec, "MONOOUT"); /* add palm27x specific controls */ - err = snd_soc_add_controls(codec, palm27x_controls, - ARRAY_SIZE(palm27x_controls)); - if (err < 0) - return err; + for (i = 0; i < ARRAY_SIZE(palm27x_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&palm27x_controls[i], + codec, NULL)); + if (err < 0) + return err; + } /* add palm27x specific widgets */ snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, diff --git a/trunk/sound/soc/pxa/poodle.c b/trunk/sound/soc/pxa/poodle.c index ef7c6c8dc8f1..6e9827189fff 100644 --- a/trunk/sound/soc/pxa/poodle.c +++ b/trunk/sound/soc/pxa/poodle.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -78,7 +77,7 @@ static void poodle_ext_control(struct snd_soc_codec *codec) static int poodle_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ poodle_ext_control(codec); @@ -241,17 +240,19 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = { */ static int poodle_wm8731_init(struct snd_soc_codec *codec) { - int err; + int i, err; snd_soc_dapm_nc_pin(codec, "LLINEIN"); snd_soc_dapm_nc_pin(codec, "RLINEIN"); snd_soc_dapm_enable_pin(codec, "MICIN"); /* Add poodle specific controls */ - err = snd_soc_add_controls(codec, wm8731_poodle_controls, - ARRAY_SIZE(wm8731_poodle_controls)); - if (err < 0) - return err; + for (i = 0; i < ARRAY_SIZE(wm8731_poodle_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8731_poodle_controls[i], codec, NULL)); + if (err < 0) + return err; + } /* Add poodle specific widgets */ snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, @@ -282,42 +283,17 @@ static struct snd_soc_card snd_soc_poodle = { .num_links = 1, }; -/* - * FIXME: This is a temporary bodge to avoid cross-tree merge issues. - * New drivers should register the wm8731 I2C device in the machine - * setup code (under arch/arm for ARM systems). - */ -static int wm8731_i2c_register(void) -{ - struct i2c_board_info info; - struct i2c_adapter *adapter; - struct i2c_client *client; - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = 0x1b; - strlcpy(info.type, "wm8731", I2C_NAME_SIZE); - - adapter = i2c_get_adapter(0); - if (!adapter) { - printk(KERN_ERR "can't get i2c adapter 0\n"); - return -ENODEV; - } - - client = i2c_new_device(adapter, &info); - i2c_put_adapter(adapter); - if (!client) { - printk(KERN_ERR "can't add i2c device at 0x%x\n", - (unsigned int)info.addr); - return -ENODEV; - } - - return 0; -} +/* poodle audio private data */ +static struct wm8731_setup_data poodle_wm8731_setup = { + .i2c_bus = 0, + .i2c_address = 0x1b, +}; /* poodle audio subsystem */ static struct snd_soc_device poodle_snd_devdata = { .card = &snd_soc_poodle, .codec_dev = &soc_codec_dev_wm8731, + .codec_data = &poodle_wm8731_setup, }; static struct platform_device *poodle_snd_device; @@ -329,10 +305,6 @@ static int __init poodle_init(void) if (!machine_is_poodle()) return -ENODEV; - ret = wm8731_i2c_register(); - if (ret != 0) - return ret; - locomo_gpio_set_dir(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_AMP_ON, 0); /* should we mute HP at startup - burning power ?*/ diff --git a/trunk/sound/soc/pxa/pxa-ssp.c b/trunk/sound/soc/pxa/pxa-ssp.c index b0bf40973d5b..73cb6b4c2f2d 100644 --- a/trunk/sound/soc/pxa/pxa-ssp.c +++ b/trunk/sound/soc/pxa/pxa-ssp.c @@ -1,3 +1,4 @@ +#define DEBUG /* * pxa-ssp.c -- ALSA Soc Audio Layer * @@ -20,8 +21,6 @@ #include #include -#include - #include #include #include @@ -222,9 +221,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, int ret = 0; if (!cpu_dai->active) { - priv->dev.port = cpu_dai->id + 1; - priv->dev.irq = NO_IRQ; - clk_enable(priv->dev.ssp->clk); + ret = ssp_init(&priv->dev, cpu_dai->id + 1, SSP_NO_IRQ); + if (ret < 0) + return ret; ssp_disable(&priv->dev); } return ret; @@ -239,7 +238,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, if (!cpu_dai->active) { ssp_disable(&priv->dev); - clk_disable(priv->dev.ssp->clk); + ssp_exit(&priv->dev); } } @@ -299,7 +298,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int val; u32 sscr0 = ssp_read_reg(ssp, SSCR0) & - ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); + ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC); dev_dbg(&ssp->pdev->dev, "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n", @@ -327,7 +326,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, case PXA_SSP_CLK_AUDIO: priv->sysclk = 0; ssp_set_scr(&priv->dev, 1); - sscr0 |= SSCR0_ACS; + sscr0 |= SSCR0_ADC; break; default: return -ENODEV; @@ -521,20 +520,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, u32 sscr1; u32 sspsp; - /* check if we need to change anything at all */ - if (priv->dai_fmt == fmt) - return 0; - - /* we can only change the settings if the port is not in use */ - if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { - dev_err(&ssp->pdev->dev, - "can't change hardware dai format: stream is in use"); - return -EINVAL; - } - /* reset port settings */ sscr0 = ssp_read_reg(ssp, SSCR0) & - (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); + (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC); sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); sspsp = 0; @@ -557,18 +545,18 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - sscr0 |= SSCR0_PSP; + sscr0 |= SSCR0_MOD | SSCR0_PSP; sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; - /* See hw_params() */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: - sspsp |= SSPSP_SFRMP; + sspsp |= SSPSP_FSRT; break; case SND_SOC_DAIFMT_NB_IF: + sspsp |= SSPSP_SFRMP | SSPSP_FSRT; break; case SND_SOC_DAIFMT_IB_IF: - sspsp |= SSPSP_SCMODE(3); + sspsp |= SSPSP_SFRMP; break; default: return -EINVAL; @@ -654,65 +642,34 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, sscr0 |= SSCR0_FPCKE; #endif sscr0 |= SSCR0_DataSize(16); + if (params_channels(params) > 1) + sscr0 |= SSCR0_EDSS; break; case SNDRV_PCM_FORMAT_S24_LE: sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8)); + /* we must be in network mode (2 slots) for 24 bit stereo */ break; case SNDRV_PCM_FORMAT_S32_LE: sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); + /* we must be in network mode (2 slots) for 32 bit stereo */ break; } ssp_write_reg(ssp, SSCR0, sscr0); switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - sspsp = ssp_read_reg(ssp, SSPSP); - - if (((sscr0 & SSCR0_SCR) == SSCR0_SerClkDiv(4)) && - (width == 16)) { - /* This is a special case where the bitclk is 64fs - * and we're not dealing with 2*32 bits of audio - * samples. - * - * The SSP values used for that are all found out by - * trying and failing a lot; some of the registers - * needed for that mode are only available on PXA3xx. - */ - -#ifdef CONFIG_PXA3xx - if (!cpu_is_pxa3xx()) - return -EINVAL; - - sspsp |= SSPSP_SFRMWDTH(width * 2); - sspsp |= SSPSP_SFRMDLY(width * 4); - sspsp |= SSPSP_EDMYSTOP(3); - sspsp |= SSPSP_DMYSTOP(3); - sspsp |= SSPSP_DMYSTRT(1); -#else - return -EINVAL; -#endif - } else { - /* The frame width is the width the LRCLK is - * asserted for; the delay is expressed in - * half cycle units. We need the extra cycle - * because the data starts clocking out one BCLK - * after LRCLK changes polarity. - */ - sspsp |= SSPSP_SFRMWDTH(width + 1); - sspsp |= SSPSP_SFRMDLY((width + 1) * 2); - sspsp |= SSPSP_DMYSTRT(1); - } - + /* Cleared when the DAI format is set */ + sspsp = ssp_read_reg(ssp, SSPSP) | SSPSP_SFRMWDTH(width); ssp_write_reg(ssp, SSPSP, sspsp); break; default: break; } - /* When we use a network mode, we always require TDM slots + /* We always use a network mode so we always require TDM slots * - complain loudly and fail if they've not been set up yet. */ - if ((sscr0 & SSCR0_MOD) && !(ssp_read_reg(ssp, SSTSA) & 0xf)) { + if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) { dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n"); return -EINVAL; } @@ -794,7 +751,7 @@ static int pxa_ssp_probe(struct platform_device *pdev, if (!priv) return -ENOMEM; - priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio"); + priv->dev.ssp = ssp_request(dai->id, "SoC audio"); if (priv->dev.ssp == NULL) { ret = -ENODEV; goto err_priv; @@ -825,19 +782,6 @@ static void pxa_ssp_remove(struct platform_device *pdev, SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops pxa_ssp_dai_ops = { - .startup = pxa_ssp_startup, - .shutdown = pxa_ssp_shutdown, - .trigger = pxa_ssp_trigger, - .hw_params = pxa_ssp_hw_params, - .set_sysclk = pxa_ssp_set_dai_sysclk, - .set_clkdiv = pxa_ssp_set_dai_clkdiv, - .set_pll = pxa_ssp_set_dai_pll, - .set_fmt = pxa_ssp_set_dai_fmt, - .set_tdm_slot = pxa_ssp_set_dai_tdm_slot, - .set_tristate = pxa_ssp_set_dai_tristate, -}; - struct snd_soc_dai pxa_ssp_dai[] = { { .name = "pxa2xx-ssp1", @@ -858,7 +802,18 @@ struct snd_soc_dai pxa_ssp_dai[] = { .rates = PXA_SSP_RATES, .formats = PXA_SSP_FORMATS, }, - .ops = &pxa_ssp_dai_ops, + .ops = { + .startup = pxa_ssp_startup, + .shutdown = pxa_ssp_shutdown, + .trigger = pxa_ssp_trigger, + .hw_params = pxa_ssp_hw_params, + .set_sysclk = pxa_ssp_set_dai_sysclk, + .set_clkdiv = pxa_ssp_set_dai_clkdiv, + .set_pll = pxa_ssp_set_dai_pll, + .set_fmt = pxa_ssp_set_dai_fmt, + .set_tdm_slot = pxa_ssp_set_dai_tdm_slot, + .set_tristate = pxa_ssp_set_dai_tristate, + }, }, { .name = "pxa2xx-ssp2", .id = 1, @@ -878,7 +833,18 @@ struct snd_soc_dai pxa_ssp_dai[] = { .rates = PXA_SSP_RATES, .formats = PXA_SSP_FORMATS, }, - .ops = &pxa_ssp_dai_ops, + .ops = { + .startup = pxa_ssp_startup, + .shutdown = pxa_ssp_shutdown, + .trigger = pxa_ssp_trigger, + .hw_params = pxa_ssp_hw_params, + .set_sysclk = pxa_ssp_set_dai_sysclk, + .set_clkdiv = pxa_ssp_set_dai_clkdiv, + .set_pll = pxa_ssp_set_dai_pll, + .set_fmt = pxa_ssp_set_dai_fmt, + .set_tdm_slot = pxa_ssp_set_dai_tdm_slot, + .set_tristate = pxa_ssp_set_dai_tristate, + }, }, { .name = "pxa2xx-ssp3", @@ -899,7 +865,18 @@ struct snd_soc_dai pxa_ssp_dai[] = { .rates = PXA_SSP_RATES, .formats = PXA_SSP_FORMATS, }, - .ops = &pxa_ssp_dai_ops, + .ops = { + .startup = pxa_ssp_startup, + .shutdown = pxa_ssp_shutdown, + .trigger = pxa_ssp_trigger, + .hw_params = pxa_ssp_hw_params, + .set_sysclk = pxa_ssp_set_dai_sysclk, + .set_clkdiv = pxa_ssp_set_dai_clkdiv, + .set_pll = pxa_ssp_set_dai_pll, + .set_fmt = pxa_ssp_set_dai_fmt, + .set_tdm_slot = pxa_ssp_set_dai_tdm_slot, + .set_tristate = pxa_ssp_set_dai_tristate, + }, }, { .name = "pxa2xx-ssp4", @@ -920,7 +897,18 @@ struct snd_soc_dai pxa_ssp_dai[] = { .rates = PXA_SSP_RATES, .formats = PXA_SSP_FORMATS, }, - .ops = &pxa_ssp_dai_ops, + .ops = { + .startup = pxa_ssp_startup, + .shutdown = pxa_ssp_shutdown, + .trigger = pxa_ssp_trigger, + .hw_params = pxa_ssp_hw_params, + .set_sysclk = pxa_ssp_set_dai_sysclk, + .set_clkdiv = pxa_ssp_set_dai_clkdiv, + .set_pll = pxa_ssp_set_dai_pll, + .set_fmt = pxa_ssp_set_dai_fmt, + .set_tdm_slot = pxa_ssp_set_dai_tdm_slot, + .set_tristate = pxa_ssp_set_dai_tristate, + }, }, }; EXPORT_SYMBOL_GPL(pxa_ssp_dai); diff --git a/trunk/sound/soc/pxa/pxa2xx-ac97.c b/trunk/sound/soc/pxa/pxa2xx-ac97.c index 01c21c6cdbbc..812c2b4d3e07 100644 --- a/trunk/sound/soc/pxa/pxa2xx-ac97.c +++ b/trunk/sound/soc/pxa/pxa2xx-ac97.c @@ -106,13 +106,13 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai) static int pxa2xx_ac97_probe(struct platform_device *pdev, struct snd_soc_dai *dai) { - return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev)); + return pxa2xx_ac97_hw_probe(pdev); } static void pxa2xx_ac97_remove(struct platform_device *pdev, struct snd_soc_dai *dai) { - pxa2xx_ac97_hw_remove(to_platform_device(dai->dev)); + pxa2xx_ac97_hw_remove(pdev); } static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, @@ -164,18 +164,6 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = { - .hw_params = pxa2xx_ac97_hw_params, -}; - -static struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = { - .hw_params = pxa2xx_ac97_hw_aux_params, -}; - -static struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { - .hw_params = pxa2xx_ac97_hw_mic_params, -}; - /* * There is only 1 physical AC97 interface for pxa2xx, but it * has extra fifo's that can be used for aux DACs and ADCs. @@ -201,7 +189,8 @@ struct snd_soc_dai pxa_ac97_dai[] = { .channels_max = 2, .rates = PXA2XX_AC97_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &pxa_ac97_hifi_dai_ops, + .ops = { + .hw_params = pxa2xx_ac97_hw_params,}, }, { .name = "pxa2xx-ac97-aux", @@ -219,7 +208,8 @@ struct snd_soc_dai pxa_ac97_dai[] = { .channels_max = 1, .rates = PXA2XX_AC97_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &pxa_ac97_aux_dai_ops, + .ops = { + .hw_params = pxa2xx_ac97_hw_aux_params,}, }, { .name = "pxa2xx-ac97-mic", @@ -231,52 +221,23 @@ struct snd_soc_dai pxa_ac97_dai[] = { .channels_max = 1, .rates = PXA2XX_AC97_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &pxa_ac97_mic_dai_ops, + .ops = { + .hw_params = pxa2xx_ac97_hw_mic_params,}, }, }; EXPORT_SYMBOL_GPL(pxa_ac97_dai); EXPORT_SYMBOL_GPL(soc_ac97_ops); -static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++) - pxa_ac97_dai[i].dev = &pdev->dev; - - /* Punt most of the init to the SoC probe; we may need the machine - * driver to do interesting things with the clocking to get us up - * and running. - */ - return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); -} - -static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); - - return 0; -} - -static struct platform_driver pxa2xx_ac97_driver = { - .probe = pxa2xx_ac97_dev_probe, - .remove = __devexit_p(pxa2xx_ac97_dev_remove), - .driver = { - .name = "pxa2xx-ac97", - .owner = THIS_MODULE, - }, -}; - static int __init pxa_ac97_init(void) { - return platform_driver_register(&pxa2xx_ac97_driver); + return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); } module_init(pxa_ac97_init); static void __exit pxa_ac97_exit(void) { - platform_driver_unregister(&pxa2xx_ac97_driver); + snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); } module_exit(pxa_ac97_exit); diff --git a/trunk/sound/soc/pxa/pxa2xx-i2s.c b/trunk/sound/soc/pxa/pxa2xx-i2s.c index e6c24408c5f9..517991fb1099 100644 --- a/trunk/sound/soc/pxa/pxa2xx-i2s.c +++ b/trunk/sound/soc/pxa/pxa2xx-i2s.c @@ -25,11 +25,20 @@ #include #include +#include #include #include "pxa2xx-pcm.h" #include "pxa2xx-i2s.h" +struct pxa2xx_gpio { + u32 sys; + u32 rx; + u32 tx; + u32 clk; + u32 frm; +}; + /* * I2S Controller Register and Bit Definitions */ @@ -97,6 +106,21 @@ static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { DCMD_BURST32 | DCMD_WIDTH4, }; +static struct pxa2xx_gpio gpio_bus[] = { + { /* I2S SoC Slave */ + .rx = GPIO29_SDATA_IN_I2S_MD, + .tx = GPIO30_SDATA_OUT_I2S_MD, + .clk = GPIO28_BITCLK_IN_I2S_MD, + .frm = GPIO31_SYNC_I2S_MD, + }, + { /* I2S SoC Master */ + .rx = GPIO29_SDATA_IN_I2S_MD, + .tx = GPIO30_SDATA_OUT_I2S_MD, + .clk = GPIO28_BITCLK_OUT_I2S_MD, + .frm = GPIO31_SYNC_I2S_MD, + }, +}; + static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -157,6 +181,9 @@ static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai, if (clk_id != PXA2XX_I2S_SYSCLK) return -ENODEV; + if (pxa_i2s.master && dir == SND_SOC_CLOCK_OUT) + pxa_gpio_mode(gpio_bus[pxa_i2s.master].sys); + return 0; } @@ -167,6 +194,10 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + pxa_gpio_mode(gpio_bus[pxa_i2s.master].rx); + pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx); + pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm); + pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk); BUG_ON(IS_ERR(clk_i2s)); clk_enable(clk_i2s); pxa_i2s_wait(); @@ -304,15 +335,6 @@ static int pxa2xx_i2s_resume(struct snd_soc_dai *dai) SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) -static struct snd_soc_dai_ops pxa_i2s_dai_ops = { - .startup = pxa2xx_i2s_startup, - .shutdown = pxa2xx_i2s_shutdown, - .trigger = pxa2xx_i2s_trigger, - .hw_params = pxa2xx_i2s_hw_params, - .set_fmt = pxa2xx_i2s_set_dai_fmt, - .set_sysclk = pxa2xx_i2s_set_dai_sysclk, -}; - struct snd_soc_dai pxa_i2s_dai = { .name = "pxa2xx-i2s", .id = 0, @@ -328,7 +350,14 @@ struct snd_soc_dai pxa_i2s_dai = { .channels_max = 2, .rates = PXA2XX_I2S_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &pxa_i2s_dai_ops, + .ops = { + .startup = pxa2xx_i2s_startup, + .shutdown = pxa2xx_i2s_shutdown, + .trigger = pxa2xx_i2s_trigger, + .hw_params = pxa2xx_i2s_hw_params, + .set_fmt = pxa2xx_i2s_set_dai_fmt, + .set_sysclk = pxa2xx_i2s_set_dai_sysclk, + }, }; EXPORT_SYMBOL_GPL(pxa_i2s_dai); @@ -369,6 +398,11 @@ static struct platform_driver pxa2xx_i2s_driver = { static int __init pxa2xx_i2s_init(void) { + if (cpu_is_pxa27x()) + gpio_bus[1].sys = GPIO113_I2S_SYSCLK_MD; + else + gpio_bus[1].sys = GPIO32_SYSCLK_I2S_MD; + clk_i2s = ERR_PTR(-ENOENT); return platform_driver_register(&pxa2xx_i2s_driver); } diff --git a/trunk/sound/soc/pxa/spitz.c b/trunk/sound/soc/pxa/spitz.c index 6ca9f53080c6..a3b9e6bdf979 100644 --- a/trunk/sound/soc/pxa/spitz.c +++ b/trunk/sound/soc/pxa/spitz.c @@ -109,7 +109,7 @@ static void spitz_ext_control(struct snd_soc_codec *codec) static int spitz_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ spitz_ext_control(codec); @@ -278,7 +278,7 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = { */ static int spitz_wm8750_init(struct snd_soc_codec *codec) { - int err; + int i, err; /* NC codec pins */ snd_soc_dapm_nc_pin(codec, "RINPUT1"); @@ -290,10 +290,12 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec) snd_soc_dapm_nc_pin(codec, "MONO1"); /* Add spitz specific controls */ - err = snd_soc_add_controls(codec, wm8750_spitz_controls, - ARRAY_SIZE(wm8750_spitz_controls)); - if (err < 0) - return err; + for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8750_spitz_controls[i], codec, NULL)); + if (err < 0) + return err; + } /* Add spitz specific widgets */ snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, diff --git a/trunk/sound/soc/pxa/tosa.c b/trunk/sound/soc/pxa/tosa.c index fc781374b1bf..c77194f74c9b 100644 --- a/trunk/sound/soc/pxa/tosa.c +++ b/trunk/sound/soc/pxa/tosa.c @@ -82,7 +82,7 @@ static void tosa_ext_control(struct snd_soc_codec *codec) static int tosa_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ tosa_ext_control(codec); @@ -188,16 +188,18 @@ static const struct snd_kcontrol_new tosa_controls[] = { static int tosa_ac97_init(struct snd_soc_codec *codec) { - int err; + int i, err; snd_soc_dapm_nc_pin(codec, "OUT3"); snd_soc_dapm_nc_pin(codec, "MONOOUT"); /* add tosa specific controls */ - err = snd_soc_add_controls(codec, tosa_controls, - ARRAY_SIZE(tosa_controls)); - if (err < 0) - return err; + for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&tosa_controls[i],codec, NULL)); + if (err < 0) + return err; + } /* add tosa specific widgets */ snd_soc_dapm_new_controls(codec, tosa_dapm_widgets, diff --git a/trunk/sound/soc/pxa/zylonite.c b/trunk/sound/soc/pxa/zylonite.c index 9a386b4c4ed1..f8e9ecd589d3 100644 --- a/trunk/sound/soc/pxa/zylonite.c +++ b/trunk/sound/soc/pxa/zylonite.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -27,17 +26,6 @@ #include "pxa2xx-ac97.h" #include "pxa-ssp.h" -/* - * There is a physical switch SW15 on the board which changes the MCLK - * for the WM9713 between the standard AC97 master clock and the - * output of the CLK_POUT signal from the PXA. - */ -static int clk_pout; -module_param(clk_pout, int, 0); -MODULE_PARM_DESC(clk_pout, "Use CLK_POUT as WM9713 MCLK (SW15 on board)."); - -static struct clk *pout; - static struct snd_soc_card zylonite; static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = { @@ -73,8 +61,10 @@ static const struct snd_soc_dapm_route audio_map[] = { static int zylonite_wm9713_init(struct snd_soc_codec *codec) { - if (clk_pout) - snd_soc_dai_set_pll(&codec->dai[0], 0, clk_get_rate(pout), 0); + /* Currently we only support use of the AC97 clock here. If + * CLK_POUT is selected by SW15 then the clock API will need + * to be used to request and enable it here. + */ snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, ARRAY_SIZE(zylonite_dapm_widgets)); @@ -96,35 +86,40 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; unsigned int pll_out = 0; + unsigned int acds = 0; unsigned int wm9713_div = 0; int ret = 0; - int rate = params_rate(params); - int width = snd_pcm_format_physical_width(params_format(params)); - /* Only support ratios that we can generate neatly from the AC97 - * based master clock - in particular, this excludes 44.1kHz. - * In most applications the voice DAC will be used for telephony - * data so multiples of 8kHz will be the common case. - */ - switch (rate) { + switch (params_rate(params)) { case 8000: wm9713_div = 12; + pll_out = 2048000; break; case 16000: wm9713_div = 6; + pll_out = 4096000; break; case 48000: + default: wm9713_div = 2; + pll_out = 12288000; + acds = 1; break; - default: - /* Don't support OSS emulation */ - return -EINVAL; } - /* Add 1 to the width for the leading clock cycle */ - pll_out = rate * (width + 1) * 8; + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1); + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, + params_channels(params), + params_channels(params)); if (ret < 0) return ret; @@ -132,22 +127,19 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - if (clk_pout) - ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV, - WM9713_PCMDIV(wm9713_div)); - else - ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV, - WM9713_PCMDIV(wm9713_div)); + ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, acds); if (ret < 0) return ret; - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1); if (ret < 0) return ret; - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + /* Note that if the PLL is in use the WM9713_PCMCLK_PLL_DIV needs + * to be set instead. + */ + ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV, + WM9713_PCMDIV(wm9713_div)); if (ret < 0) return ret; @@ -181,72 +173,8 @@ static struct snd_soc_dai_link zylonite_dai[] = { }, }; -static int zylonite_probe(struct platform_device *pdev) -{ - int ret; - - if (clk_pout) { - pout = clk_get(NULL, "CLK_POUT"); - if (IS_ERR(pout)) { - dev_err(&pdev->dev, "Unable to obtain CLK_POUT: %ld\n", - PTR_ERR(pout)); - return PTR_ERR(pout); - } - - ret = clk_enable(pout); - if (ret != 0) { - dev_err(&pdev->dev, "Unable to enable CLK_POUT: %d\n", - ret); - clk_put(pout); - return ret; - } - - dev_dbg(&pdev->dev, "MCLK enabled at %luHz\n", - clk_get_rate(pout)); - } - - return 0; -} - -static int zylonite_remove(struct platform_device *pdev) -{ - if (clk_pout) { - clk_disable(pout); - clk_put(pout); - } - - return 0; -} - -static int zylonite_suspend_post(struct platform_device *pdev, - pm_message_t state) -{ - if (clk_pout) - clk_disable(pout); - - return 0; -} - -static int zylonite_resume_pre(struct platform_device *pdev) -{ - int ret = 0; - - if (clk_pout) { - ret = clk_enable(pout); - if (ret != 0) - dev_err(&pdev->dev, "Unable to enable CLK_POUT: %d\n", - ret); - } - - return ret; -} - static struct snd_soc_card zylonite = { .name = "Zylonite", - .probe = &zylonite_probe, - .remove = &zylonite_remove, - .suspend_post = &zylonite_suspend_post, - .resume_pre = &zylonite_resume_pre, .platform = &pxa2xx_soc_platform, .dai_link = zylonite_dai, .num_links = ARRAY_SIZE(zylonite_dai), diff --git a/trunk/sound/soc/s3c24xx/Kconfig b/trunk/sound/soc/s3c24xx/Kconfig index 2f3a21eee051..fcd03acf10f6 100644 --- a/trunk/sound/soc/s3c24xx/Kconfig +++ b/trunk/sound/soc/s3c24xx/Kconfig @@ -1,31 +1,19 @@ config SND_S3C24XX_SOC - tristate "SoC Audio for the Samsung S3CXXXX chips" - depends on ARCH_S3C2410 || ARCH_S3C64XX + tristate "SoC Audio for the Samsung S3C24XX chips" + depends on ARCH_S3C2410 help Say Y or M if you want to add support for codecs attached to - the S3C24XX and S3C64XX AC97, I2S or SSP interface. You will - also need to select the audio interfaces to support below. + the S3C24XX AC97, I2S or SSP interface. You will also need + to select the audio interfaces to support below. config SND_S3C24XX_SOC_I2S tristate - select S3C2410_DMA - -config SND_S3C_I2SV2_SOC - tristate config SND_S3C2412_SOC_I2S tristate - select SND_S3C_I2SV2_SOC - select S3C2410_DMA - -config SND_S3C64XX_SOC_I2S - tristate - select SND_S3C_I2SV2_SOC - select S3C64XX_DMA config SND_S3C2443_SOC_AC97 tristate - select S3C2410_DMA select AC97_BUS select SND_SOC_AC97_BUS @@ -38,14 +26,6 @@ config SND_S3C24XX_SOC_NEO1973_WM8753 Say Y if you want to add support for SoC audio on smdk2440 with the WM8753. -config SND_S3C24XX_SOC_JIVE_WM8750 - tristate "SoC I2S Audio support for Jive" - depends on SND_S3C24XX_SOC && MACH_JIVE - select SND_SOC_WM8750 - select SND_S3C2412_SOC_I2S - help - Sat Y if you want to add support for SoC audio on the Jive. - config SND_S3C24XX_SOC_SMDK2443_WM9710 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" depends on SND_S3C24XX_SOC && MACH_SMDK2443 @@ -68,5 +48,4 @@ config SND_S3C24XX_SOC_S3C24XX_UDA134X tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" depends on SND_S3C24XX_SOC select SND_S3C24XX_SOC_I2S - select SND_SOC_L3 select SND_SOC_UDA134X diff --git a/trunk/sound/soc/s3c24xx/Makefile b/trunk/sound/soc/s3c24xx/Makefile index 07a93a2ebe5f..96b3f3f617d4 100644 --- a/trunk/sound/soc/s3c24xx/Makefile +++ b/trunk/sound/soc/s3c24xx/Makefile @@ -2,25 +2,19 @@ snd-soc-s3c24xx-objs := s3c24xx-pcm.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o -snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o -snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o -obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o -obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o # S3C24XX Machine Support -snd-soc-jive-wm8750-objs := jive_wm8750.o snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o -obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o diff --git a/trunk/sound/soc/s3c24xx/jive_wm8750.c b/trunk/sound/soc/s3c24xx/jive_wm8750.c deleted file mode 100644 index 32063790d95b..000000000000 --- a/trunk/sound/soc/s3c24xx/jive_wm8750.c +++ /dev/null @@ -1,201 +0,0 @@ -/* sound/soc/s3c24xx/jive_wm8750.c - * - * Copyright 2007,2008 Simtec Electronics - * - * Based on sound/soc/pxa/spitz.c - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * 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 -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "s3c24xx-pcm.h" -#include "s3c2412-i2s.h" - -#include "../codecs/wm8750.h" - -static const struct snd_soc_dapm_route audio_map[] = { - { "Headphone Jack", NULL, "LOUT1" }, - { "Headphone Jack", NULL, "ROUT1" }, - { "Internal Speaker", NULL, "LOUT2" }, - { "Internal Speaker", NULL, "ROUT2" }, - { "LINPUT1", NULL, "Line Input" }, - { "RINPUT1", NULL, "Line Input" }, -}; - -static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Internal Speaker", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), -}; - -static int jive_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - struct s3c_i2sv2_rate_calc div; - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - s3c_i2sv2_calc_rate(&div, NULL, params_rate(params), - s3c2412_get_iisclk()); - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER, - div.clk_div - 1); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops jive_ops = { - .hw_params = jive_hw_params, -}; - -static int jive_wm8750_init(struct snd_soc_codec *codec) -{ - int err; - - /* These endpoints are not being used. */ - snd_soc_dapm_nc_pin(codec, "LINPUT2"); - snd_soc_dapm_nc_pin(codec, "RINPUT2"); - snd_soc_dapm_nc_pin(codec, "LINPUT3"); - snd_soc_dapm_nc_pin(codec, "RINPUT3"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONO"); - - /* Add jive specific widgets */ - err = snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, - ARRAY_SIZE(wm8750_dapm_widgets)); - if (err) { - printk(KERN_ERR "%s: failed to add widgets (%d)\n", - __func__, err); - return err; - } - - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); - - return 0; -} - -static struct snd_soc_dai_link jive_dai = { - .name = "wm8750", - .stream_name = "WM8750", - .cpu_dai = &s3c2412_i2s_dai, - .codec_dai = &wm8750_dai, - .init = jive_wm8750_init, - .ops = &jive_ops, -}; - -/* jive audio machine driver */ -static struct snd_soc_machine snd_soc_machine_jive = { - .name = "Jive", - .dai_link = &jive_dai, - .num_links = 1, -}; - -/* jive audio private data */ -static struct wm8750_setup_data jive_wm8750_setup = { -}; - -/* jive audio subsystem */ -static struct snd_soc_device jive_snd_devdata = { - .machine = &snd_soc_machine_jive, - .platform = &s3c24xx_soc_platform, - .codec_dev = &soc_codec_dev_wm8750_spi, - .codec_data = &jive_wm8750_setup, -}; - -static struct platform_device *jive_snd_device; - -static int __init jive_init(void) -{ - int ret; - - if (!machine_is_jive()) - return 0; - - printk("JIVE WM8750 Audio support\n"); - - jive_snd_device = platform_device_alloc("soc-audio", -1); - if (!jive_snd_device) - return -ENOMEM; - - platform_set_drvdata(jive_snd_device, &jive_snd_devdata); - jive_snd_devdata.dev = &jive_snd_device->dev; - ret = platform_device_add(jive_snd_device); - - if (ret) - platform_device_put(jive_snd_device); - - return ret; -} - -static void __exit jive_exit(void) -{ - platform_device_unregister(jive_snd_device); -} - -module_init(jive_init); -module_exit(jive_exit); - -MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("ALSA SoC Jive Audio support"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s3c24xx/neo1973_wm8753.c b/trunk/sound/soc/s3c24xx/neo1973_wm8753.c index 289fadf60b10..45bb12e8ea44 100644 --- a/trunk/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/trunk/sound/soc/s3c24xx/neo1973_wm8753.c @@ -29,17 +29,25 @@ #include #include #include -#include +#include #include #include -#include +#include #include "../codecs/wm8753.h" #include "lm4857.h" #include "s3c24xx-pcm.h" #include "s3c24xx-i2s.h" +/* Debugging stuff */ +#define S3C24XX_SOC_NEO1973_WM8753_DEBUG 0 +#if S3C24XX_SOC_NEO1973_WM8753_DEBUG +#define DBG(x...) printk(KERN_DEBUG "s3c24xx-soc-neo1973-wm8753: " x) +#else +#define DBG(x...) +#endif + /* define the scenarios */ #define NEO_AUDIO_OFF 0 #define NEO_GSM_CALL_AUDIO_HANDSET 1 @@ -64,7 +72,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, int ret = 0; unsigned long iis_clkrate; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); iis_clkrate = s3c24xx_i2s_get_clockrate(); @@ -150,7 +158,7 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); /* disable the PLL */ return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); @@ -173,7 +181,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, int ret = 0; unsigned long iis_clkrate; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); iis_clkrate = s3c24xx_i2s_get_clockrate(); @@ -216,7 +224,7 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); /* disable the PLL */ return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); @@ -238,7 +246,7 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); switch (neo1973_scenario) { case NEO_AUDIO_OFF: @@ -322,7 +330,7 @@ static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (neo1973_scenario == ucontrol->value.integer.value[0]) return 0; @@ -336,7 +344,7 @@ static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; static void lm4857_write_regs(void) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (i2c_master_send(i2c, lm4857_regs, 4) != 4) printk(KERN_ERR "lm4857: i2c write failed\n"); @@ -349,7 +357,7 @@ static int lm4857_get_reg(struct snd_kcontrol *kcontrol, int shift = (kcontrol->private_value >> 8) & 0x0F; int mask = (kcontrol->private_value >> 16) & 0xFF; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; return 0; @@ -377,7 +385,7 @@ static int lm4857_get_mode(struct snd_kcontrol *kcontrol, { u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (value) value -= 5; @@ -391,7 +399,7 @@ static int lm4857_set_mode(struct snd_kcontrol *kcontrol, { u8 value = ucontrol->value.integer.value[0]; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (value) value += 5; @@ -498,9 +506,9 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { */ static int neo1973_wm8753_init(struct snd_soc_codec *codec) { - int err; + int i, err; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); /* set up NC codec pins */ snd_soc_dapm_nc_pin(codec, "LOUT2"); @@ -518,10 +526,13 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec) set_scenario_endpoints(codec, NEO_AUDIO_OFF); /* add neo1973 specific controls */ - err = snd_soc_add_controls(codec, wm8753_neo1973_controls, - ARRAY_SIZE(8753_neo1973_controls)); - if (err < 0) - return err; + for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8753_neo1973_controls[i], + codec, NULL)); + if (err < 0) + return err; + } /* set up neo1973 specific audio routes */ err = snd_soc_dapm_add_routes(codec, dapm_routes, @@ -574,15 +585,21 @@ static struct snd_soc_card neo1973 = { .num_links = ARRAY_SIZE(neo1973_dai), }; +static struct wm8753_setup_data neo1973_wm8753_setup = { + .i2c_bus = 0, + .i2c_address = 0x1a, +}; + static struct snd_soc_device neo1973_snd_devdata = { .card = &neo1973, .codec_dev = &soc_codec_dev_wm8753, + .codec_data = &neo1973_wm8753_setup, }; static int lm4857_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); i2c = client; @@ -592,7 +609,7 @@ static int lm4857_i2c_probe(struct i2c_client *client, static int lm4857_i2c_remove(struct i2c_client *client) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); i2c = NULL; @@ -603,7 +620,7 @@ static u8 lm4857_state; static int lm4857_suspend(struct i2c_client *dev, pm_message_t state) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); dev_dbg(&dev->dev, "lm4857_suspend\n"); lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf; @@ -616,7 +633,7 @@ static int lm4857_suspend(struct i2c_client *dev, pm_message_t state) static int lm4857_resume(struct i2c_client *dev) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (lm4857_state) { lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f); @@ -627,7 +644,7 @@ static int lm4857_resume(struct i2c_client *dev) static void lm4857_shutdown(struct i2c_client *dev) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); dev_dbg(&dev->dev, "lm4857_shutdown\n"); lm4857_regs[LM4857_CTRL] &= 0xf0; @@ -658,7 +675,7 @@ static int __init neo1973_init(void) { int ret; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (!machine_is_neo1973_gta01()) { printk(KERN_INFO @@ -689,7 +706,7 @@ static int __init neo1973_init(void) static void __exit neo1973_exit(void) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); i2c_del_driver(&lm4857_i2c_driver); platform_device_unregister(neo1973_snd_device); diff --git a/trunk/sound/soc/s3c24xx/s3c-i2s-v2.c b/trunk/sound/soc/s3c24xx/s3c-i2s-v2.c deleted file mode 100644 index 295a4c910262..000000000000 --- a/trunk/sound/soc/s3c24xx/s3c-i2s-v2.c +++ /dev/null @@ -1,638 +0,0 @@ -/* sound/soc/s3c24xx/s3c-i2c-v2.c - * - * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs. - * - * Copyright (c) 2006 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com - * linux@wolfsonmicro.com - * - * Copyright (c) 2008, 2007, 2004-2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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 - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "s3c-i2s-v2.h" - -#define S3C2412_I2S_DEBUG_CON 0 - -static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) -{ - return cpu_dai->private_data; -} - -#define bit_set(v, b) (((v) & (b)) ? 1 : 0) - -#if S3C2412_I2S_DEBUG_CON -static void dbg_showcon(const char *fn, u32 con) -{ - printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn, - bit_set(con, S3C2412_IISCON_LRINDEX), - bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY), - bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY), - bit_set(con, S3C2412_IISCON_TXFIFO_FULL), - bit_set(con, S3C2412_IISCON_RXFIFO_FULL)); - - printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n", - fn, - bit_set(con, S3C2412_IISCON_TXDMA_PAUSE), - bit_set(con, S3C2412_IISCON_RXDMA_PAUSE), - bit_set(con, S3C2412_IISCON_TXCH_PAUSE), - bit_set(con, S3C2412_IISCON_RXCH_PAUSE)); - printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn, - bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE), - bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE), - bit_set(con, S3C2412_IISCON_IIS_ACTIVE)); -} -#else -static inline void dbg_showcon(const char *fn, u32 con) -{ -} -#endif - - -/* Turn on or off the transmission path. */ -void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) -{ - void __iomem *regs = i2s->regs; - u32 fic, con, mod; - - pr_debug("%s(%d)\n", __func__, on); - - fic = readl(regs + S3C2412_IISFIC); - con = readl(regs + S3C2412_IISCON); - mod = readl(regs + S3C2412_IISMOD); - - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); - - if (on) { - con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; - con &= ~S3C2412_IISCON_TXDMA_PAUSE; - con &= ~S3C2412_IISCON_TXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXONLY: - case S3C2412_IISMOD_MODE_TXRX: - /* do nothing, we are in the right mode */ - break; - - case S3C2412_IISMOD_MODE_RXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXRX; - break; - - default: - dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); - } - - writel(con, regs + S3C2412_IISCON); - writel(mod, regs + S3C2412_IISMOD); - } else { - /* Note, we do not have any indication that the FIFO problems - * tha the S3C2410/2440 had apply here, so we should be able - * to disable the DMA and TX without resetting the FIFOS. - */ - - con |= S3C2412_IISCON_TXDMA_PAUSE; - con |= S3C2412_IISCON_TXCH_PAUSE; - con &= ~S3C2412_IISCON_TXDMA_ACTIVE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXRX: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_RXONLY; - break; - - case S3C2412_IISMOD_MODE_TXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - con &= ~S3C2412_IISCON_IIS_ACTIVE; - break; - - default: - dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); - } - - writel(mod, regs + S3C2412_IISMOD); - writel(con, regs + S3C2412_IISCON); - } - - fic = readl(regs + S3C2412_IISFIC); - dbg_showcon(__func__, con); - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); -} -EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl); - -void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) -{ - void __iomem *regs = i2s->regs; - u32 fic, con, mod; - - pr_debug("%s(%d)\n", __func__, on); - - fic = readl(regs + S3C2412_IISFIC); - con = readl(regs + S3C2412_IISCON); - mod = readl(regs + S3C2412_IISMOD); - - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); - - if (on) { - con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; - con &= ~S3C2412_IISCON_RXDMA_PAUSE; - con &= ~S3C2412_IISCON_RXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXRX: - case S3C2412_IISMOD_MODE_RXONLY: - /* do nothing, we are in the right mode */ - break; - - case S3C2412_IISMOD_MODE_TXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXRX; - break; - - default: - dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); - } - - writel(mod, regs + S3C2412_IISMOD); - writel(con, regs + S3C2412_IISCON); - } else { - /* See txctrl notes on FIFOs. */ - - con &= ~S3C2412_IISCON_RXDMA_ACTIVE; - con |= S3C2412_IISCON_RXDMA_PAUSE; - con |= S3C2412_IISCON_RXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_RXONLY: - con &= ~S3C2412_IISCON_IIS_ACTIVE; - mod &= ~S3C2412_IISMOD_MODE_MASK; - break; - - case S3C2412_IISMOD_MODE_TXRX: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXONLY; - break; - - default: - dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); - } - - writel(con, regs + S3C2412_IISCON); - writel(mod, regs + S3C2412_IISMOD); - } - - fic = readl(regs + S3C2412_IISFIC); - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); -} -EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl); - -/* - * Wait for the LR signal to allow synchronisation to the L/R clock - * from the codec. May only be needed for slave mode. - */ -static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s) -{ - u32 iiscon; - unsigned long timeout = jiffies + msecs_to_jiffies(5); - - pr_debug("Entered %s\n", __func__); - - while (1) { - iiscon = readl(i2s->regs + S3C2412_IISCON); - if (iiscon & S3C2412_IISCON_LRINDEX) - break; - - if (timeout < jiffies) { - printk(KERN_ERR "%s: timeout\n", __func__); - return -ETIMEDOUT; - } - } - - return 0; -} - -/* - * Set S3C2412 I2S DAI format - */ -static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - iismod = readl(i2s->regs + S3C2412_IISMOD); - pr_debug("hw_params r: IISMOD: %x \n", iismod); - -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) -#define IISMOD_MASTER_MASK S3C2412_IISMOD_MASTER_MASK -#define IISMOD_SLAVE S3C2412_IISMOD_SLAVE -#define IISMOD_MASTER S3C2412_IISMOD_MASTER_INTERNAL -#endif - -#if defined(CONFIG_PLAT_S3C64XX) -/* From Rev1.1 datasheet, we have two master and two slave modes: - * IMS[11:10]: - * 00 = master mode, fed from PCLK - * 01 = master mode, fed from CLKAUDIO - * 10 = slave mode, using PCLK - * 11 = slave mode, using I2SCLK - */ -#define IISMOD_MASTER_MASK (1 << 11) -#define IISMOD_SLAVE (1 << 11) -#define IISMOD_MASTER (0x0) -#endif - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - i2s->master = 0; - iismod &= ~IISMOD_MASTER_MASK; - iismod |= IISMOD_SLAVE; - break; - case SND_SOC_DAIFMT_CBS_CFS: - i2s->master = 1; - iismod &= ~IISMOD_MASTER_MASK; - iismod |= IISMOD_MASTER; - break; - default: - pr_debug("unknwon master/slave format\n"); - return -EINVAL; - } - - iismod &= ~S3C2412_IISMOD_SDF_MASK; - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - iismod |= S3C2412_IISMOD_SDF_MSB; - break; - case SND_SOC_DAIFMT_LEFT_J: - iismod |= S3C2412_IISMOD_SDF_LSB; - break; - case SND_SOC_DAIFMT_I2S: - iismod |= S3C2412_IISMOD_SDF_IIS; - break; - default: - pr_debug("Unknown data format\n"); - return -EINVAL; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("hw_params w: IISMOD: %x \n", iismod); - return 0; -} - -static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai_link *dai = rtd->dai; - struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dai->cpu_dai->dma_data = i2s->dma_playback; - else - dai->cpu_dai->dma_data = i2s->dma_capture; - - /* Working copies of register */ - iismod = readl(i2s->regs + S3C2412_IISMOD); - pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - iismod |= S3C2412_IISMOD_8BIT; - break; - case SNDRV_PCM_FORMAT_S16_LE: - iismod &= ~S3C2412_IISMOD_8BIT; - break; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); - return 0; -} - -static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_i2sv2_info *i2s = to_info(rtd->dai->cpu_dai); - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - unsigned long irqs; - int ret = 0; - - pr_debug("Entered %s\n", __func__); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - /* On start, ensure that the FIFOs are cleared and reset. */ - - writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH, - i2s->regs + S3C2412_IISFIC); - - /* clear again, just in case */ - writel(0x0, i2s->regs + S3C2412_IISFIC); - - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (!i2s->master) { - ret = s3c2412_snd_lrsync(i2s); - if (ret) - goto exit_err; - } - - local_irq_save(irqs); - - if (capture) - s3c2412_snd_rxctrl(i2s, 1); - else - s3c2412_snd_txctrl(i2s, 1); - - local_irq_restore(irqs); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - local_irq_save(irqs); - - if (capture) - s3c2412_snd_rxctrl(i2s, 0); - else - s3c2412_snd_txctrl(i2s, 0); - - local_irq_restore(irqs); - break; - default: - ret = -EINVAL; - break; - } - -exit_err: - return ret; -} - -/* - * Set S3C2412 Clock dividers - */ -static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, - int div_id, int div) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 reg; - - pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div); - - switch (div_id) { - case S3C_I2SV2_DIV_BCLK: - reg = readl(i2s->regs + S3C2412_IISMOD); - reg &= ~S3C2412_IISMOD_BCLK_MASK; - writel(reg | div, i2s->regs + S3C2412_IISMOD); - - pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); - break; - - case S3C_I2SV2_DIV_RCLK: - if (div > 3) { - /* convert value to bit field */ - - switch (div) { - case 256: - div = S3C2412_IISMOD_RCLK_256FS; - break; - - case 384: - div = S3C2412_IISMOD_RCLK_384FS; - break; - - case 512: - div = S3C2412_IISMOD_RCLK_512FS; - break; - - case 768: - div = S3C2412_IISMOD_RCLK_768FS; - break; - - default: - return -EINVAL; - } - } - - reg = readl(i2s->regs + S3C2412_IISMOD); - reg &= ~S3C2412_IISMOD_RCLK_MASK; - writel(reg | div, i2s->regs + S3C2412_IISMOD); - pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); - break; - - case S3C_I2SV2_DIV_PRESCALER: - if (div >= 0) { - writel((div << 8) | S3C2412_IISPSR_PSREN, - i2s->regs + S3C2412_IISPSR); - } else { - writel(0x0, i2s->regs + S3C2412_IISPSR); - } - pr_debug("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR)); - break; - - default: - return -EINVAL; - } - - return 0; -} - -/* default table of all avaialable root fs divisors */ -static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; - -int s3c2412_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, - unsigned int *fstab, - unsigned int rate, struct clk *clk) -{ - unsigned long clkrate = clk_get_rate(clk); - unsigned int div; - unsigned int fsclk; - unsigned int actual; - unsigned int fs; - unsigned int fsdiv; - signed int deviation = 0; - unsigned int best_fs = 0; - unsigned int best_div = 0; - unsigned int best_rate = 0; - unsigned int best_deviation = INT_MAX; - - if (fstab == NULL) - fstab = iis_fs_tab; - - for (fs = 0; fs < ARRAY_SIZE(iis_fs_tab); fs++) { - fsdiv = iis_fs_tab[fs]; - - fsclk = clkrate / fsdiv; - div = fsclk / rate; - - if ((fsclk % rate) > (rate / 2)) - div++; - - if (div <= 1) - continue; - - actual = clkrate / (fsdiv * div); - deviation = actual - rate; - - printk(KERN_DEBUG "%dfs: div %d => result %d, deviation %d\n", - fsdiv, div, actual, deviation); - - deviation = abs(deviation); - - if (deviation < best_deviation) { - best_fs = fsdiv; - best_div = div; - best_rate = actual; - best_deviation = deviation; - } - - if (deviation == 0) - break; - } - - printk(KERN_DEBUG "best: fs=%d, div=%d, rate=%d\n", - best_fs, best_div, best_rate); - - info->fs_div = best_fs; - info->clk_div = best_div; - - return 0; -} -EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate); - -int s3c_i2sv2_probe(struct platform_device *pdev, - struct snd_soc_dai *dai, - struct s3c_i2sv2_info *i2s, - unsigned long base) -{ - struct device *dev = &pdev->dev; - - i2s->dev = dev; - - /* record our i2s structure for later use in the callbacks */ - dai->private_data = i2s; - - i2s->regs = ioremap(base, 0x100); - if (i2s->regs == NULL) { - dev_err(dev, "cannot ioremap registers\n"); - return -ENXIO; - } - - i2s->iis_pclk = clk_get(dev, "iis"); - if (i2s->iis_pclk == NULL) { - dev_err(dev, "failed to get iis_clock\n"); - iounmap(i2s->regs); - return -ENOENT; - } - - clk_enable(i2s->iis_pclk); - - s3c2412_snd_txctrl(i2s, 0); - s3c2412_snd_rxctrl(i2s, 0); - - return 0; -} - -EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); - -#ifdef CONFIG_PM -static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - u32 iismod; - - if (dai->active) { - i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD); - i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON); - i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR); - - /* some basic suspend checks */ - - iismod = readl(i2s->regs + S3C2412_IISMOD); - - if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) - pr_warning("%s: RXDMA active?\n", __func__); - - if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) - pr_warning("%s: TXDMA active?\n", __func__); - - if (iismod & S3C2412_IISCON_IIS_ACTIVE) - pr_warning("%s: IIS active\n", __func__); - } - - return 0; -} - -static int s3c2412_i2s_resume(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - - pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n", - dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); - - if (dai->active) { - writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); - writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD); - writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR); - - writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH, - i2s->regs + S3C2412_IISFIC); - - ndelay(250); - writel(0x0, i2s->regs + S3C2412_IISFIC); - } - - return 0; -} -#else -#define s3c2412_i2s_suspend NULL -#define s3c2412_i2s_resume NULL -#endif - -int s3c_i2sv2_register_dai(struct snd_soc_dai *dai) -{ - dai->ops.trigger = s3c2412_i2s_trigger; - dai->ops.hw_params = s3c2412_i2s_hw_params; - dai->ops.set_fmt = s3c2412_i2s_set_fmt; - dai->ops.set_clkdiv = s3c2412_i2s_set_clkdiv; - - dai->suspend = s3c2412_i2s_suspend; - dai->resume = s3c2412_i2s_resume; - - return snd_soc_register_dai(dai); -} - -EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); diff --git a/trunk/sound/soc/s3c24xx/s3c-i2s-v2.h b/trunk/sound/soc/s3c24xx/s3c-i2s-v2.h deleted file mode 100644 index f66854a77fb2..000000000000 --- a/trunk/sound/soc/s3c24xx/s3c-i2s-v2.h +++ /dev/null @@ -1,90 +0,0 @@ -/* sound/soc/s3c24xx/s3c-i2s-v2.h - * - * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver - * - * Copyright (c) 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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 code is the core support for the I2S block found in a number of - * Samsung SoC devices which is unofficially named I2S-V2. Currently the - * S3C2412 and the S3C64XX series use this block to provide 1 or 2 I2S - * channels via configurable GPIO. - */ - -#ifndef __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H -#define __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H __FILE__ - -#define S3C_I2SV2_DIV_BCLK (1) -#define S3C_I2SV2_DIV_RCLK (2) -#define S3C_I2SV2_DIV_PRESCALER (3) - -/** - * struct s3c_i2sv2_info - S3C I2S-V2 information - * @dev: The parent device passed to use from the probe. - * @regs: The pointer to the device registe block. - * @master: True if the I2S core is the I2S bit clock master. - * @dma_playback: DMA information for playback channel. - * @dma_capture: DMA information for capture channel. - * @suspend_iismod: PM save for the IISMOD register. - * @suspend_iiscon: PM save for the IISCON register. - * @suspend_iispsr: PM save for the IISPSR register. - * - * This is the private codec state for the hardware associated with an - * I2S channel such as the register mappings and clock sources. - */ -struct s3c_i2sv2_info { - struct device *dev; - void __iomem *regs; - - struct clk *iis_pclk; - struct clk *iis_cclk; - struct clk *iis_clk; - - unsigned char master; - - struct s3c24xx_pcm_dma_params *dma_playback; - struct s3c24xx_pcm_dma_params *dma_capture; - - u32 suspend_iismod; - u32 suspend_iiscon; - u32 suspend_iispsr; -}; - -struct s3c_i2sv2_rate_calc { - unsigned int clk_div; /* for prescaler */ - unsigned int fs_div; /* for root frame clock */ -}; - -extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, - unsigned int *fstab, - unsigned int rate, struct clk *clk); - -/** - * s3c_i2sv2_probe - probe for i2s device helper - * @pdev: The platform device supplied to the original probe. - * @dai: The ASoC DAI structure supplied to the original probe. - * @i2s: Our local i2s structure to fill in. - * @base: The base address for the registers. - */ -extern int s3c_i2sv2_probe(struct platform_device *pdev, - struct snd_soc_dai *dai, - struct s3c_i2sv2_info *i2s, - unsigned long base); - -/** - * s3c_i2sv2_register_dai - register dai with soc core - * @dai: The snd_soc_dai structure to register - * - * Fill in any missing fields and then register the given dai with the - * soc core. - */ -extern int s3c_i2sv2_register_dai(struct snd_soc_dai *dai); - -#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ diff --git a/trunk/sound/soc/s3c24xx/s3c2412-i2s.c b/trunk/sound/soc/s3c24xx/s3c2412-i2s.c index 1ca3cdaa8213..f3fc0aba0aaf 100644 --- a/trunk/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/trunk/sound/soc/s3c24xx/s3c2412-i2s.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -31,16 +30,26 @@ #include #include -#include +#include +#include + +#include -#include -#include +#include +#include #include #include "s3c24xx-pcm.h" #include "s3c2412-i2s.h" #define S3C2412_I2S_DEBUG 0 +#define S3C2412_I2S_DEBUG_CON 0 + +#if S3C2412_I2S_DEBUG +#define DBG(x...) printk(KERN_INFO x) +#else +#define DBG(x...) do { } while (0) +#endif static struct s3c2410_dma_client s3c2412_dma_client_out = { .name = "I2S PCM Stereo out" @@ -64,7 +73,431 @@ static struct s3c24xx_pcm_dma_params s3c2412_i2s_pcm_stereo_in = { .dma_size = 4, }; -static struct s3c_i2sv2_info s3c2412_i2s; +struct s3c2412_i2s_info { + struct device *dev; + void __iomem *regs; + struct clk *iis_clk; + struct clk *iis_pclk; + struct clk *iis_cclk; + + u32 suspend_iismod; + u32 suspend_iiscon; + u32 suspend_iispsr; +}; + +static struct s3c2412_i2s_info s3c2412_i2s; + +#define bit_set(v, b) (((v) & (b)) ? 1 : 0) + +#if S3C2412_I2S_DEBUG_CON +static void dbg_showcon(const char *fn, u32 con) +{ + printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn, + bit_set(con, S3C2412_IISCON_LRINDEX), + bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY), + bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY), + bit_set(con, S3C2412_IISCON_TXFIFO_FULL), + bit_set(con, S3C2412_IISCON_RXFIFO_FULL)); + + printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n", + fn, + bit_set(con, S3C2412_IISCON_TXDMA_PAUSE), + bit_set(con, S3C2412_IISCON_RXDMA_PAUSE), + bit_set(con, S3C2412_IISCON_TXCH_PAUSE), + bit_set(con, S3C2412_IISCON_RXCH_PAUSE)); + printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn, + bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE), + bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE), + bit_set(con, S3C2412_IISCON_IIS_ACTIVE)); +} +#else +static inline void dbg_showcon(const char *fn, u32 con) +{ +} +#endif + +/* Turn on or off the transmission path. */ +static void s3c2412_snd_txctrl(int on) +{ + struct s3c2412_i2s_info *i2s = &s3c2412_i2s; + void __iomem *regs = i2s->regs; + u32 fic, con, mod; + + DBG("%s(%d)\n", __func__, on); + + fic = readl(regs + S3C2412_IISFIC); + con = readl(regs + S3C2412_IISCON); + mod = readl(regs + S3C2412_IISMOD); + + DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); + + if (on) { + con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; + con &= ~S3C2412_IISCON_TXDMA_PAUSE; + con &= ~S3C2412_IISCON_TXCH_PAUSE; + + switch (mod & S3C2412_IISMOD_MODE_MASK) { + case S3C2412_IISMOD_MODE_TXONLY: + case S3C2412_IISMOD_MODE_TXRX: + /* do nothing, we are in the right mode */ + break; + + case S3C2412_IISMOD_MODE_RXONLY: + mod &= ~S3C2412_IISMOD_MODE_MASK; + mod |= S3C2412_IISMOD_MODE_TXRX; + break; + + default: + dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); + } + + writel(con, regs + S3C2412_IISCON); + writel(mod, regs + S3C2412_IISMOD); + } else { + /* Note, we do not have any indication that the FIFO problems + * tha the S3C2410/2440 had apply here, so we should be able + * to disable the DMA and TX without resetting the FIFOS. + */ + + con |= S3C2412_IISCON_TXDMA_PAUSE; + con |= S3C2412_IISCON_TXCH_PAUSE; + con &= ~S3C2412_IISCON_TXDMA_ACTIVE; + + switch (mod & S3C2412_IISMOD_MODE_MASK) { + case S3C2412_IISMOD_MODE_TXRX: + mod &= ~S3C2412_IISMOD_MODE_MASK; + mod |= S3C2412_IISMOD_MODE_RXONLY; + break; + + case S3C2412_IISMOD_MODE_TXONLY: + mod &= ~S3C2412_IISMOD_MODE_MASK; + con &= ~S3C2412_IISCON_IIS_ACTIVE; + break; + + default: + dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); + } + + writel(mod, regs + S3C2412_IISMOD); + writel(con, regs + S3C2412_IISCON); + } + + fic = readl(regs + S3C2412_IISFIC); + dbg_showcon(__func__, con); + DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); +} + +static void s3c2412_snd_rxctrl(int on) +{ + struct s3c2412_i2s_info *i2s = &s3c2412_i2s; + void __iomem *regs = i2s->regs; + u32 fic, con, mod; + + DBG("%s(%d)\n", __func__, on); + + fic = readl(regs + S3C2412_IISFIC); + con = readl(regs + S3C2412_IISCON); + mod = readl(regs + S3C2412_IISMOD); + + DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); + + if (on) { + con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; + con &= ~S3C2412_IISCON_RXDMA_PAUSE; + con &= ~S3C2412_IISCON_RXCH_PAUSE; + + switch (mod & S3C2412_IISMOD_MODE_MASK) { + case S3C2412_IISMOD_MODE_TXRX: + case S3C2412_IISMOD_MODE_RXONLY: + /* do nothing, we are in the right mode */ + break; + + case S3C2412_IISMOD_MODE_TXONLY: + mod &= ~S3C2412_IISMOD_MODE_MASK; + mod |= S3C2412_IISMOD_MODE_TXRX; + break; + + default: + dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); + } + + writel(mod, regs + S3C2412_IISMOD); + writel(con, regs + S3C2412_IISCON); + } else { + /* See txctrl notes on FIFOs. */ + + con &= ~S3C2412_IISCON_RXDMA_ACTIVE; + con |= S3C2412_IISCON_RXDMA_PAUSE; + con |= S3C2412_IISCON_RXCH_PAUSE; + + switch (mod & S3C2412_IISMOD_MODE_MASK) { + case S3C2412_IISMOD_MODE_RXONLY: + con &= ~S3C2412_IISCON_IIS_ACTIVE; + mod &= ~S3C2412_IISMOD_MODE_MASK; + break; + + case S3C2412_IISMOD_MODE_TXRX: + mod &= ~S3C2412_IISMOD_MODE_MASK; + mod |= S3C2412_IISMOD_MODE_TXONLY; + break; + + default: + dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); + } + + writel(con, regs + S3C2412_IISCON); + writel(mod, regs + S3C2412_IISMOD); + } + + fic = readl(regs + S3C2412_IISFIC); + DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); +} + + +/* + * Wait for the LR signal to allow synchronisation to the L/R clock + * from the codec. May only be needed for slave mode. + */ +static int s3c2412_snd_lrsync(void) +{ + u32 iiscon; + unsigned long timeout = jiffies + msecs_to_jiffies(5); + + DBG("Entered %s\n", __func__); + + while (1) { + iiscon = readl(s3c2412_i2s.regs + S3C2412_IISCON); + if (iiscon & S3C2412_IISCON_LRINDEX) + break; + + if (timeout < jiffies) { + printk(KERN_ERR "%s: timeout\n", __func__); + return -ETIMEDOUT; + } + } + + return 0; +} + +/* + * Check whether CPU is the master or slave + */ +static inline int s3c2412_snd_is_clkmaster(void) +{ + u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); + + DBG("Entered %s\n", __func__); + + iismod &= S3C2412_IISMOD_MASTER_MASK; + return !(iismod == S3C2412_IISMOD_SLAVE); +} + +/* + * Set S3C2412 I2S DAI format + */ +static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + u32 iismod; + + + DBG("Entered %s\n", __func__); + + iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); + DBG("hw_params r: IISMOD: %x \n", iismod); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iismod &= ~S3C2412_IISMOD_MASTER_MASK; + iismod |= S3C2412_IISMOD_SLAVE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + iismod &= ~S3C2412_IISMOD_MASTER_MASK; + iismod |= S3C2412_IISMOD_MASTER_INTERNAL; + break; + default: + DBG("unknwon master/slave format\n"); + return -EINVAL; + } + + iismod &= ~S3C2412_IISMOD_SDF_MASK; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + iismod |= S3C2412_IISMOD_SDF_MSB; + break; + case SND_SOC_DAIFMT_LEFT_J: + iismod |= S3C2412_IISMOD_SDF_LSB; + break; + case SND_SOC_DAIFMT_I2S: + iismod |= S3C2412_IISMOD_SDF_IIS; + break; + default: + DBG("Unknown data format\n"); + return -EINVAL; + } + + writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD); + DBG("hw_params w: IISMOD: %x \n", iismod); + return 0; +} + +static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + u32 iismod; + + DBG("Entered %s\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + rtd->dai->cpu_dai->dma_data = &s3c2412_i2s_pcm_stereo_out; + else + rtd->dai->cpu_dai->dma_data = &s3c2412_i2s_pcm_stereo_in; + + /* Working copies of register */ + iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); + DBG("%s: r: IISMOD: %x\n", __func__, iismod); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + iismod |= S3C2412_IISMOD_8BIT; + break; + case SNDRV_PCM_FORMAT_S16_LE: + iismod &= ~S3C2412_IISMOD_8BIT; + break; + } + + writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD); + DBG("%s: w: IISMOD: %x\n", __func__, iismod); + return 0; +} + +static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + unsigned long irqs; + int ret = 0; + + DBG("Entered %s\n", __func__); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* On start, ensure that the FIFOs are cleared and reset. */ + + writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH, + s3c2412_i2s.regs + S3C2412_IISFIC); + + /* clear again, just in case */ + writel(0x0, s3c2412_i2s.regs + S3C2412_IISFIC); + + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!s3c2412_snd_is_clkmaster()) { + ret = s3c2412_snd_lrsync(); + if (ret) + goto exit_err; + } + + local_irq_save(irqs); + + if (capture) + s3c2412_snd_rxctrl(1); + else + s3c2412_snd_txctrl(1); + + local_irq_restore(irqs); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + local_irq_save(irqs); + + if (capture) + s3c2412_snd_rxctrl(0); + else + s3c2412_snd_txctrl(0); + + local_irq_restore(irqs); + break; + default: + ret = -EINVAL; + break; + } + +exit_err: + return ret; +} + +/* default table of all avaialable root fs divisors */ +static unsigned int s3c2412_iis_fs[] = { 256, 512, 384, 768, 0 }; + +int s3c2412_iis_calc_rate(struct s3c2412_rate_calc *info, + unsigned int *fstab, + unsigned int rate, struct clk *clk) +{ + unsigned long clkrate = clk_get_rate(clk); + unsigned int div; + unsigned int fsclk; + unsigned int actual; + unsigned int fs; + unsigned int fsdiv; + signed int deviation = 0; + unsigned int best_fs = 0; + unsigned int best_div = 0; + unsigned int best_rate = 0; + unsigned int best_deviation = INT_MAX; + + + if (fstab == NULL) + fstab = s3c2412_iis_fs; + + for (fs = 0;; fs++) { + fsdiv = s3c2412_iis_fs[fs]; + + if (fsdiv == 0) + break; + + fsclk = clkrate / fsdiv; + div = fsclk / rate; + + if ((fsclk % rate) > (rate / 2)) + div++; + + if (div <= 1) + continue; + + actual = clkrate / (fsdiv * div); + deviation = actual - rate; + + printk(KERN_DEBUG "%dfs: div %d => result %d, deviation %d\n", + fsdiv, div, actual, deviation); + + deviation = abs(deviation); + + if (deviation < best_deviation) { + best_fs = fsdiv; + best_div = div; + best_rate = actual; + best_deviation = deviation; + } + + if (deviation == 0) + break; + } + + printk(KERN_DEBUG "best: fs=%d, div=%d, rate=%d\n", + best_fs, best_div, best_rate); + + info->fs_div = best_fs; + info->clk_div = best_div; + + return 0; +} +EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate); /* * Set S3C2412 Clock source @@ -74,17 +507,15 @@ static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, { u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); - pr_debug("%s(%p, %d, %u, %d)\n", __func__, cpu_dai, clk_id, + DBG("%s(%p, %d, %u, %d)\n", __func__, cpu_dai, clk_id, freq, dir); switch (clk_id) { case S3C2412_CLKSRC_PCLK: - s3c2412_i2s.master = 1; iismod &= ~S3C2412_IISMOD_MASTER_MASK; iismod |= S3C2412_IISMOD_MASTER_INTERNAL; break; case S3C2412_CLKSRC_I2SCLK: - s3c2412_i2s.master = 0; iismod &= ~S3C2412_IISMOD_MASTER_MASK; iismod |= S3C2412_IISMOD_MASTER_EXTERNAL; break; @@ -96,6 +527,74 @@ static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, return 0; } +/* + * Set S3C2412 Clock dividers + */ +static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, + int div_id, int div) +{ + struct s3c2412_i2s_info *i2s = &s3c2412_i2s; + u32 reg; + + DBG("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div); + + switch (div_id) { + case S3C2412_DIV_BCLK: + reg = readl(i2s->regs + S3C2412_IISMOD); + reg &= ~S3C2412_IISMOD_BCLK_MASK; + writel(reg | div, i2s->regs + S3C2412_IISMOD); + + DBG("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); + break; + + case S3C2412_DIV_RCLK: + if (div > 3) { + /* convert value to bit field */ + + switch (div) { + case 256: + div = S3C2412_IISMOD_RCLK_256FS; + break; + + case 384: + div = S3C2412_IISMOD_RCLK_384FS; + break; + + case 512: + div = S3C2412_IISMOD_RCLK_512FS; + break; + + case 768: + div = S3C2412_IISMOD_RCLK_768FS; + break; + + default: + return -EINVAL; + } + } + + reg = readl(s3c2412_i2s.regs + S3C2412_IISMOD); + reg &= ~S3C2412_IISMOD_RCLK_MASK; + writel(reg | div, i2s->regs + S3C2412_IISMOD); + DBG("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); + break; + + case S3C2412_DIV_PRESCALER: + if (div >= 0) { + writel((div << 8) | S3C2412_IISPSR_PSREN, + i2s->regs + S3C2412_IISPSR); + } else { + writel(0x0, i2s->regs + S3C2412_IISPSR); + } + DBG("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR)); + break; + + default: + return -EINVAL; + } + + return 0; +} struct clk *s3c2412_get_iisclk(void) { @@ -107,30 +606,34 @@ EXPORT_SYMBOL_GPL(s3c2412_get_iisclk); static int s3c2412_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) { - int ret; + DBG("Entered %s\n", __func__); - pr_debug("Entered %s\n", __func__); + s3c2412_i2s.dev = &pdev->dev; - ret = s3c_i2sv2_probe(pdev, dai, &s3c2412_i2s, S3C2410_PA_IIS); - if (ret) - return ret; + s3c2412_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); + if (s3c2412_i2s.regs == NULL) + return -ENXIO; - s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; - s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; + s3c2412_i2s.iis_pclk = clk_get(&pdev->dev, "iis"); + if (s3c2412_i2s.iis_pclk == NULL) { + DBG("failed to get iis_clock\n"); + iounmap(s3c2412_i2s.regs); + return -ENODEV; + } s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk"); if (s3c2412_i2s.iis_cclk == NULL) { - pr_debug("failed to get i2sclk clock\n"); + DBG("failed to get i2sclk clock\n"); iounmap(s3c2412_i2s.regs); return -ENODEV; } - /* Set MPLL as the source for IIS CLK */ - clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); + + clk_enable(s3c2412_i2s.iis_pclk); clk_enable(s3c2412_i2s.iis_cclk); - s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; + s3c2412_i2s.iis_clk = s3c2412_i2s.iis_pclk; /* Configure the I2S pins in correct mode */ s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); @@ -139,22 +642,78 @@ static int s3c2412_i2s_probe(struct platform_device *pdev, s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); + s3c2412_snd_txctrl(0); + s3c2412_snd_rxctrl(0); + return 0; } +#ifdef CONFIG_PM +static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) +{ + struct s3c2412_i2s_info *i2s = &s3c2412_i2s; + u32 iismod; + + if (dai->active) { + i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD); + i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON); + i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR); + + /* some basic suspend checks */ + + iismod = readl(i2s->regs + S3C2412_IISMOD); + + if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) + pr_warning("%s: RXDMA active?\n", __func__); + + if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) + pr_warning("%s: TXDMA active?\n", __func__); + + if (iismod & S3C2412_IISCON_IIS_ACTIVE) + pr_warning("%s: IIS active\n", __func__); + } + + return 0; +} + +static int s3c2412_i2s_resume(struct snd_soc_dai *dai) +{ + struct s3c2412_i2s_info *i2s = &s3c2412_i2s; + + pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n", + dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); + + if (dai->active) { + writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); + writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD); + writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR); + + writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH, + i2s->regs + S3C2412_IISFIC); + + ndelay(250); + writel(0x0, i2s->regs + S3C2412_IISFIC); + + } + + return 0; +} +#else +#define s3c2412_i2s_suspend NULL +#define s3c2412_i2s_resume NULL +#endif /* CONFIG_PM */ + #define S3C2412_I2S_RATES \ (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) -static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { - .set_sysclk = s3c2412_i2s_set_sysclk, -}; - struct snd_soc_dai s3c2412_i2s_dai = { - .name = "s3c2412-i2s", - .id = 0, - .probe = s3c2412_i2s_probe, + .name = "s3c2412-i2s", + .id = 0, + .probe = s3c2412_i2s_probe, + .suspend = s3c2412_i2s_suspend, + .resume = s3c2412_i2s_resume, .playback = { .channels_min = 2, .channels_max = 2, @@ -167,13 +726,19 @@ struct snd_soc_dai s3c2412_i2s_dai = { .rates = S3C2412_I2S_RATES, .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &s3c2412_i2s_dai_ops, + .ops = { + .trigger = s3c2412_i2s_trigger, + .hw_params = s3c2412_i2s_hw_params, + .set_fmt = s3c2412_i2s_set_fmt, + .set_clkdiv = s3c2412_i2s_set_clkdiv, + .set_sysclk = s3c2412_i2s_set_sysclk, + }, }; EXPORT_SYMBOL_GPL(s3c2412_i2s_dai); static int __init s3c2412_i2s_init(void) { - return s3c_i2sv2_register_dai(&s3c2412_i2s_dai); + return snd_soc_register_dai(&s3c2412_i2s_dai); } module_init(s3c2412_i2s_init); @@ -183,6 +748,7 @@ static void __exit s3c2412_i2s_exit(void) } module_exit(s3c2412_i2s_exit); + /* Module information */ MODULE_AUTHOR("Ben Dooks, "); MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); diff --git a/trunk/sound/soc/s3c24xx/s3c2412-i2s.h b/trunk/sound/soc/s3c24xx/s3c2412-i2s.h index 92848e54be16..aac08a25e541 100644 --- a/trunk/sound/soc/s3c24xx/s3c2412-i2s.h +++ b/trunk/sound/soc/s3c24xx/s3c2412-i2s.h @@ -15,11 +15,9 @@ #ifndef __SND_SOC_S3C24XX_S3C2412_I2S_H #define __SND_SOC_S3C24XX_S3C2412_I2S_H __FILE__ -#include "s3c-i2s-v2.h" - -#define S3C2412_DIV_BCLK S3C_I2SV2_DIV_BCLK -#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK -#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER +#define S3C2412_DIV_BCLK (1) +#define S3C2412_DIV_RCLK (2) +#define S3C2412_DIV_PRESCALER (3) #define S3C2412_CLKSRC_PCLK (0) #define S3C2412_CLKSRC_I2SCLK (1) @@ -28,4 +26,13 @@ extern struct clk *s3c2412_get_iisclk(void); extern struct snd_soc_dai s3c2412_i2s_dai; +struct s3c2412_rate_calc { + unsigned int clk_div; /* for prescaler */ + unsigned int fs_div; /* for root frame clock */ +}; + +extern int s3c2412_iis_calc_rate(struct s3c2412_rate_calc *info, + unsigned int *fstab, + unsigned int rate, struct clk *clk); + #endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */ diff --git a/trunk/sound/soc/s3c24xx/s3c2443-ac97.c b/trunk/sound/soc/s3c24xx/s3c2443-ac97.c index 3698f707c44d..5822d2dd49ba 100644 --- a/trunk/sound/soc/s3c24xx/s3c2443-ac97.c +++ b/trunk/sound/soc/s3c24xx/s3c2443-ac97.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include @@ -355,16 +355,6 @@ static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops s3c2443_ac97_dai_ops = { - .hw_params = s3c2443_ac97_hw_params, - .trigger = s3c2443_ac97_trigger, -}; - -static struct snd_soc_dai_ops s3c2443_ac97_mic_dai_ops = { - .hw_params = s3c2443_ac97_hw_mic_params, - .trigger = s3c2443_ac97_mic_trigger, -}; - struct snd_soc_dai s3c2443_ac97_dai[] = { { .name = "s3c2443-ac97", @@ -384,7 +374,9 @@ struct snd_soc_dai s3c2443_ac97_dai[] = { .channels_max = 2, .rates = s3c2443_AC97_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c2443_ac97_dai_ops, + .ops = { + .hw_params = s3c2443_ac97_hw_params, + .trigger = s3c2443_ac97_trigger}, }, { .name = "pxa2xx-ac97-mic", @@ -396,7 +388,9 @@ struct snd_soc_dai s3c2443_ac97_dai[] = { .channels_max = 1, .rates = s3c2443_AC97_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c2443_ac97_mic_dai_ops, + .ops = { + .hw_params = s3c2443_ac97_hw_mic_params, + .trigger = s3c2443_ac97_mic_trigger,}, }, }; EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c index cc066964dad6..6f4d439b57aa 100644 --- a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -4,7 +4,7 @@ * (c) 2006 Wolfson Microelectronics PLC. * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com * - * Copyright 2004-2005 Simtec Electronics + * (c) 2004-2005 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks * @@ -30,15 +30,22 @@ #include #include #include -#include +#include #include #include -#include +#include #include "s3c24xx-pcm.h" #include "s3c24xx-i2s.h" +#define S3C24XX_I2S_DEBUG 0 +#if S3C24XX_I2S_DEBUG +#define DBG(x...) printk(KERN_DEBUG "s3c24xx-i2s: " x) +#else +#define DBG(x...) +#endif + static struct s3c2410_dma_client s3c24xx_dma_client_out = { .name = "I2S PCM Stereo out" }; @@ -77,13 +84,13 @@ static void s3c24xx_snd_txctrl(int on) u32 iiscon; u32 iismod; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); + DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); if (on) { iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE; @@ -113,7 +120,7 @@ static void s3c24xx_snd_txctrl(int on) writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); } - pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); + DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); } static void s3c24xx_snd_rxctrl(int on) @@ -122,13 +129,13 @@ static void s3c24xx_snd_rxctrl(int on) u32 iiscon; u32 iismod; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); + DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); if (on) { iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; @@ -158,7 +165,7 @@ static void s3c24xx_snd_rxctrl(int on) writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); } - pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); + DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); } /* @@ -170,7 +177,7 @@ static int s3c24xx_snd_lrsync(void) u32 iiscon; int timeout = 50; /* 5ms */ - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); while (1) { iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); @@ -190,7 +197,7 @@ static int s3c24xx_snd_lrsync(void) */ static inline int s3c24xx_snd_is_clkmaster(void) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1; } @@ -203,10 +210,10 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, { u32 iismod; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params r: IISMOD: %x \n", iismod); + DBG("hw_params r: IISMOD: %lx \n", iismod); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: @@ -231,7 +238,7 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, } writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params w: IISMOD: %x \n", iismod); + DBG("hw_params w: IISMOD: %lx \n", iismod); return 0; } @@ -242,7 +249,7 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; u32 iismod; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; @@ -251,7 +258,7 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, /* Working copies of register */ iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params r: IISMOD: %x\n", iismod); + DBG("hw_params r: IISMOD: %lx\n", iismod); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: @@ -269,7 +276,7 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, } writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params w: IISMOD: %x\n", iismod); + DBG("hw_params w: IISMOD: %lx\n", iismod); return 0; } @@ -278,7 +285,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, { int ret = 0; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -320,7 +327,7 @@ static int s3c24xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, { u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); iismod &= ~S3C2440_IISMOD_MPLL; @@ -346,7 +353,7 @@ static int s3c24xx_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, { u32 reg; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); switch (div_id) { case S3C24XX_DIV_BCLK: @@ -382,7 +389,7 @@ EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); static int s3c24xx_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); if (s3c24xx_i2s.regs == NULL) @@ -390,7 +397,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev, s3c24xx_i2s.iis_clk = clk_get(&pdev->dev, "iis"); if (s3c24xx_i2s.iis_clk == NULL) { - pr_err("failed to get iis_clock\n"); + DBG("failed to get iis_clock\n"); iounmap(s3c24xx_i2s.regs); return -ENODEV; } @@ -414,7 +421,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev, #ifdef CONFIG_PM static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); s3c24xx_i2s.iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); s3c24xx_i2s.iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); @@ -428,7 +435,7 @@ static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai) static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) { - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); clk_enable(s3c24xx_i2s.iis_clk); writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); @@ -449,14 +456,6 @@ static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) -static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { - .trigger = s3c24xx_i2s_trigger, - .hw_params = s3c24xx_i2s_hw_params, - .set_fmt = s3c24xx_i2s_set_fmt, - .set_clkdiv = s3c24xx_i2s_set_clkdiv, - .set_sysclk = s3c24xx_i2s_set_sysclk, -}; - struct snd_soc_dai s3c24xx_i2s_dai = { .name = "s3c24xx-i2s", .id = 0, @@ -473,7 +472,13 @@ struct snd_soc_dai s3c24xx_i2s_dai = { .channels_max = 2, .rates = S3C24XX_I2S_RATES, .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c24xx_i2s_dai_ops, + .ops = { + .trigger = s3c24xx_i2s_trigger, + .hw_params = s3c24xx_i2s_hw_params, + .set_fmt = s3c24xx_i2s_set_fmt, + .set_clkdiv = s3c24xx_i2s_set_clkdiv, + .set_sysclk = s3c24xx_i2s_set_sysclk, + }, }; EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c index a9d68fa2b34a..7c64d31d067e 100644 --- a/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -4,7 +4,7 @@ * (c) 2006 Wolfson Microelectronics PLC. * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com * - * Copyright 2004-2005 Simtec Electronics + * (c) 2004-2005 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks * @@ -29,10 +29,17 @@ #include #include #include -#include +#include #include "s3c24xx-pcm.h" +#define S3C24XX_PCM_DEBUG 0 +#if S3C24XX_PCM_DEBUG +#define DBG(x...) printk(KERN_DEBUG "s3c24xx-pcm: " x) +#else +#define DBG(x...) +#endif + static const struct snd_pcm_hardware s3c24xx_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -77,16 +84,16 @@ static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) dma_addr_t pos = prtd->dma_pos; int ret; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); while (prtd->dma_loaded < prtd->dma_limit) { unsigned long len = prtd->dma_period; - pr_debug("dma_loaded: %d\n", prtd->dma_loaded); + DBG("dma_loaded: %d\n", prtd->dma_loaded); if ((pos + len) > prtd->dma_end) { len = prtd->dma_end - pos; - pr_debug(KERN_DEBUG "%s: corrected dma len %ld\n", + DBG(KERN_DEBUG "%s: corrected dma len %ld\n", __func__, len); } @@ -112,7 +119,7 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, struct snd_pcm_substream *substream = dev_id; struct s3c24xx_runtime_data *prtd; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) return; @@ -141,7 +148,7 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, unsigned long totbytes = params_buffer_bytes(params); int ret = 0; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ @@ -154,14 +161,14 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, /* prepare DMA */ prtd->params = dma; - pr_debug("params %p, client %p, channel %d\n", prtd->params, + DBG("params %p, client %p, channel %d\n", prtd->params, prtd->params->client, prtd->params->channel); ret = s3c2410_dma_request(prtd->params->channel, prtd->params->client, NULL); if (ret < 0) { - printk(KERN_ERR "failed to get dma channel\n"); + DBG(KERN_ERR "failed to get dma channel\n"); return ret; } } @@ -189,7 +196,7 @@ static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream) { struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); /* TODO - do we need to ensure DMA flushed */ snd_pcm_set_runtime_buffer(substream, NULL); @@ -207,7 +214,7 @@ static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream) struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; int ret = 0; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ @@ -252,7 +259,7 @@ static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; int ret = 0; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); spin_lock(&prtd->lock); @@ -290,7 +297,7 @@ s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) unsigned long res; dma_addr_t src, dst; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); spin_lock(&prtd->lock); s3c2410_dma_getposition(prtd->params->channel, &src, &dst); @@ -302,7 +309,7 @@ s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) spin_unlock(&prtd->lock); - pr_debug("Pointer %x %x\n", src, dst); + DBG("Pointer %x %x\n", src, dst); /* we seem to be getting the odd error from the pcm library due * to out-of-bounds pointers. this is maybe due to the dma engine @@ -323,7 +330,7 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct s3c24xx_runtime_data *prtd; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); @@ -342,10 +349,10 @@ static int s3c24xx_pcm_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct s3c24xx_runtime_data *prtd = runtime->private_data; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (!prtd) - pr_debug("s3c24xx_pcm_close called with prtd == NULL\n"); + DBG("s3c24xx_pcm_close called with prtd == NULL\n"); kfree(prtd); @@ -357,7 +364,7 @@ static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); return dma_mmap_writecombine(substream->pcm->card->dev, vma, runtime->dma_area, @@ -383,7 +390,7 @@ static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) struct snd_dma_buffer *buf = &substream->dma_buffer; size_t size = s3c24xx_pcm_hardware.buffer_bytes_max; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); buf->dev.type = SNDRV_DMA_TYPE_DEV; buf->dev.dev = pcm->card->dev; @@ -402,7 +409,7 @@ static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm) struct snd_dma_buffer *buf; int stream; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); for (stream = 0; stream < 2; stream++) { substream = pcm->streams[stream].substream; @@ -426,7 +433,7 @@ static int s3c24xx_pcm_new(struct snd_card *card, { int ret = 0; - pr_debug("Entered %s\n", __func__); + DBG("Entered %s\n", __func__); if (!card->dev->dma_mask) card->dev->dma_mask = &s3c24xx_pcm_dmamask; diff --git a/trunk/sound/soc/s3c24xx/s3c24xx_uda134x.c b/trunk/sound/soc/s3c24xx/s3c24xx_uda134x.c index 8e79a416db57..a0a4d1832a14 100644 --- a/trunk/sound/soc/s3c24xx/s3c24xx_uda134x.c +++ b/trunk/sound/soc/s3c24xx/s3c24xx_uda134x.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include "s3c24xx-pcm.h" #include "s3c24xx-i2s.h" diff --git a/trunk/sound/soc/s3c24xx/s3c64xx-i2s.c b/trunk/sound/soc/s3c24xx/s3c64xx-i2s.c deleted file mode 100644 index 33c5de7e255f..000000000000 --- a/trunk/sound/soc/s3c24xx/s3c64xx-i2s.c +++ /dev/null @@ -1,222 +0,0 @@ -/* sound/soc/s3c24xx/s3c64xx-i2s.c - * - * ALSA SoC Audio Layer - S3C64XX I2S driver - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "s3c24xx-pcm.h" -#include "s3c64xx-i2s.h" - -static struct s3c2410_dma_client s3c64xx_dma_client_out = { - .name = "I2S PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c64xx_dma_client_in = { - .name = "I2S PCM Stereo in" -}; - -static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_out[2] = { - [0] = { - .channel = DMACH_I2S0_OUT, - .client = &s3c64xx_dma_client_out, - .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD, - .dma_size = 4, - }, - [1] = { - .channel = DMACH_I2S1_OUT, - .client = &s3c64xx_dma_client_out, - .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD, - .dma_size = 4, - }, -}; - -static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_in[2] = { - [0] = { - .channel = DMACH_I2S0_IN, - .client = &s3c64xx_dma_client_in, - .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD, - .dma_size = 4, - }, - [1] = { - .channel = DMACH_I2S1_IN, - .client = &s3c64xx_dma_client_in, - .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD, - .dma_size = 4, - }, -}; - -static struct s3c_i2sv2_info s3c64xx_i2s[2]; - -static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) -{ - return cpu_dai->private_data; -} - -static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 iismod = readl(i2s->regs + S3C2412_IISMOD); - - switch (clk_id) { - case S3C64XX_CLKSRC_PCLK: - iismod &= ~S3C64XX_IISMOD_IMS_SYSMUX; - break; - - case S3C64XX_CLKSRC_MUX: - iismod |= S3C64XX_IISMOD_IMS_SYSMUX; - break; - - default: - return -EINVAL; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - - return 0; -} - - -unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - - return clk_get_rate(i2s->iis_cclk); -} -EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); - -static int s3c64xx_i2s_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ - struct device *dev = &pdev->dev; - struct s3c_i2sv2_info *i2s; - int ret; - - dev_dbg(dev, "%s: probing dai %d\n", __func__, pdev->id); - - if (pdev->id < 0 || pdev->id > ARRAY_SIZE(s3c64xx_i2s)) { - dev_err(dev, "id %d out of range\n", pdev->id); - return -EINVAL; - } - - i2s = &s3c64xx_i2s[pdev->id]; - - ret = s3c_i2sv2_probe(pdev, dai, i2s, - pdev->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0); - if (ret) - return ret; - - i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; - i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; - - i2s->iis_cclk = clk_get(dev, "audio-bus"); - if (IS_ERR(i2s->iis_cclk)) { - dev_err(dev, "failed to get audio-bus"); - iounmap(i2s->regs); - return -ENODEV; - } - - /* configure GPIO for i2s port */ - switch (pdev->id) { - case 0: - s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); - s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); - s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK); - s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI); - s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0); - break; - case 1: - s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK); - s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK); - s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK); - s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI); - s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0); - } - - return 0; -} - - -#define S3C64XX_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) - -#define S3C64XX_I2S_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) - -static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { - .set_sysclk = s3c64xx_i2s_set_sysclk, -}; - -struct snd_soc_dai s3c64xx_i2s_dai = { - .name = "s3c64xx-i2s", - .id = 0, - .probe = s3c64xx_i2s_probe, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .ops = &s3c64xx_i2s_dai_ops, -}; -EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); - -static int __init s3c64xx_i2s_init(void) -{ - return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai); -} -module_init(s3c64xx_i2s_init); - -static void __exit s3c64xx_i2s_exit(void) -{ - snd_soc_unregister_dai(&s3c64xx_i2s_dai); -} -module_exit(s3c64xx_i2s_exit); - -/* Module information */ -MODULE_AUTHOR("Ben Dooks, "); -MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); -MODULE_LICENSE("GPL"); - - - diff --git a/trunk/sound/soc/s3c24xx/s3c64xx-i2s.h b/trunk/sound/soc/s3c24xx/s3c64xx-i2s.h deleted file mode 100644 index b7ffe3c38b66..000000000000 --- a/trunk/sound/soc/s3c24xx/s3c64xx-i2s.h +++ /dev/null @@ -1,31 +0,0 @@ -/* sound/soc/s3c24xx/s3c64xx-i2s.h - * - * ALSA SoC Audio Layer - S3C64XX I2S driver - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * 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. - */ - -#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H -#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__ - -#include "s3c-i2s-v2.h" - -#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK -#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK -#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER - -#define S3C64XX_CLKSRC_PCLK (0) -#define S3C64XX_CLKSRC_MUX (1) - -extern struct snd_soc_dai s3c64xx_i2s_dai; - -extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); - -#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ diff --git a/trunk/sound/soc/sh/hac.c b/trunk/sound/soc/sh/hac.c index 41db75af3c69..eab31838badf 100644 --- a/trunk/sound/soc/sh/hac.c +++ b/trunk/sound/soc/sh/hac.c @@ -267,10 +267,6 @@ static int hac_hw_params(struct snd_pcm_substream *substream, #define AC97_FMTS \ SNDRV_PCM_FMTBIT_S16_LE -static struct snd_soc_dai_ops hac_dai_ops = { - .hw_params = hac_hw_params, -}; - struct snd_soc_dai sh4_hac_dai[] = { { .name = "HAC0", @@ -288,7 +284,9 @@ struct snd_soc_dai sh4_hac_dai[] = { .channels_min = 2, .channels_max = 2, }, - .ops = &hac_dai_ops, + .ops = { + .hw_params = hac_hw_params, + }, }, #ifdef CONFIG_CPU_SUBTYPE_SH7760 { @@ -307,7 +305,9 @@ struct snd_soc_dai sh4_hac_dai[] = { .channels_min = 2, .channels_max = 2, }, - .ops = &hac_dai_ops, + .ops = { + .hw_params = hac_hw_params, + }, }, #endif diff --git a/trunk/sound/soc/sh/ssi.c b/trunk/sound/soc/sh/ssi.c index 56fa0872abbb..d1e5390fddeb 100644 --- a/trunk/sound/soc/sh/ssi.c +++ b/trunk/sound/soc/sh/ssi.c @@ -336,16 +336,6 @@ static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) -static struct snd_soc_dai_ops ssi_dai_ops = { - .startup = ssi_startup, - .shutdown = ssi_shutdown, - .trigger = ssi_trigger, - .hw_params = ssi_hw_params, - .set_sysclk = ssi_set_sysclk, - .set_clkdiv = ssi_set_clkdiv, - .set_fmt = ssi_set_fmt, -}; - struct snd_soc_dai sh4_ssi_dai[] = { { .name = "SSI0", @@ -362,7 +352,15 @@ struct snd_soc_dai sh4_ssi_dai[] = { .channels_min = 2, .channels_max = 8, }, - .ops = &ssi_dai_ops, + .ops = { + .startup = ssi_startup, + .shutdown = ssi_shutdown, + .trigger = ssi_trigger, + .hw_params = ssi_hw_params, + .set_sysclk = ssi_set_sysclk, + .set_clkdiv = ssi_set_clkdiv, + .set_fmt = ssi_set_fmt, + }, }, #ifdef CONFIG_CPU_SUBTYPE_SH7760 { @@ -380,7 +378,15 @@ struct snd_soc_dai sh4_ssi_dai[] = { .channels_min = 2, .channels_max = 8, }, - .ops = &ssi_dai_ops, + .ops = { + .startup = ssi_startup, + .shutdown = ssi_shutdown, + .trigger = ssi_trigger, + .hw_params = ssi_hw_params, + .set_sysclk = ssi_set_sysclk, + .set_clkdiv = ssi_set_clkdiv, + .set_fmt = ssi_set_fmt, + }, }, #endif }; diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index 6e710f705a74..ec3f8bb4b51d 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -133,8 +133,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) mutex_lock(&pcm_mutex); /* startup the audio subsystem */ - if (cpu_dai->ops->startup) { - ret = cpu_dai->ops->startup(substream, cpu_dai); + if (cpu_dai->ops.startup) { + ret = cpu_dai->ops.startup(substream, cpu_dai); if (ret < 0) { printk(KERN_ERR "asoc: can't open interface %s\n", cpu_dai->name); @@ -150,8 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) } } - if (codec_dai->ops->startup) { - ret = codec_dai->ops->startup(substream, codec_dai); + if (codec_dai->ops.startup) { + ret = codec_dai->ops.startup(substream, codec_dai); if (ret < 0) { printk(KERN_ERR "asoc: can't open codec %s\n", codec_dai->name); @@ -234,7 +234,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) cpu_dai->capture.active = codec_dai->capture.active = 1; cpu_dai->active = codec_dai->active = 1; cpu_dai->runtime = runtime; - card->codec->active++; + socdev->codec->active++; mutex_unlock(&pcm_mutex); return 0; @@ -247,8 +247,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) platform->pcm_ops->close(substream); platform_err: - if (cpu_dai->ops->shutdown) - cpu_dai->ops->shutdown(substream, cpu_dai); + if (cpu_dai->ops.shutdown) + cpu_dai->ops.shutdown(substream, cpu_dai); out: mutex_unlock(&pcm_mutex); return ret; @@ -264,7 +264,7 @@ static void close_delayed_work(struct work_struct *work) struct snd_soc_card *card = container_of(work, struct snd_soc_card, delayed_work.work); struct snd_soc_device *socdev = card->socdev; - struct snd_soc_codec *codec = card->codec; + struct snd_soc_codec *codec = socdev->codec; struct snd_soc_dai *codec_dai; int i; @@ -319,7 +319,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream) struct snd_soc_platform *platform = card->platform; struct snd_soc_dai *cpu_dai = machine->cpu_dai; struct snd_soc_dai *codec_dai = machine->codec_dai; - struct snd_soc_codec *codec = card->codec; + struct snd_soc_codec *codec = socdev->codec; mutex_lock(&pcm_mutex); @@ -340,11 +340,11 @@ static int soc_codec_close(struct snd_pcm_substream *substream) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) snd_soc_dai_digital_mute(codec_dai, 1); - if (cpu_dai->ops->shutdown) - cpu_dai->ops->shutdown(substream, cpu_dai); + if (cpu_dai->ops.shutdown) + cpu_dai->ops.shutdown(substream, cpu_dai); - if (codec_dai->ops->shutdown) - codec_dai->ops->shutdown(substream, codec_dai); + if (codec_dai->ops.shutdown) + codec_dai->ops.shutdown(substream, codec_dai); if (machine->ops && machine->ops->shutdown) machine->ops->shutdown(substream); @@ -387,7 +387,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) struct snd_soc_platform *platform = card->platform; struct snd_soc_dai *cpu_dai = machine->cpu_dai; struct snd_soc_dai *codec_dai = machine->codec_dai; - struct snd_soc_codec *codec = card->codec; + struct snd_soc_codec *codec = socdev->codec; int ret = 0; mutex_lock(&pcm_mutex); @@ -408,16 +408,16 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) } } - if (codec_dai->ops->prepare) { - ret = codec_dai->ops->prepare(substream, codec_dai); + if (codec_dai->ops.prepare) { + ret = codec_dai->ops.prepare(substream, codec_dai); if (ret < 0) { printk(KERN_ERR "asoc: codec DAI prepare error\n"); goto out; } } - if (cpu_dai->ops->prepare) { - ret = cpu_dai->ops->prepare(substream, cpu_dai); + if (cpu_dai->ops.prepare) { + ret = cpu_dai->ops.prepare(substream, cpu_dai); if (ret < 0) { printk(KERN_ERR "asoc: cpu DAI prepare error\n"); goto out; @@ -494,8 +494,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, } } - if (codec_dai->ops->hw_params) { - ret = codec_dai->ops->hw_params(substream, params, codec_dai); + if (codec_dai->ops.hw_params) { + ret = codec_dai->ops.hw_params(substream, params, codec_dai); if (ret < 0) { printk(KERN_ERR "asoc: can't set codec %s hw params\n", codec_dai->name); @@ -503,8 +503,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, } } - if (cpu_dai->ops->hw_params) { - ret = cpu_dai->ops->hw_params(substream, params, cpu_dai); + if (cpu_dai->ops.hw_params) { + ret = cpu_dai->ops.hw_params(substream, params, cpu_dai); if (ret < 0) { printk(KERN_ERR "asoc: interface %s hw params failed\n", cpu_dai->name); @@ -526,12 +526,12 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, return ret; platform_err: - if (cpu_dai->ops->hw_free) - cpu_dai->ops->hw_free(substream, cpu_dai); + if (cpu_dai->ops.hw_free) + cpu_dai->ops.hw_free(substream, cpu_dai); interface_err: - if (codec_dai->ops->hw_free) - codec_dai->ops->hw_free(substream, codec_dai); + if (codec_dai->ops.hw_free) + codec_dai->ops.hw_free(substream, codec_dai); codec_err: if (machine->ops && machine->ops->hw_free) @@ -553,7 +553,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) struct snd_soc_platform *platform = card->platform; struct snd_soc_dai *cpu_dai = machine->cpu_dai; struct snd_soc_dai *codec_dai = machine->codec_dai; - struct snd_soc_codec *codec = card->codec; + struct snd_soc_codec *codec = socdev->codec; mutex_lock(&pcm_mutex); @@ -570,11 +570,11 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) platform->pcm_ops->hw_free(substream); /* now free hw params for the DAI's */ - if (codec_dai->ops->hw_free) - codec_dai->ops->hw_free(substream, codec_dai); + if (codec_dai->ops.hw_free) + codec_dai->ops.hw_free(substream, codec_dai); - if (cpu_dai->ops->hw_free) - cpu_dai->ops->hw_free(substream, cpu_dai); + if (cpu_dai->ops.hw_free) + cpu_dai->ops.hw_free(substream, cpu_dai); mutex_unlock(&pcm_mutex); return 0; @@ -591,8 +591,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_soc_dai *codec_dai = machine->codec_dai; int ret; - if (codec_dai->ops->trigger) { - ret = codec_dai->ops->trigger(substream, cmd, codec_dai); + if (codec_dai->ops.trigger) { + ret = codec_dai->ops.trigger(substream, cmd, codec_dai); if (ret < 0) return ret; } @@ -603,8 +603,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return ret; } - if (cpu_dai->ops->trigger) { - ret = cpu_dai->ops->trigger(substream, cmd, cpu_dai); + if (cpu_dai->ops.trigger) { + ret = cpu_dai->ops.trigger(substream, cmd, cpu_dai); if (ret < 0) return ret; } @@ -629,7 +629,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) struct snd_soc_card *card = socdev->card; struct snd_soc_platform *platform = card->platform; struct snd_soc_codec_device *codec_dev = socdev->codec_dev; - struct snd_soc_codec *codec = card->codec; + struct snd_soc_codec *codec = socdev->codec; int i; /* Due to the resume being scheduled into a workqueue we could @@ -645,8 +645,8 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) /* mute any active DAC's */ for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *dai = card->dai_link[i].codec_dai; - if (dai->ops->digital_mute && dai->playback.active) - dai->ops->digital_mute(dai, 1); + if (dai->ops.digital_mute && dai->playback.active) + dai->ops.digital_mute(dai, 1); } /* suspend all pcms */ @@ -705,7 +705,7 @@ static void soc_resume_deferred(struct work_struct *work) struct snd_soc_device *socdev = card->socdev; struct snd_soc_platform *platform = card->platform; struct snd_soc_codec_device *codec_dev = socdev->codec_dev; - struct snd_soc_codec *codec = card->codec; + struct snd_soc_codec *codec = socdev->codec; struct platform_device *pdev = to_platform_device(socdev->dev); int i; @@ -741,8 +741,8 @@ static void soc_resume_deferred(struct work_struct *work) /* unmute any active DACs */ for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *dai = card->dai_link[i].codec_dai; - if (dai->ops->digital_mute && dai->playback.active) - dai->ops->digital_mute(dai, 0); + if (dai->ops.digital_mute && dai->playback.active) + dai->ops.digital_mute(dai, 0); } for (i = 0; i < card->num_links; i++) { @@ -982,8 +982,8 @@ static struct platform_driver soc_driver = { static int soc_new_pcm(struct snd_soc_device *socdev, struct snd_soc_dai_link *dai_link, int num) { + struct snd_soc_codec *codec = socdev->codec; struct snd_soc_card *card = socdev->card; - struct snd_soc_codec *codec = card->codec; struct snd_soc_platform *platform = card->platform; struct snd_soc_dai *codec_dai = dai_link->codec_dai; struct snd_soc_dai *cpu_dai = dai_link->cpu_dai; @@ -998,7 +998,7 @@ static int soc_new_pcm(struct snd_soc_device *socdev, rtd->dai = dai_link; rtd->socdev = socdev; - codec_dai->codec = card->codec; + codec_dai->codec = socdev->codec; /* check client and interface hw capabilities */ sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name, @@ -1048,8 +1048,9 @@ static int soc_new_pcm(struct snd_soc_device *socdev, } /* codec register dump */ -static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) +static ssize_t soc_codec_reg_show(struct snd_soc_device *devdata, char *buf) { + struct snd_soc_codec *codec = devdata->codec; int i, step = 1, count = 0; if (!codec->reg_cache_size) @@ -1089,7 +1090,7 @@ static ssize_t codec_reg_show(struct device *dev, struct device_attribute *attr, char *buf) { struct snd_soc_device *devdata = dev_get_drvdata(dev); - return soc_codec_reg_show(devdata->card->codec, buf); + return soc_codec_reg_show(devdata, buf); } static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); @@ -1106,10 +1107,12 @@ static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, { ssize_t ret; struct snd_soc_codec *codec = file->private_data; + struct device *card_dev = codec->card->dev; + struct snd_soc_device *devdata = card_dev->driver_data; char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; - ret = soc_codec_reg_show(codec, buf); + ret = soc_codec_reg_show(devdata, buf); if (ret >= 0) ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); kfree(buf); @@ -1306,19 +1309,19 @@ EXPORT_SYMBOL_GPL(snd_soc_test_bits); */ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) { + struct snd_soc_codec *codec = socdev->codec; struct snd_soc_card *card = socdev->card; - struct snd_soc_codec *codec = card->codec; - int ret, i; + int ret = 0, i; mutex_lock(&codec->mutex); /* register a sound card */ - ret = snd_card_create(idx, xid, codec->owner, 0, &codec->card); - if (ret < 0) { + codec->card = snd_card_new(idx, xid, codec->owner, 0); + if (!codec->card) { printk(KERN_ERR "asoc: can't create sound card for codec %s\n", codec->name); mutex_unlock(&codec->mutex); - return ret; + return -ENODEV; } codec->card->dev = socdev->dev; @@ -1352,8 +1355,8 @@ EXPORT_SYMBOL_GPL(snd_soc_new_pcms); */ int snd_soc_init_card(struct snd_soc_device *socdev) { + struct snd_soc_codec *codec = socdev->codec; struct snd_soc_card *card = socdev->card; - struct snd_soc_codec *codec = card->codec; int ret = 0, i, ac97 = 0, err = 0; for (i = 0; i < card->num_links; i++) { @@ -1404,7 +1407,7 @@ int snd_soc_init_card(struct snd_soc_device *socdev) if (err < 0) printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); - soc_init_codec_debugfs(codec); + soc_init_codec_debugfs(socdev->codec); mutex_unlock(&codec->mutex); out: @@ -1421,19 +1424,18 @@ EXPORT_SYMBOL_GPL(snd_soc_init_card); */ void snd_soc_free_pcms(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; #ifdef CONFIG_SND_SOC_AC97_BUS struct snd_soc_dai *codec_dai; int i; #endif mutex_lock(&codec->mutex); - soc_cleanup_codec_debugfs(codec); + soc_cleanup_codec_debugfs(socdev->codec); #ifdef CONFIG_SND_SOC_AC97_BUS for (i = 0; i < codec->num_dai; i++) { codec_dai = &codec->dai[i]; - if (codec_dai->ac97_control && codec->ac97 && - strcmp(codec->name, "AC97") != 0) { + if (codec_dai->ac97_control && codec->ac97) { soc_ac97_dev_unregister(codec); goto free_card; } @@ -1495,37 +1497,6 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, } EXPORT_SYMBOL_GPL(snd_soc_cnew); -/** - * snd_soc_add_controls - add an array of controls to a codec. - * Convienience function to add a list of controls. Many codecs were - * duplicating this code. - * - * @codec: codec to add controls to - * @controls: array of controls to add - * @num_controls: number of elements in the array - * - * Return 0 for success, else error. - */ -int snd_soc_add_controls(struct snd_soc_codec *codec, - const struct snd_kcontrol_new *controls, int num_controls) -{ - struct snd_card *card = codec->card; - int err, i; - - for (i = 0; i < num_controls; i++) { - const struct snd_kcontrol_new *control = &controls[i]; - err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); - if (err < 0) { - dev_err(codec->dev, "%s: Failed to add %s\n", - codec->name, control->name); - return err; - } - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_add_controls); - /** * snd_soc_info_enum_double - enumerated double mixer info callback * @kcontrol: mixer control @@ -2052,8 +2023,8 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { - if (dai->ops->set_sysclk) - return dai->ops->set_sysclk(dai, clk_id, freq, dir); + if (dai->ops.set_sysclk) + return dai->ops.set_sysclk(dai, clk_id, freq, dir); else return -EINVAL; } @@ -2072,8 +2043,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) { - if (dai->ops->set_clkdiv) - return dai->ops->set_clkdiv(dai, div_id, div); + if (dai->ops.set_clkdiv) + return dai->ops.set_clkdiv(dai, div_id, div); else return -EINVAL; } @@ -2091,8 +2062,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv); int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, unsigned int freq_in, unsigned int freq_out) { - if (dai->ops->set_pll) - return dai->ops->set_pll(dai, pll_id, freq_in, freq_out); + if (dai->ops.set_pll) + return dai->ops.set_pll(dai, pll_id, freq_in, freq_out); else return -EINVAL; } @@ -2107,8 +2078,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); */ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - if (dai->ops->set_fmt) - return dai->ops->set_fmt(dai, fmt); + if (dai->ops.set_fmt) + return dai->ops.set_fmt(dai, fmt); else return -EINVAL; } @@ -2126,8 +2097,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int mask, int slots) { - if (dai->ops->set_sysclk) - return dai->ops->set_tdm_slot(dai, mask, slots); + if (dai->ops.set_sysclk) + return dai->ops.set_tdm_slot(dai, mask, slots); else return -EINVAL; } @@ -2142,8 +2113,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); */ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) { - if (dai->ops->set_sysclk) - return dai->ops->set_tristate(dai, tristate); + if (dai->ops.set_sysclk) + return dai->ops.set_tristate(dai, tristate); else return -EINVAL; } @@ -2158,8 +2129,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate); */ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) { - if (dai->ops->digital_mute) - return dai->ops->digital_mute(dai, mute); + if (dai->ops.digital_mute) + return dai->ops.digital_mute(dai, mute); else return -EINVAL; } @@ -2212,9 +2183,6 @@ static int snd_soc_unregister_card(struct snd_soc_card *card) return 0; } -static struct snd_soc_dai_ops null_dai_ops = { -}; - /** * snd_soc_register_dai - Register a DAI with the ASoC core * @@ -2229,9 +2197,6 @@ int snd_soc_register_dai(struct snd_soc_dai *dai) if (!dai->dev) printk(KERN_WARNING "No device for DAI %s\n", dai->name); - if (!dai->ops) - dai->ops = &null_dai_ops; - INIT_LIST_HEAD(&dai->list); mutex_lock(&client_mutex); diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index 735903a74675..a2f1da8b4646 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -54,15 +54,14 @@ static int dapm_up_seq[] = { snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac, - snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga, - snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post + snd_soc_dapm_mixer, snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, + snd_soc_dapm_spk, snd_soc_dapm_post }; - static int dapm_down_seq[] = { snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, - snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer, - snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias, - snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post + snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic, + snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_value_mux, + snd_soc_dapm_post }; static int dapm_status = 1; @@ -102,8 +101,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, { switch (w->id) { case snd_soc_dapm_switch: - case snd_soc_dapm_mixer: - case snd_soc_dapm_mixer_named_ctl: { + case snd_soc_dapm_mixer: { int val; struct soc_mixer_control *mc = (struct soc_mixer_control *) w->kcontrols[i].private_value; @@ -325,32 +323,15 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, if (path->name != (char*)w->kcontrols[i].name) continue; - /* add dapm control with long name. - * for dapm_mixer this is the concatenation of the - * mixer and kcontrol name. - * for dapm_mixer_named_ctl this is simply the - * kcontrol name. - */ - name_len = strlen(w->kcontrols[i].name) + 1; - if (w->id != snd_soc_dapm_mixer_named_ctl) - name_len += 1 + strlen(w->name); - + /* add dapm control with long name */ + name_len = 2 + strlen(w->name) + + strlen(w->kcontrols[i].name); path->long_name = kmalloc(name_len, GFP_KERNEL); - if (path->long_name == NULL) return -ENOMEM; - switch (w->id) { - default: - snprintf(path->long_name, name_len, "%s %s", - w->name, w->kcontrols[i].name); - break; - case snd_soc_dapm_mixer_named_ctl: - snprintf(path->long_name, name_len, "%s", - w->kcontrols[i].name); - break; - } - + snprintf(path->long_name, name_len, "%s %s", + w->name, w->kcontrols[i].name); path->long_name[name_len - 1] = '\0'; path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, @@ -521,137 +502,6 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(dapm_reg_event); -/* - * Scan a single DAPM widget for a complete audio path and update the - * power status appropriately. - */ -static int dapm_power_widget(struct snd_soc_codec *codec, int event, - struct snd_soc_dapm_widget *w) -{ - int in, out, power_change, power, ret; - - /* vmid - no action */ - if (w->id == snd_soc_dapm_vmid) - return 0; - - /* active ADC */ - if (w->id == snd_soc_dapm_adc && w->active) { - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - w->power = (in != 0) ? 1 : 0; - dapm_update_bits(w); - return 0; - } - - /* active DAC */ - if (w->id == snd_soc_dapm_dac && w->active) { - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - w->power = (out != 0) ? 1 : 0; - dapm_update_bits(w); - return 0; - } - - /* pre and post event widgets */ - if (w->id == snd_soc_dapm_pre) { - if (!w->event) - return 0; - - if (event == SND_SOC_DAPM_STREAM_START) { - ret = w->event(w, - NULL, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - return ret; - } else if (event == SND_SOC_DAPM_STREAM_STOP) { - ret = w->event(w, - NULL, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - return ret; - } - return 0; - } - if (w->id == snd_soc_dapm_post) { - if (!w->event) - return 0; - - if (event == SND_SOC_DAPM_STREAM_START) { - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - return ret; - } else if (event == SND_SOC_DAPM_STREAM_STOP) { - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - return ret; - } - return 0; - } - - /* all other widgets */ - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - power = (out != 0 && in != 0) ? 1 : 0; - power_change = (w->power == power) ? 0 : 1; - w->power = power; - - if (!power_change) - return 0; - - /* call any power change event handlers */ - if (w->event) - pr_debug("power %s event for %s flags %x\n", - w->power ? "on" : "off", - w->name, w->event_flags); - - /* power up pre event */ - if (power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - return ret; - } - - /* power down pre event */ - if (!power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - return ret; - } - - /* Lower PGA volume to reduce pops */ - if (w->id == snd_soc_dapm_pga && !power) - dapm_set_pga(w, power); - - dapm_update_bits(w); - - /* Raise PGA volume to reduce pops */ - if (w->id == snd_soc_dapm_pga && power) - dapm_set_pga(w, power); - - /* power up post event */ - if (power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - return ret; - } - - /* power down post event */ - if (!power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - return ret; - } - - return 0; -} - /* * Scan each dapm widget for complete audio path. * A complete path is a route that has valid endpoints i.e.:- @@ -664,7 +514,7 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, static int dapm_power_widgets(struct snd_soc_codec *codec, int event) { struct snd_soc_dapm_widget *w; - int i, c = 1, *seq = NULL, ret = 0; + int in, out, i, c = 1, *seq = NULL, ret = 0, power_change, power; /* do we have a sequenced stream event */ if (event == SND_SOC_DAPM_STREAM_START) { @@ -675,20 +525,135 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) seq = dapm_down_seq; } - for (i = 0; i < c; i++) { + for(i = 0; i < c; i++) { list_for_each_entry(w, &codec->dapm_widgets, list) { /* is widget in stream order */ if (seq && seq[i] && w->id != seq[i]) continue; - ret = dapm_power_widget(codec, event, w); - if (ret != 0) - return ret; + /* vmid - no action */ + if (w->id == snd_soc_dapm_vmid) + continue; + + /* active ADC */ + if (w->id == snd_soc_dapm_adc && w->active) { + in = is_connected_input_ep(w); + dapm_clear_walk(w->codec); + w->power = (in != 0) ? 1 : 0; + dapm_update_bits(w); + continue; + } + + /* active DAC */ + if (w->id == snd_soc_dapm_dac && w->active) { + out = is_connected_output_ep(w); + dapm_clear_walk(w->codec); + w->power = (out != 0) ? 1 : 0; + dapm_update_bits(w); + continue; + } + + /* pre and post event widgets */ + if (w->id == snd_soc_dapm_pre) { + if (!w->event) + continue; + + if (event == SND_SOC_DAPM_STREAM_START) { + ret = w->event(w, + NULL, SND_SOC_DAPM_PRE_PMU); + if (ret < 0) + return ret; + } else if (event == SND_SOC_DAPM_STREAM_STOP) { + ret = w->event(w, + NULL, SND_SOC_DAPM_PRE_PMD); + if (ret < 0) + return ret; + } + continue; + } + if (w->id == snd_soc_dapm_post) { + if (!w->event) + continue; + + if (event == SND_SOC_DAPM_STREAM_START) { + ret = w->event(w, + NULL, SND_SOC_DAPM_POST_PMU); + if (ret < 0) + return ret; + } else if (event == SND_SOC_DAPM_STREAM_STOP) { + ret = w->event(w, + NULL, SND_SOC_DAPM_POST_PMD); + if (ret < 0) + return ret; + } + continue; + } + + /* all other widgets */ + in = is_connected_input_ep(w); + dapm_clear_walk(w->codec); + out = is_connected_output_ep(w); + dapm_clear_walk(w->codec); + power = (out != 0 && in != 0) ? 1 : 0; + power_change = (w->power == power) ? 0: 1; + w->power = power; + + if (!power_change) + continue; + + /* call any power change event handlers */ + if (w->event) + pr_debug("power %s event for %s flags %x\n", + w->power ? "on" : "off", + w->name, w->event_flags); + + /* power up pre event */ + if (power && w->event && + (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { + ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); + if (ret < 0) + return ret; + } + + /* power down pre event */ + if (!power && w->event && + (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { + ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); + if (ret < 0) + return ret; + } + + /* Lower PGA volume to reduce pops */ + if (w->id == snd_soc_dapm_pga && !power) + dapm_set_pga(w, power); + + dapm_update_bits(w); + + /* Raise PGA volume to reduce pops */ + if (w->id == snd_soc_dapm_pga && power) + dapm_set_pga(w, power); + + /* power up post event */ + if (power && w->event && + (w->event_flags & SND_SOC_DAPM_POST_PMU)) { + ret = w->event(w, + NULL, SND_SOC_DAPM_POST_PMU); + if (ret < 0) + return ret; + } + + /* power down post event */ + if (!power && w->event && + (w->event_flags & SND_SOC_DAPM_POST_PMD)) { + ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); + if (ret < 0) + return ret; + } } } - return 0; + return ret; } #ifdef DEBUG @@ -722,7 +687,6 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action) case snd_soc_dapm_adc: case snd_soc_dapm_pga: case snd_soc_dapm_mixer: - case snd_soc_dapm_mixer_named_ctl: if (w->name) { in = is_connected_input_ep(w); dapm_clear_walk(w->codec); @@ -796,7 +760,6 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, int found = 0; if (widget->id != snd_soc_dapm_mixer && - widget->id != snd_soc_dapm_mixer_named_ctl && widget->id != snd_soc_dapm_switch) return -ENODEV; @@ -832,7 +795,7 @@ static ssize_t dapm_widget_show(struct device *dev, struct device_attribute *attr, char *buf) { struct snd_soc_device *devdata = dev_get_drvdata(dev); - struct snd_soc_codec *codec = devdata->card->codec; + struct snd_soc_codec *codec = devdata->codec; struct snd_soc_dapm_widget *w; int count = 0; char *state = "not set"; @@ -850,7 +813,6 @@ static ssize_t dapm_widget_show(struct device *dev, case snd_soc_dapm_adc: case snd_soc_dapm_pga: case snd_soc_dapm_mixer: - case snd_soc_dapm_mixer_named_ctl: if (w->name) count += sprintf(buf + count, "%s: %s\n", w->name, w->power ? "On":"Off"); @@ -914,7 +876,7 @@ static void dapm_free_widgets(struct snd_soc_codec *codec) } static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, - const char *pin, int status) + char *pin, int status) { struct snd_soc_dapm_widget *w; @@ -1029,7 +991,6 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, break; case snd_soc_dapm_switch: case snd_soc_dapm_mixer: - case snd_soc_dapm_mixer_named_ctl: ret = dapm_connect_mixer(codec, wsource, wsink, path, control); if (ret != 0) goto err; @@ -1107,7 +1068,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) switch(w->id) { case snd_soc_dapm_switch: case snd_soc_dapm_mixer: - case snd_soc_dapm_mixer_named_ctl: dapm_new_mixer(codec, w); break; case snd_soc_dapm_mux: @@ -1435,76 +1395,6 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); -/** - * snd_soc_dapm_info_pin_switch - Info for a pin switch - * - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a pin switch control. - */ -int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch); - -/** - * snd_soc_dapm_get_pin_switch - Get information for a pin switch - * - * @kcontrol: mixer control - * @ucontrol: Value - */ -int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - const char *pin = (const char *)kcontrol->private_value; - - mutex_lock(&codec->mutex); - - ucontrol->value.integer.value[0] = - snd_soc_dapm_get_pin_status(codec, pin); - - mutex_unlock(&codec->mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); - -/** - * snd_soc_dapm_put_pin_switch - Set information for a pin switch - * - * @kcontrol: mixer control - * @ucontrol: Value - */ -int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - const char *pin = (const char *)kcontrol->private_value; - - mutex_lock(&codec->mutex); - - if (ucontrol->value.integer.value[0]) - snd_soc_dapm_enable_pin(codec, pin); - else - snd_soc_dapm_disable_pin(codec, pin); - - snd_soc_dapm_sync(codec); - - mutex_unlock(&codec->mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); - /** * snd_soc_dapm_new_control - create new dapm control * @codec: audio codec @@ -1637,8 +1527,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, enum snd_soc_bias_level level) { + struct snd_soc_codec *codec = socdev->codec; struct snd_soc_card *card = socdev->card; - struct snd_soc_codec *codec = socdev->card->codec; int ret = 0; if (card->set_bias_level) @@ -1659,7 +1549,7 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin) { return snd_soc_dapm_set_pin(codec, pin, 1); } @@ -1674,7 +1564,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin) { return snd_soc_dapm_set_pin(codec, pin, 0); } @@ -1694,7 +1584,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin) { return snd_soc_dapm_set_pin(codec, pin, 0); } @@ -1709,7 +1599,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); * * Returns 1 for connected otherwise 0. */ -int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin) { struct snd_soc_dapm_widget *w; @@ -1730,7 +1620,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); */ void snd_soc_dapm_free(struct snd_soc_device *socdev) { - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = socdev->codec; snd_soc_dapm_sys_remove(socdev->dev); dapm_free_widgets(codec); diff --git a/trunk/sound/soc/soc-jack.c b/trunk/sound/soc/soc-jack.c deleted file mode 100644 index 28346fb2e70c..000000000000 --- a/trunk/sound/soc/soc-jack.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * soc-jack.c -- ALSA SoC jack handling - * - * Copyright 2008 Wolfson Microelectronics PLC. - * - * Author: Mark Brown - * - * 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 - -/** - * snd_soc_jack_new - Create a new jack - * @card: ASoC card - * @id: an identifying string for this jack - * @type: a bitmask of enum snd_jack_type values that can be detected by - * this jack - * @jack: structure to use for the jack - * - * Creates a new jack object. - * - * Returns zero if successful, or a negative error code on failure. - * On success jack will be initialised. - */ -int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, - struct snd_soc_jack *jack) -{ - jack->card = card; - INIT_LIST_HEAD(&jack->pins); - - return snd_jack_new(card->codec->card, id, type, &jack->jack); -} -EXPORT_SYMBOL_GPL(snd_soc_jack_new); - -/** - * snd_soc_jack_report - Report the current status for a jack - * - * @jack: the jack - * @status: a bitmask of enum snd_jack_type values that are currently detected. - * @mask: a bitmask of enum snd_jack_type values that being reported. - * - * If configured using snd_soc_jack_add_pins() then the associated - * DAPM pins will be enabled or disabled as appropriate and DAPM - * synchronised. - * - * Note: This function uses mutexes and should be called from a - * context which can sleep (such as a workqueue). - */ -void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) -{ - struct snd_soc_codec *codec = jack->card->codec; - struct snd_soc_jack_pin *pin; - int enable; - int oldstatus; - - if (!jack) { - WARN_ON_ONCE(!jack); - return; - } - - mutex_lock(&codec->mutex); - - oldstatus = jack->status; - - jack->status &= ~mask; - jack->status |= status; - - /* The DAPM sync is expensive enough to be worth skipping */ - if (jack->status == oldstatus) - goto out; - - list_for_each_entry(pin, &jack->pins, list) { - enable = pin->mask & status; - - if (pin->invert) - enable = !enable; - - if (enable) - snd_soc_dapm_enable_pin(codec, pin->pin); - else - snd_soc_dapm_disable_pin(codec, pin->pin); - } - - snd_soc_dapm_sync(codec); - - snd_jack_report(jack->jack, status); - -out: - mutex_unlock(&codec->mutex); -} -EXPORT_SYMBOL_GPL(snd_soc_jack_report); - -/** - * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack - * - * @jack: ASoC jack - * @count: Number of pins - * @pins: Array of pins - * - * After this function has been called the DAPM pins specified in the - * pins array will have their status updated to reflect the current - * state of the jack whenever the jack status is updated. - */ -int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, - struct snd_soc_jack_pin *pins) -{ - int i; - - for (i = 0; i < count; i++) { - if (!pins[i].pin) { - printk(KERN_ERR "No name for pin %d\n", i); - return -EINVAL; - } - if (!pins[i].mask) { - printk(KERN_ERR "No mask for pin %d (%s)\n", i, - pins[i].pin); - return -EINVAL; - } - - INIT_LIST_HEAD(&pins[i].list); - list_add(&(pins[i].list), &jack->pins); - } - - /* Update to reflect the last reported status; canned jack - * implementations are likely to set their state before the - * card has an opportunity to associate pins. - */ - snd_soc_jack_report(jack, 0, 0); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins); - -#ifdef CONFIG_GPIOLIB -/* gpio detect */ -static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) -{ - struct snd_soc_jack *jack = gpio->jack; - int enable; - int report; - - if (gpio->debounce_time > 0) - mdelay(gpio->debounce_time); - - enable = gpio_get_value(gpio->gpio); - if (gpio->invert) - enable = !enable; - - if (enable) - report = gpio->report; - else - report = 0; - - snd_soc_jack_report(jack, report, gpio->report); -} - -/* irq handler for gpio pin */ -static irqreturn_t gpio_handler(int irq, void *data) -{ - struct snd_soc_jack_gpio *gpio = data; - - schedule_work(&gpio->work); - - return IRQ_HANDLED; -} - -/* gpio work */ -static void gpio_work(struct work_struct *work) -{ - struct snd_soc_jack_gpio *gpio; - - gpio = container_of(work, struct snd_soc_jack_gpio, work); - snd_soc_jack_gpio_detect(gpio); -} - -/** - * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack - * - * @jack: ASoC jack - * @count: number of pins - * @gpios: array of gpio pins - * - * This function will request gpio, set data direction and request irq - * for each gpio in the array. - */ -int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, - struct snd_soc_jack_gpio *gpios) -{ - int i, ret; - - for (i = 0; i < count; i++) { - if (!gpio_is_valid(gpios[i].gpio)) { - printk(KERN_ERR "Invalid gpio %d\n", - gpios[i].gpio); - ret = -EINVAL; - goto undo; - } - if (!gpios[i].name) { - printk(KERN_ERR "No name for gpio %d\n", - gpios[i].gpio); - ret = -EINVAL; - goto undo; - } - - ret = gpio_request(gpios[i].gpio, gpios[i].name); - if (ret) - goto undo; - - ret = gpio_direction_input(gpios[i].gpio); - if (ret) - goto err; - - ret = request_irq(gpio_to_irq(gpios[i].gpio), - gpio_handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - jack->card->dev->driver->name, - &gpios[i]); - if (ret) - goto err; - - INIT_WORK(&gpios[i].work, gpio_work); - gpios[i].jack = jack; - } - - return 0; - -err: - gpio_free(gpios[i].gpio); -undo: - snd_soc_jack_free_gpios(jack, i, gpios); - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios); - -/** - * snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack - * - * @jack: ASoC jack - * @count: number of pins - * @gpios: array of gpio pins - * - * Release gpio and irq resources for gpio pins associated with an ASoC jack. - */ -void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, - struct snd_soc_jack_gpio *gpios) -{ - int i; - - for (i = 0; i < count; i++) { - free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]); - gpio_free(gpios[i].gpio); - gpios[i].jack = NULL; - } -} -EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios); -#endif /* CONFIG_GPIOLIB */ diff --git a/trunk/sound/sparc/amd7930.c b/trunk/sound/sparc/amd7930.c index 574af56ba8a6..f87933e48812 100644 --- a/trunk/sound/sparc/amd7930.c +++ b/trunk/sound/sparc/amd7930.c @@ -954,8 +954,7 @@ static int __devinit snd_amd7930_create(struct snd_card *card, amd->regs = of_ioremap(&op->resource[0], 0, resource_size(&op->resource[0]), "amd7930"); if (!amd->regs) { - snd_printk(KERN_ERR - "amd7930-%d: Unable to map chip registers.\n", dev); + snd_printk("amd7930-%d: Unable to map chip registers.\n", dev); return -EIO; } @@ -963,7 +962,7 @@ static int __devinit snd_amd7930_create(struct snd_card *card, if (request_irq(irq, snd_amd7930_interrupt, IRQF_DISABLED | IRQF_SHARED, "amd7930", amd)) { - snd_printk(KERN_ERR "amd7930-%d: Unable to grab IRQ %d\n", + snd_printk("amd7930-%d: Unable to grab IRQ %d\n", dev, irq); snd_amd7930_free(amd); return -EBUSY; @@ -1019,10 +1018,9 @@ static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_de return -ENOENT; } - err = snd_card_create(index[dev_num], id[dev_num], THIS_MODULE, 0, - &card); - if (err < 0) - return err; + card = snd_card_new(index[dev_num], id[dev_num], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "AMD7930"); strcpy(card->shortname, "Sun AMD7930"); diff --git a/trunk/sound/sparc/cs4231.c b/trunk/sound/sparc/cs4231.c index 7d93fa705ccf..41c387587474 100644 --- a/trunk/sound/sparc/cs4231.c +++ b/trunk/sound/sparc/cs4231.c @@ -1563,7 +1563,6 @@ static int __init cs4231_attach_begin(struct snd_card **rcard) { struct snd_card *card; struct snd_cs4231 *chip; - int err; *rcard = NULL; @@ -1575,10 +1574,10 @@ static int __init cs4231_attach_begin(struct snd_card **rcard) return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_cs4231), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_cs4231)); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "CS4231"); strcpy(card->shortname, "Sun CS4231"); diff --git a/trunk/sound/sparc/dbri.c b/trunk/sound/sparc/dbri.c index af95ff1e126c..23ed6f04a718 100644 --- a/trunk/sound/sparc/dbri.c +++ b/trunk/sound/sparc/dbri.c @@ -2612,10 +2612,10 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id return -ENODEV; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_dbri), &card); - if (err < 0) - return err; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_dbri)); + if (card == NULL) + return -ENOMEM; strcpy(card->driver, "DBRI"); strcpy(card->shortname, "Sun DBRI"); diff --git a/trunk/sound/spi/at73c213.c b/trunk/sound/spi/at73c213.c index 4c7b051f9d17..09802e8a6fb8 100644 --- a/trunk/sound/spi/at73c213.c +++ b/trunk/sound/spi/at73c213.c @@ -965,11 +965,12 @@ static int __devinit snd_at73c213_probe(struct spi_device *spi) return PTR_ERR(board->dac_clk); } + retval = -ENOMEM; + /* Allocate "card" using some unused identifiers. */ snprintf(id, sizeof id, "at73c213_%d", board->ssc_id); - retval = snd_card_create(-1, id, THIS_MODULE, - sizeof(struct snd_at73c213), &card); - if (retval < 0) + card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct snd_at73c213)); + if (!card) goto out; chip = card->private_data; diff --git a/trunk/sound/synth/emux/emux_hwdep.c b/trunk/sound/synth/emux/emux_hwdep.c index ff0b2a8fd25b..0a5391436add 100644 --- a/trunk/sound/synth/emux/emux_hwdep.c +++ b/trunk/sound/synth/emux/emux_hwdep.c @@ -24,6 +24,25 @@ #include #include "emux_voice.h" +/* + * open the hwdep device + */ +static int +snd_emux_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + + +/* + * close the device + */ +static int +snd_emux_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + #define TMP_CLIENT_ID 0x1001 @@ -127,6 +146,8 @@ snd_emux_init_hwdep(struct snd_emux *emu) emu->hwdep = hw; strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME); hw->iface = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE; + hw->ops.open = snd_emux_hwdep_open; + hw->ops.release = snd_emux_hwdep_release; hw->ops.ioctl = snd_emux_hwdep_ioctl; hw->exclusive = 1; hw->private_data = emu; diff --git a/trunk/sound/synth/emux/emux_oss.c b/trunk/sound/synth/emux/emux_oss.c index 87e42206c4ef..5c47b6c09264 100644 --- a/trunk/sound/synth/emux/emux_oss.c +++ b/trunk/sound/synth/emux/emux_oss.c @@ -132,7 +132,7 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) p = snd_emux_create_port(emu, tmpname, 32, 1, &callback); if (p == NULL) { - snd_printk(KERN_ERR "can't create port\n"); + snd_printk("can't create port\n"); snd_emux_dec_count(emu); mutex_unlock(&emu->register_mutex); return -ENOMEM; diff --git a/trunk/sound/synth/emux/emux_seq.c b/trunk/sound/synth/emux/emux_seq.c index ca5f7effb4df..335aa2ce2574 100644 --- a/trunk/sound/synth/emux/emux_seq.c +++ b/trunk/sound/synth/emux/emux_seq.c @@ -74,15 +74,15 @@ snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index) emu->client = snd_seq_create_kernel_client(card, index, "%s WaveTable", emu->name); if (emu->client < 0) { - snd_printk(KERN_ERR "can't create client\n"); + snd_printk("can't create client\n"); return -ENODEV; } if (emu->num_ports < 0) { - snd_printk(KERN_WARNING "seqports must be greater than zero\n"); + snd_printk("seqports must be greater than zero\n"); emu->num_ports = 1; } else if (emu->num_ports >= SNDRV_EMUX_MAX_PORTS) { - snd_printk(KERN_WARNING "too many ports." + snd_printk("too many ports." "limited max. ports %d\n", SNDRV_EMUX_MAX_PORTS); emu->num_ports = SNDRV_EMUX_MAX_PORTS; } @@ -100,7 +100,7 @@ snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index) p = snd_emux_create_port(emu, tmpname, MIDI_CHANNELS, 0, &pinfo); if (p == NULL) { - snd_printk(KERN_ERR "can't create port\n"); + snd_printk("can't create port\n"); return -ENOMEM; } @@ -147,12 +147,12 @@ snd_emux_create_port(struct snd_emux *emu, char *name, /* Allocate structures for this channel */ if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "no memory\n"); + snd_printk("no memory\n"); return NULL; } p->chset.channels = kcalloc(max_channels, sizeof(struct snd_midi_channel), GFP_KERNEL); if (p->chset.channels == NULL) { - snd_printk(KERN_ERR "no memory\n"); + snd_printk("no memory\n"); kfree(p); return NULL; } @@ -376,12 +376,12 @@ int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card) goto __error; } emu->vmidi[i] = rmidi; - /* snd_printk(KERN_DEBUG "virmidi %d ok\n", i); */ + //snd_printk("virmidi %d ok\n", i); } return 0; __error: - /* snd_printk(KERN_DEBUG "error init..\n"); */ + //snd_printk("error init..\n"); snd_emux_delete_virmidi(emu); return -ENOMEM; } diff --git a/trunk/sound/synth/emux/emux_synth.c b/trunk/sound/synth/emux/emux_synth.c index 3e921b386fd5..2cc6f6f79065 100644 --- a/trunk/sound/synth/emux/emux_synth.c +++ b/trunk/sound/synth/emux/emux_synth.c @@ -956,8 +956,7 @@ void snd_emux_lock_voice(struct snd_emux *emu, int voice) if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF) emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED; else - snd_printk(KERN_WARNING - "invalid voice for lock %d (state = %x)\n", + snd_printk("invalid voice for lock %d (state = %x)\n", voice, emu->voices[voice].state); spin_unlock_irqrestore(&emu->voice_lock, flags); } @@ -974,8 +973,7 @@ void snd_emux_unlock_voice(struct snd_emux *emu, int voice) if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED) emu->voices[voice].state = SNDRV_EMUX_ST_OFF; else - snd_printk(KERN_WARNING - "invalid voice for unlock %d (state = %x)\n", + snd_printk("invalid voice for unlock %d (state = %x)\n", voice, emu->voices[voice].state); spin_unlock_irqrestore(&emu->voice_lock, flags); } diff --git a/trunk/sound/synth/emux/soundfont.c b/trunk/sound/synth/emux/soundfont.c index 63c8f45c0c22..36d53bd317ed 100644 --- a/trunk/sound/synth/emux/soundfont.c +++ b/trunk/sound/synth/emux/soundfont.c @@ -133,7 +133,7 @@ snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data, int rc; if (count < (long)sizeof(patch)) { - snd_printk(KERN_ERR "patch record too small %ld\n", count); + snd_printk("patch record too small %ld\n", count); return -EINVAL; } if (copy_from_user(&patch, data, sizeof(patch))) @@ -143,16 +143,15 @@ snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data, data += sizeof(patch); if (patch.key != SNDRV_OSS_SOUNDFONT_PATCH) { - snd_printk(KERN_ERR "The wrong kind of patch %x\n", patch.key); + snd_printk("'The wrong kind of patch' %x\n", patch.key); return -EINVAL; } if (count < patch.len) { - snd_printk(KERN_ERR "Patch too short %ld, need %d\n", - count, patch.len); + snd_printk("Patch too short %ld, need %d\n", count, patch.len); return -EINVAL; } if (patch.len < 0) { - snd_printk(KERN_ERR "poor length %d\n", patch.len); + snd_printk("poor length %d\n", patch.len); return -EINVAL; } @@ -196,8 +195,7 @@ snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data, case SNDRV_SFNT_REMOVE_INFO: /* patch must be opened */ if (!sflist->currsf) { - snd_printk(KERN_ERR "soundfont: remove_info: " - "patch not opened\n"); + snd_printk("soundfont: remove_info: patch not opened\n"); rc = -EINVAL; } else { int bank, instr; @@ -533,7 +531,7 @@ load_info(struct snd_sf_list *sflist, const void __user *data, long count) return -EINVAL; if (count < (long)sizeof(hdr)) { - printk(KERN_ERR "Soundfont error: invalid patch zone length\n"); + printk("Soundfont error: invalid patch zone length\n"); return -EINVAL; } if (copy_from_user((char*)&hdr, data, sizeof(hdr))) @@ -543,14 +541,12 @@ load_info(struct snd_sf_list *sflist, const void __user *data, long count) count -= sizeof(hdr); if (hdr.nvoices <= 0 || hdr.nvoices >= 100) { - printk(KERN_ERR "Soundfont error: Illegal voice number %d\n", - hdr.nvoices); + printk("Soundfont error: Illegal voice number %d\n", hdr.nvoices); return -EINVAL; } if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) { - printk(KERN_ERR "Soundfont Error: " - "patch length(%ld) is smaller than nvoices(%d)\n", + printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n", count, hdr.nvoices); return -EINVAL; } @@ -956,7 +952,7 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data, int rc; if (count < (long)sizeof(patch)) { - snd_printk(KERN_ERR "patch record too small %ld\n", count); + snd_printk("patch record too small %ld\n", count); return -EINVAL; } if (copy_from_user(&patch, data, sizeof(patch))) @@ -1038,8 +1034,7 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data, /* panning position; -128 - 127 => 0-127 */ zone->v.pan = (patch.panning + 128) / 2; #if 0 - snd_printk(KERN_DEBUG - "gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n", + snd_printk("gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n", (int)patch.base_freq, zone->v.rate_offset, zone->v.root, zone->v.tune, zone->v.low, zone->v.high); #endif @@ -1073,8 +1068,7 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data, zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release); zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]); #if 0 - snd_printk(KERN_DEBUG - "gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n", + snd_printk("gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n", zone->v.parm.volatkhld, zone->v.parm.voldcysus, zone->v.parm.volrelease, diff --git a/trunk/sound/usb/caiaq/caiaq-device.c b/trunk/sound/usb/caiaq/caiaq-device.c index 09aed2363cc9..41c36b055f6b 100644 --- a/trunk/sound/usb/caiaq/caiaq-device.c +++ b/trunk/sound/usb/caiaq/caiaq-device.c @@ -336,10 +336,9 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev) log("Unable to set up control system (ret=%d)\n", ret); } -static int create_card(struct usb_device* usb_dev, struct snd_card **cardp) +static struct snd_card* create_card(struct usb_device* usb_dev) { int devnum; - int err; struct snd_card *card; struct snd_usb_caiaqdev *dev; @@ -348,12 +347,12 @@ static int create_card(struct usb_device* usb_dev, struct snd_card **cardp) break; if (devnum >= SNDRV_CARDS) - return -ENODEV; + return NULL; - err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, - sizeof(struct snd_usb_caiaqdev), &card); - if (err < 0) - return err; + card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, + sizeof(struct snd_usb_caiaqdev)); + if (!card) + return NULL; dev = caiaqdev(card); dev->chip.dev = usb_dev; @@ -363,8 +362,7 @@ static int create_card(struct usb_device* usb_dev, struct snd_card **cardp) spin_lock_init(&dev->spinlock); snd_card_set_dev(card, &usb_dev->dev); - *cardp = card; - return 0; + return card; } static int __devinit init_card(struct snd_usb_caiaqdev *dev) @@ -443,10 +441,10 @@ static int __devinit snd_probe(struct usb_interface *intf, struct snd_card *card; struct usb_device *device = interface_to_usbdev(intf); - ret = create_card(device, &card); + card = create_card(device); - if (ret < 0) - return ret; + if (!card) + return -ENOMEM; usb_set_intfdata(intf, card); ret = init_card(caiaqdev(card)); diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index 8f3cdb37a0ec..19e37451c216 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -3466,10 +3466,10 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, return -ENXIO; } - err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card); - if (err < 0) { + card = snd_card_new(index[idx], id[idx], THIS_MODULE, 0); + if (card == NULL) { snd_printk(KERN_ERR "cannot create card instance %d\n", idx); - return err; + return -ENOMEM; } chip = kzalloc(sizeof(*chip), GFP_KERNEL); diff --git a/trunk/sound/usb/usbmixer.c b/trunk/sound/usb/usbmixer.c index 2bde79216fa5..00397c8a765b 100644 --- a/trunk/sound/usb/usbmixer.c +++ b/trunk/sound/usb/usbmixer.c @@ -78,6 +78,7 @@ struct usb_mixer_interface { /* Sound Blaster remote control stuff */ const struct rc_config *rc_cfg; + unsigned long rc_hwdep_open; u32 rc_code; wait_queue_head_t rc_waitq; struct urb *rc_urb; @@ -1796,6 +1797,24 @@ static void snd_usb_soundblaster_remote_complete(struct urb *urb) wake_up(&mixer->rc_waitq); } +static int snd_usb_sbrc_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ + struct usb_mixer_interface *mixer = hw->private_data; + + if (test_and_set_bit(0, &mixer->rc_hwdep_open)) + return -EBUSY; + return 0; +} + +static int snd_usb_sbrc_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + struct usb_mixer_interface *mixer = hw->private_data; + + clear_bit(0, &mixer->rc_hwdep_open); + smp_mb__after_clear_bit(); + return 0; +} + static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf, long count, loff_t *offset) { @@ -1848,8 +1867,9 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC; hwdep->private_data = mixer; hwdep->ops.read = snd_usb_sbrc_hwdep_read; + hwdep->ops.open = snd_usb_sbrc_hwdep_open; + hwdep->ops.release = snd_usb_sbrc_hwdep_release; hwdep->ops.poll = snd_usb_sbrc_hwdep_poll; - hwdep->exclusive = 1; mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL); if (!mixer->rc_urb) diff --git a/trunk/sound/usb/usx2y/us122l.c b/trunk/sound/usb/usx2y/us122l.c index 98276aafefe6..73e59f4403a4 100644 --- a/trunk/sound/usb/usx2y/us122l.c +++ b/trunk/sound/usb/usx2y/us122l.c @@ -478,21 +478,19 @@ static bool us122l_create_card(struct snd_card *card) return true; } -static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) +static struct snd_card *usx2y_create_card(struct usb_device *device) { int dev; struct snd_card *card; - int err; - for (dev = 0; dev < SNDRV_CARDS; ++dev) if (enable[dev] && !snd_us122l_card_used[dev]) break; if (dev >= SNDRV_CARDS) - return -ENODEV; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct us122l), &card); - if (err < 0) - return err; + return NULL; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct us122l)); + if (!card) + return NULL; snd_us122l_card_used[US122L(card)->chip.index = dev] = 1; US122L(card)->chip.dev = device; @@ -511,57 +509,46 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) US122L(card)->chip.dev->devnum ); snd_card_set_dev(card, &device->dev); - *cardp = card; - return 0; + return card; } -static int us122l_usb_probe(struct usb_interface *intf, - const struct usb_device_id *device_id, - struct snd_card **cardp) +static void *us122l_usb_probe(struct usb_interface *intf, + const struct usb_device_id *device_id) { struct usb_device *device = interface_to_usbdev(intf); - struct snd_card *card; - int err; - - err = usx2y_create_card(device, &card); - if (err < 0) - return err; + struct snd_card *card = usx2y_create_card(device); - if (!us122l_create_card(card)) { - snd_card_free(card); - return -EINVAL; - } + if (!card) + return NULL; - err = snd_card_register(card); - if (err < 0) { + if (!us122l_create_card(card) || + snd_card_register(card) < 0) { snd_card_free(card); - return err; + return NULL; } usb_get_dev(device); - *cardp = card; - return 0; + return card; } static int snd_us122l_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct snd_card *card; - int err; - snd_printdd(KERN_DEBUG"%p:%i\n", intf, intf->cur_altsetting->desc.bInterfaceNumber); if (intf->cur_altsetting->desc.bInterfaceNumber != 1) return 0; - err = us122l_usb_probe(usb_get_intf(intf), id, &card); - if (err < 0) { - usb_put_intf(intf); - return err; + card = us122l_usb_probe(usb_get_intf(intf), id); + + if (card) { + usb_set_intfdata(intf, card); + return 0; } - usb_set_intfdata(intf, card); - return 0; + usb_put_intf(intf); + return -EIO; } static void snd_us122l_disconnect(struct usb_interface *intf) diff --git a/trunk/sound/usb/usx2y/usX2Yhwdep.c b/trunk/sound/usb/usx2y/usX2Yhwdep.c index 4af8740db717..1558a5c4094f 100644 --- a/trunk/sound/usb/usx2y/usX2Yhwdep.c +++ b/trunk/sound/usb/usx2y/usX2Yhwdep.c @@ -30,6 +30,9 @@ #include "usbusx2y.h" #include "usX2Yhwdep.h" +int usX2Y_hwdep_pcm_new(struct snd_card *card); + + static int snd_us428ctls_vm_fault(struct vm_area_struct *area, struct vm_fault *vmf) { @@ -103,6 +106,16 @@ static unsigned int snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, } +static int snd_usX2Y_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + +static int snd_usX2Y_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + return 0; +} + static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw, struct snd_hwdep_dsp_status *info) { @@ -254,6 +267,8 @@ int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device) hw->iface = SNDRV_HWDEP_IFACE_USX2Y; hw->private_data = usX2Y(card); + hw->ops.open = snd_usX2Y_hwdep_open; + hw->ops.release = snd_usX2Y_hwdep_release; hw->ops.dsp_status = snd_usX2Y_hwdep_dsp_status; hw->ops.dsp_load = snd_usX2Y_hwdep_dsp_load; hw->ops.mmap = snd_us428ctls_mmap; diff --git a/trunk/sound/usb/usx2y/usbusx2y.c b/trunk/sound/usb/usx2y/usbusx2y.c index 5ce0da23ee96..11639bd72a51 100644 --- a/trunk/sound/usb/usx2y/usbusx2y.c +++ b/trunk/sound/usb/usx2y/usbusx2y.c @@ -227,9 +227,9 @@ static void i_usX2Y_In04Int(struct urb *urb) if (usX2Y->US04) { if (0 == usX2Y->US04->submitted) - do { + do err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC); - } while (!err && usX2Y->US04->submitted < usX2Y->US04->len); + while (!err && usX2Y->US04->submitted < usX2Y->US04->len); } else if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) { if (us428ctls->p4outLast != us428ctls->p4outSent) { @@ -333,21 +333,18 @@ static struct usb_device_id snd_usX2Y_usb_id_table[] = { { /* terminator */ } }; -static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) +static struct snd_card *usX2Y_create_card(struct usb_device *device) { int dev; struct snd_card * card; - int err; - for (dev = 0; dev < SNDRV_CARDS; ++dev) if (enable[dev] && !snd_usX2Y_card_used[dev]) break; if (dev >= SNDRV_CARDS) - return -ENODEV; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct usX2Ydev), &card); - if (err < 0) - return err; + return NULL; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct usX2Ydev)); + if (!card) + return NULL; snd_usX2Y_card_used[usX2Y(card)->chip.index = dev] = 1; card->private_free = snd_usX2Y_card_private_free; usX2Y(card)->chip.dev = device; @@ -365,36 +362,26 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) usX2Y(card)->chip.dev->bus->busnum, usX2Y(card)->chip.dev->devnum ); snd_card_set_dev(card, &device->dev); - *cardp = card; - return 0; + return card; } -static int usX2Y_usb_probe(struct usb_device *device, - struct usb_interface *intf, - const struct usb_device_id *device_id, - struct snd_card **cardp) +static void *usX2Y_usb_probe(struct usb_device *device, struct usb_interface *intf, const struct usb_device_id *device_id) { int err; struct snd_card * card; - - *cardp = NULL; if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && - le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) - return -EINVAL; - - err = usX2Y_create_card(device, &card); - if (err < 0) - return err; + le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428) || + !(card = usX2Y_create_card(device))) + return NULL; if ((err = usX2Y_hwdep_new(card, device)) < 0 || (err = snd_card_register(card)) < 0) { snd_card_free(card); - return err; + return NULL; } - *cardp = card; - return 0; + return card; } /* @@ -402,14 +389,13 @@ static int usX2Y_usb_probe(struct usb_device *device, */ static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct snd_card *card; - int err; - - err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card); - if (err < 0) - return err; - dev_set_drvdata(&intf->dev, card); - return 0; + void *chip; + chip = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id); + if (chip) { + usb_set_intfdata(intf, chip); + return 0; + } else + return -EIO; } static void snd_usX2Y_disconnect(struct usb_interface *intf) diff --git a/trunk/sound/usb/usx2y/usx2yhwdeppcm.h b/trunk/sound/usb/usx2y/usx2yhwdeppcm.h index 9c4fb84b2aa0..c3382fdc386b 100644 --- a/trunk/sound/usb/usx2y/usx2yhwdeppcm.h +++ b/trunk/sound/usb/usx2y/usx2yhwdeppcm.h @@ -18,5 +18,3 @@ struct snd_usX2Y_hwdep_pcm_shm { volatile unsigned captured_iso_frames; int capture_iso_start; }; - -int usX2Y_hwdep_pcm_new(struct snd_card *card);